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?
is four sets of .- Therefore, the biggest IPv4 address is
. is half the size a SQL long int. This causes no hurdles for the database.
Converting an IPv4 address to a decimal number.
- Let's convert
into a decimal number. - First, we will split the IP address into 4 parts by '.' resulting in
. denotes our resulting decimal representation of the IP address.
How big is IPv6?
is eight sets of .- Therefore, the biggest IPv6 address is
. A very large number. - This is twice the size as a SQL long int. Uh oh.
Converting an IPv6 address to a decimal number.
- Let's convert
into a decimal number. - First, we will split the IP address into 8 parts by ':' resulting in
. denotes our resulting decimal representation of the IP address.
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?
- We want to store
as a key in SQL denotes the upper 64 bits and denotes the bottom 64 bits.
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,
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.