diff options
-rw-r--r-- | it.class | 18 | ||||
-rwxr-xr-x | tests/it.t | 10 |
2 files changed, 28 insertions, 0 deletions
@@ -315,6 +315,24 @@ static function toascii($text) /** + * Check whether an IP adress lies within a given range. Supports IPv4 and IPv6 + * @param $ip IP address (192.168.42.123) + * @param $cidr IP range in CIDR notation (192.168.42.64/26) + * @return true if $ip is within $cidr + */ +function cidr_match($ip, $cidr) +{ + list($subnet, $mask) = explode('/', $cidr); + $ip_bin = inet_pton($ip); + $subnet_bin = inet_pton($subnet); + $valid_bytes = $mask >> 3; + $bitmask = 256 - (1 << (8 - ($mask & 7))); + $lastbyte_matched = $bitmask ? (ord($ip_bin{$valid_bytes}) & $bitmask) == (ord($subnet_bin{$valid_bytes}) & $bitmask) : true; + return substr($ip_bin, 0, $valid_bytes) == substr($subnet_bin, 0, $valid_bytes) && $lastbyte_matched; +} + + +/** * Convert regex for preg (adds and escapes delimiter, adds modifiers) * @param $pattern Regex to convert * @param $p['casesensitive'] Regex is case sensitive (omit modifier i) @@ -315,6 +315,16 @@ is(it::grep('match', array('foo' => 'match', 'bar' => 'gna')), array('foo' => 'm setlocale(LC_CTYPE, $oldlocale); ini_set('default_charset', $oldcharset); # end of tests that must run with specific charset +# it::cidr_match tests +is(it::cidr_match('192.168.2.3', '192.168.2.5/32'), false, "cidr_match full IP no match"); +is(it::cidr_match('192.168.2.5', '192.168.2.5/32'), true, "cidr_match full IP match"); +is(it::cidr_match('192.168.1.1', '192.168.42.0/24'), false, "cidr_match no match"); +is(it::cidr_match('192.168.42.1', '192.168.42.0/24'), true, "cidr_match basic match"); +is(it::cidr_match('192.168.42.42', '192.168.0.0/16'), true, "cidr_match class b"); +is(it::cidr_match('192.168.42.42', '192.168.42.64/26'), false, "cidr_match offset no match"); +is(it::cidr_match('192.168.42.42', '192.168.42.32/27'), true, "cidr_match offset"); +is(it::cidr_match('2001:918:ff83:101:798e:77c0:b722:fe56', '2001:918:ff83:101::/64'), true, "cidr_match ipv6"); +is(it::cidr_match('2001:918:ff83:102:798e:77c0:b722:fe56', '2001:918:ff83:101::/64'), false, "cidr_match ipv6 no match" ); # it::filter_keys tests |