Random Post: Hey, That's A Catchy Tune...
RSS .92| RSS 2.0| ATOM 0.3
  • Home
  • About
  • Bill’s Discography
  • Bill’s Links
  • Email
  • Subscribe To billgrady.com
  •  

    IP Matching With CIDR Notation In PHP

    May 21st, 2009

    Sometimes you can’t find an answer, no matter how hard you Google. I consider myself luck to have found this answer!

    The Problem: You have a list of IP ranges in CIDR notation. You need to take visiting IPs and evaluate if they are within this list of allowed addresses. And, you need to do it in PHP.

    The Answer: Load your CIDR list into an array and evaluate each visiting IP with the following function (found here)…

    function ipfilter($ip) {
        $source = array("10.0.0.0/8",
            "192.168.1.1/32",
            "127.0.0.0/8");
        foreach ($source as $line) {
        
    
            // Get the base and the bits from the CIDR
            list($base, $bits) = explode('/', $line);
           
            // Now split it up into it's classes
            list($a, $b, $c, $d) = explode('.', $base);
           
            // Now do some bit shifting/switching to convert to ints
            $i    = ($a << 24) + ($b << 16) + ( $c << 8 ) + $d;
            $mask = $bits == 0 ? 0: (~0 << (32 - $bits));
           
            // Here's our lowest int
            $low = $i & $mask;
           
            // Here's our highest int
            $high = $i | (~$mask & 0xFFFFFFFF);
           
            // Now split the ip we're checking against up into classes
            list($a, $b, $c, $d) = explode('.', $ip);
           
            // Now convert the ip we're checking against to an int
            $check = ($a << 24) + ($b << 16) + ( $c << 8 ) + $d;
           
            // If the ip is within the range, including highest/lowest values,
            // then it's witin the CIDR range
            if ($check >= $low && $check <= $high) {
                return 1;
            }
        }
        return 0;

    }

    Is it efficient? I don’t know. Does it work? Yes it does. And thats more than I can say about other solutions to this problem that I found (here and elsewhere).