/** * check whether the expression matches an address * * @param AddressInterface $address * @return boolean */ public function matches(AddressInterface $address) { $addrChunks = $address->getChunks(); $exprChunks = preg_split('/[.:]/', $this->expression); if (count($exprChunks) !== count($addrChunks)) { throw new \UnexpectedValueException('Address and expression do not contain the same amount of chunks. Did you mix IPv4 and IPv6?'); } foreach ($exprChunks as $idx => $exprChunk) { $addrChunk = $addrChunks[$idx]; if (strpos($exprChunk, '*') === false) { // It's okay if the expression contains '.0.' and the IP contains '.000.', // we just care for the numerical value (and it's also okay to interprete // IPv4 chunks as hex values, as long as we interprete both as hex). if (hexdec($addrChunk) !== hexdec($exprChunk)) { return false; } } else { $exprChunk = str_replace('*', '[0-9a-f]+?', $exprChunk); if (!preg_match('/^' . $exprChunk . '$/', $addrChunk)) { return false; } } } return true; }
/** * check whether the expression matches an address * * @param AddressInterface $address * @return boolean */ public function matches(AddressInterface $address) { $lower = $this->lower->getExpanded(); $addr = $address->getExpanded(); // http://stackoverflow.com/questions/594112/matching-an-ip-to-a-cidr-mask-in-php5 if ($address instanceof IPv4 && $this->lower instanceof IPv4) { $addr = ip2long($addr); $lower = ip2long($lower); $netmask = -1 << 32 - $this->netmask & ip2long('255.255.255.255'); $lower &= $netmask; return ($addr & $netmask) == $lower; } elseif ($address instanceof IPv6 && $this->lower instanceof IPv6) { $lower = unpack('n*', inet_pton($lower)); $addr = unpack('n*', inet_pton($addr)); for ($i = 1; $i <= ceil($this->netmask / 16); $i++) { $left = $this->netmask - 16 * ($i - 1); $left = $left <= 16 ? $left : 16; $mask = ~(0xffff >> $left) & 0xffff; if (($addr[$i] & $mask) != ($lower[$i] & $mask)) { return false; } } return true; } throw new \LogicException('Can only compare IPs of the same version.'); }
/** * check whether the expression matches an address * * @param AddressInterface $address * @return boolean */ public function matches(AddressInterface $address) { return $address->getCompact() === $this->expression; }