Introducing IPv6 | Understanding IPv6 Addresses
IPv6 is becoming a hotter and hotter topic as more and more folks realize its necessity. I know this for several reasons, not the least of which is an ever increasing flow of requests for solid IPv6 information. In trying to find a way to fill this gap, without dedicating all of my off-hours time, I am pursuing multiple avenues. This 4-part series Introducing IPv6 is one of them.
The content I’ll be posting here is adapted from the first chapter of my first book; Day One: Exploring IPv6. This series will provide a quick, vender-agnostic look at the IPv6 protocol, from address length to packet format, and more in between. With it, I hope to provide you with a solid foundation for you to build your IPv6 configuration and operation knowledge on top of. So why don’t you dive right in to part 1:
Understanding IPv6 Addresses
One of the first things you notice when digging into IPv6 is that the addresses look quite different than IPv4 addresses.
The primary difference between IPv4 and IPv6 addresses is length. IPv4 addresses are 32 bits long and IPv6 addresses are 128 bits long. This means that an IPv4 address is made up of 32 1s and 0s while an IPv6 address is made up of 128 of them – 128 binary digits. This massive length forces IPv6 addresses to be written using a different notation than IPv4 addresses and thus makes them very easy to distinguish from IPv4 addresses.
This length and new notation can also make them not so easy to understand though. Here’s a 128-bit IPv6 address in binary notation, the way that they are written inside of IPv6 packets:
If you were to use the dotted-decimal notation that is familiar to us in IPv4 (e.g. 192.0.2.1), you would need to break this 128-bit address into 16, 8-bit sections and the resulting address would look something like this: 220.127.116.11.0.0.0.0.0.0.0.0.0.0.0.1. That is a little unwieldy to say the least!
Instead, flip that on it’s head and break the address into 8, 16-bit sections as illustrated here:
0010000000000001 0000110110111000 0000000000000000 0000000000000000 0000000000000000 0000000000000000 0000000000000000 0000000000000001
It’s still unwieldy, so since hexadecimal (HEX) notation symbolizes 4 bits in each digit, it is used to compress the address into a more human-readable format. The example below uses the second 16-bits (2nd block) of the IPv6 address above, and shows the binary to hexadecimal conversion.
0000110110111000 --> 0000 1101 1011 1000 --> 0 d b 8
A 128-bit IPv6 address uses a maximum of 48 digits when written in decimal notation but only 32 digits or less are needed when hex notation is used.
Once converted to hex, each 16-bit segment is delimited by colons (:), this is of course different from IPv4 addresses which use periods (.) to delimit each 8-bit segment when written in decimal format.
When an IPv6 address is written in hex notation, you have the flexibility to shorten the address considerably by reducing the number of zeros displayed. This can be accomplished in two ways:
- Zero Suppression: Because it is known that all 8 segments consist of 16 bits it is possible to remove leading zeros from each section without making the address ambiguous. For example – 0db8 can be written as db8. You (and your routers) know that only leading zeros (not zeros in the middle or end of a segment) can be suppressed and that there must be 4 hex digits in each segment. You can therefore conclude that db8 is the same as 0db8.
- Zero Compression: Similarly, because it is known that each address must be made up of 8 segments, it is possible to compress multiple contiguous segments of all zeros without confusing the address, as long as it is only done once within a single address. When compressing segments a double colon (::) is used. For example, if we were to see 2001:0db8::3f6c, we would know that the :: represents 5 contiguous segments of all zeros, since the address must contain 8 segments in total.
This idea of zero suppression is really not all that foreign; in IPv4 the same method is used. You don’t write 192.000.002.001, but rather 192.0.2.1 – all of the leading zeros are suppressed.
The next example shows our IPv6 address both directly converted to hex and also after all possible zero suppression and compression. You can see how much easier the address is to read after removing the unneeded zeros:
2001:0db8:0000:0000:0000:0000:0000:0001 --> 2001:db8::1
Much like IPv4 with CIDR (Classless Inter-Domain Routing), one of the great advantages of IPv6 addressing is its hierarchical structure. IPv6 addresses can be broken into prefixes of varying length and these subnet prefixes are represented with the same ip-address/prefix-length notation used for IPv4 CIDR prefixes. In the case of IPv6:
- ip-address is an IPv6 address in any of the hex notations listed above.
- prefix-length is a decimal value specifying the number of the leftmost bits in the address that make up the prefix.
For example, assuming that the IPv6 address used above is part of a 64-bit prefix, it could be represented in the following ways:
The prefix itself is represented as 2001:db8::/64. And yes, the double colon is required.
I really hope you found this information useful! Now you can dig into the various types of IPv6 addresses in Part 2: Classifying IPv6 Addresses (Hint: There’s more than just Multicast and Unicast). Plus you can always go read the whole book!