Check if an IP address is private

Ok this is 7 years old post. But I thought I can share my solution, so that maybe someone somewhere somehow might find it helpful.

My solution is based on the builtin PHP filter_var() function. Which means I do not have to pre-define all the private ranges or the reserved ones every single time I need to validate a given value. Or loop through the ranges. Instead I let PHP worries about it for me.

class IP
{
    static public function is_ip($ip=NULL) : bool
    {
        return filter_var(
            $ip,
            FILTER_VALIDATE_IP,
            FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6
        ) === $ip ? TRUE : FALSE;
    }

    static public function is_ipv4($ip=NULL) : bool
    {
        return filter_var(
            $ip,
            FILTER_VALIDATE_IP,
            FILTER_FLAG_IPV4
        ) === $ip ? TRUE : FALSE;
    }

    static public function is_ipv6($ip=NULL) : bool
    {
        return filter_var(
            $ip,
            FILTER_VALIDATE_IP,
            FILTER_FLAG_IPV6
        ) === $ip ? TRUE : FALSE;
    }

    static public function is_public_ip($ip=NULL) : bool
    {
        return filter_var(
            $ip,
            FILTER_VALIDATE_IP,
            FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE
        ) === $ip ? TRUE : FALSE;
    }

    static public function is_public_ipv4($ip=NULL) : bool
    {
        return filter_var(
            $ip,
            FILTER_VALIDATE_IP,
            FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE
        ) === $ip ? TRUE : FALSE;
    }

    static public function is_public_ipv6($ip=NULL) : bool
    {
        return filter_var(
            $ip,
            FILTER_VALIDATE_IP,
            FILTER_FLAG_IPV6 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE
        ) === $ip ? TRUE : FALSE;
    }

    static public function is_private_ip($ip=NULL) : bool
    {
        return self::is_ip($ip) && !self::is_public_ip($ip);
    }

    static public function is_private_ipv4($ip=NULL) : bool
    {
        return self::is_ipv4($ip) && !self::is_public_ipv4($ip);
    }

    static public function is_private_ipv6($ip=NULL) : bool
    {
        return self::is_ipv6($ip) && !self::is_public_ipv6($ip);
    }
}

It allows you to validate the given value in general whether or not it is an IP. or be more specific about it. you can validate the following types:

  • IP
  • IPv4
  • IPv6
  • public IP
  • public IPv4
  • public IPv6
  • private IP
  • private IPv4
  • private IPv6

let's test it:

$arr = array(
    '127.0.0.0', '127.0.0.1', '127.1.2.3', '127.1.2.255',

    '192.168.0.0', '192.168.0.1', '192.168.2.3', '192.168.2.255',

    '172.16.0.0', '172.16.0.1', '172.16.2.3', '172.16.2.255',
    '172.19.0.0', '172.19.0.1', '172.19.2.3', '172.19.2.255',

    '10.0.0.0', '10.0.0.1', '10.0.2.3', '10.0.2.255',
    '10.5.0.0', '10.5.0.1', '10.5.2.3', '10.5.2.255',

    '8.8.8.8', '8.8.4.4', '255.255.255',

    '182.168.1.300', '256.1.2.3', '0.500.0.0',
    'I am not an IP', NULL, '185.128.72.151'
);

foreach ($arr as $item) {
    echo "$item --> " . (IP::is_private_ip($item) === TRUE ? 'is private' : 'is NOT private or NOT an IP') . PHP_EOL;
}

I think this should solve the problem.

filter_var used with the following validation rules will return false if the IP address is a private one.

$user_ip = '127.0.0.1';
filter_var(
    $user_ip, 
    FILTER_VALIDATE_IP, 
    FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE |  FILTER_FLAG_NO_RES_RANGE
)

Check the links above for the php documentation


function ip_is_private ($ip) {
    $pri_addrs = array (
                      '10.0.0.0|10.255.255.255', // single class A network
                      '172.16.0.0|172.31.255.255', // 16 contiguous class B network
                      '192.168.0.0|192.168.255.255', // 256 contiguous class C network
                      '169.254.0.0|169.254.255.255', // Link-local address also refered to as Automatic Private IP Addressing
                      '127.0.0.0|127.255.255.255' // localhost
                     );

    $long_ip = ip2long ($ip);
    if ($long_ip != -1) {

        foreach ($pri_addrs AS $pri_addr) {
            list ($start, $end) = explode('|', $pri_addr);

             // IF IS PRIVATE
             if ($long_ip >= ip2long ($start) && $long_ip <= ip2long ($end)) {
                 return true;
             }
        }
    }

    return false;
}

See http://mebsd.com/coding-snipits/check-private-ip-function-php.html

You might also want to check out about the private address spaces here

Tags:

Php

Ip

Private