PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 2.15.2
Independent Analytics – WordPress Analytics Plugin v2.15.2
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 2 weeks ago Pattern.php 2 weeks ago RangeInterface.php 2 weeks ago Single.php 2 weeks ago Subnet.php 2 weeks ago Type.php 2 weeks ago
Subnet.php
348 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 use IAWPSCOPED\IPLib\Service\BinaryMath;
11 /**
12 * Represents an address range in subnet format (eg CIDR).
13 *
14 * @example 127.0.0.1/32
15 * @example ::/8
16 *
17 * @phpstan-consistent-constructor
18 * @internal
19 */
20 class Subnet extends AbstractRange
21 {
22 /**
23 * Starting address of the range.
24 *
25 * @var \IPLib\Address\AddressInterface
26 */
27 protected $fromAddress;
28 /**
29 * Final address of the range.
30 *
31 * @var \IPLib\Address\AddressInterface
32 */
33 protected $toAddress;
34 /**
35 * Number of the same bits of the range.
36 *
37 * @var int
38 */
39 protected $networkPrefix;
40 /**
41 * The type of the range of this IP range.
42 *
43 * @var int|null
44 *
45 * @since 1.5.0
46 */
47 protected $rangeType;
48 /**
49 * The 6to4 address IPv6 address range.
50 *
51 * @var self|null
52 */
53 private static $sixToFour;
54 /**
55 * Initializes the instance.
56 *
57 * @param \IPLib\Address\AddressInterface $fromAddress
58 * @param \IPLib\Address\AddressInterface $toAddress
59 * @param int $networkPrefix
60 *
61 * @internal
62 */
63 public function __construct(AddressInterface $fromAddress, AddressInterface $toAddress, $networkPrefix)
64 {
65 $this->fromAddress = $fromAddress;
66 $this->toAddress = $toAddress;
67 $this->networkPrefix = $networkPrefix;
68 }
69 /**
70 * {@inheritdoc}
71 *
72 * @see \IPLib\Range\RangeInterface::__toString()
73 */
74 public function __toString()
75 {
76 return $this->toString();
77 }
78 /**
79 * @deprecated since 1.17.0: use the parseString() method instead.
80 * For upgrading:
81 * - if $supportNonDecimalIPv4 is true, use the ParseStringFlag::IPV4_MAYBE_NON_DECIMAL flag
82 *
83 * @param string|mixed $range
84 * @param bool $supportNonDecimalIPv4
85 *
86 * @return static|null
87 *
88 * @see \IPLib\Range\Subnet::parseString()
89 * @since 1.10.0 added the $supportNonDecimalIPv4 argument
90 */
91 public static function fromString($range, $supportNonDecimalIPv4 = \false)
92 {
93 return static::parseString($range, ParseStringFlag::MAY_INCLUDE_PORT | ParseStringFlag::MAY_INCLUDE_ZONEID | ($supportNonDecimalIPv4 ? ParseStringFlag::IPV4_MAYBE_NON_DECIMAL : 0));
94 }
95 /**
96 * Try get the range instance starting from its string representation.
97 *
98 * @param string|mixed $range
99 * @param int $flags A combination or zero or more flags
100 *
101 * @return static|null
102 *
103 * @see \IPLib\ParseStringFlag
104 * @since 1.17.0
105 */
106 public static function parseString($range, $flags = 0)
107 {
108 if (!\is_string($range)) {
109 return null;
110 }
111 $parts = \explode('/', $range);
112 if (\count($parts) !== 2) {
113 return null;
114 }
115 $flags = (int) $flags;
116 if (\strpos($parts[0], ':') === \false && $flags & ParseStringFlag::IPV4SUBNET_MAYBE_COMPACT) {
117 $missingDots = 3 - \substr_count($parts[0], '.');
118 if ($missingDots > 0) {
119 $parts[0] .= \str_repeat('.0', $missingDots);
120 }
121 }
122 $address = Factory::parseAddressString($parts[0], $flags);
123 if ($address === null) {
124 return null;
125 }
126 if (!\preg_match('/^[0-9]{1,9}$/', $parts[1])) {
127 return null;
128 }
129 $networkPrefix = (int) $parts[1];
130 $addressBytes = $address->getBytes();
131 $totalBytes = \count($addressBytes);
132 $numDifferentBits = $totalBytes * 8 - $networkPrefix;
133 if ($numDifferentBits < 0) {
134 return null;
135 }
136 $numSameBytes = $networkPrefix >> 3;
137 $sameBytes = \array_slice($addressBytes, 0, $numSameBytes);
138 $differentBytesStart = $totalBytes === $numSameBytes ? array() : \array_fill(0, $totalBytes - $numSameBytes, 0);
139 $differentBytesEnd = $totalBytes === $numSameBytes ? array() : \array_fill(0, $totalBytes - $numSameBytes, 255);
140 $startSameBits = $networkPrefix % 8;
141 if ($startSameBits !== 0) {
142 $varyingByte = $addressBytes[$numSameBytes];
143 $differentBytesStart[0] = $varyingByte & (int) \bindec(\str_pad(\str_repeat('1', $startSameBits), 8, '0', \STR_PAD_RIGHT));
144 $differentBytesEnd[0] = $differentBytesStart[0] + (int) \bindec(\str_repeat('1', 8 - $startSameBits));
145 }
146 $fromAddress = Factory::addressFromBytes(\array_merge($sameBytes, $differentBytesStart));
147 /** @var \IPLib\Address\AddressInterface $fromAddress */
148 $toAddress = Factory::addressFromBytes(\array_merge($sameBytes, $differentBytesEnd));
149 /** @var \IPLib\Address\AddressInterface $toAddress */
150 return new static($fromAddress, $toAddress, $networkPrefix);
151 }
152 /**
153 * {@inheritdoc}
154 *
155 * @see \IPLib\Range\RangeInterface::toString()
156 */
157 public function toString($long = \false)
158 {
159 return $this->fromAddress->toString($long) . '/' . $this->networkPrefix;
160 }
161 /**
162 * {@inheritdoc}
163 *
164 * @see \IPLib\Range\RangeInterface::getAddressType()
165 */
166 public function getAddressType()
167 {
168 return $this->fromAddress->getAddressType();
169 }
170 /**
171 * {@inheritdoc}
172 *
173 * @see \IPLib\Range\RangeInterface::getStartAddress()
174 */
175 public function getStartAddress()
176 {
177 return $this->fromAddress;
178 }
179 /**
180 * {@inheritdoc}
181 *
182 * @see \IPLib\Range\RangeInterface::getEndAddress()
183 */
184 public function getEndAddress()
185 {
186 return $this->toAddress;
187 }
188 /**
189 * {@inheritdoc}
190 *
191 * @see \IPLib\Range\RangeInterface::getComparableStartString()
192 */
193 public function getComparableStartString()
194 {
195 return $this->fromAddress->getComparableString();
196 }
197 /**
198 * {@inheritdoc}
199 *
200 * @see \IPLib\Range\RangeInterface::getComparableEndString()
201 */
202 public function getComparableEndString()
203 {
204 return $this->toAddress->getComparableString();
205 }
206 /**
207 * {@inheritdoc}
208 *
209 * @see \IPLib\Range\RangeInterface::asSubnet()
210 */
211 public function asSubnet()
212 {
213 return $this;
214 }
215 /**
216 * {@inheritdoc}
217 *
218 * @see \IPLib\Range\RangeInterface::asPattern()
219 * @since 1.8.0
220 */
221 public function asPattern()
222 {
223 $address = $this->getStartAddress();
224 $networkPrefix = $this->getNetworkPrefix();
225 switch ($address->getAddressType()) {
226 case AddressType::T_IPv4:
227 return $networkPrefix % 8 === 0 ? new Pattern($address, $address, 4 - $networkPrefix / 8) : null;
228 case AddressType::T_IPv6:
229 return $networkPrefix % 16 === 0 ? new Pattern($address, $address, 8 - $networkPrefix / 16) : null;
230 }
231 }
232 /**
233 * Get the 6to4 address IPv6 address range.
234 *
235 * @return self
236 *
237 * @since 1.5.0
238 */
239 public static function get6to4()
240 {
241 if (self::$sixToFour === null) {
242 $subnet = self::parseString('2002::/16');
243 /** @var Subnet $subnet */
244 self::$sixToFour = $subnet;
245 }
246 return self::$sixToFour;
247 }
248 /**
249 * {@inheritdoc}
250 *
251 * @see \IPLib\Range\RangeInterface::getNetworkPrefix()
252 * @since 1.7.0
253 */
254 public function getNetworkPrefix()
255 {
256 return $this->networkPrefix;
257 }
258 /**
259 * {@inheritdoc}
260 *
261 * @see \IPLib\Range\RangeInterface::getSubnetMask()
262 */
263 public function getSubnetMask()
264 {
265 if ($this->getAddressType() !== AddressType::T_IPv4) {
266 return null;
267 }
268 $bytes = array();
269 $prefix = $this->getNetworkPrefix();
270 while ($prefix >= 8) {
271 $bytes[] = 255;
272 $prefix -= 8;
273 }
274 if ($prefix !== 0) {
275 $bytes[] = \bindec(\str_pad(\str_repeat('1', $prefix), 8, '0'));
276 }
277 $bytes = \array_pad($bytes, 4, 0);
278 return IPv4::fromBytes($bytes);
279 }
280 /**
281 * {@inheritdoc}
282 *
283 * @see \IPLib\Range\RangeInterface::getReverseDNSLookupName()
284 */
285 public function getReverseDNSLookupName()
286 {
287 switch ($this->getAddressType()) {
288 case AddressType::T_IPv4:
289 $unitSize = 8;
290 // bytes
291 $maxUnits = 4;
292 $isHex = \false;
293 $rxUnit = '\\d+';
294 break;
295 case AddressType::T_IPv6:
296 $unitSize = 4;
297 // nibbles
298 $maxUnits = 32;
299 $isHex = \true;
300 $rxUnit = '[0-9A-Fa-f]';
301 break;
302 }
303 $totBits = $unitSize * $maxUnits;
304 $prefixUnits = (int) ($this->networkPrefix / $unitSize);
305 $extraBits = ($totBits - $this->networkPrefix) % $unitSize;
306 if ($extraBits !== 0) {
307 $prefixUnits += 1;
308 }
309 $numVariants = 1 << $extraBits;
310 $result = array();
311 $unitsToRemove = $maxUnits - $prefixUnits;
312 $initialPointer = \preg_replace("/^(({$rxUnit})\\.){{$unitsToRemove}}/", '', $this->getStartAddress()->getReverseDNSLookupName());
313 /** @var string $initialPointer */
314 $chunks = \explode('.', $initialPointer, 2);
315 for ($index = 0; $index < $numVariants; $index++) {
316 if ($index !== 0) {
317 $chunks[0] = $isHex ? \dechex(1 + (int) \hexdec($chunks[0])) : (string) (1 + (int) $chunks[0]);
318 }
319 $result[] = \implode('.', $chunks);
320 }
321 return $result;
322 }
323 /**
324 * {@inheritdoc}
325 *
326 * @see \IPLib\Range\RangeInterface::getSize()
327 */
328 public function getSize()
329 {
330 $fromAddress = $this->fromAddress;
331 $maxPrefix = $fromAddress::getNumberOfBits();
332 $prefix = $this->getNetworkPrefix();
333 return \pow(2, $maxPrefix - $prefix);
334 }
335 /**
336 * {@inheritdoc}
337 *
338 * @see \IPLib\Range\RangeInterface::getExactSize()
339 */
340 public function getExactSize()
341 {
342 $fromAddress = $this->fromAddress;
343 $maxPrefix = $fromAddress::getNumberOfBits();
344 $prefix = $this->getNetworkPrefix();
345 return BinaryMath::getInstance()->pow2string($maxPrefix - $prefix);
346 }
347 }
348