by Russ White, Cisco Systems
IP addresses, both IPv4 and IPv6, appear to be complicated when you first encounter them, but in reality they are simple constructions, and a using a few basic rules will allow you to find the important information for any situation very quickly—and with minimal math. In this article, we review some of the basics of IPv4 address layout, and then consider a technique to make working with IPv4 addresses easier. Although this is not the “conventional” method you might have been taught to work with in IP address space, you will find it is very easy and fast. We conclude with a discussion of applying those techniques to the IPv6 address space.
IPv4 addresses are essentially 32-bit binary numbers; computer systems and routers do not see any sorts of divisions within the IPv4 address space. To make IPv4 addresses more human-readable, however, we break them up into four sections divided by dots, or periods, commonly called “octets.” An octet is a set of eight binary digits, sometimes also called a “byte.” We do not use byte here, because the real definition of a byte can vary from computer to computer, whereas an octet remains the same length in all situations. Figure 1 illustrates the IPv4 address structure.
Because each octet represents a binary (base 2) number between 0 and 28, each octet will be between 0 and 255. This part of IPv4 addresses is simple—but what about subnet masks? To understand a subnet mask, we need to understand how a device actually uses subnet masks to determine where to send a specific packet, as Figure 2 illustrates.
If host A, which has the local IP address 10.1.1.2 with a subnet mask of 255.255.255.0, wants to send a packet to 10.1.3.2, how does it know whether D is connected to the same network (broadcast domain) or not? If D is connected to the same network, then A should look for D’s local Layer 2 address to transmit the packet to. If D is not connected to the same network, then A needs to send any packets destined to D to A’s local default gateway.
To discover whether D is connected or not, A takes its local address and performs a logical AND between this and the subnet mask. A then takes the destination (remote) address and performs the same logical AND (using its local subnet mask). If the two resulting numbers, called the network address or prefix, match, then the destination must be on the local segment, and A can simply look up the destination in the Address Resolution Protocol (ARP) cache, and send the packet locally. If the two numbers do not match, then A needs to send the packet to its default gateway.
Note: ARP is a protocol used to discover the mappings between the IP addresses of devices attached to the same network as the local device and the Layer 2 address of devices attached to the same network as the local device. Essentially, a device sends an ARP broadcast containing the IP address of some other device it believes to be connected, and the device with the specified IP address replies with its Layer 2 address, providing a mapping between these two addresses.
If a subnet mask is a “dotted decimal” version of the binary subnet mask, then what is the prefix length? The prefix length is just a shorthand way of expressing the subnet mask. The prefix length is the number of bits set in the subnet mask; for instance, if the subnet mask is 255.255.255.0, there are 24 1’s in the binary version of the subnet mask, so the prefix length is 24 bits. Figure 3 illustrates network masks and prefix lengths.
Working with IPv4 Addresses
Now that we understand how an IPv4 address is formed and what the subnet length and prefix length are, how do we work with them? The most basic questions we face when working with an IP address follow:
There are two ways to find the answers to these questions: the hard way and the easy way. We cover the hard way first, and then show you the easy way.
The Hard Way
The hard way to determine the prefix and host addresses is to convert the address into binary, perform logical AND and NOR operations on the address and the subnet mask, and then convert the resulting numbers back to decimal. Figure 4 illustrates the process of converting a single octet of the IPv4 address into binary; the number converted in this case is 192.
The process is simple, but tedious; divide the octet value by 2, take the remainder off, and then divide by 2 again, until you reach 0. The remainders, reversed in direction, are the binary numbers representing the value of the octet. Performing this process for all four octets, we have the binary IP address, and can use logical AND and NOR operations to find the prefix (network address) and the host address, as Figure 5 shows for the address 192.168.100.80/26.
The Easy Way
All this conversion from binary to decimal and from decimal to binary is tedious— is there an easier way? Yes. First, we start with the observation that we work only with the numbers within one octet at a time, no matter what the prefix length is. We can assume all the octets before this working octet are part of the network address, and octets after this working octet are part of the host address.
The first thing we need to do, then, is to find out which octet is our working octet. This task is actually quite simple: just divide the prefix length by 8, discard the remainder, and add 1. The following table provides some examples.
Note: Another way to look at this task is that you will ignore the octets indicated by the division. For instance, for 192.168.100.80/26, the result of dividing 26 by 8 is 3, so you will ignore the first three octets of the IP address, and work only with the fourth octet. This process has the same result.
When we know the working octet, what do we do with it? Well, we could simply use the procedure outlined, convert the single octet to binary, perform AND and NOR operations on it with the right bits from the subnet mask, and then put it all back together to find the network and host addresses—but there is an easier way to find the network and host parts of the working octet. Start by doing the same math, only this time we want to work with the remainder rather than the result.
Take the remainder, and use the following table to find the corresponding jump within the octet; this number is the distance, in decimal form, between the network addresses within the octet.
In this chart, the first column represents the prefix length within this octet, the second column represents the prefix value when this bit is set to 1, the number of hosts in the subnet for this prefix length, and the jump between network addresses with the specified prefix length.
The number 2 corresponds to 64, so the jump is 64—there is a network at 0, 64, 128, 192, and 224 in this octet. Now all we need to do is figure out which one of those networks this address is in. This task is fairly simple: just take the largest network number that fits into the number in the working octet. In this case, the largest number that fits into 80 is 64, so our network address is 192.168.100.64/26.
Now, what about the host address? That is easy when we have the network address—just subtract the network address from the IP address, and you have the host address within the network: 80 – 64 = 16. This process takes a little practice, but it is not hard when you become accustomed to the steps.
In the second and third examples, you see that the working octet is actually the third, rather than the fourth, octet. To find the host address in these examples, you simply find the host address in the third octet, and then “tack on” the fourth octet as part of the host address as well, because part of the third octet—and all of the fourth octet—are actually part of the host address.
Summarization and Subnets
Subnets and supernets are probably the hardest part of IP addressing for most people to understand and handle quickly, but they are both based on a very simple concept—aggregation. Figure 6 shows how aggregation works.
The figure shows four hosts with the addresses 10.1.0.1, 10.1.0.2, 10.1.0.3, and 10.1.0.4. Router A advertises 10.1.1.0/24, meaning: “Any host within the address range 10.1.0.0 through 10.1.0.255 is reachable through me.” Note that not all the hosts within this range exist, and that is okay—if a host within that range of addresses is reachable, it is reachable through Router A. In IP, the address that A is advertising is called a network address, and you can conveniently think of it as an address for the wire the hosts and router are attached to, rather than a specific device.
For many people, the confusing part comes next. Router B is also advertising 10.1.1.0/24, which is another network address. Router C can combine—or aggregate—these two advertisements into a single advertisement. Although we have just removed the correspondence between the wire and the network address, we have not changed the fundamental meaning of the advertisement itself. In other words, Router C is saying: “Any host within the range of addresses from 10.1.0.0 through 10.1.1.255 is reachable through me.” There is no wire with this address space, but devices beyond Router C do not know this, so it does not matter.
To better handle aggregated address space, we define two new terms, subnets and supernets. A subnet is a network that is contained entirely within another network; a supernet is a network that entirely contains another network. For instance, 10.1.0.0/24 and 10.1.1.0/24 are both subnets of 10.1.0.0/23, whereas 10.1.0.0/23 is a supernet of 10.1.0.0/24 and 10.1.1.0/24.
Now we consider a binary representation of these three addresses, and try to make more sense out of the concept of aggregation from an addressing perspective; Figure 7 illustrates.
By looking at the binary form of 10.1.0.0/24 and 10.1.1.0/24, we can see that only the 24th bit in the network address changes. If we change the prefix length to 23, we have effectively “masked out” this single bit, making the 10.1.0.0/23 address cover the same address range as the 10.1.0.0/24 and 10.1.1.0/24 addresses combined.
The Hardest Subnetting Problem
The hardest subnetting problem most people face is that of trying to decide what the smallest subnet is that will provide a given number of hosts on a specific segment, and yet not waste any address space. The way this sort of problem is normally phrased is something like the following:
This appears to be a very difficult problem to solve, but the chart we used previously to find the jump within a single octet actually makes this task quite easy. First, we run through the steps, and then we solve the example problem to see how it actually works.
This process seems pretty simple, but does it work? Let’s try it with our example.
It is a simple matter of iterating from the largest to the smallest block, and using the simple chart we used before to determine how large of a jump we need to cover the host addresses we need to fit onto the subnet. Figure 8 illustrates the resulting hierarchy of subnets.
In this illustration:
Working with IPv6 Addresses
IPv6 addresses appear to be much more difficult to work with—but they really are not. Although they are larger, they are still made up of the same fundamental components, and hosts and routers still use the addresses the same way. All we really need to do is realize that each pair of hexadecimal numbers in the IPv6 address is actually an octet of binary address space. The chart, the mechanisms used to find the network and host addresses, and the concepts of super and subnets remain the same.
For example, suppose we have the IPv6 address 2002:FF10:9876: DD0A:9090:4896:AC56:0E01/63 and we want to know what the network number is (host numbers are less useful in IPv6 networks, because they are often the MAC address of the system itself).
The numbers are longer, but the principle is the same, as long as you remember that every pair of digits in the IPv6 address is a single octet.
IP addresses appear to be very complex on first approach, but their inbuilt structure actually provides easy ways to divide the problems into pieces and approach one piece of the problem at a time—the same way we design and build networks on a large scale. If you learn to use some simple techniques and understand how IP addresses are structured, they are relatively easy to work with.