Reputation: 26117
I have an IPv6 Address with a CIDR prefix. Ex: 2001:0:3238:DFE1:0063::FEFB/32
I am looking to write a function such that IPv6 address is converted to match the number of bits in the CIDR prefix provided. This means, if a prefix of 32 is provided, the IP address should have 32 bits in it starting from left and the rest should be zeroes. In the above example, the desired output should be:
2001:0000:0000:0000:0000:0000:0000:0000/32
I do have other functions in place to shortcut the desired IP like this 2001::/32
The CIDR prefix can range from 0-128.
This is what I have this so far, based on this Post here, but I am not sure if it's giving the desired output. Can someone look at it and help? Am I thinking straight about CIDR representation here?
public function getCIDRMatchedIP( $ipAddress )
{
// Split in address and prefix length
list($firstaddrstr, $prefixlen) = explode('/', $ipAddress);
// Parse the address into a binary string
$firstaddrbin = inet_pton($firstaddrstr);
// Convert the binary string to a string with hexadecimal characters
# unpack() can be replaced with bin2hex()
# unpack() is used for symmetry with pack() below
$firstaddrhex = reset(unpack('H*', $firstaddrbin));
// Overwriting first address string to make sure notation is optimal
$firstaddrstr = inet_ntop($firstaddrbin);
$cidrMatchedString = $firstaddrstr.'/'.$prefixlen;
echo $cidrMatchedString;
}
Upvotes: 1
Views: 832
Reputation: 2204
Here :
function getCIDRMatchedIP($ip)
{
if (strpos($ip, "::") !== false) {
$parts = explode(":", $ip);
$cnt = 0;
// Count number of parts with a number in it
for ($i = 0; $i < count($parts); $i++) {
if (is_numeric("0x" . $parts[$i]))
$cnt++;
}
// This is how many 0000 blocks is needed
$needed = 8 - $cnt;
$ip = str_replace("::", str_repeat(":0000", $needed), $ip);
}
list($ip, $prefix_len) = explode('/', $ip);
$parts = explode(":", $ip);
// This is the start bit mask
$bstring = str_repeat("1", $prefix_len) . str_repeat("0", 128 - $prefix_len);
$mins = str_split($bstring, 16);
$start = array();
for ($i = 0; $i < 8; $i++) {
$min = base_convert($mins[$i], 2, 16);
$start[] = sprintf("%04s", dechex(hexdec($parts[$i]) & hexdec($min)));
}
$start = implode(':', $start);
return $start . '/' . $prefix_len;
}
And the you call the function getCIDRMatchedIP
:
echo getCIDRMatchedIP('2001:0:3238:DFE1:0063::FEFB/32');
Upvotes: 1