1 | <?php |
||||
2 | |||||
3 | /* |
||||
4 | The MIT License (MIT) |
||||
5 | |||||
6 | Copyright (c) 2015 Vectorface, Inc. |
||||
7 | |||||
8 | Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
9 | of this software and associated documentation files (the "Software"), to deal |
||||
10 | in the Software without restriction, including without limitation the rights |
||||
11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
12 | copies of the Software, and to permit persons to whom the Software is |
||||
13 | furnished to do so, subject to the following conditions: |
||||
14 | |||||
15 | The above copyright notice and this permission notice shall be included in |
||||
16 | all copies or substantial portions of the Software. |
||||
17 | |||||
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
24 | THE SOFTWARE. |
||||
25 | */ |
||||
26 | |||||
27 | namespace Vectorface\Whip\IpRange; |
||||
28 | |||||
29 | /** |
||||
30 | * A class representing an IPv6 address range. |
||||
31 | * @copyright Vectorface, Inc 2015 |
||||
32 | * @author Daniel Bruce <[email protected]> |
||||
33 | */ |
||||
34 | class Ipv6Range implements IpRange |
||||
35 | { |
||||
36 | /** The size of the IPv6 range mask. */ |
||||
37 | private string|false $mask; |
||||
38 | |||||
39 | /** The binary substring of the range minus the mask. */ |
||||
40 | private string $rangeSubstring; |
||||
41 | |||||
42 | /** |
||||
43 | * Constructor for the class. |
||||
44 | * |
||||
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(string $range) |
|||
50 | { |
||||
51 | 9 | $this->extractNetworkAndMaskFromRange($range); |
|||
52 | 9 | } |
|||
53 | |||||
54 | /** |
||||
55 | * Returns whether a given IP address falls within this range. |
||||
56 | * |
||||
57 | * @param string $ipAddress The given IP address. |
||||
58 | * @return bool Returns true if the IP address falls within the range |
||||
59 | * and false otherwise. |
||||
60 | 3 | */ |
|||
61 | public function containsIp(string $ipAddress) : bool |
||||
62 | { |
||||
63 | // if the mask is false this means we have a full IP address as a |
||||
64 | 3 | // range so compare against the whole string |
|||
65 | 1 | if (false === $this->mask) { |
|||
66 | return $this->rangeSubstring === $this->convertToBinaryString($ipAddress); |
||||
67 | } |
||||
68 | |||||
69 | 2 | // remove the masked part of the address |
|||
70 | 2 | $ipAddressSubstring = substr( |
|||
71 | 2 | $this->convertToBinaryString($ipAddress), |
|||
72 | 2 | 0, |
|||
73 | $this->mask |
||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||
74 | 2 | ); |
|||
75 | return $this->rangeSubstring === $ipAddressSubstring; |
||||
76 | } |
||||
77 | |||||
78 | /** |
||||
79 | * Extracts the mask and binary string substring of the range to compare |
||||
80 | * against incoming IP addresses. |
||||
81 | * |
||||
82 | 9 | * @param string $range The IPv6 range as a string. |
|||
83 | */ |
||||
84 | 9 | private function extractNetworkAndMaskFromRange(string $range) : void |
|||
85 | { |
||||
86 | 3 | if (str_contains($range, '/')) { |
|||
87 | // handle the CIDR notation |
||||
88 | list($network, $this->mask) = explode('/', $range); |
||||
89 | 3 | // store a substring of the binary representation of the range |
|||
90 | 3 | // minus the masked part |
|||
91 | 3 | $this->rangeSubstring = substr( |
|||
92 | 3 | $this->convertToBinaryString($network), |
|||
93 | 0, |
||||
94 | $this->mask |
||||
0 ignored issues
–
show
$this->mask of type string is incompatible with the type integer|null expected by parameter $length of substr() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
95 | ); |
||||
96 | 6 | } else { |
|||
97 | 6 | // handle a single IP address |
|||
98 | $this->rangeSubstring = $this->convertToBinaryString($range); |
||||
99 | 9 | $this->mask = false; |
|||
100 | } |
||||
101 | } |
||||
102 | |||||
103 | /** |
||||
104 | * Converts an IPv6 address to a binary string. |
||||
105 | * |
||||
106 | 9 | * @param string $address The IPv6 address in standard notation. |
|||
107 | * @return string Returns the address as a string of bits. |
||||
108 | 9 | */ |
|||
109 | 9 | private function convertToBinaryString(string $address) : string |
|||
110 | 9 | { |
|||
111 | return implode('', array_map( |
||||
112 | [__CLASS__, 'hexToBinary'], |
||||
113 | str_split(bin2hex(inet_pton($address))) |
||||
0 ignored issues
–
show
It seems like
str_split(bin2hex(inet_pton($address))) can also be of type true ; however, parameter $array of array_map() does only seem to accept array , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
114 | )); |
||||
115 | } |
||||
116 | /** |
||||
117 | * Converts a hexadecimal character to a 4-digit binary string. |
||||
118 | 9 | * |
|||
119 | * @param string $hex The hexadecimal character. |
||||
120 | 9 | * @return string Returns a 4-digit binary string. |
|||
121 | */ |
||||
122 | private static function hexToBinary(string $hex) : string |
||||
123 | { |
||||
124 | return str_pad(base_convert($hex, 16, 2), 4, '0', STR_PAD_LEFT); |
||||
125 | } |
||||
126 | } |
||||
127 |