netMatch ipv6 version 6 ip addresses
A PHP based netMatch function updated to match ipv6 (version 6 and 4) ip addresses to multiple mixed networks.
Supports all network representations that satisfy php’s inet_pton(), which includes ipv6 condensed ‘::1′ and alternative ”fe80:0:0:0:0:0:192.168.1.64’ addresses.
# netmatch6 cobbled 2/16, Classless inter-domain routing (CIDR)
# inspired by various at php.net/manual/en/function.ip2long.php, stephane at deluca dot biz 2006
# Supports ipv4 and ipv6 Condensed and Alternative ( ip portion of cidr nust pass php's inet_pton() ):
# $CIDRs[] = "fe80::c0a8:140/124";
# $CIDRs = array( '::1/128', '127.0.0.1/32', '192.168.1.64/28', 'fe80:0:0000:0:0:0:c0a8:140/124', 'fe80:0:0:0:0:0:192.168.1.64/124');
# relies on functions: filter_var, custom ip2bin, and inet_pton
# returns bool true or string
#
function netMatch6 ( $CIDRs = array(), $ip = '::1' ) {
$ip_is_in_the_net = false;
$msg = "";
# ip4
if( false !== $ip_f = filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ) {
$mask_min = 0; $mask_max = 32;
}
# ip6
elseif( false !== $ip_f = filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) {
$mask_min = 12; $mask_max = 128; # Cisco CCNA: Network Basics, Ch 7, Lab D, 2013
}
else return "Apparently $ip is NOT a valid v4 nor v6 address"; // die( $ip );
$ip_bin_str = ip2bin( $ip_f );
foreach ($CIDRs as $cidr)
{
list( $net, $mask ) = explode( '/', $cidr );
if( false === $net_f = filter_var( $net, FILTER_VALIDATE_IP ) ) return "Invalid \$net $net"; // die( var_dump( $net ) );
# gotta let the next one fail silent in case a subsequent net matches
if( false === $mask_f = filter_var( $mask, FILTER_VALIDATE_INT, array( "options" => array( "min_range"=>$mask_min, "max_range"=>$mask_max ) ) ) ) $msg .= "Bitmask $mask is outside the range $mask_min to $mask_max | ";
$net_bin_str = ip2bin( $net_f );
//die( "$ip_bin_str = \$ip_bin_str <br /> $net_bin_str = \$net_bin_str <br /> & \$mask = $mask on line ".__LINE__ );
if( 0 == strncmp( $net_bin_str, $ip_bin_str, $mask_f ) ) return $ip_is_in_the_net = true;
}
return $msg; # could not find a CIDR network that includes the ip address passed in
} # end netMatch
# return string representation of an ip(4|6) address converted to a binary number
# inspired by anjo2 2006 php.net/manual/en/function.ip2long.php#104163
# relies on inet_pton()
#
function ip2bin ( $ip )
{
# filter user provided ips if you haven't already
$ipbin = "";
if( ( $ip_n = inet_pton( $ip ) ) === false ) return false; // die( strlen( $ip_n )." on line ".__LINE__ );
$bytes = strlen( $ip_n ) - 1; # going to retrieve from the zero ordinal
while ($bytes >= 0)
{
$bin = sprintf( "%08b", ord( $ip_n[ $bytes ] ) );
$ipbin = $bin.$ipbin;
$bytes--;
}
return $ipbin;
} # end ip2bin