## Introduction

We are in the transition phase from IPv4 to IPv6 addressing structure, and I believe that the network engineers should easily plan their IPv6 addressing /subnetting infrastructure without any error. In this article, I tried to explain how IPv6 subnetting works by giving examples. I also wrote and distributed a free IPv6 Subnetting Tool / Calculator using Java JDK 1.7.0.17, and it is based on Swing Application Framework. It enables you to plan/subnet your assigned address with all 128bits of an IPv6 address. You can find the application in the second part of this article. I distributed the application in the hope that it will be useful for your subnet calculations. I will try to develop the software continuously, so please don't hesitate to comment/inform for any bugs or new feature suggestions.

## 1. How Does '/' (slash or prefix-length notation) Work with IPv6?

The '/' indicates the bits which are fixed for your subnetwork. Fixed means that you do not have any control on these bits, you must not change them (I like to call them "**don't touch only watch bits**"). IPv6 is 128 bits long and your network/organization is assigned "128 minus /prefix-lengthValue" and these are the bits given under your control. You can do your subnetting with these bits and assign addresses to your computer/car/mobile/etc.

For example, assume that the prefix '2001:db8:1234::/48' is assigned to your network by your service provider (or by RIPE, ARIN, etc). In this case, /48 indicates that starting from the left-most bit up to and including the 48th bit, these bits are fixed and must not be changed (don't touch only watch). And the rest of the bits which have the length of 128-48=80bits are given to your control.

So, the importance of '/' prefix-length comes from the point that it indicates the boundary of your network. In other words, from which number your assigned network starts and at which number it ends.

## 2. Finding IPv6 Start and End Addresses of our Subnet

If we have for example 192.168.3.0/24 subnet prefix, then 24 bits are fixed. You must not change these bits. And our netmask will be 255.255.255.0, we can do subnetting by using 32-24=8bits by taking care of subnet and broadcast addresses, as we all know very well with our IPv4 experience.

### 2.1 Three useful Bitwise Operators: & , | , ~

& (AND), | (OR), ~ (NOT or bit INVERTER): We will use these three bitwise operators in our calculations. I think everybody is familiar -at least from university digital logic courses- and knows how they operate. I will not explain the details here again. You can search for 'bitwise operators' for further information.

Now with our IPv6 subnet-prefix assigned, how can we find our subnets and starting and end addresses of it? We can easily calculate them with the help of these three logic operators as follows. I will try to demonstrate on both IPv4 and IPv6.

#### With IPv4

What is our mask if we have '/24'? Remember CIDR notation, it is simply 255.255.255.0 which is 24 bits all '**set**' or '**all one**' starting from the left-most bit up to and including 24^{th} bit.

Finding Start Address is to '`AND`

' the address with your mask which is:

`(192.168.3.5) & (255.255.255.0) = 192.168.3.0 `

This is our Starting Address, or as we call Network address.

Finding End Address is to '`OR`

' the address with your inverted (`NOT`

) mask which is:

`(192.168.3.5) | ~(255.255.255.0) = 192.168.3.255 `

This is our End Address, or as we call Broadcast address.

#### With IPv6

What is our mask if we have '/48'? Simply it is **ffff:ffff:ffff::** for which all 48 bits are '**set**' or '**all one**' starting from the left-most bits up to and including 48^{th} bit. As you can see, the evaluation way of the mask is exactly the same as in IPv4. As for our IPv6 subnet prefix '2001:db8:1234::/48', again the same calculation method applies. It is also useful to remember that we always use 'hexadecimal' instead of decimal numbers for addressing since IPv6 is completely based on hexadecimal numbers. So,

Finding Start Address is to '`AND`

' the address with your mask which is:

`(2001:db8:1234::) & (ffff:ffff:ffff::) = 2001:db8:1234::`

(you can also try for other addresses, e.g. (2001:db8:1234:abcd::ef ) & ( ffff:ffff:ffff:: ) = 2001:db8:1234:: again same result.)

Finding End Address is to '`OR`

' the address with your inverted (`NOT`

) mask which is:

`(2001:db8:1234::) | ~(ffff:ffff:ffff::) = 2001:db8:1234:ffff:ffff:ffff:ffff:ffff`

As a result, for the subnet-prefix '2001:db8:1234::/48' we have the range or interval of our subnet:

```
IPv6 subnet Start Address> 2001:db8:1234:0:0:0:0:0 (or compressing zeros 2001:db8:1234::)
IPv6 subnet End Address> 2001:db8:1234:ffff:ffff:ffff:ffff:ffff
```

Also remember that we don't have broadcast mechanism in IPv6, so we don't have broadcast address.

## 3. How Can We Do Subnetting With Our IPv6 Subnet-prefix?

As we know, our first prefix-length indicates our fixed bits and we can borrow bits starting from (but excluding) prefix-length value towards the right-most bit (from left to right).

#### Example

Let's use the subnet-prefix '**2001:db8:1234::/48**', and **borrow 2 bits** for subnetting.

The beauty of number conversion shows itself when we do hexadecimal to binary conversion. When converting from hex-to-binary or vice versa, you can simply and directly convert each hex-digit into binary form without caring about the digit weights. In hexadecimal notation, each hex-digit corresponds to **4 bits**, usually called as '**nibble**'. Our example address in expanded form and with nibbles are:

```
2 0 0 1 : 0 d b 8 : 1 2 3 4 : 0 0 ...(all the rest zeros)
0010 0000 0000 0001 : 0000 1101 1011 1000 : 0001 0010 0011 0100 : 0000 0000 ... (all the rest zeros)
```

Let's borrow 2 bits starting with /49 up to /50 (we include 50.bit) :

0010 0000 0000 0001 : 0000 1101 1011 1000 : 0001 0010 0011 0100 : ** 00**00 ... (all the rest zeros)

By borrowing 2 bits, we can have 2^{2}= 4 unique subnets, which are:

`0010 0000 0000 0001 : 0000 1101 1011 1000 : 0001 0010 0011 0100 : `*00*00 ... (allthe rest zeros)

`0010 0000 0000 0001 : 0000 1101 1011 1000 : 0001 0010 0011 0100 : `*01*00 ... (all the rest zeros)

`0010 0000 0000 0001 : 0000 1101 1011 1000 : 0001 0010 0011 0100 : `*10*00 ... (all the rest zeros)

`0010 0000 0000 0001 : 0000 1101 1011 1000 : 0001 0010 0011 0100 : `*11*00 ... (all the rest zeros)

Let's convert these numbers back into hexadecimal and see the result:

`2001:db8:1234:`**0**000::/50 (First subnet)

`2001:db8:1234:`**4**000::/50 (Second subnet)

`2001:db8:1234:`**8**000::/50 (Third subnet)

`2001:db8:1234:`**c**000::/50 (Fourth subnet)

If you are a service provider, you can assign these subnet-prefixes to your customers one by one with '/50' prefix-length, e.g. 2001:db8:1234:0000::/50 for one customer, and 2001:db8:1234:4000:/50 for other, etc.

And now your customers should know the End of their assigned address space. At this point, remember finding Start and End addresses of our subnet and perform the calculations.

First of all, your customers will have mask of '/50' which is all 50 bits 'set' or all 50 bits are 'ones' giving us the mask of '**ffff:ffff:ffff:c000::**'. Now using this mask, we can easily calculate the start-end addresses, i.e., the range or interval of our subnet. Let's do it one by one.

```
1st. Customer subnet Start address=
(2001:db8:1234:0000::) & (ffff:ffff:ffff:c000::) = 2001:db8:1234:
```**0**000:0:0:0:0 = 2001:db8:1234::
1st. Customer subnet End address=
(2001:db8:1234:0000::) |~(ffff:ffff:ffff:c000::) = 2001:db8:1234:**3**fff:ffff:ffff:ffff:ffff
2nd. Customer subnet Start address=
(2001:db8:1234:4000::) & (ffff:ffff:ffff:c000::) = 2001:db8:1234:**4**000:0:0:0:0 = 2001:db8:1234:4000::
2nd. Customer subnet End address=
(2001:db8:1234:4000::) |~(ffff:ffff:ffff:c000::) = 2001:db8:1234:**7**fff:ffff:ffff:ffff:ffff
3rd. Customer subnet Start address=
(2001:db8:1234:8000::) & (ffff:ffff:ffff:c000::) = 2001:db8:1234:**8**000:0:0:0:0 = 2001:db8:1234:8000::
3rd. Customer subnet End address=
(2001:db8:1234:8000::) |~(ffff:ffff:ffff:c000::) = 2001:db8:1234:**b**fff:ffff:ffff:ffff:ffff
4th. Customer subnet Start address=
(2001:db8:1234:c000::) & (ffff:ffff:ffff:c000::) = 2001:db8:1234:**c**000:0:0:0:0= 2001:db8:1234:c000::
4th. Customer subnet End address=
(2001:db8:1234:c000::) |~(ffff:ffff:ffff:c000::) = 2001:db8:1234:**f**fff:ffff:ffff:ffff:ffff

Notice that each of the subnet-prefixes can also be used again to perform subnetting. For example, the 4^{th} customer may use the subnet-prefix '2001:db8:1234:d000::/50' to do subnetting by borrowing bits again say from /50 to /54, according to their needs of course.

## Summary

In order to find the starting and end address of your subnet, you only need to know IPv6 address and prefix-length value. Remember these bitwise operations (which are also valid for IPv4):

```
(IPv6 Address) & (/prefix-length mask) is equal to (IPv6 subnet Start address)
(IPv6 Address) | ~(/prefix-length mask) is equal to (IPv6 subnet End address)
```

**(Follow the link for the second part of this article: Subnetting with IPv6 Part 2/2[^] )**

## History

- 28 September 2013, v1.0
- 26 January 2014, v1.1 : A few typing corrections