Dead-simple Netmask/Netblock/CIDR Matching Code
Sunday 12 July 2009 at 3:59 pmSo I’m writing up some code to check if an IP address is within a given netblock given a CIDR notation. If you don’t know what CIDR notation is, move along.
I’m writing in PHP, but this code can be applied to any language. At the end of the day, IP addresses are all simply big numbers written out into a notation that helps us remember them. Most of us can’t remember a number between 0 and 4,294,967,295, but for some reason remembering 198.6.1.1 is easier.
So if you own 198.6.0.0/16, you own the IP addresses between 198.6.0.0 and 198.6.255.255, or 3322281984 to 3322347519. Now, how do you figure out if 198.6.5.22 is in that group, programatically? OK, this example is kind of easy, but what about 198.6.5.0/27? Is .22 in that netblock or not? It is. How do you tell your code that?
Instead of using some bloody library that uses regular expressions and some bizarre foreach loops, you could do this.
And to validate that the first part of the CIDR block is valid:
I thought I was being all smart and whatnot, finding libraries of 100 lines of code to do what I figured out how to do in 2 or 3 lines of code. Then I found this little beauty in the comments on php.net:
Hurrah for bitwise operators! $matchThisIp AND NOT 1 shifted (32 – $mask) -1 == $net. WTF? I’m sure it works, I’m sure it makes sense, and it sure is a lot shorter than my version. But bitwise math just boggles my mind. I’d like to leave that to the Assembly crowd. So now you have TWO ways, bitwise and, well, mine, to check to see if a provide CIDR block is valid, and if an IP Address is within a CIDR block using only a few lines of code. I’m sure this could easily be ported to PHP, Python, Ruby, Perl, .NET, Cocoa… I’ll leave that trivial task up to you.