MW. MW. - 5 months ago 21
PHP Question

Matching IPv6 address to a CIDR subnet

Is there a good way to match an IPv6 address to an IPv6 subnet using CIDR notation?
What I am looking for is the IPv6 equivalent to this:
matching an IP to a CIDR mask in php5?

The example given above can't be used since an IPv6 address is 128 bits long, preventing the bitwise left-shift from working properly. Can you think of any other way?

EDIT: Added my own solution to the list of answers.


Since you cannot convert IPv6 addresses to integer, you should operate bits, like this:


// converts inet_pton output to string with bits
function inet_to_bits($inet) 
   $unpacked = unpack('A16', $inet);
   $unpacked = str_split($unpacked[1]);
   $binaryip = '';
   foreach ($unpacked as $char) {
             $binaryip .= str_pad(decbin(ord($char)), 8, '0', STR_PAD_LEFT);
   return $binaryip;

$ip = inet_pton($ip);


$net_bits   =substr($binarynet,0,$maskbits);

if($ip_net_bits!==$net_bits) echo 'Not in subnet';
else echo 'In subnet';

Also, if you use some database to store IPs, it may already have all the functions to compare them. For example, Postgres has an inet type and can determine, whether IP is contained within subnet like this:

   '21DA:00D3:0000:2F3B:02AC:00FF:FE28:9C5A'::inet << 

9.11. Network Address Functions and Operators in PostgreSQL