Introduction The IP protocol of the TCP/IP suite supports internetworking at Layer 3. IP creates a virtual network that is independent of the underlying Layer 2 technologies. A unicast IPv4 address identifies an interface in that virtual network. In most cases a host will have only one IP interface and therefore we often say that the IPv4 address uniquely identifies a host. IPv4 addresses are 32 bit unsigned binary integers. The IP address space is therefore the range of numbers between 0 and (2**32)-1. There are special addresses and addresses ranges within the overall address range such that not all of the addresses can actually be used for a unicast interface. However, to learn the mathematics of working with unicast IPv4 addresses these special cases can be ignored. IPv4 delivery is hierarchical. Datagrams are delivered first to the correct network and then to the correct host on the network. IPv4 addressing supports this delivery by treating the 32 bit address as two fields: a network part and a host part. When IP addresses were first conceived the first few most significant bits implicitly identified the boundary between the network part and the host part of the 32 address number in a scheme that is now called classful addressing. However, the resulting address allocation was inefficient. The current approach to IPv4 addressing is called Classless InterDomain Routing or CIDR. The boundary between the network and host part of the 32 bit address can be anywhere within the address. The boundary must be explicitly identified with a netmask, a second 32 bit unsigned number with ones in the bits that represent the network and zeroes in the bits that represent the host in the companion IP address. These are contiguous fields with the network bits being the more significant bits and therefore appearing on the left side of the two-field netmask. The notation that describes a netmask with N network bits and 32-N=H host bits is /N. 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 Network part 1 1 0 0 0 0 0 0 0 0 0 0 0 0 Host part Figure 1: A /20 CIDR netmask showing network and host fields Although the IPv4 addresses and netmasks are 32 bit unsigned binary integers they can also be represented in the dotted-decimal format. In dotted decimal the 32 bit numbers are treated as 4 octets of 8 bits each, the octets are converted from binary to decimal, and the decimal values are separated by a dot. Both netmasks and addresses can be expressed in dotted decimal; the /20 netmask in Figure 1 could also be written as 255.255.240.0. A subsequent section shows how to convert between the two notations. Figure 2 illustrates an address in both binary and dotted decimal. 1 0 1 0 1 1 0 0 1st octet = 172 0 0 0 1 0 0 0 0 0 0 2nd octet = 16 0 0 0 1 1 1 1 3rd octet = 7 1 0 0 0 0 1 1 4th octet = 195 Figure 2: The IPv4 address 172.16.7.195 also shown as a 32-bit, unsigned binary number The dotted decimal notation can also be thought of as a “base 256” number of 4 places. Recall that in the decimal number system we talk about the 1’s place, the 10’s place, the 100’s place, and the 1000’s place as the first four “places” in a number. Describing these as powers of 10 the places are the 10**0 place, the 10**1 place, and so on. Similarly, the octets in the dotted decimal value (from right to left) are the 256**0, 256**1, 256**2, and 256**3 places respectively, where 256=2**8. Viewing dotted decimal in this manner allows comparison of the mathematics to the somewhat familiar math of hexadecimal (base 16). Only the network bits are needed to identify the network. Therefore within a given network the network bits are identical on every host and only the host bits change from host to host. Because the host bits are on the right side of the netmask a single network within the internetwork corresponds to a block of contiguous addresses in the address space. These are represented by all of the possible combinations of the host bits. This is called a CIDR block of addresses. There are two addresses in every CIDR block that have special meaning for that block. The smallest address in the block, i.e., the one with all host bits set to zero, is called the network address for that block. The largest address in the block is the directed-broadcast address for that block. Neither of these addresses can be assigned to an interface on a network. Network:111 Directed-broadcast address Network:110 Network:101 Block size Network:100 Assignable (unreserved) addresses Network:011 Network:010 Network:001 Network:000 Figure 3: A /29 CIDR block Network address By itself the netmask determines the size of a CIDR block but not a specific CIDR block of that size. We can imagine that a netmask of /N divides the 2**32 address space into 2**N blocks of size 2**(32-N) hosts. A particular address will fall into only one of the CIDR blocks of that size. However, there are theoretically 32 different values of /N and therefore 32 different partitions of the address space into different block sizes. So a particular address that is the network address for a /N block may or may not be the network address for the /N-1 block that contains it, for example. The same is true for the directed-broadcast address. Thus we cannot memorize an address as being a network address or a directed-broadcast address; we must compute these addresses given a netmask of some size and one of the addresses within a particular CIDR block of that size. We find at least 3 categories of problems that call for these computations: network design, network configuration, and network debugging. In network design problems we may need to create a network that supports some number of current hosts, perhaps a router interface, and some anticipated number of future hosts. How big should we make the CIDR block when requesting addresses for that network? Once the network is in place we may need to configure the hosts to use the directed broadcast address for that network in a simulation application, for example. Or we may need to specify that network in the routing table of a remote router. Finally, in debugging we may simply be told that a host with a particular IP address is having trouble talking to a host with a different IP address. Are these on the same network or different networks? What should the routing table entries be on these hosts and on the intervening routers? These problems call for certain basic conversions. First for a given netmask we must be able to convert between CIDR /N notation and the corresponding dotted-decimal netmask. And we must be able to determine the size of the corresponding block and the number of assignable addresses in that block. For a given netmask and a specific address we must be able to identify the network address and directed-broadcast address for that specific CIDR block. And of course we need to understand these processes well enough to combine them in various ways and to work them in the opposite direction. Understanding the binary details The sum of powers of two Our goal is to develop ways to avoid doing address mathematics the hard way: i.e., by working with the binary address and netmask and then converting to dotted-decimal. Instead, we want to develop shortcuts using mostly the dotted-decimal notation, some knowledge of the powers of two, and the special characteristics of the netmask. We start by looking at the mathematics to see how the shortcuts are developed. If the shortcuts “make sense” mathematically then they are likely to be more easily remembered. One formula is used repeatedly in the following. The series of powers of two starting with 2**0 is a well-known formula. m 2i i 2m 1 1 0 Another useful version for our purposes is the following. Try a few examples to verify the result. k 1 2i i 2k 11 1 2k 1 0 231=27x224 230=26x224 229=25x224 228=24x224 227=23x224 226=22x224 225=21x224 224=20x224=20x28x28x28 223=27x216 222=26x216 221=25x216 220=24x216 219=23x216 218=22x216 217=21x216 216=20x216=20x28x28 215=27x28 214=26x28 213=25x28 212=24x28 211=23x28 210=22x28 29=21x28 28=20x28 27x20=128 26x20=64 25x20=32 24x20=16 23x20=8 22x20=4 21x20=2 20x20=1 The formula above is useful because the netmask is a very structured binary number. If we take the netmask and invert all of the bits, so that the network bits are 0 and the host bits are 1 then we have the following: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 Network part Host part Figure 4: A /20 netmask with the bits inverted If we convert this binary number to decimal we add up the powers of two corresponding to each bit – which is exactly what the formula does for us. So the formula will be useful when working with the netmask. Working with the binary netmask Block size A netmask serves two related purposes in address arithmetic. It fundamentally defines a CIDR block size, but as described above it also partitions the address space into a number of non-overlapping blocks of that size. In other words, a CIDR block of a certain size cannot start at an arbitrary address; it can only start at a multiple of that CIDR block size. Assume we have a netmask of certain length /N. N is the number of network bits and therefore the number of host bits is 32-N=H. The CIDR block by definition includes all of the possible combinations of the host bits – so the CIDR block size B is the number of possible combinations of host bits H. The first bit combination in each block will be 0. The final combination will be the sum of the powers of 2 from 2**0 to 2**(H-1) as illustrated above in Figure 4. The latter value can be evaluated using the second version of the formula: H 1 2i i 2H 1 0 Note from Figure 4 above that this is also the value of the inverted netmask for H host bits! This is almost the total number of combinations – we have to add 1 for the all zero combination. (If you have trouble with this – write out 8 binary numbers starting at 000 and ending with 111). So the total number of combinations of H host bits, the block size B, is B = ((2**H)-1) + 1 or simply B=2**H total combinations. Thus a /N netmask has a block size B=2**(32-N). And the number of assignable address is B-2. The binary representation of the block size for a CIDR block with H host bits will have the bit H set to one and all other bits set to zero. Note in the normal (non-inverted) netmask this is the least significant bit of the network field. This is the mathematical proof that the network address of a block will be a multiple of the block size. And the math above shows that the block size will be the inverted mask + 1. This can be seen in Figure 4 by adding 1 and carrying all the way until a final carry goes from the host field into the network field. Block sizes are illustrated in Figure 5 with small blocks at the bottom of the address space. 231=27x224 230=26x224 224=20x224 223=27x216 216=20x216 215=27x28 29=512=21x28=2x256 28=256=20x28=1x256 27=128 26=64 25=32 24=16 23=8 22=4 21=2 20=1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 16 0.0.0.16 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 15 0.0.0.15 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 14 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 13 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 12 0.0.0.12 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 11 0.0.0.11 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 10 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 9 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 8 0.0.0.8 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 7 0.0.0.7 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 5 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 4 0.0.0.4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 3 0.0.0.3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 /30 /29 /30 /28 /30 /29 /30 0.0.0.0 32 bits Figure 5: CIDR blocks starting on a multiple of the block size Block start The CIDR block size B also determines the possible starting values for blocks of that size. Once we pick a particular address A to go with that block size there will be exactly one block of that size B that contains the address. The first address in that containing block (the network address) must be a multiple of the block size B, so the network address associated with an address A is the smallest multiple of the block size B that is less than or equal to A. For a given netmask and address there are several ways to compute the network address but the most straightforward (for a computer) is to logically AND the two 32 bit values together. This is why the term netmask is used. The host bits of 0 on the right of the netmask when ANDed with the corresponding bits of the address produce a result of 0. The network bits of 1 on the left side of the netmask when ANDed with the corresponding bits of the address merely copy the network bits to the result. In other words the host bits have been masked off leaving only the network bits in the result. Address Address Mask Mask Mask Network Network Broadcast Broadcast 1 0 1 0 1 1 0 0 0 0 0 1 0 0 0 0 172 16 Network 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 255 255 1 0 1 0 1 1 0 0 0 0 0 1 0 0 0 0 172 16 1 0 1 0 1 1 0 0 0 0 0 1 0 0 0 0 172 16 0 0 0 0 0 1 1 1 1 1 0 0 0 0 1 7 195 Host 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 255 224 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 7 192 0 0 0 0 0 1 1 1 1 1 0 1 1 1 1 7 223 1 0 0 1 Figure 6: Binary AND operation with the netmask Once we have the network address for the block containing a particular address A then it is straightforward to find the directed-broadcast address. For a block size with B=2**H we have already determined that the final address in the block is the network address + (2**H) – 1, or the network address + B – 1. Figure 5 above also illustrates another way to do this while in binary – simply set the host bits to 1. Working with dotted-decimal notation Thinking in base 256 If we want to do dotted decimal additional and subtraction we need to think in base 256. When we are adding and we exceed the base then we carry into the next place and keep the remainder in the current place. For dotted decimal base 256 this means addition follows the pattern 0.0.0.255 + 0.0.0.1 = 0.0.0.256 = 0.0.1.0. Similarly subtraction follows a similar borrowing pattern. For example: 0.4.0.0 – 0.0.0.1 = 0.3.256.0 – 0.0.0.1 = 0.3.255.256 – 0.0.0.1 = 0.3.255.255 We can treat the block size as dotted decimal. If we have a block size of 2**12 = 4096 for H=12 then that is equivalent to a block size of (2**4) x (2**8), i.e., a 16 in the third octet, or 0.0.16.0. A block size will always have the form of a power of two in one of the octets with all of the other octets zero. Similarly the inverted mask can be treated as dotted decimal. For the /20 netmask shown in Figure 4 there are 12 host bits, with 4 in the 3rd octet and 8 in the 4th octet. Each series for powers of two helps here – the 3rd octet is (2**4)-1 = 15, and the 4th octet is (2**8)-1=255. So the inverted mask for /20 is 0.0.15.255. And 0.0.15.255 + 0.0.0.1 = 0.0.16.0 verifying the relationship between the block size and the inverted netmask. There is one final observation to make about the dotted-decimal numbers. If all of the bits in the netmask were 1 then it would be the dotted decimal value 255.255.255.255. It should be clear that adding a netmask and its inverted netmask will produce this 255.255.255.255. Therefore, if we can find the inverted netmask we can subtract it from 255.255.255.255 to obtain the dotted decimal value of the netmask. For the /20 example we would have 255.255.255.255 – 0.0.15.255 = 255.255.240.0. Using the various observations above we can look at the actual computations. Converting from a CIDR notation netmask to a dotted-decimal First consider the problem of changing between /N CIDR netmask notation and the dotted-decimal equivalent. As noted above the key is the number of host bits H=32-N. From that we can immediately compute the block size B=2**H and the number of assignable addresses as B-2. We allocate the host bits to the various octets from the right. For example, with /N=/20 we have H=3220=12. We would have 8 host bits in the 4th octet (call that H4=8), 4 host bits in the 3rd octet (H3=4), and 0 host bits in the 1st and 2nd octets (H1= H2=0). Using the series of powers-of-two formula we can then compute the octets of the inverted netmask. Octet one: Octet two: Octet three: Octet four: (2** H1)-1 = (2**0)-1 =0; (2** H2)-1 = (2**0)-1 =0; (2** H3)-1 = (2**4)-1=15; (2** H4)-1 = (2**8)-1=255. The result is 0.0.15.255 and the netmask is therefore 255.255.255.255 – 0.0.15.255 = 255.255.240.0 To compute the mask directly one recognizes that each octet_value=255-((2**Hoctet)-1). That simplifies to 256-(2**Hoctet). So for any octet in the dotted-decimal mask raise 2 to the power of the host bits in that octet and subtract from 256. Returning to our example: with H1= H2=0 we have 256-2**0=255; H3=4 so 256-2**4=240; and H4=8 so 256-2**8=0. Of course one quickly learns to just do the octet where the network:host boundary occurs, but the math above shows that it works in general. Thus the dotted-decimal mask corresponding to /20 is 255.255.240.0. Converting from a dotted-decimal netmask to a CIDR notation Going from the dotted-decimal mask to CIDR is also an octet-by-octet operation initially. For each octet the goal is to find the number of host bits in that octet and then add the four values to obtain the total number of host bits. This value is subtracted from 32 to obtain the /N of the CIDR notation. In each octet we use the formula from the section above but in the other direction: 256 2Hoctet octet _ value 256 octet _ value 2Hoctet log2 256 octet _ value H octet So for our example 255.255.240.0, octet 4 has dotted-decimal netmask value of 0; log2(256-0)= log2256=8. For octets 1 and 2, log2(256-255)= log21=0. And for octet 3, log2(256-240)= log216=4. The total number of host bits is 0+0+4+8=12=H, and therefore N=32-H=20 and this is a /20 netmask. Again, the octet with the network:host boundary is the only interesting octet, but the formula works for all octets. Once H is known the block size and number of assignable addresses are the same computation as before. So this gives us the capability to go between /N notation, the equivalent dotted-decimal netmask, and from either starting point to determine the block size that goes with the netmask. Finding the network address using dotted-decimal notation Recall that the network address will be the largest multiple of the block size that is less than or equal to an address. This comparison can also be done using a dotted-decimal block size. We learned above how to find the block size in dotted decimal given the number of host bits H. The block size converted to dotted decimal only has one octet that is not zero – call that octetblock – because there is only one non-zero bit in the binary representation of the block size. If we were to count by the block size we would go through multiple dotted-decimal network address values with the same values of the octets to the left of octetblock before we actually would increment the octet to the left of octetblock . For example, if the address A is 157.25.34.12 and the block size is 0.0.16.0, then we count 157.25.0.0 to 157.25.240.0 by 0.0.16.0 before we finally get to 157.26.0.0. One of these blocks with network address 157.25.0.0 through 157.25.240.0 must contain the address A – so the network address will always copy the octets in A to the left of octetblock . Any octet to the right of octetblock must be zero in the network address – recall that the single non-zero bit of the block size is the least significant bit of the network field in the netmask. So all bits - and therefore all octets - to the right would be zeroed by the masking operation. What is left is only a comparison in octetblock . We find the largest multiple of octetblock that is less than or equal to that octet’s value in address A. For example, with our /20 we had a block size of 0.0.16.0 in dotted-decimal. If our address A is notionally X.Y.Z.W then we find the smallest value that is 16xJ ≤ Z for some J and write the network address as X.Y.16xJ.0. More specifically, using the numbers in Figure 5, we have an address of 172.16.7.195 and a netmask of 255.255.255.224. Using our techniques above we determine that this is H=5 and /N=27. H=5 means that the block size is 2**5=32 in the 4th octet. Since we started with a dotted decimal netmask we can also observe that this is 256-224 in the 4th octet – using the same mathematics we used when converting from dotted-decimal netmask to CIDR notation. Either way you arrive at the answer the block size is 0.0.0.32 in dotted-decimal. We have 3 more-significant octets that we simply copy to the network address. In the 4th octet we find the smallest multiple of 32 that is less than or equal to 195. 192=32x6 and 224=32x7 is too large, so the 4th octet is 192. Thus the network address is 172.16.7.192. Finding the directed-broadcast address using dotted-decimal notation As noted earlier, we find the directed-broadcast address by first finding the network address, and then adding the block size – 1; i.e., the inverse netmask. In other words, subtract one from the block size in dotted decimal to obtain the inverse netmask in dotted decimal, and then add it to the network address. Using similar arguments as above the computation of the inverse netmask will reduce to subtracting 1 in the non-zero octet of the block size and making all less-significant octets (if any) equal to 255. (See the dotted decimal subtraction example in a preceding section) The resulting value can then be easily added to the network address because the octets (if any) of the inverse mask that are 255 will add to network address octets that are 0. And the addition in the remaining octet will not result in a carry. Examples 143.25.18.35/28: There are 28 network bits so there are 32-28=4 host bits. That means a block size of 2**4=16. The number of assignable addresses is 16-2=14. All the host bits are in the 4th octet so that is the only octet of significant interest. 16 from 256 = 240, so that is the netmask 4th octet, and the others will be 255. (0 host bits, 2**0=1, 256-1=255). So the netmask is also written as 255.255.255.240. Similarly the block size converted to dotted decimal is 0.0.0.16 and the 1 subtracted from that is 0.0.0.15. The largest multiple of 16 less than or equal to the value 35 in the 4th octet is 32. The higher octets are simply copied to the network address, which is 143.25.18.32. Adding 0.0.0.15 to 143.25.18.32 gives 143.25.18.47, the directed-broadcast address for the network where the original address is located. 147.15.26.12/19: There are 19 network bits so there are 32-19=13 host bits. That means a block size of 2**13=8192. The number of assignable addresses is 8192-2=8190. There are 8 host bits in the 4th octet and 5 host bits in the 3rd octet so that is the octet of interest. 2**5 is 32, 256-32=224 so that is the 3rd octet value. The 1st and 2nd will be 255, the 4th octet will be 0. So the netmask is also written as 255.255.224.0. Similarly the block size converted to dotted decimal is 0.0.32.0 and the 1 subtracted from that is 0.0.31.255. The largest multiple of 32 less than or equal to the value 26 in the 3rd octet is 0. The higher octets are simply copied to the network address, the lower octet is set to 0, and the network address is therefore 147.15.0.0. Adding 0.0.31.255 to 147.15.0.0 gives 147.15.31.255, the directed-broadcast address for the network where the original address is located. 147.37.21.46 255.252.0.0: The 2nd octet is the interesting octet here. In the second octet we have 256-252=4, which is 2**2 so there are 2 host bits in the 2nd octet, 8 in the 3rd, and 8 in the 4th. This is a total of 18 host bits. The block size is 2**18 and the number of assignable addresses is (2**18)-2. Note that we are unlikely to see something this big as an address allocation – it is more likely to be a routing table CIDR block or used for access control. The number of network bits is 32-18 = 14 so this is also a /14 netmask. The block size in dotted decimal is 0.4.0.0 and subtracting 1 gives 0.3.255.255. The largest multiple of 4 that is less than or equal to the value 37 in the 2nd octet is 36. Copy the first octet, set the second octet to 36, set the 3rd and 4th octet to 0 for the network address of 147.36.0.0. Add 0.3.255.255 to 147.36.0.0 to obtain the directed broadcast address for this network = 147.39.255.255. 215.211.156.56 255.255.255.0: We might recognize this immediately as a /24 network, but let’s do the math. In the 4th octet, 2560=256, 2**8=256, so there are 8 host bits in the 4th octet. In the other octets, 256-255=1, 2**0=1 so there are 0 host bits in the other octets. That is a total of 8 host bits, so the CIDR mask is 32-8 = /24. The block size is 2**8=256, and there are 256-2=254 non-reserved addresses than can be assigned. Converting the block size to dotted decimal is interesting at an octet boundary. There are 8 host bits, so bit 8 is the bit that is one in the binary representation of the block size. That is not in the 4th octet, however, but rather is the 0th bit of the 3rd octet, so the dotted decimal for the block size is 0.0.1.0. To find the inverted netmask we use 0.0.1.0 – 1 which is 0.0.0.255. Another way to think of this is that with 8 host bits in the 4th octet this is a block size of 0.0.0.256. But that implies a carry to become 0.0.1.0. Given this dotted-decimal block size of 1 in the 3rd octet we find the largest value of 1 that is less than or equal to 156 and that of course is 156 itself. So we copy the higher octets to the network address, put 156 in the 3rd octet, and put 0 in the lower octets. The result is a network address of 215.211.156.0. To find the directed-broadcast address add the 0.0.0.255 to the 215.211.156.0 to obtain 215.211.156.255. Conclusion Many texts try to teach IPv4 address arithmetic – but in many cases these approaches shy away from the mathematical background. The result is often many seemingly un-related rules depending on the size of the mask. This document shows a mathematical orientation to the problem. It captures the same rules but in a consistent manner. But there is no single best way to do this. Ultimately everyone must find the technique that works best in their mind and arrive at the correct answers.