PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 2.14.6
Independent Analytics – WordPress Analytics Plugin v2.14.6
2.15.5 2.15.4 2.15.3 2.15.2 2.15.1 2.15.0 2.14.10 trunk 1.1 1.10 1.10.1 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.17.1 1.17.2 1.17.3 1.17.4 1.18 1.18.1 1.19.0 1.19.1 1.2 1.20.0 1.21.0 1.22.0 1.22.1 1.23.0 1.23.1 1.24.0 1.24.1 1.25.0 1.25.1 1.26.0 1.27.0 1.28.0 1.28.1 1.28.2 1.28.3 1.29.0 1.3 1.30.0 1.30.1 1.4 1.5 1.6 1.7 1.8 1.9 2.0.0 2.0.1 2.1.4 2.1.5 2.1.6 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.10 2.11.2 2.11.3 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.9 2.12.0 2.12.1 2.12.2 2.13.1 2.13.2 2.13.5 2.13.6 2.14.0 2.14.1 2.14.2 2.14.4 2.14.6 2.14.7 2.14.8 2.14.9 2.2.0 2.2.1 2.3.1 2.3.2 2.4.2 2.4.3 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.7.1 2.7.2 2.7.3 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7
independent-analytics / vendor / mlocati / ip-lib / src / Range / Subnet.php
independent-analytics / vendor / mlocati / ip-lib / src / Range Last commit date
AbstractRange.php 1 year ago Pattern.php 1 year ago RangeInterface.php 1 year ago Single.php 1 year ago Subnet.php 1 year ago Type.php 1 year ago
Subnet.php
327 lines
1 <?php
2
3 namespace IAWPSCOPED\IPLib\Range;
4
5 use IAWPSCOPED\IPLib\Address\AddressInterface;
6 use IAWPSCOPED\IPLib\Address\IPv4;
7 use IAWPSCOPED\IPLib\Address\Type as AddressType;
8 use IAWPSCOPED\IPLib\Factory;
9 use IAWPSCOPED\IPLib\ParseStringFlag;
10 /**
11 * Represents an address range in subnet format (eg CIDR).
12 *
13 * @example 127.0.0.1/32
14 * @example ::/8
15 * @internal
16 */
17 class Subnet extends AbstractRange
18 {
19 /**
20 * Starting address of the range.
21 *
22 * @var \IPLib\Address\AddressInterface
23 */
24 protected $fromAddress;
25 /**
26 * Final address of the range.
27 *
28 * @var \IPLib\Address\AddressInterface
29 */
30 protected $toAddress;
31 /**
32 * Number of the same bits of the range.
33 *
34 * @var int
35 */
36 protected $networkPrefix;
37 /**
38 * The type of the range of this IP range.
39 *
40 * @var int|null
41 *
42 * @since 1.5.0
43 */
44 protected $rangeType;
45 /**
46 * The 6to4 address IPv6 address range.
47 *
48 * @var self|null
49 */
50 private static $sixToFour;
51 /**
52 * Initializes the instance.
53 *
54 * @param \IPLib\Address\AddressInterface $fromAddress
55 * @param \IPLib\Address\AddressInterface $toAddress
56 * @param int $networkPrefix
57 *
58 * @internal
59 */
60 public function __construct(AddressInterface $fromAddress, AddressInterface $toAddress, $networkPrefix)
61 {
62 $this->fromAddress = $fromAddress;
63 $this->toAddress = $toAddress;
64 $this->networkPrefix = $networkPrefix;
65 }
66 /**
67 * {@inheritdoc}
68 *
69 * @see \IPLib\Range\RangeInterface::__toString()
70 */
71 public function __toString()
72 {
73 return $this->toString();
74 }
75 /**
76 * @deprecated since 1.17.0: use the parseString() method instead.
77 * For upgrading:
78 * - if $supportNonDecimalIPv4 is true, use the ParseStringFlag::IPV4_MAYBE_NON_DECIMAL flag
79 *
80 * @param string|mixed $range
81 * @param bool $supportNonDecimalIPv4
82 *
83 * @return static|null
84 *
85 * @see \IPLib\Range\Subnet::parseString()
86 * @since 1.10.0 added the $supportNonDecimalIPv4 argument
87 */
88 public static function fromString($range, $supportNonDecimalIPv4 = \false)
89 {
90 return static::parseString($range, ParseStringFlag::MAY_INCLUDE_PORT | ParseStringFlag::MAY_INCLUDE_ZONEID | ($supportNonDecimalIPv4 ? ParseStringFlag::IPV4_MAYBE_NON_DECIMAL : 0));
91 }
92 /**
93 * Try get the range instance starting from its string representation.
94 *
95 * @param string|mixed $range
96 * @param int $flags A combination or zero or more flags
97 *
98 * @return static|null
99 *
100 * @see \IPLib\ParseStringFlag
101 * @since 1.17.0
102 */
103 public static function parseString($range, $flags = 0)
104 {
105 if (!\is_string($range)) {
106 return null;
107 }
108 $parts = \explode('/', $range);
109 if (\count($parts) !== 2) {
110 return null;
111 }
112 $flags = (int) $flags;
113 if (\strpos($parts[0], ':') === \false && $flags & ParseStringFlag::IPV4SUBNET_MAYBE_COMPACT) {
114 $missingDots = 3 - \substr_count($parts[0], '.');
115 if ($missingDots > 0) {
116 $parts[0] .= \str_repeat('.0', $missingDots);
117 }
118 }
119 $address = Factory::parseAddressString($parts[0], $flags);
120 if ($address === null) {
121 return null;
122 }
123 if (!\preg_match('/^[0-9]{1,9}$/', $parts[1])) {
124 return null;
125 }
126 $networkPrefix = (int) $parts[1];
127 $addressBytes = $address->getBytes();
128 $totalBytes = \count($addressBytes);
129 $numDifferentBits = $totalBytes * 8 - $networkPrefix;
130 if ($numDifferentBits < 0) {
131 return null;
132 }
133 $numSameBytes = $networkPrefix >> 3;
134 $sameBytes = \array_slice($addressBytes, 0, $numSameBytes);
135 $differentBytesStart = $totalBytes === $numSameBytes ? array() : \array_fill(0, $totalBytes - $numSameBytes, 0);
136 $differentBytesEnd = $totalBytes === $numSameBytes ? array() : \array_fill(0, $totalBytes - $numSameBytes, 255);
137 $startSameBits = $networkPrefix % 8;
138 if ($startSameBits !== 0) {
139 $varyingByte = $addressBytes[$numSameBytes];
140 $differentBytesStart[0] = $varyingByte & \bindec(\str_pad(\str_repeat('1', $startSameBits), 8, '0', \STR_PAD_RIGHT));
141 $differentBytesEnd[0] = $differentBytesStart[0] + \bindec(\str_repeat('1', 8 - $startSameBits));
142 }
143 return new static(Factory::addressFromBytes(\array_merge($sameBytes, $differentBytesStart)), Factory::addressFromBytes(\array_merge($sameBytes, $differentBytesEnd)), $networkPrefix);
144 }
145 /**
146 * {@inheritdoc}
147 *
148 * @see \IPLib\Range\RangeInterface::toString()
149 */
150 public function toString($long = \false)
151 {
152 return $this->fromAddress->toString($long) . '/' . $this->networkPrefix;
153 }
154 /**
155 * {@inheritdoc}
156 *
157 * @see \IPLib\Range\RangeInterface::getAddressType()
158 */
159 public function getAddressType()
160 {
161 return $this->fromAddress->getAddressType();
162 }
163 /**
164 * {@inheritdoc}
165 *
166 * @see \IPLib\Range\RangeInterface::getStartAddress()
167 */
168 public function getStartAddress()
169 {
170 return $this->fromAddress;
171 }
172 /**
173 * {@inheritdoc}
174 *
175 * @see \IPLib\Range\RangeInterface::getEndAddress()
176 */
177 public function getEndAddress()
178 {
179 return $this->toAddress;
180 }
181 /**
182 * {@inheritdoc}
183 *
184 * @see \IPLib\Range\RangeInterface::getComparableStartString()
185 */
186 public function getComparableStartString()
187 {
188 return $this->fromAddress->getComparableString();
189 }
190 /**
191 * {@inheritdoc}
192 *
193 * @see \IPLib\Range\RangeInterface::getComparableEndString()
194 */
195 public function getComparableEndString()
196 {
197 return $this->toAddress->getComparableString();
198 }
199 /**
200 * {@inheritdoc}
201 *
202 * @see \IPLib\Range\RangeInterface::asSubnet()
203 */
204 public function asSubnet()
205 {
206 return $this;
207 }
208 /**
209 * {@inheritdoc}
210 *
211 * @see \IPLib\Range\RangeInterface::asPattern()
212 * @since 1.8.0
213 */
214 public function asPattern()
215 {
216 $address = $this->getStartAddress();
217 $networkPrefix = $this->getNetworkPrefix();
218 switch ($address->getAddressType()) {
219 case AddressType::T_IPv4:
220 return $networkPrefix % 8 === 0 ? new Pattern($address, $address, 4 - $networkPrefix / 8) : null;
221 case AddressType::T_IPv6:
222 return $networkPrefix % 16 === 0 ? new Pattern($address, $address, 8 - $networkPrefix / 16) : null;
223 }
224 }
225 /**
226 * Get the 6to4 address IPv6 address range.
227 *
228 * @return self
229 *
230 * @since 1.5.0
231 */
232 public static function get6to4()
233 {
234 if (self::$sixToFour === null) {
235 self::$sixToFour = self::parseString('2002::/16');
236 }
237 return self::$sixToFour;
238 }
239 /**
240 * Get subnet prefix.
241 *
242 * @return int
243 *
244 * @since 1.7.0
245 */
246 public function getNetworkPrefix()
247 {
248 return $this->networkPrefix;
249 }
250 /**
251 * {@inheritdoc}
252 *
253 * @see \IPLib\Range\RangeInterface::getSubnetMask()
254 */
255 public function getSubnetMask()
256 {
257 if ($this->getAddressType() !== AddressType::T_IPv4) {
258 return null;
259 }
260 $bytes = array();
261 $prefix = $this->getNetworkPrefix();
262 while ($prefix >= 8) {
263 $bytes[] = 255;
264 $prefix -= 8;
265 }
266 if ($prefix !== 0) {
267 $bytes[] = \bindec(\str_pad(\str_repeat('1', $prefix), 8, '0'));
268 }
269 $bytes = \array_pad($bytes, 4, 0);
270 return IPv4::fromBytes($bytes);
271 }
272 /**
273 * {@inheritdoc}
274 *
275 * @see \IPLib\Range\RangeInterface::getReverseDNSLookupName()
276 */
277 public function getReverseDNSLookupName()
278 {
279 switch ($this->getAddressType()) {
280 case AddressType::T_IPv4:
281 $unitSize = 8;
282 // bytes
283 $maxUnits = 4;
284 $isHex = \false;
285 $rxUnit = '\\d+';
286 break;
287 case AddressType::T_IPv6:
288 $unitSize = 4;
289 // nibbles
290 $maxUnits = 32;
291 $isHex = \true;
292 $rxUnit = '[0-9A-Fa-f]';
293 break;
294 }
295 $totBits = $unitSize * $maxUnits;
296 $prefixUnits = (int) ($this->networkPrefix / $unitSize);
297 $extraBits = ($totBits - $this->networkPrefix) % $unitSize;
298 if ($extraBits !== 0) {
299 $prefixUnits += 1;
300 }
301 $numVariants = 1 << $extraBits;
302 $result = array();
303 $unitsToRemove = $maxUnits - $prefixUnits;
304 $initialPointer = \preg_replace("/^(({$rxUnit})\\.){{$unitsToRemove}}/", '', $this->getStartAddress()->getReverseDNSLookupName());
305 $chunks = \explode('.', $initialPointer, 2);
306 for ($index = 0; $index < $numVariants; $index++) {
307 if ($index !== 0) {
308 $chunks[0] = $isHex ? \dechex(1 + \hexdec($chunks[0])) : (string) (1 + (int) $chunks[0]);
309 }
310 $result[] = \implode('.', $chunks);
311 }
312 return $result;
313 }
314 /**
315 * {@inheritdoc}
316 *
317 * @see \IPLib\Range\RangeInterface::getSize()
318 */
319 public function getSize()
320 {
321 $fromAddress = $this->fromAddress;
322 $maxPrefix = $fromAddress::getNumberOfBits();
323 $prefix = $this->getNetworkPrefix();
324 return \pow(2, $maxPrefix - $prefix);
325 }
326 }
327