|
|
@ -7,6 +7,8 @@ |
|
|
|
|
|
|
|
|
|
|
|
namespace yii\helpers; |
|
|
|
namespace yii\helpers; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
use yii\base\NotSupportedException; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Class BaseIpHelper provides concrete implementation for [[IpHelper]] |
|
|
|
* Class BaseIpHelper provides concrete implementation for [[IpHelper]] |
|
|
|
* |
|
|
|
* |
|
|
@ -61,6 +63,7 @@ class BaseIpHelper |
|
|
|
* @param string $range the valid IPv4 or IPv6 CIDR range, e.g. `10.0.0.0/8` or `2001:af::/64` |
|
|
|
* @param string $range the valid IPv4 or IPv6 CIDR range, e.g. `10.0.0.0/8` or `2001:af::/64` |
|
|
|
* @return bool whether $subnet is contained by $range |
|
|
|
* @return bool whether $subnet is contained by $range |
|
|
|
* |
|
|
|
* |
|
|
|
|
|
|
|
* @throws NotSupportedException |
|
|
|
* @see https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing |
|
|
|
* @see https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static function inRange($subnet, $range) |
|
|
|
public static function inRange($subnet, $range) |
|
|
@ -102,19 +105,22 @@ class BaseIpHelper |
|
|
|
* |
|
|
|
* |
|
|
|
* @param string $ip the valid IPv4 or IPv6 address |
|
|
|
* @param string $ip the valid IPv4 or IPv6 address |
|
|
|
* @return string bits as a string |
|
|
|
* @return string bits as a string |
|
|
|
|
|
|
|
* @throws NotSupportedException |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static function ip2bin($ip) |
|
|
|
public static function ip2bin($ip) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
$ipBinary = null; |
|
|
|
if (static::getIpVersion($ip) === self::IPV4) { |
|
|
|
if (static::getIpVersion($ip) === self::IPV4) { |
|
|
|
return str_pad(base_convert(ip2long($ip), 10, 2), self::IPV4_ADDRESS_LENGTH, '0', STR_PAD_LEFT); |
|
|
|
$ipBinary = pack('N', ip2long($ip)); |
|
|
|
|
|
|
|
} elseif (@inet_pton('::1') === false) { |
|
|
|
|
|
|
|
throw new NotSupportedException('IPv6 is not supported by inet_pton()!'); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
$ipBinary = inet_pton($ip); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
$unpack = unpack('A16', inet_pton($ip)); |
|
|
|
|
|
|
|
$binStr = array_shift($unpack); |
|
|
|
|
|
|
|
$bytes = self::IPV6_ADDRESS_LENGTH / 8; // 128 bit / 8 = 16 bytes |
|
|
|
|
|
|
|
$result = ''; |
|
|
|
$result = ''; |
|
|
|
while ($bytes-- > 0) { |
|
|
|
for ($i = 0; $i < strlen($ipBinary); $i += 4) { |
|
|
|
$result = sprintf('%08b', isset($binStr[$bytes]) ? ord($binStr[$bytes]) : '0') . $result; |
|
|
|
$result .= str_pad(decbin(unpack('N', substr($ipBinary, $i, 4))[1]), 32, '0', STR_PAD_LEFT); |
|
|
|
} |
|
|
|
} |
|
|
|
return $result; |
|
|
|
return $result; |
|
|
|
} |
|
|
|
} |
|
|
|