javiertoledos of Creative Science Labs
11/9/2015 - 7:24 PM

IP filtering using ranges in PHP

IP filtering using ranges in PHP

function ipv6_bin_string($ip) {
    $binNum = '';
    foreach (unpack('C*', inet_pton($ip)) as $byte) {
        $binNum .= str_pad(decbin($byte), 8, "0", STR_PAD_LEFT);
    }
    return $binNum;
}

function ip_filter ($IP, $ipv4_networks = array(), $ipv6_networks = array() ){
    $result = false;
    if (filter_var($IP, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
        $ip_ip = ip2long ($IP);
        foreach ($ipv4_networks as $cidr) {
            list ($net, $mask) = explode ("/", $cidr);
            $ip_net = ip2long ($net);
            $ip_mask = ~((1 << (32 - $mask)) - 1);

            $ip_ip_net = $ip_ip & $ip_mask;

            $result = ($ip_ip_net == $ip_net);
            if ($result) break;
        }
    } elseif(filter_var($IP, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
        $ip_bin = ipv6_bin_string($IP);

        foreach ($ipv6_networks as $net_range) {
            list ($net, $mask) = explode ("/", $net_range);
            $ip_net = ipv6_bin_string($net);
            $result = (substr($ip_net,0,intval($mask)) == substr($ip_bin,0,intval($mask)));
            if ($result) break;
        }
    }
    return $result;
}