public function setNetwork($subnet, $netmask = null) { if ($netmask === null && strpos($subnet, '/') === false) { throw new Zend_Validate_Exception('If the netmask is not specified then the CIDR (e.g. /24) must be provided'); } if ($netmask === null) { $cidr = substr($subnet, strpos($subnet, '/') + 1); $subnet = substr($subnet, 0, strpos($subnet, '/')); try { $ipVersion = App_Util_Ip::getIpVersion($subnet); if ($ipVersion == App_Util_Ip::v4) { $netmask = App_Util_Ip::long2ipv4($cidr); } else { $netmask = App_Util_Ip::long2ipv6($cidr); } } catch (\Application\Exceptions\InvalidArgumentException $e) { throw new Zend_Validate_Exception('Invalid CIDR specified'); } } else { // Only for IPv6 we want to convert the prefix to IP, for other cases everything is fine if (App_Util_Ip::getIpVersion($subnet) == App_Util_Ip::v6) { $maskPrefix = explode("/", $netmask); if (count($maskPrefix) == 2) { $netmask = $maskPrefix[1]; } $netmask = App_Util_Ip::long2ipv6($netmask); } } // Final conversion to be able to make bytewise operations try { // this is kind of evil but it works fine for ipv4. For newer php // versions dtr_pton is not working as expected for some ips $this->_version = App_Util_Ip::getIpVersion($subnet); if ($this->_version == App_Util_Ip::v4) { $this->_subnet = ip2long($subnet); $this->_netmask = ip2long($netmask); } else { $this->_subnet = App_Util_Ip::dtr_pton($subnet); $this->_netmask = App_Util_Ip::dtr_pton($netmask); } } catch (Exception $e) { throw new Zend_Validate_Exception("Unexpected error. Incorrect address"); } }
public function isValid($value, $context = array()) { if (!isset($context['network'])) { $this->_error(self::NOT_IP_ADDRESS); return false; } $network = $context['network']; $maskPrefix = explode("/", $value); if (count($maskPrefix) == 2) { $value = $maskPrefix[1]; } $network_bytearray = App_Util_Ip::dtr_pton($network); if (is_numeric($value)) { if ($value <= 128 && $value > 0) { if (!filter_var($network, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { $this->_error(self::INCOMPATIBLE_IP); return false; } $mask_bytearray = App_Util_Ip::dtr_pton(App_Util_Ip::long2ipv6($value)); if (($network_bytearray & $mask_bytearray) != $network_bytearray) { $this->_error(self::INCOMPATIBLE_NETWORK); return false; } return true; } else { $this->_error(self::INVALID_IPV6_PREFFIX); return false; } } if (parent::isValid($value)) { if (!filter_var($network, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { $this->_error(self::INCOMPATIBLE_IP); return false; } $mask_bytearray = App_Util_Ip::dtr_pton($value); if (($network_bytearray & $mask_bytearray) != $network_bytearray) { $this->_error(self::INCOMPATIBLE_NETWORK); return false; } return true; } return false; }
public function testLong2Ipv6() { $this->assertEquals("ffff:ffff:0:0:0:0:0:0", App_Util_Ip::long2ipv6(32)); }