Added CIDR IP range checking function, closes #88.
This commit is contained in:
parent
a37f48fdd6
commit
74910eddb6
3 changed files with 39 additions and 91 deletions
|
@ -19,35 +19,6 @@ if (MSZ_DEBUG) {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($_GET['cidr'])) {
|
|
||||||
header('Content-Type: text/plain');
|
|
||||||
|
|
||||||
$checks = [
|
|
||||||
[
|
|
||||||
'cidr' => '104.16.0.0/12',
|
|
||||||
'addrs' => [
|
|
||||||
'104.28.8.4',
|
|
||||||
'104.28.9.4',
|
|
||||||
'94.211.73.13',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach ($checks as $check) {
|
|
||||||
$mask = ip_cidr_to_mask($check['cidr']);
|
|
||||||
|
|
||||||
echo 'MASK> ' . inet_ntop($mask) . "\t" . decbin_str($mask) . PHP_EOL;
|
|
||||||
|
|
||||||
foreach ($check['addrs'] as $addr) {
|
|
||||||
$addr = inet_pton($addr);
|
|
||||||
echo 'ADDR> ' . inet_ntop($addr) . "\t" . decbin_str($addr) . "\t" . ip_match_mask($addr, $mask) . PHP_EOL;
|
|
||||||
}
|
|
||||||
|
|
||||||
echo PHP_EOL;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config_get_default(false, 'Site', 'embed_linked_data')) {
|
if (config_get_default(false, 'Site', 'embed_linked_data')) {
|
||||||
|
|
|
@ -13,17 +13,17 @@ function ip_remote_address(string $fallback = '::1'): string
|
||||||
return $_SERVER['REMOTE_ADDR'] ?? $fallback;
|
return $_SERVER['REMOTE_ADDR'] ?? $fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ip_country_code(string $ipAddr, string $fallback = 'XX'): string
|
function ip_country_code(string $address, string $fallback = 'XX'): string
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return geoip_country($ipAddr)->country->isoCode ?? $fallback;
|
return geoip_country($address)->country->isoCode ?? $fallback;
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return $fallback;
|
return $fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ip_detect_string_version(string $address): int
|
function ip_get_string_version(string $address): int
|
||||||
{
|
{
|
||||||
if (filter_var($address, FILTER_VALIDATE_IP) === false) {
|
if (filter_var($address, FILTER_VALIDATE_IP) === false) {
|
||||||
return MSZ_IP_UNKNOWN;
|
return MSZ_IP_UNKNOWN;
|
||||||
|
@ -40,13 +40,13 @@ function ip_detect_string_version(string $address): int
|
||||||
return MSZ_IP_UNKNOWN;
|
return MSZ_IP_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ip_detect_raw_version(string $raw, bool $returnWidth = false): int
|
function ip_get_raw_version(string $raw): int
|
||||||
{
|
{
|
||||||
$rawLength = strlen($raw);
|
$rawLength = strlen($raw);
|
||||||
|
|
||||||
foreach (MSZ_IP_SIZES as $version => $length) {
|
foreach (MSZ_IP_SIZES as $version => $length) {
|
||||||
if ($rawLength === $length) {
|
if ($rawLength === $length) {
|
||||||
return $returnWidth ? $length : $version;
|
return $version;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,54 +58,42 @@ function ip_get_raw_width(int $version): int
|
||||||
return MSZ_IP_SIZES[$version] ?? 0;
|
return MSZ_IP_SIZES[$version] ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Takes 1.2.3.4/n notation, returns subnet mask in raw bytes
|
function ip_match_cidr_raw(string $address, string $subnet, int $mask = 0): bool
|
||||||
function ip_cidr_to_mask(string $ipRange): string
|
|
||||||
{
|
{
|
||||||
[$address, $bits] = explode('/', $ipRange, 2);
|
$version = ip_get_raw_version($subnet);
|
||||||
|
$bits = ip_get_raw_width($version) * 8;
|
||||||
|
|
||||||
|
if (empty($mask)) {
|
||||||
|
$mask = $bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($mask < 1 || $mask > $bits || $version !== ip_get_raw_version($subnet)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ($i = 0; $i < ceil($mask / 8); $i++) {
|
||||||
|
$byteMask = (0xFF00 >> min(8, $mask - ($i * 8))) & 0xFF;
|
||||||
|
$addressByte = ord($address[$i]) & $byteMask;
|
||||||
|
$subnetByte = ord($subnet[$i]) & $byteMask;
|
||||||
|
|
||||||
|
if ($addressByte !== $subnetByte) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function ip_match_cidr(string $address, string $cidr): bool
|
||||||
|
{
|
||||||
|
if (strpos($cidr, '/') !== false) {
|
||||||
|
[$subnet, $mask] = explode('/', $cidr, 2);
|
||||||
|
} else {
|
||||||
|
$subnet = $cidr;
|
||||||
|
}
|
||||||
|
|
||||||
$address = inet_pton($address);
|
$address = inet_pton($address);
|
||||||
$width = ip_detect_raw_version($address, true) * 8;
|
$subnet = inet_pton($subnet);
|
||||||
|
|
||||||
if ($bits < 1 || $bits > $width) {
|
return ip_match_cidr_raw($address, $subnet, $mask ?? 0);
|
||||||
return str_repeat(chr(0), $width);
|
|
||||||
}
|
|
||||||
|
|
||||||
$mask = '';
|
|
||||||
|
|
||||||
for ($i = 0; $i < floor($width / 8); $i++) {
|
|
||||||
$addressByte = ord($address[$i]);
|
|
||||||
$maskByte = 0;
|
|
||||||
|
|
||||||
for ($j = 0; $j < 8; $j++) {
|
|
||||||
$offset = (8 * $i) + $j;
|
|
||||||
$bit = 0x80 >> $j;
|
|
||||||
|
|
||||||
if ($offset < $bits && ($addressByte & $bit) > 0) {
|
|
||||||
$maskByte |= $bit;
|
|
||||||
} else {
|
|
||||||
$maskByte &= ~$bit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$mask .= chr($maskByte);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Takes a RAW IP and a RAW MASK
|
|
||||||
function ip_match_mask(string $ipAddress, string $mask): int
|
|
||||||
{
|
|
||||||
$width = strlen($mask);
|
|
||||||
$result = false;
|
|
||||||
|
|
||||||
if (strlen($ipAddress) !== $width) {
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ($i = 0; $i < $width; $i++) {
|
|
||||||
$result &= ($ipAddress[$i] & ~$mask[$i]) === 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
}
|
||||||
|
|
11
utility.php
11
utility.php
|
@ -342,14 +342,3 @@ function is_user_int($value): bool
|
||||||
{
|
{
|
||||||
return ctype_digit(strval($value));
|
return ctype_digit(strval($value));
|
||||||
}
|
}
|
||||||
|
|
||||||
function decbin_str(string $str): string
|
|
||||||
{
|
|
||||||
$out = '';
|
|
||||||
|
|
||||||
for ($i = 0; $i < strlen($str); $i++) {
|
|
||||||
$out .= str_pad(decbin(ord($str[$i])), 8, '0');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $out;
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue