I adapted the php.net answer and made it better.
function netMatch($network, $ip) { $network=trim($network); $orig_network = $network; $ip = trim($ip); if ($ip == $network) { echo "used network ($network) for ($ip)\n"; return TRUE; } $network = str_replace(' ', '', $network); if (strpos($network, '*') !== FALSE) { if (strpos($network, '/') !== FALSE) { $asParts = explode('/', $network); $network = @ $asParts[0]; } $nCount = substr_count($network, '*'); $network = str_replace('*', '0', $network); if ($nCount == 1) { $network .= '/24'; } else if ($nCount == 2) { $network .= '/16'; } else if ($nCount == 3) { $network .= '/8'; } else if ($nCount > 3) { return TRUE; // if *.*.*.*, then all, so matched } } echo "from original network($orig_network), used network ($network) for ($ip)\n"; $d = strpos($network, '-'); if ($d === FALSE) { $ip_arr = explode('/', $network); if (!preg_match("@\d*\.\d*\.\d*\.\d*@", $ip_arr[0], $matches)){ $ip_arr[0].=".0"; // Alternate form 194.1.4/24 } $network_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); return ($ip_long & $mask) == ($network_long & $mask); } else { $from = trim(ip2long(substr($network, 0, $d))); $to = trim(ip2long(substr($network, $d+1))); $ip = ip2long($ip); return ($ip>=$from and $ip<=$to); } } function ech($b) { if ($b) { echo "MATCHED\n"; } else { echo "DID NOT MATCH\n"; } } echo "CLASS A TESTS\n"; ech(netMatch('10.168.1.0-10.168.1.100', '10.168.1.90')); ech(netMatch('10.168.*.*', '10.168.1.90')); ech(netMatch('10.168.0.0/16', '10.168.1.90')); ech(netMatch('10.169.1.0/24', '10.168.1.90')); ech(netMatch('10.168.1.90', '10.168.1.90')); echo "\nCLASS B TESTS\n"; ech(netMatch('130.168.1.0-130.168.1.100', '130.168.1.90')); ech(netMatch('130.168.*.*', '130.168.1.90')); ech(netMatch('130.168.0.0/16', '130.168.1.90')); ech(netMatch('130.169.1.0/24', '130.168.1.90')); ech(netMatch('130.168.1.90', '130.168.1.90')); echo "\nCLASS C TESTS\n"; ech(netMatch('192.168.1.0-192.168.1.100', '192.168.1.90')); ech(netMatch('192.168.*.*', '192.168.1.90')); ech(netMatch('192.168.0.0/16', '192.168.1.90')); ech(netMatch('192.169.1.0/24', '192.168.1.90')); ech(netMatch('192.168.1.90', '192.168.1.90')); echo "\nCLASS D TESTS\n"; ech(netMatch('230.168.1.0-230.168.1.100', '230.168.1.90')); ech(netMatch('230.168.*.*', '230.168.1.90')); ech(netMatch('230.168.0.0/16', '230.168.1.90')); ech(netMatch('230.169.1.0/24', '230.168.1.90')); ech(netMatch('230.168.1.90', '230.168.1.90')); echo "\nCLASS E TESTS\n"; ech(netMatch('250.168.1.0-250.168.1.100', '250.168.1.90')); ech(netMatch('250.168.*.*', '250.168.1.90')); ech(netMatch('250.168.0.0/16', '250.168.1.90')); ech(netMatch('250.169.1.0/24', '250.168.1.90')); ech(netMatch('250.168.1.90', '250.168.1.90'));
This is the result:
CLASS A TESTS from orig network (10.168.1.0-10.168.1.100) used network (10.168.1.0-10.168.1.100) for (10.168.1.90) MATCHED from orig network (10.168.*.*) used network (10.168.0.0/16) for (10.168.1.90) MATCHED from orig network (10.168.0.0/16) used network (10.168.0.0/16) for (10.168.1.90) MATCHED from orig network (10.169.1.0/24) used network (10.169.1.0/24) for (10.168.1.90) DID NOT MATCH used network (10.168.1.90) for (10.168.1.90) MATCHED CLASS B TESTS from orig network (130.168.1.0-130.168.1.100) used network (130.168.1.0-130.168.1.100) for (130.168.1.90) MATCHED from orig network (130.168.*.*) used network (130.168.0.0/16) for (130.168.1.90) MATCHED from orig network (130.168.0.0/16) used network (130.168.0.0/16) for (130.168.1.90) MATCHED from orig network (130.169.1.0/24) used network (130.169.1.0/24) for (130.168.1.90) DID NOT MATCH used network (130.168.1.90) for (130.168.1.90) MATCHED CLASS C TESTS from orig network (192.168.1.0-192.168.1.100) used network (192.168.1.0-192.168.1.100) for (192.168.1.90) MATCHED from orig network (192.168.*.*) used network (192.168.0.0/16) for (192.168.1.90) MATCHED from orig network (192.168.0.0/16) used network (192.168.0.0/16) for (192.168.1.90) MATCHED from orig network (192.169.1.0/24) used network (192.169.1.0/24) for (192.168.1.90) DID NOT MATCH used network (192.168.1.90) for (192.168.1.90) MATCHED CLASS D TESTS from orig network (230.168.1.0-230.168.1.100) used network (230.168.1.0-230.168.1.100) for (230.168.1.90) MATCHED from orig network (230.168.*.*) used network (230.168.0.0/16) for (230.168.1.90) MATCHED from orig network (230.168.0.0/16) used network (230.168.0.0/16) for (230.168.1.90) MATCHED from orig network (230.169.1.0/24) used network (230.169.1.0/24) for (230.168.1.90) DID NOT MATCH used network (230.168.1.90) for (230.168.1.90) MATCHED CLASS E TESTS from orig network (250.168.1.0-250.168.1.100) used network (250.168.1.0-250.168.1.100) for (250.168.1.90) MATCHED from orig network (250.168.*.*) used network (250.168.0.0/16) for (250.168.1.90) MATCHED from orig network (250.168.0.0/16) used network (250.168.0.0/16) for (250.168.1.90) MATCHED from orig network (250.169.1.0/24) used network (250.169.1.0/24) for (250.168.1.90) DID NOT MATCH used network (250.168.1.90) for (250.168.1.90) MATCHED