Last updated: 7 October 2021

Most IPv6 addresses are /64 addresses. However, that is not set in stone. If you need to create one or more IPv6 subnets, the basics are the same as subnetting in IPv4. The main difference is that IPv6 addresses use hexadecimal digits. To understand IPv6 subnetting you need to understand base-16 numbers.

Finding the network prefix

In most cases finding the network portion of an IPv6 address is straight forward. An IPv6 address is made up of eight hextets, and each hextet has four hexadecimal digits. So, as long as the prefix can be divided by four it easy enough to find the network. You simply count bits.

For instance, in a /64 address the first four hextets make up the network:

2001:0DB8:85A3:08D3:1319:8A2E:0370:7348/64

Each hextet has 16 bits, so the first four hextets are the network and the remaining 64 bits can be used for hosts.

The same goes for a /56 address. To get to 56 you take the first three hextets (3 * 16 = 48) and the first two digits in the fourth hextet:

2001:0DB8:85A3:08D3:1319:8A2E:0370:7348/64

You can switch all the host bits to zero and write the address like so:

2001:0DB8:85A3:0800:0000:0000:0000:0000/56

Counting bits in a hexadecimal digit

But what do you do if you have, say, a /58 prefix? 58 isn’t a multiple of four, so you can’t simply count bits.

To find the prefix you first take the digits that are a multiple of four. In this case that takes you to 56. Next, you look at how many bits you need from the next digit. For this example we need the first two bits, as 56 + 2 equals 58. If that sounds confusing, remember that each digit in an IPv6 address has four bits. So, to get from 56 to 58 you need the first two bits of the next digit.

The next digit in the address is a D. To get the first two digits you need to convert the hexadecimal D to binary. A hexadecimal D is 1101 in binary. If that doesn’t make sense, my article about base-16 numbers explains how to convert base-16 to and from base-2.

We now got the four bits that make up the hexadecimal D. We are only interested in the first two bits, which is 11. The last two bits are not part of the network and can be set to 0. So, that gives us 1100.

And finally, you need to convert the binary 1100 to a hexadecimal. That gives you a C, and so the network address is 2001:0DB8:85A3:08C0:0000:0000:0000:0000/58.

IPv6 ranges

Let’s do one more example. In my introduction to IPv6 addresses I mentioned that the global unicast address uses the 2000::/3 prefix. A /3 address uses only the first three bits of the first digit:

  • The number 2 in binary is 0010.
  • You need the first three bits and anything after that is always 0. The fourth digit is already a zero, so the value is still 0010.
  • Next, you convert 0010 to hexadecimal. That gives you 2.

A hextet uses 16 bits, so in base-2 the first hextet is 0010 0000 0000 0000. It is worth noting that you can now easily get the IP range (that is, the first and last IP address). The first IP address is 001 followed by all zeros, and the last IP address is 001 followed by all ones:

0010 0000 0000 0000 | First IP
0011 1111 1111 1111 | Last IP

You can simply look up what the base-2 values are in base-16. We already know the first hextet – it is 2000:

0010 0000 0000 0000 | Base-2
2    0    0    0    | Base-16

And the range ends with 0011 1111 1111 1111, which translates to 3FFF:

0011 1111 1111 1111 | Base-2
3    F    F    F    | Base-16

So, global unicast addresses are in the range 2000::/3 to 3FFF::/3. Most IPv6 addresses that start with a 2 or a 3 are therefore global unicast addresses. There are some exceptions though. For instance, for this article I used an address that start with 2001:0DB8. Those addresses are reserved for documentation and education, in the same way that the domain example.com is reserved for educational purposes.