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 PH
I created my own solution, using the following code:
function iPv6MaskToByteArray($subnetMask) {
$addr = str_repeat("f", $subnetMask / 4);
switch ($subnetMask % 4) {
case 0:
break;
case 1:
$addr .= "8";
break;
case 2:
$addr .= "c";
break;
case 3:
$addr .= "e";
break;
}
$addr = str_pad($addr, 32, '0');
$addr = pack("H*" , $addr);
return $addr;
}
function iPv6CidrMatch($address, $subnetAddress, $subnetMask) {
$binMask = iPv6MaskToByteArray($subnetMask);
return ($address & $binMask) == $subnetAddress;
}
Note that $address and $subnetAddress were obtained by running the string address through inet_pton. Call the function as follows:
$subnet = inet_pton("2001:06b8::");
$mask = 32;
$addr = inet_pton("2001:06b8:0000:0000:0000:0000:1428:07ab");
$match = iPv6CidrMatch($addr, $subnet, $mask); // TRUE