|
@@ -121,6 +121,16 @@ class RequestMatcher implements RequestMatcherInterface
|
|
|
}
|
|
|
|
|
|
protected function checkIp($ip)
|
|
|
+ {
|
|
|
+ // IPv6 address
|
|
|
+ if (false !== strpos($ip, ':')) {
|
|
|
+ return $this->checkIp6($ip);
|
|
|
+ } else {
|
|
|
+ return $this->checkIp4($ip);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ protected function checkIp4($ip)
|
|
|
{
|
|
|
if (false !== strpos($this->ip, '/')) {
|
|
|
list($address, $netmask) = explode('/', $this->ip);
|
|
@@ -135,4 +145,27 @@ class RequestMatcher implements RequestMatcherInterface
|
|
|
|
|
|
return 0 === substr_compare(sprintf('%032b', ip2long($ip)), sprintf('%032b', ip2long($address)), 0, $netmask);
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @author David Soria Parra <dsp at php dot net>
|
|
|
+ * @see https://github.com/dsp/v6tools
|
|
|
+ */
|
|
|
+ protected function checkIp6($ip)
|
|
|
+ {
|
|
|
+ list($address, $netmask) = explode('/', $this->ip);
|
|
|
+
|
|
|
+ $bytes_addr = unpack("n*", inet_pton($address));
|
|
|
+ $bytes_test = unpack("n*", inet_pton($ip));
|
|
|
+
|
|
|
+ for ($i = 1; $i <= ceil($netmask / 16); $i++) {
|
|
|
+ $left = $netmask - 16 * ($i-1);
|
|
|
+ $left = ($left <= 16) ?: 16;
|
|
|
+ $mask = ~(0xffff >> $left) & 0xffff;
|
|
|
+ if (($bytes_addr[$i] & $mask) != ($bytes_test[$i] & $mask)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
}
|