public static function subnetMatch($subnet, $ip, &$prefix = -1){

		$ip = ip2long($ip);

		if(strpos($subnet, '/') !== false){

			list($net, $prefix) = explode('/', $subnet, 2);

			// Ensure the provided CIDR-prefix (e.g. subnet mask) is valid

			if(!ctype_digit($prefix) || $prefix > 32){

				$prefix = -1;

				return false;
			}

			$net = ip2long($net);
			$prefix = (int) $prefix;
		}
		else{

			$net = ip2long($subnet);
			$prefix = 32;
		}

		// Empty/invalid IP-address or invalid subnet provided

		if(empty($ip) || $net === false){

			return false;
		}

		// Empty prefix; all IP-addresses will match (short-circuit)

		if($prefix === 0){

			if(!empty($net)){

				ExceptionHandler::notice("Invalid CIDR-notation '$subnet',
					assuming '0.0.0.0/0'");
			}

			return true;
		}

		if($prefix < 32){

			$mask = 0xffffffff << (32 - $prefix);

			$net_mask = $net & $mask;
			$ip_mask = $ip & $mask;

			/*
			 * When properly specified in CIDR-notation, both the input subnet
			 * and the "masked" input subnet (as calculated above) should be
			 * equal. Non-fatal, but a strong indication someone wasn't paying
			 * attention while configuring the subnet...
			 */

			if($net_mask !== $net){

				ExceptionHandler::notice("Invalid CIDR-notation '$subnet',
					assuming " . long2ip($net_mask) . "/$prefix");
			}

			return (($net_mask ^ $ip_mask) === 0);
		}
		else{

			return ($net === $ip);
		}
	}