function ip_in_network6($ip, $net_addr, $net_mask = false) { if (!$net_mask && strpos($net_addr, "/") !== false) { $cidr_arr = explode("/", $net_addr); $net_addr = $cidr_arr[0]; $net_mask = $cidr_arr[1]; } $ip = inet6_expand($ip); $net_addr = inet6_expand($net_addr); $net_mask_hex = inet6_expand(inet6_prefix_to_mask($net_mask)); $ip_dec_arr = inet6_to_int64($ip); $net_dec_arr = inet6_to_int64($net_addr); $mask_dec_arr = inet6_to_int64($net_mask_hex); // Need to handle >64 bit net masks if ($net_mask > 64) { $net_mask_64_arr[0] = 64; $net_mask_64_arr[1] = 64 - (128 - $net_mask); } else { $net_mask_64_arr[0] = $net_mask; $net_mask_64_arr[1] = false; } if ((substr(gmp_convert($ip_dec_arr[0], 10, 2), 0, $net_mask_64_arr[0]) & substr(gmp_convert($mask_dec_arr[0], 10, 2), 0, $net_mask_64_arr[0])) == substr(gmp_convert($net_dec_arr[0], 10, 2), 0, $net_mask_64_arr[0])) { if ($net_mask_64_arr[1]) { if ((substr(gmp_convert($ip_dec_arr[1], 10, 2), 0, $net_mask_64_arr[1]) & substr(gmp_convert($mask_dec_arr[1], 10, 2), 0, $net_mask_64_arr[1])) != substr(gmp_convert($net_dec_arr[1], 10, 2), 0, $net_mask_64_arr[1])) { return false; } } return true; } }
/** * Convert an IPv6 address and prefix size to an address range for the network. * * This will take an IPv6 address and prefix and return the first and last address available for the network. * * @param string $addr A valid IPv6 address * @param integer $prefix The prefix size, an integer between 1 and 127 (inclusive) * @return array An array with two strings containing the start and end address for the IPv6 network */ function inet6_to_range($addr, $prefix) { $size = 128 - $prefix; $addr = gmp_init('0x' . str_replace(':', '', inet6_expand($addr))); $mask = gmp_init('0x' . str_replace(':', '', inet6_expand(inet6_prefix_to_mask($prefix)))); $prefix = gmp_and($addr, $mask); $start = gmp_strval(gmp_add($prefix, '0x1'), 16); $end = '0b'; for ($i = 0; $i < $size; $i++) { $end .= '1'; } $end = gmp_strval(gmp_add($prefix, gmp_init($end)), 16); for ($i = 0; $i < 8; $i++) { $start_result .= substr($start, $i * 4, 4); if ($i != 7) { $start_result .= ':'; } } // for for ($i = 0; $i < 8; $i++) { $end_result .= substr($end, $i * 4, 4); if ($i != 7) { $end_result .= ':'; } } // for $result = array(inet6_compress($start_result), inet6_compress($end_result)); return $result; }