1 | <?php |
||
34 | class Ipv6Range implements IpRange |
||
35 | { |
||
36 | |||
37 | /** The size of the IPv6 range mask. */ |
||
38 | private $mask; |
||
39 | |||
40 | /** The binary substring of the range minus the mask. */ |
||
41 | private $rangeSubstring; |
||
42 | |||
43 | /** |
||
44 | * Constructor for the class. |
||
45 | * @param string $range The IPv6 range as a string. Supported range styles: |
||
46 | * - CIDR notation (2400:cb00::/32) |
||
47 | * - a specific IP address (::1) |
||
48 | */ |
||
49 | 9 | public function __construct($range) |
|
53 | |||
54 | /** |
||
55 | * Returns whether or not a given IP address falls within this range. |
||
56 | * @param string $ipAddress The given IP address. |
||
57 | * @return boolean Returns true if the IP address falls within the range |
||
58 | * and false otherwise. |
||
59 | */ |
||
60 | 3 | public function containsIp($ipAddress) |
|
61 | { |
||
62 | // if the mask is false this means we have a full IP address as a |
||
63 | // range so compare against the whole string |
||
64 | 3 | if (false === $this->mask) { |
|
65 | 1 | return ($this->rangeSubstring === $this->convertToBinaryString($ipAddress)); |
|
66 | } |
||
67 | |||
68 | // remove the masked part of the address |
||
69 | 2 | $ipAddressSubstring = substr( |
|
70 | 2 | $this->convertToBinaryString($ipAddress), |
|
71 | 2 | 0, |
|
72 | 2 | $this->mask |
|
73 | ); |
||
74 | 2 | return ($this->rangeSubstring === $ipAddressSubstring); |
|
75 | } |
||
76 | |||
77 | /** |
||
78 | * Extracts the mask and binary string substring of the range to compare |
||
79 | * against incoming IP addresses. |
||
80 | * @param string $range The IPv6 range as a string. |
||
81 | */ |
||
82 | 9 | private function extractNetworkAndMaskFromRange($range) |
|
83 | { |
||
84 | 9 | if (false !== strpos($range, '/')) { |
|
85 | // handle the CIDR notation |
||
86 | 3 | list($network, $this->mask) = explode('/', $range); |
|
87 | // store a substring of the binary representation of the range |
||
88 | // minus the masked part |
||
89 | 3 | $this->rangeSubstring = substr( |
|
90 | 3 | $this->convertToBinaryString($network), |
|
91 | 3 | 0, |
|
92 | 3 | $this->mask |
|
93 | ); |
||
94 | } else { |
||
95 | // handle a single IP address |
||
96 | 6 | $this->rangeSubstring = $this->convertToBinaryString($range); |
|
97 | 6 | $this->mask = false; |
|
98 | } |
||
99 | 9 | } |
|
100 | |||
101 | /** |
||
102 | * Converts an IPv6 address to a binary string. |
||
103 | * @param string $address The IPv6 address in standard notation. |
||
104 | * @return string Returns the address as a string of bits. |
||
105 | */ |
||
106 | 9 | private function convertToBinaryString($address) |
|
107 | { |
||
108 | 9 | return implode('', array_map( |
|
109 | 9 | array(__CLASS__, 'hexToBinary'), |
|
110 | str_split(bin2hex(inet_pton($address))) |
||
111 | )); |
||
112 | } |
||
113 | /** |
||
114 | * Converts a hexadecimal character to a 4-digit binary string. |
||
115 | * @param string $hex The hexadecimal character. |
||
116 | * @return string Returns a 4-digit binary string. |
||
117 | */ |
||
118 | 9 | private static function hexToBinary($hex) |
|
122 | } |
||
123 |