Linkdump

Dead-simple Netmask/Netblock/CIDR Matching Code

Sunday 12 July 2009 at 3:59 pm

So 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.

$cidr = ’198.6.5.0/27’; $checkip = ’198.6.5.22’; list($startIp, $netmask) = split(’\/’, $cidr); if (ip2long($startip) <= ip2long($checkip) and ip2long($checkip) <= (ip2long($startip) + pow(2,32-$netmask))) { echo “Yes!\n”; } else { echo “No!\n”; }

And to validate that the first part of the CIDR block is valid:

if ((ip2long($startip)%pow(2,32-$netmask)) != 0) { echo “Invalid Netblock notation.\n”; } else { echo “Netblock notation good!\n”; }

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:

function netMatch ($CIDR,$IP) { list ($net, $mask) = explode (’/’, $CIDR); return ( ip2long ($IP) & ~((1 << (32 – $mask)) – 1) ) == ip2long ($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.

 

About

This is the archive page for The Beckman Chronicles. Click to go to the frontpage of this site.

Archives

01 Jan - 31 Jan 2003
01 Feb - 28 Feb 2003
01 Mar - 31 Mar 2003
01 Apr - 30 Apr 2003
01 May - 31 May 2003
01 Jun - 30 Jun 2003
01 Jul - 31 Jul 2003
01 Aug - 31 Aug 2003
01 Sep - 30 Sep 2003
01 Oct - 31 Oct 2003
01 Feb - 29 Feb 2004
01 Jul - 31 Jul 2004
01 Aug - 31 Aug 2004
01 Oct - 31 Oct 2004
01 Mar - 31 Mar 2005
01 Apr - 30 Apr 2005
01 May - 31 May 2005
01 Jun - 30 Jun 2005
01 Jan - 31 Jan 2006
01 Jun - 30 Jun 2006
01 Dec - 31 Dec 2006
01 Feb - 28 Feb 2007
01 Apr - 30 Apr 2007
01 Sep - 30 Sep 2007
01 Mar - 31 Mar 2008
01 May - 31 May 2008
01 Jun - 30 Jun 2008
01 Apr - 30 Apr 2009
01 Jul - 31 Jul 2009
01 Aug - 31 Aug 2009

Last Comments

russ (PurpleCow.com has…): I hear this is where Prin…
matt (My first day with…): I have a Microsoft Natura…
russ (My first day with…): For almost the last 15 ye…
Lennie (OSX, ssh, FreeBSD…): Just plain luck I guess, …
beckman (OSX, ssh, FreeBSD…): @Luis: glad it helped! I…
Luis (OSX, ssh, FreeBSD…): Hey Beckman, this is like…
beckman (Save the Environm…): @michael: sure, you’ll lo…
michael (Save the Environm…): Swiss Cheese? What about …
russ (Save the Environm…): But if I’m going to eat 9…
jon livesey (SimpleShare NAS d…): Great hint. Some Freebs…

Links

Purplecow.com
The Internet License Plate Database
Tossable Digits - Cheap, Anonymous, Disposable Phone Numbers
Love & Onions (Jen, my wife)
Roadie Speaks Blog
BananaForce
AdCritic.com
Slashdot
I Love Ben Brown

Search!

Stuff

Powered by Pivot - 1.40.5: 'Dreadwind'
XML: RSS Feed
XML: Atom Feed