[HttpFoundation] IPv6 support for RequestMatcher

This commit is contained in:
Igor Wiedler 2011-04-22 17:37:22 +02:00
parent 5a80c2ff17
commit 9ae5023a70
2 changed files with 35 additions and 0 deletions

View File

@ -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;
}
}

View File

@ -35,6 +35,8 @@ class RequestMatcherTest extends \PHPUnit_Framework_TestCase
array(true, '192.168.1.1', '192.168.1.1/1'),
array(true, '192.168.1.1', '192.168.1.0/24'),
array(false, '192.168.1.1', '1.2.3.4/1'),
array(true, '2a01:198:603:0:396e:4789:8e99:890f', '2a01:198:603:0::/65'),
array(false, '2a00:198:603:0:396e:4789:8e99:890f', '2a01:198:603:0::/65'),
);
}