DANNY FRITZ()

User Manual

Generated on
2026-01-18

MySQL and IPv6

Published on

I work on DNS Management software for Purdue's network security department called Roster. It is a very fun and interesting project to work on. I'm constantly finding myself way over my head on features I am implementing. Making it a learning experience in the process.

My current issue once again requires me to read up on key issues. I will be indexing and keying ipv6 from a MySQL database.

Easy you say, just insert the IP in the database and be done with it! But wait! This works just fine for IPv4 because an IPv4 address as a decimal is only 32 bits. Soon, you will find it doesn't work so easily for the 128bit IPv6 counterpart.

Get ready for a doozy of a post.

We're going to be using our fun friend, bit ops. Now, don't be confusing that with sarcasm, I actually do love bit ops. But beware, we will be doing maths very soon! And we will be using the << and & binary operations, the magical mathematical functions computer science majors like to keep to themselves.

How big is IPv4?

Converting an IPv4 address to a decimal number.

How big is IPv6?

Converting an IPv6 address to a decimal number.

Oh no, so it can not be done! IPv6 is simply far too large to insert into a 64bit int space! But wait, maybe we can split it into two 64bit integers for upper and lower and use that! And that would be the answer:

How do you split an IPv6 into 2 64bit ints?

Now comes the fun part: CIDR Blocks. However, CIDR blocks isn't so bad of a guy.

The reason for keying the database by IP address is that we can do selections on blocks of IP addresses quickly. Currently, the process is to dump the entire database into a python data structure and then to exhaustively check if each IP exists or not.

This works, but when you are asking for larger subnets, it starts becoming incredibly taxing and takes a long time. A class C subnet, 255.255.255.0, includes 256 IP addresses. A class B subnet, 255.255.0.0, includes 2552=65026 IP addresses. And a class A subnet, 255.0.0.0, includes 2553=16581376 IP addresses. Not to mention the possibility to try and grab a CIDR block of the subnet 0.0.0.0 and checking for 2554=4228250626 IP addresses by literally checking each one. This is not a good solution. And I'll just throw it out there that an IPv6 class A subnet FFFF:0:0:0:0:0:0:0 is about 2x10149 IP addresses. Not something you want to exhaustively check for.

With the database keyed by IP address, you just insert the lower IP address and the upper IP address and the database will do what it does best and return the according range of IP addresses. Simple.