Skip to content

May 21, 2009

2

IP Matching With CIDR Notation In PHP

Sometimes you can’t find an answer, no matter how hard you Google. I consider myself lucky 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).

Read more from News
2 Comments Post a comment
  1. Feb 23 2010

    I wish I could claim it as my own, but the code and comments are both from the zend site. I posted this only to make it easier for people to find the solution. Glad it helped!

  2. Feb 23 2010

    Thanks for the excellent function, Bill! I also tried some functions from http://www.php.net; some of them I could tell wouldn’t always work, and some seemed like the would until I tested them. I guess when all else fails you just need to go back to the basics of converting bitmasks and IP addresses. I appreciate the commented code! You will find this code in Tera-WURFL 2.1.1 (TeraWurflWebservice.php) once I release it!

Share your thoughts, post a comment.

(required)
(required)

Note: HTML is allowed. Your email address will never be published.

Subscribe to comments

%d bloggers like this: