If you don't intend to use wildcards as 123.3.2*.3
, which would match any IP between 123.3.20.3
and 123.3.29.3
, then the solution below would work fine.
Loop over the IPs in the array, and if there exists a wildcard in it, create two new IPs - one where the wildcard *
is replaced by 0, the other replaced by 255. This is the lower and upper limit. Then you convert it to an integer, instead of an IP-string, using the ip2long()
function. Do this both on the IP itself, and the value in the array as you loop them.
Then its only a matter of comparing them, that it is in fact between the upper and lower limit.
If there is no wildcard in the string, do a direct comparison.
$allowedIps = ['123.2.*.*', '123.3.2.3', '123.3.*.3'];
$IP = '123.3.1.3';
$match = 0;
foreach ($allowedIps as $allowed) {
// If there is no wildcard, we check for the specific IP instead, and not a range
if (strpos($allowed, "*") !== false) {
$lowest = str_replace("*", "0", $allowed);
$highest = str_replace("*", "255", $allowed);
if (ip2long($IP) >= ip2long($lowest) && ip2long($IP) <= ip2long($highest)) {
echo "$IP matched $allowed";
$match = 1;
break;
}
} elseif (ip2long($IP) === ip2long($allowed)) {
echo "Matched ".$allowed;
$match = 1;
break;
}
}
Probably wouldn't even need the condition to check if there are wildcards, as it wouldn't replace anything and both conditions in the subsequent if
condition would be true.
Fair warning, I have not fully tested this, and there might be some obscure cases where the conditions might fail. You might be better off doing this outside of PHP as well.