note 63913 deleted from function.ip2long by nlopess
| From: | nlopess@php.net | Date: | Sun, 21 Oct 2007 22:02:48 +0000 |
| Subject: | note 63913 deleted from function.ip2long by nlopess | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-131606@lists.php.net to get a copy of this message | ||
Note Submitter: jcheger at acytec dot com
----
This function is an enhancement of Ken's one (see above: ken at expitrans dot com / net_match).
It compares an IP address to several networks, and negative ones as well. Adapted for IP ACLs.
/**
* Compare an IP address to network(s)
*
* The network(s) argument may be a string or an array. A negative network
* match must start with a "!". Depending on the 3rd parameter, it will
* return true or false on the first match, or any negative rule will have
* absolute priority (default).
*
* Samples:
* match_network ("192.168.1.0/24", "192.168.1.1") -> true
*
* match_network (array ("192.168.1.0/24", "!192.168.1.1"),
"192.168.1.1") -> false
* match_network (array ("192.168.1.0/24", "!192.168.1.1"),
"192.168.1.1", true) -> true
* match_network (array ("!192.168.1.0/24", "192.168.1.1"),
"192.168.1.1") -> false
* match_network (array ("!192.168.1.0/24", "192.168.1.1"),
"192.168.1.1", true) -> false
*
* @param mixed Network to match
* @param string IP address
* @param bool true: first match will return / false: priority to negative rules (default)
* @see http://php.benscom.com/manual/en/function.ip2long.php#56373
*/
function match_network ($nets, $ip, $first=false) {
$return = false;
if (!is_array ($nets)) $nets = array ($nets);
foreach ($nets as $net) {
$rev = (preg_match ("/^\!/", $net)) ? true : false;
$net = preg_replace ("/^\!/", "", $net);
$ip_arr = explode('/', $net);
$net_long = ip2long($ip_arr[0]);
$x = ip2long($ip_arr[1]);
$mask = long2ip($x) == $ip_arr[1] ? $x : 0xffffffff << (32 - $ip_arr[1]);
$ip_long = ip2long($ip);
if ($rev) {
if (($ip_long & $mask) == ($net_long & $mask)) return false;
} else {
if (($ip_long & $mask) == ($net_long & $mask)) $return = true;
if ($first && $return) return true;
}
}
return $return;
}