Update
This commit is contained in:
parent
d03c450bc7
commit
11ab5c993e
614
library/Scores/Validate/IpInNetwork.php
Normal file
614
library/Scores/Validate/IpInNetwork.php
Normal file
@ -0,0 +1,614 @@
|
||||
<?php
|
||||
class Scores_Validate_IpInNetwork extends Zend_Validate_Ip
|
||||
{
|
||||
const NOT_IN_NETWORK = 'notInNetwork';
|
||||
const LOW_IN_NETWORK = 'lowInNetwork';
|
||||
const HIGH_IN_NETWORK = 'highInNetwork';
|
||||
const INVALID_NETWORK = 'invalidNetwork';
|
||||
const MISSING_NETWORK = 'missingNetwork';
|
||||
|
||||
/**
|
||||
* A CIDR number (valid values 0-32)
|
||||
* @var int
|
||||
*/
|
||||
protected $_cidr = 0;
|
||||
|
||||
/**
|
||||
* A decimal 32-bit netmask
|
||||
* @var string
|
||||
*/
|
||||
protected $_netmask = '255.255.255.255';
|
||||
|
||||
/**
|
||||
* A 4-octet IPv4 network address
|
||||
* @var string
|
||||
*/
|
||||
protected $_network = null;
|
||||
|
||||
/**
|
||||
* A network/mask notation or network range
|
||||
* @var string
|
||||
*/
|
||||
protected $_notation = null;
|
||||
|
||||
/**
|
||||
* Unsigned decimal "from" IP address
|
||||
* @var string
|
||||
*/
|
||||
protected $_rangeFrom = null;
|
||||
|
||||
/**
|
||||
* Unsigned decimal "to" IP address
|
||||
* @var string
|
||||
*/
|
||||
protected $_rangeTo = 0;
|
||||
|
||||
/**
|
||||
* Will throw Exception instead of trigger_error if true
|
||||
* @var false
|
||||
*/
|
||||
protected $_throw = false;
|
||||
|
||||
/**
|
||||
* Constructor for IpInNetwork class
|
||||
*
|
||||
* @desc <p>Accepts an array with options. Also adds the error messages to the parent's message templates.</p>
|
||||
* @example <p>List of allow options and their use:
|
||||
* $options argument must be an array and allows two key/value pairs for this class and passes on any remaining
|
||||
* values to the parent class Zend_Validate_Ip. If key 'network' exists it will pass on the value to method
|
||||
* setNetworkNotation and for key 'throw' to setThrow4Notation.</p>
|
||||
* @see Zend_Validate_Ip::__construct()
|
||||
* @see Scores_Validate_IpInNetwork::setNetworkNotation()
|
||||
* @see Scores_Validate_IpInNetwork::setThrow4Notation()
|
||||
* @param array $options
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($options = array()) {
|
||||
if ( !empty($options) && is_array($options) ) {
|
||||
if ( array_key_exists('throw',$options) ) {
|
||||
$this->setThrow4Notation($options['throw']);
|
||||
unset($options['throw']);
|
||||
}
|
||||
if ( array_key_exists('network',$options) ) {
|
||||
$this->setNetworkNotation($options['network']);
|
||||
unset($options['network']);
|
||||
}
|
||||
}
|
||||
|
||||
$this->setMessages(array());
|
||||
|
||||
parent::__construct($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-PHPdoc)
|
||||
* @see Zend_Validate_Abstract::setMessages()
|
||||
*/
|
||||
public function setMessages(array $messages) {
|
||||
$newMessages = array(
|
||||
self::MISSING_NETWORK => 'No valid network has been given to validate against',
|
||||
self::INVALID_NETWORK => 'The network is not an accepted format',
|
||||
self::NOT_IN_NETWORK => "The ip '%value%' does not match the provided 32 network",
|
||||
self::LOW_IN_NETWORK => "The ip '%value%' is lower in range than the provided network",
|
||||
self::HIGH_IN_NETWORK => "The ip '%value%' is higher in range than the provided network",
|
||||
);
|
||||
|
||||
foreach ( $newMessages as $messageKey => $messageString ) {
|
||||
if ( !isset($this->_messageTemplates[$messageKey]) ) {
|
||||
$this->_messageTemplates[$messageKey] = $messageString;
|
||||
} elseif ( !empty($messages) && array_key_exists($messageKey,$messages) ) {
|
||||
$this->_messageTemplates[$messageKey] = $messages[$messageKey];
|
||||
unset($messages[$messageKey]);
|
||||
}
|
||||
}
|
||||
|
||||
empty($messages) || parent::setMessages($messages) ;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* (non-PHPdoc)
|
||||
* @see Zend_Validate_Ip::isValid()
|
||||
*/
|
||||
public function isValid($value) {
|
||||
if ( true === parent::isValid($value) ) {
|
||||
$notation = $this->_getNotation();
|
||||
if ( !empty($notation) ) {
|
||||
// a valid notation has been set
|
||||
$network = $this->_getNetwork();
|
||||
if ( !empty($network) ) {
|
||||
if ( true === $this->_validateIpInNetwork($value) ) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if ( true === $this->_validateIpInRange($value) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// NOTE: Errors are only available in regards to the value (ip address) and not the network/netmask (notation)
|
||||
$errors = $this->getErrors();
|
||||
if ( empty($errors) ) {
|
||||
$this->_error(self::NOT_IN_NETWORK);
|
||||
}
|
||||
} else {
|
||||
$this->_error(self::MISSING_NETWORK);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the IP in a given network
|
||||
*
|
||||
* @since Version 0.1.36
|
||||
* @version 0.1.36 2012/01/14 16:34:00 CST
|
||||
* @author aw
|
||||
* @desc <p>Takes the CIDR and network (IP) address and validates the given IP address against it. Sets the appropriate
|
||||
* errors if the IP is not a match for the network.</p>
|
||||
* @param string $ip
|
||||
* @return bool
|
||||
*/
|
||||
protected function _validateIpInNetwork($ip) {
|
||||
$netmask = $this->getCidr();
|
||||
$network = $this->_getNetwork();
|
||||
|
||||
// lets get this out of the way first
|
||||
if ( 32 === $netmask ) {
|
||||
// this network has to match the IP
|
||||
if ( $network === $ip ) {
|
||||
return true;
|
||||
} else {
|
||||
$this->_error(self::NOT_IN_NETWORK);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// get the unsigned integers for the IP and network address
|
||||
$ip_addr_uDec = $this->_makeUnsignedAddress($ip);
|
||||
$lNetwork_uDec = $this->_makeUnsignedAddress($network);
|
||||
|
||||
// let verify the IP against the lower end of the range
|
||||
if ( $ip_addr_uDec < $lNetwork_uDec ) {
|
||||
// the ip is below the network range
|
||||
$this->_error(self::LOW_IN_NETWORK);
|
||||
return false;
|
||||
}
|
||||
|
||||
// well then, finally verify the IP against the uppoer end of the range
|
||||
|
||||
// add the decimal representation of the netmask to the network IP
|
||||
$netmask_uDec1 = $netmask < 31 ? pow(2, (32-$netmask)) - 1 : 1 ;
|
||||
$netmask_uDec = pow(2, 32-$netmask) - 1 ;
|
||||
$uNetwork_uDec = $lNetwork_uDec + $netmask_uDec;
|
||||
|
||||
if ( $ip_addr_uDec > $uNetwork_uDec ) {
|
||||
// the ip is above the network range
|
||||
$this->_error(self::HIGH_IN_NETWORK);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the IP in a given range
|
||||
*
|
||||
* @since Version 0.1.36
|
||||
* @version 0.1.36 2012/01/16 13:06:00 CST
|
||||
* @author aw
|
||||
* @desc <p>Takes the "from" and "to" (IP) address and validates the given IP address against it. Sets the appropriate
|
||||
* errors if the IP is not within the defined range.</p>
|
||||
* @param string $ip
|
||||
* @return bool
|
||||
*/
|
||||
protected function _validateIpInRange($ip) {
|
||||
$uInt_Ip = $this->_makeUnsignedAddress($ip);
|
||||
|
||||
if ( is_numeric($this->_rangeFrom) && $uInt_Ip >= $this->_rangeFrom ) {
|
||||
if ( $uInt_Ip <= $this->_rangeTo ) {
|
||||
return true;
|
||||
} elseif ( is_numeric($this->_rangeTo) ) {
|
||||
$this->_error(self::HIGH_IN_NETWORK);
|
||||
return false;
|
||||
}
|
||||
} elseif ( is_numeric($this->_rangeFrom) ) {
|
||||
$this->_error(self::LOW_IN_NETWORK);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->_error(self::MISSING_NETWORK);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the network (notation) to the properties
|
||||
*
|
||||
* @since Version 0.1.36
|
||||
* @version 0.1.36 2012/01/14 13:43:00 CST
|
||||
* @author aw
|
||||
* @desc <p>The network is usually a notation with a network/netmask combination. The method uses two methods to validate
|
||||
* the netmask and the network address. If the notation is a range fromIPAddress-toIPAddress the netmask and network address
|
||||
* are ignored. The isValid() will then attempt to validate the value within the range and not the network segment.</p>
|
||||
* string $notation network/address (128.0.0.0/24) (128.0.0.0/255.255.255.0) or (128.0.0.0-128.0.0.255)
|
||||
* @return object|false Awd_Validate_IpInNetwork
|
||||
*/
|
||||
public function setNetworkNotation($notation) {
|
||||
$network = false !== strpos($notation, '/') ? $this->_evaluateNetmask($notation) : false ;
|
||||
if ( false !== $network) {
|
||||
// a valid CIDR/netmask has been found
|
||||
if ( true === parent::isValid($network) ) {
|
||||
if ( $this->_validateNetwork($network) ) {
|
||||
$this->_network = $network;
|
||||
$this->_notation = $notation;
|
||||
|
||||
return $this;
|
||||
}
|
||||
} else {
|
||||
$this->_invalidNetwork(__LINE__);
|
||||
}
|
||||
} elseif ( false !== strpos($notation, '-') ) {
|
||||
// the notation is looking like a from-to IP range
|
||||
if ( true === $this->_validateRange($notation) ) {
|
||||
$this->_notation = $notation;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value for _throw property
|
||||
*
|
||||
* @since Version 0.1.36
|
||||
* @version 0.1.35 2012/01/17 08:23:00 CST
|
||||
* @author aw
|
||||
* @desc <p>The value determines if the application will throw an exception or trigger an E_USER_WARNING if
|
||||
* an error was found in the submitted network notation. The default is false.</p>
|
||||
* @throws E_USER_WARNING if the argument is not of type bool
|
||||
* bool $throw
|
||||
* @return object Awd_Validate_IpInNetwork
|
||||
*/
|
||||
public function setThrow4Notation($throw = false) {
|
||||
if ( !is_bool($throw) ) {
|
||||
$msg = '[AWD] Programming error: The argument is not a boolean value';
|
||||
trigger_error($msg,E_USER_WARNING);
|
||||
}
|
||||
|
||||
|
||||
$this->_throw = $throw;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value for _throw property
|
||||
*
|
||||
* @since Version 0.1.36
|
||||
* @version 0.1.35 2012/01/17 08:27:00 CST
|
||||
* @author aw
|
||||
* @desc <p>The value determines if the application will throw an exception or trigger an E_USER_WARNING if
|
||||
* an error was found in the submitted network notation. The default is false.</p>
|
||||
* @return bool
|
||||
*/
|
||||
public function getThrow4Notation() {
|
||||
return (bool) $this->_throw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the network (notation) as it has been set if valid
|
||||
*
|
||||
* @since Version 0.1.36
|
||||
* @version 0.1.36 2012/01/14 16:08:00 CST
|
||||
* @author aw
|
||||
* @desc <p>If empty the network (notation) was either not set or not valid. Hence, this method can be used to
|
||||
* verify if setting a network range or notation was successful with the constructor.</p>
|
||||
* @return string
|
||||
*/
|
||||
public function getNetworkNotation() {
|
||||
return (string) $this->_getNotation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Protected method to gets the network (notation) as it has been set if valid
|
||||
*
|
||||
* @since Version 0.1.36
|
||||
* @version 0.1.36 2012/01/14 16:08:00 CST
|
||||
* @author aw
|
||||
* @desc <p>Note that the notation is only available when it passed the internal validation. Internally (protected)
|
||||
* the network represents the network (IP) address whereas the notation is the full string as set when is valid.
|
||||
* The notation is a representation of network range or network/mask. This method essentially returns internally
|
||||
* (protected) the same result as the public method getNetworkNotation().</p>
|
||||
* @return string|null
|
||||
*/
|
||||
protected function _getNotation() {
|
||||
return empty($this->_notation) ? null : (string) $this->_notation ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the network address from the notation if a valid address and mask has been set
|
||||
*
|
||||
* @since Version 0.1.36
|
||||
* @version 0.1.36 2012/01/14 16:18:00 CST
|
||||
* @author aw
|
||||
* @desc <p>Note that internally (protected) the network represents the network (IP) address extracted from the
|
||||
* "network notation", i.e. a representation of network range or network/mask. If the notation was not valid or a
|
||||
* network range has been set this value will be empty.</p>
|
||||
* @return string
|
||||
*/
|
||||
protected function _getNetwork() {
|
||||
return (string) $this->_network;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the CIDR from the notation if a valid address and mask has been set
|
||||
*
|
||||
* @since Version 0.1.36
|
||||
* @version 0.1.36 2012/01/14 16:26:00 CST
|
||||
* @author aw
|
||||
* @desc <p>The CIDR has been extracted from the "network notation", i.e. a representation of network/mask or
|
||||
* network/CIDR. If the notation was not valid or a network range has been set this value will be empty.</p>
|
||||
* @return int
|
||||
*/
|
||||
public function getCidr() {
|
||||
return (int) $this->_cidr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates the netmask from a notation
|
||||
*
|
||||
* @since Version 0.1.36
|
||||
* @version 0.1.36 2012/01/15 10:12:00 CST
|
||||
* @author aw
|
||||
* @desc <p>The notation is usually set as a {network/CIDR} or {network/netmask} notation. This method examines
|
||||
* the string following a slash. A CIDR mask will be verified for its number whereas a netmask is passed to
|
||||
* another method _validateNetmask() for validation and if valid converted into a CIDR representation. In
|
||||
* either case if the value is valid the remaining network (IP) address is returned or false on failure.</p>
|
||||
* @throws Calls method _invalidNetwork() when a failure is detected
|
||||
* @param string $notation
|
||||
* @return string|bool (false)
|
||||
*/
|
||||
protected function _evaluateNetmask($notation) {
|
||||
// split the notation in network and netmask information
|
||||
list($network, $netmask) = explode('/', $notation, 2);
|
||||
if ( is_numeric($netmask) ) {
|
||||
// does look like a CIDR netmask
|
||||
$between = new Zend_Validate_Between(array('min'=>1,'max'=>32));
|
||||
if ( true === $between->isValid($netmask) ) {
|
||||
$this->_cidr = (int) $netmask;
|
||||
return $network;
|
||||
} else {
|
||||
$error_msgs = $between->getMessages();
|
||||
if ( !empty($error_msgs) && is_array($error_msgs) ) {
|
||||
$msg = array_shift($error_msgs);
|
||||
} else {
|
||||
// fallback, should not really be an option
|
||||
$msg = sprintf('The netmask [ %s ] is not a valid option',$netmask);
|
||||
}
|
||||
|
||||
// oops, this CIDR is not a valid range
|
||||
return $this->_invalidNetwork(__LINE__.' - '.$msg);
|
||||
}
|
||||
} elseif ( !empty($netmask) ) {
|
||||
// looks more like 32-bit (like 255.255.255.0) format
|
||||
if ( true === ($line = $this->_validateNetmask($netmask)) ) {
|
||||
return $network;
|
||||
}
|
||||
|
||||
return $this->_invalidNetwork($line);
|
||||
}
|
||||
|
||||
return $this->_invalidNetwork(__LINE__);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a 32-bit netmask
|
||||
*
|
||||
* @since Version 0.1.36
|
||||
* @version 0.1.36 2012/01/16 10:34:00 CST
|
||||
* @author aw
|
||||
* @desc <p>A netmask is a decimal representation of 32-bit string where the beginning sequence is a complete
|
||||
* set of 1 (one) followed by a complete set of 0 (zero). If valid the netmask string will be a CIDR numeric
|
||||
* value and set to the proected property _cidr. If not valid the returned value is the line plus the index if
|
||||
* the failure is in one of the segments.</p>
|
||||
* @param string $netmask
|
||||
* @return true|string
|
||||
*/
|
||||
protected function _validateNetmask($netmask) {
|
||||
$classes = explode('.', $netmask);
|
||||
if ( 4 !== count($classes) ) {
|
||||
return __LINE__;
|
||||
}
|
||||
|
||||
$cidr = 0; $end = false;
|
||||
foreach ( $classes as $index => $segment ) {
|
||||
if ( !is_numeric($segment) ) {
|
||||
return __LINE__;
|
||||
} elseif ( 0 === (int) $segment ) {
|
||||
$end = true; // all following segment have to be 0 (zero) as well
|
||||
continue;
|
||||
}
|
||||
$matches = array();
|
||||
|
||||
// evaluate the binary representation of the segment
|
||||
$bin = decbin($segment);
|
||||
if ( 8 !== strlen($bin) || 0 === preg_match('/^([1]{1,8})([0]*)$/', decbin($segment), $matches) ) {
|
||||
if ( 8 !== strlen($bin) ) {
|
||||
// this segment is not a complete byte (8 bits) i.e. a value below 128
|
||||
return __LINE__.':'.++$index; // NOTE: Index begins at 0 (zero)
|
||||
}
|
||||
// this segment is a complete byte (8 bits), i.e. a value above 128, but not a valid binary mask (like 11110000)
|
||||
return __LINE__.':'.++$index; // NOTE: Index begins at 0 (zero)
|
||||
} elseif ( true === $end ) {
|
||||
// a mask was found in the previous segment; therefore, this segment should be 0 (zero)
|
||||
return __LINE__.':'.++$index; // NOTE: Index begins at 0 (zero)
|
||||
}
|
||||
$len = strlen($matches[1]);
|
||||
if ( $len < 8 ) { $end = true; }
|
||||
$cidr += $len;
|
||||
}
|
||||
|
||||
$this->_cidr = $cidr;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the network address in a subnet notation
|
||||
*
|
||||
* @since Version 0.1.36
|
||||
* @version 0.1.36 2012/01/16 10:34:00 CST
|
||||
* @author aw
|
||||
* @desc <p>The network address in a CIDR or subnet mask notation is the base of the assigned block.
|
||||
* Because the size of the block is specified by the CIDR or subnet mask the base of a network address
|
||||
* has to fit and match into the block size. This method evaluates the block size and then validates
|
||||
* if the base of network address fits into the assigned block. If not valid the line plus the index
|
||||
* of the failed segment is sent to method _invalidNetwork() triggering or throwing an error.</p>
|
||||
* @param string $network
|
||||
* @return true|string
|
||||
*/
|
||||
protected function _validateNetwork($network) {
|
||||
$cidr = $this->getCidr();
|
||||
$class = $cidr / 8;
|
||||
|
||||
// an integer indicates a classful (unicast) network
|
||||
if ( is_int($class) ) {
|
||||
$iClass = $class;
|
||||
$maskBits = 0;
|
||||
} else {
|
||||
$iClass = (int) floor($class);
|
||||
$maskBits = (int) 8 - ($cidr - ($iClass * 8));
|
||||
$hosts = (int) pow(2, $maskBits); // number of usable hosts in a subnet
|
||||
}
|
||||
|
||||
$segments = explode('.', $network);
|
||||
// Note: $segments index begins at 0 (zero) and $iClass is the last complete segment in the netmask (8 bits (255))
|
||||
// It is irrelevant but just to clarify for $iClass: 1 = Class A, 2 = Class B, 3 = Class C
|
||||
|
||||
$complete = false;
|
||||
// check all segments following the last complete class and because we have to check for
|
||||
// subnetting in the _follow_ class we do NOT add 1 to $iClass as the index in $segments
|
||||
for ($index = $iClass; $index < 4; $index++) {
|
||||
$subNetwork = (int) $segments[$index];
|
||||
|
||||
if ( 0 === $maskBits ) {
|
||||
// this class has no subnets (aka classful network)
|
||||
// all 0 (zero) are expected as (sub)network numbers
|
||||
if ( 0 !== $subNetwork ) {
|
||||
return $this->_invalidNetwork(__LINE__.':'.++$index); // NOTE: Index begins at 0 (zero)
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
// this class has subnets (aka a classless (subnetted) network)
|
||||
if ( true === $complete ) {
|
||||
// for all following networks 0 (zero) is expected as (sub)network number
|
||||
if ( 0 !== $subNetwork ) {
|
||||
return $this->_invalidNetwork(__LINE__.':'.++$index); // NOTE: Index begins at 0 (zero)
|
||||
}
|
||||
continue;
|
||||
}
|
||||
$complete = true;
|
||||
|
||||
// the (sub)network must be a fact or hosts(/subnets)
|
||||
$block = $subNetwork / $hosts;
|
||||
if ( is_int($block) ) {
|
||||
// all clear
|
||||
// NOTE: We do NOT return yet because we may have to verify any following segments
|
||||
continue;
|
||||
} else {
|
||||
return $this->_invalidNetwork(__LINE__.':'.++$index.':'.$hosts); // NOTE: Index begins at 0 (zero)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a network range with a "from-to" IP address notation
|
||||
*
|
||||
* @since Version 0.1.36
|
||||
* @version 0.1.35 2012/01/16 12:44:00 CST
|
||||
* @author aw
|
||||
* @desc <p>A network range can be any difference (or equal) between two valid IP addresses. The method will even switch the
|
||||
* values if the "to" is lower than the "from" address.</p>
|
||||
* @param string $range
|
||||
* @return bool
|
||||
*/
|
||||
protected function _validateRange($range) {
|
||||
list($from,$to) = explode('-', $range); // Note: we do NOT care if more IP ranges have been set, i.e. the range would be invalid
|
||||
|
||||
if ( false === ($uInt_from = $this->_makeUnsignedAddress($from)) || false === ($uInt_to = $this->_makeUnsignedAddress($to)) ) {
|
||||
return $this->_invalidNetwork(__LINE__); // at least one of the addresses is not a valid IP address
|
||||
}
|
||||
|
||||
if ( $uInt_from <= $uInt_to ) {
|
||||
$this->_rangeFrom = $uInt_from;
|
||||
$this->_rangeTo = $uInt_to;
|
||||
} else {
|
||||
// the range is not in the correct order
|
||||
$this->_rangeFrom = $uInt_to;
|
||||
$this->_rangeTo = $uInt_from;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an IP address into an unsigned decimal number (see ATTENTION note for returned value)
|
||||
*
|
||||
* @since Version 0.1.36
|
||||
* @version 0.1.35 2012/01/16 12:31:00 CST
|
||||
* @author aw
|
||||
* @desc <p>Uses php function ip2long() to convert the IP into a signed value first and then returns the value with
|
||||
* sprintf($u). ATTENTION: Function sprintf returns this value as a string and typecasting will not produce the expected
|
||||
* result for IP addresses above 128.0.0.0. Do not typecast this value to an integer!</p>
|
||||
* @param string $ip
|
||||
* @return string
|
||||
*/
|
||||
private function _makeUnsignedAddress($ip) {
|
||||
if ( false === ($ip_addr_long = ip2long($ip)) ) {
|
||||
// not a valid IP address
|
||||
return false;
|
||||
}
|
||||
|
||||
// Note ip2long creates signed integers
|
||||
// a positive number means the address is in the lower half < 128 (0nnn nnnn.)
|
||||
// a negative number means the address is in the upper half >= 128 (1nnn nnnn.)
|
||||
// 127.255.255.255 = 2147483647
|
||||
// 128.0.0.1 = -2147483647
|
||||
// 128.0.0.0 = -2147483648
|
||||
|
||||
// convert to unsigned decimal number
|
||||
return sprintf('%u',$ip_addr_long);
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers an error warning or throws an exception
|
||||
*
|
||||
* @since Version 0.1.36
|
||||
* @version 0.1.36 2012/01/15 11:54:00 CST
|
||||
* @author aw
|
||||
* @desc <p>The error message contains the argument which is usually the line where the error occured. The calling method
|
||||
* may add additional information to the line number.</p>
|
||||
* @throws E_USER_WARNING If the _throw property is false (default)
|
||||
* @throws Exception If the _throw property is true
|
||||
* @param string|int $line
|
||||
* @return bool (false)
|
||||
*/
|
||||
private function _invalidNetwork($line) {
|
||||
$error_msg = 'The provided network information is not a recognized format [#'.$line.']';
|
||||
$this->_error(self::INVALID_NETWORK,$error_msg);
|
||||
$msg = '[SCORES] Application error: '.$error_msg;
|
||||
if ( false === $this->_throw ) {
|
||||
trigger_error($msg,E_USER_WARNING);
|
||||
return false;
|
||||
} else {
|
||||
throw new Exception($msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
39
library/Scores/Validate/IpInNetwork.txt
Normal file
39
library/Scores/Validate/IpInNetwork.txt
Normal file
@ -0,0 +1,39 @@
|
||||
This validator class will test an IP against a provide network notation. The
|
||||
network notation can be a network range, or network address with CIDR or 32-bit
|
||||
decimal subnet mask notation. Note that the main validation method always uses
|
||||
the CIDR notation, i.e a bitmask will be converted into a CIDR.
|
||||
|
||||
|
||||
Examples for network notations
|
||||
------------------------------
|
||||
Network Range:
|
||||
**************
|
||||
128.0.0.12-128.0.0.19
|
||||
true for all IP addresses inclusively in this range (i.e. from .12 to .19)
|
||||
|
||||
CIDR notation:
|
||||
**************
|
||||
128.0.0.8/30
|
||||
block with 4 hosts
|
||||
true for IP addresses from .8-.11 (i.e. .8, .9, .10, .11)
|
||||
|
||||
Subnet mask notation:
|
||||
*********************
|
||||
128.0.0.8/255.255.255.252
|
||||
same as CIDR notation
|
||||
|
||||
Special Notes:
|
||||
--------------
|
||||
1) The network notation is validated, i.e. you have to pass a valid network and
|
||||
CIDR or subnet mask combination. For the network range the two values must be
|
||||
valid IP addresses.
|
||||
|
||||
2) A CIDR notation of /32, subnet mask /255.255.255.255 or a range with two
|
||||
equal addresses will match for one host, i.e. the result is true if the network
|
||||
address or the range addresses are identical to the IP address
|
||||
|
||||
3) The network notation or a range has to be set prior to calling isValid() as
|
||||
is custom with all Zend validators. The notation can be set when instantiating
|
||||
the object as an array and 'network' as the index. The setter method is
|
||||
setNetworkNotation($notation) and expects a string as the argument.
|
||||
|
Loading…
Reference in New Issue
Block a user