function IpUtils::checkIp6
Compares two IPv6 addresses. In case a subnet is given, it checks if it contains the request IP.
@author David Soria Parra <dsp at php dot net>
Parameters
string $ip IPv6 address or subnet in CIDR notation:
Throws
\RuntimeException When IPV6 support is not enabled
See also
https://github.com/dsp/v6tools
File
-
vendor/
symfony/ http-foundation/ IpUtils.php, line 120
Class
- IpUtils
- Http utility functions.
Namespace
Symfony\Component\HttpFoundationCode
public static function checkIp6(string $requestIp, string $ip) : bool {
$cacheKey = $requestIp . '-' . $ip . '-v6';
if (null !== ($cacheValue = self::getCacheResult($cacheKey))) {
return $cacheValue;
}
if (!(\extension_loaded('sockets') && \defined('AF_INET6') || @inet_pton('::1'))) {
throw new \RuntimeException('Unable to check Ipv6. Check that PHP was not compiled with option "disable-ipv6".');
}
// Check to see if we were given a IP4 $requestIp or $ip by mistake
if (!filter_var($requestIp, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) {
return self::setCacheResult($cacheKey, false);
}
if (str_contains($ip, '/')) {
[
$address,
$netmask,
] = explode('/', $ip, 2);
if (!filter_var($address, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) {
return self::setCacheResult($cacheKey, false);
}
if ('0' === $netmask) {
return (bool) unpack('n*', @inet_pton($address));
}
if ($netmask < 1 || $netmask > 128) {
return self::setCacheResult($cacheKey, false);
}
}
else {
if (!filter_var($ip, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) {
return self::setCacheResult($cacheKey, false);
}
$address = $ip;
$netmask = 128;
}
$bytesAddr = unpack('n*', @inet_pton($address));
$bytesTest = unpack('n*', @inet_pton($requestIp));
if (!$bytesAddr || !$bytesTest) {
return self::setCacheResult($cacheKey, false);
}
for ($i = 1, $ceil = ceil($netmask / 16); $i <= $ceil; ++$i) {
$left = $netmask - 16 * ($i - 1);
$left = $left <= 16 ? $left : 16;
$mask = ~(0xffff >> $left) & 0xffff;
if (($bytesAddr[$i] & $mask) != ($bytesTest[$i] & $mask)) {
return self::setCacheResult($cacheKey, false);
}
}
return self::setCacheResult($cacheKey, true);
}