CodePlexProject Hosting for Open Source Software

In this article I tried to explain how IPv6 subnetting works by giving examples. I also wrote and distributed an IPv6 Subnet Calculator / Tool application using Visual C# 2013 Express based on .NET 4 Framework.

It lets you plan/subnet your assigned address for all 128 bits. You can download the application from downloads tab above. I distributed the application in the hope that it will be useful for your subnet calculations.

I will be continuously developing the software, so please don't hesitate to comment/inform for any bugs or new feature suggestions.

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 is that it indicates the boundary of your network. In other words, from which number your assigned network starts and at which number it ends.

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.

What is our mask if we have '/24'? Remember CIDR notation, it is simply 255.255.255.0 which is 24 bits all '

Finding Start Address is to 'AND' your address with your mask which is:

(192.168.3.5)

Finding End Address is to 'OR' your address with the inverted (NOT) mask which is:

(192.168.3.5)

What is our mask if we have '/48'? Simply it is ffff:ffff:ffff:: for which all 48 bits are '

Finding Start Address is to 'AND' the address with your mask which is:

( 2001:db8:1234:: )

Finding End Address is to 'OR' the address with your inverted (NOT) mask which is:

(2001:db8:1234:: )

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

IPv6 Starting Address of subnet > 2001:db8:1234:0:0:0:0:0 (or compressing zeros 2001:db8:1234:: )

IPv6 End Address of subnet > 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.

Example:

Let's use the subnet-prefix '

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

And in 4-bit binary form (or with nibbles) it is;

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 :

By borrowing 2 bits, we can have 2

- 0010 0000 0000 0001 : 0000 1101 1011 1000 : 0001 0010 0011 0100 :
00 0000 ... (all the rest zeros)__00__ - 0010 0000 0000 0001 : 0000 1101 1011 1000 : 0001 0010 0011 0100 :
00 0000 ... (all the rest zeros)__01__ - 0010 0000 0000 0001 : 0000 1101 1011 1000 : 0001 0010 0011 0100 :
00 0000 ... (all the rest zeros)__10__ - 0010 0000 0000 0001 : 0000 1101 1011 1000 : 0001 0010 0011 0100 :
00 0000 ... (all the rest zeros)__11__

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 '

1st. Customer subnet Start address=

(2001:db8:1234:

1st. Customer subnet End address=

(2001:db8:1234:

2nd. Customer subnet Start address=

(2001:db8:1234:

2nd. Customer subnet End address=

(2001:db8:1234:

3rd. Customer subnet Start address=

(2001:db8:1234:

3rd. Customer subnet End address=

(2001:db8:1234:

and

4th. Customer subnet Start address=

(2001:db8:1234:

4th. Customer subnet End address=

(2001:db8:1234:

Notice that each of the subnet-prefixes can also be used again to perform subnetting. For example 4th 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.

(IPv6 Address)

(IPv6 Address)

For this purpose the function

If the entered value is a valid IPv6 address, then we need to formalize the entered address into 16 Bytes hexadecimal value in order to perform our calculations on it. The function

These two functions might also be combined in a general library and be converted to a DLL to validate and formalize an IPv6 address but I did not do it here. Instead I wrote them in a separate class, for the sake of keeping the functions of the application simple and visible.

As I try to explain in the 'Subnetting with IPv6 Part 1/2' above article, it is easy and obvious to find the subnet start and end addresses of a given address by using the /prefix-length value. The function

Another issue is how to find the neighboring or adjacent subnet addresses, i.e. subnets that comes just after our subnet? In other words, how can we move or walk through the adjacent subnet address spaces?

Very easy and simple way of achieving this is to get the end address, and increment by one which gives the start address of the adjacent subnet address. By using this start address, find the end address, then increment by one which will give the second adjacent subnet address, and so on. As you notice we are now able to move or walk through the subnet address spaces with this algorithm.

An iterative procedure to obtain the adjacent subnet addresses might be:

The start address of the next subnet obtained.

An example code might be:

public SEaddress StartEndAddresses(SEaddress input) { UInt64 mask = Convert.ToUInt64("FFFFFFFFFFFFFFFF", 16); mask = (mask >> (input.slash)); input.End = (input.Resultv6 | mask); mask = ~mask; input.Start = (input.Resultv6 & mask); return input; }

public class SEaddress { public UInt64 Resultv6 = UInt64.MinValue; public UInt64 Start = UInt64.MinValue; public UInt64 End = UInt64.MinValue; public int slash = 0; public int subnetslash = 0; public UInt64 subnetidx = UInt64.MinValue; }

For the subnetting, we borrow the bits by using the second slider or track bar. Despite we can easily find our subnets, now another question is what is the index number of our subnet and how can we find the index number of it? i.e. is it 4th subnet, or 5th, or 6th, or which?

The answer is

Actually, using the second slider, i.e. borrowing the bits, we are creating the subnet index numbers, too. The interval between the two sliders has our subnet index number. For example, if we drag the first slider to /48 and the second slider to /52, it means that we borrow 4-bits and created 2

A solution might be that we can copy the bits in this interval by means of testing the bits and then setting it into our index variable. For testing the bit we can perform the bitwise operation

The code might be like:

input.subnetidx = UInt64.MinValue; int delta = input.subnetslash - input.slash - 1; for (int i = (63 - input.slash); i > (63 - input.subnetslash); i--) { if ( BitTest(input.Start, i) == 1) { input.subnetidx = BitSet(input.subnetidx, delta); } else { input.subnetidx = BitClear(input.subnetidx, delta); } delta--; }

public int BitTest(UInt64 ui64, int i) { /* if ith bit is set, returns 1, * if ith bit not set, returns 0, * if i>63 or i<0 returns -1 */ if (i > 63 || i < 0 ) return -1; if ((ui64 & ((UInt64)1 << i)) != 0) return 1; else return 0; }

public UInt64 BitSet(UInt64 ui64, int i) { if (i > 63 || i < 0) return UInt64.MinValue; ui64 = (ui64 | ((UInt64)1 << i)); return ui64; }

public UInt64 BitClear(UInt64 ui64, int i) { if (i > 63 || i < 0) return UInt64.MinValue; ui64 = (ui64 & ~((UInt64)1 << i)); return ui64; }

Up to this point, we know how to find the subnet start/end addresses and subnet indexes. What is left is to produce these values in a simple for loop with an 'upto' limit value and display the result.

for (int count = 0; count < upto; count++) { subnets = Subnetting(subnets); //Display the Results //... subnets.Start = subnets.End + 1; }

Last edited Feb 4 at 7:48 PM by ygvn, version 22