diff --git a/CHANGELOG.md b/CHANGELOG.md index 2978643..4ccf07c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,9 @@ - Bugfix: classify full `fc00::/7` block as private use. - Add (or update) community standards: `SECURITY.md`, `CODE_OF_CONDUCT.md` and `CONTRIBUTING.md` +- Rename `isPublicUse()` to `isGloballyReachable()`, conforming to the official + wording used in the IANA special-purpose address registries ("Public Use" + does not appear in them). Keep `isPublicUse()` as a deprecated alias. ## `6.0.0` diff --git a/src/IpInterface.php b/src/IpInterface.php index c93c318..5557748 100644 --- a/src/IpInterface.php +++ b/src/IpInterface.php @@ -127,6 +127,14 @@ public function isBenchmarking(): bool; */ public function isDocumentation(): bool; + /** + * Superseded by `isGloballyReachable()` which conforms to official wording; + * "Public Use" does not appear in the IANA special-purpose registries. + * + * @deprecated + */ + public function isPublicUse(): bool; + /** * Whether the IP appears to be publicly/globally routable. Please refer to * the IANA Special-Purpose Address Registry documents. @@ -134,7 +142,7 @@ public function isDocumentation(): bool; * @see https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml * @see https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv6-special-registry.xhtml */ - public function isPublicUse(): bool; + public function isGloballyReachable(): bool; /** Implement string casting for IP objects. */ public function __toString(): string; diff --git a/src/Version/IPv4.php b/src/Version/IPv4.php index a5e0d67..e1c88ad 100644 --- a/src/Version/IPv4.php +++ b/src/Version/IPv4.php @@ -102,6 +102,11 @@ public function isDocumentation(): bool } public function isPublicUse(): bool + { + return $this->isGloballyReachable(); + } + + public function isGloballyReachable(): bool { // Both 192.0.0.9 and 192.0.0.10 are globally routable, despite being in the future reserved block. if (in_array(Binary::toHex($this->getBinary()), ['c0000009', 'c000000a'], true)) { diff --git a/src/Version/IPv6.php b/src/Version/IPv6.php index 0be944d..d08b1f2 100644 --- a/src/Version/IPv6.php +++ b/src/Version/IPv6.php @@ -126,6 +126,11 @@ public function isDocumentation(): bool } public function isPublicUse(): bool + { + return $this->isGloballyReachable(); + } + + public function isGloballyReachable(): bool { return self::MULTICAST_GLOBAL === $this->getMulticastScope() || $this->isUnicastGlobal(); } diff --git a/src/Version/Multi.php b/src/Version/Multi.php index a9844b1..d15fb15 100644 --- a/src/Version/Multi.php +++ b/src/Version/Multi.php @@ -235,10 +235,15 @@ public function isDocumentation(): bool } public function isPublicUse(): bool + { + return $this->isGloballyReachable(); + } + + public function isGloballyReachable(): bool { return $this->isEmbedded() - ? (new IPv4($this->getShortBinary()))->isPublicUse() - : parent::isPublicUse(); + ? (new IPv4($this->getShortBinary()))->isGloballyReachable() + : parent::isGloballyReachable(); } public function isUniqueLocal(): bool diff --git a/tests/DataProvider/IPv4.php b/tests/DataProvider/IPv4.php index 41e7c1b..25753b9 100644 --- a/tests/DataProvider/IPv4.php +++ b/tests/DataProvider/IPv4.php @@ -195,9 +195,9 @@ public static function getDocumentationIpAddresses() } /** @return list */ - public static function getPublicUseIpAddresses() + public static function getGloballyReachableIpAddresses() { - return self::getCategoryOfIpAddresses(self::PUBLIC_USE_V4); + return self::getCategoryOfIpAddresses(self::GLOBALLY_REACHABLE_V4); } /** @return list */ @@ -226,16 +226,16 @@ public static function getCategorizedIpAddresses() '172.31.254.253' => self::PRIVATE_USE, '169.254.253.242' => self::LINK_LOCAL, '192.0.2.183' => self::DOCUMENTATION, - '192.1.2.183' => self::PUBLIC_USE, + '192.1.2.183' => self::GLOBALLY_REACHABLE_V4, '192.168.254.253' => self::PRIVATE_USE, '198.51.100.0' => self::DOCUMENTATION, '203.0.113.0' => self::DOCUMENTATION, - '203.2.113.0' => self::PUBLIC_USE, + '203.2.113.0' => self::GLOBALLY_REACHABLE_V4, '255.255.255.255' => self::BROADCAST, '198.18.0.0' => self::BENCHMARKING, '198.18.54.2' => self::BENCHMARKING, - '224.0.0.0' => self::PUBLIC_USE | self::MULTICAST_IPV4, - '239.255.255.255' => self::PUBLIC_USE | self::MULTICAST_IPV4, + '224.0.0.0' => self::GLOBALLY_REACHABLE_V4 | self::MULTICAST_IPV4, + '239.255.255.255' => self::GLOBALLY_REACHABLE_V4 | self::MULTICAST_IPV4, '0.0.0.0' => self::UNSPECIFIED, '10.0.0.0' => self::PRIVATE_USE, '10.255.255.255' => self::PRIVATE_USE, @@ -249,16 +249,16 @@ public static function getCategorizedIpAddresses() '169.254.255.255' => self::LINK_LOCAL, '100.64.91.200' => self::SHARED, '251.0.12.101' => self::FUTURE_RESERVED, - '192.18.0.0' => self::PUBLIC_USE, + '192.18.0.0' => self::GLOBALLY_REACHABLE_V4, '198.19.255.255' => self::BENCHMARKING, - '129.129.154.203' => self::PUBLIC_USE, - '239.248.153.114' => self::PUBLIC_USE | self::MULTICAST_IPV4, - '85.101.159.135' => self::PUBLIC_USE, - '72.64.156.77' => self::PUBLIC_USE, - '162.199.210.167' => self::PUBLIC_USE, - '2.12.191.95' => self::PUBLIC_USE, - '83.125.176.74' => self::PUBLIC_USE, - '224.0.65.129' => self::PUBLIC_USE | self::MULTICAST_IPV4, + '129.129.154.203' => self::GLOBALLY_REACHABLE_V4, + '239.248.153.114' => self::GLOBALLY_REACHABLE_V4 | self::MULTICAST_IPV4, + '85.101.159.135' => self::GLOBALLY_REACHABLE_V4, + '72.64.156.77' => self::GLOBALLY_REACHABLE_V4, + '162.199.210.167' => self::GLOBALLY_REACHABLE_V4, + '2.12.191.95' => self::GLOBALLY_REACHABLE_V4, + '83.125.176.74' => self::GLOBALLY_REACHABLE_V4, + '224.0.65.129' => self::GLOBALLY_REACHABLE_V4 | self::MULTICAST_IPV4, ]; } diff --git a/tests/DataProvider/IPv6.php b/tests/DataProvider/IPv6.php index 61a4a67..635135f 100644 --- a/tests/DataProvider/IPv6.php +++ b/tests/DataProvider/IPv6.php @@ -212,18 +212,18 @@ public static function getDocumentationIpAddresses() } /** @return list */ - public static function getPublicUseIpAddresses() + public static function getGloballyReachableIpAddresses() { - return self::getCategoryOfIpAddresses(self::PUBLIC_USE_V6); + return self::getCategoryOfIpAddresses(self::GLOBALLY_REACHABLE_V6); } /** @return list */ - public static function getPublicUseIpAddressesExcludingMapped() + public static function getGloballyReachableIpAddressesExcludingMapped() { // Exclude IPv4-embedded addresses embedded using the Mapped strategy, // they may fail the test because the IPv4 equivalent is not public (eg, // "::ffff:7f00:1"). - return self::getCategoryOfIpAddresses(self::PUBLIC_USE_V6, self::MAPPED); + return self::getCategoryOfIpAddresses(self::GLOBALLY_REACHABLE_V6, self::MAPPED); } /** @return list */ @@ -268,8 +268,8 @@ public static function getCategorizedIpAddresses() '::' => self::UNSPECIFIED | self::UNICAST_OTHER | self::COMPATIBLE, '::0' => self::UNSPECIFIED | self::UNICAST_OTHER | self::COMPATIBLE, '::1' => self::LOOPBACK | self::UNICAST_OTHER | self::COMPATIBLE, - '::0.0.0.2' => self::PUBLIC_USE_V6 | self::UNICAST_GLOBAL | self::COMPATIBLE, - '1::' => self::PUBLIC_USE_V6 | self::UNICAST_GLOBAL, + '::0.0.0.2' => self::GLOBALLY_REACHABLE_V6 | self::UNICAST_GLOBAL | self::COMPATIBLE, + '1::' => self::GLOBALLY_REACHABLE_V6 | self::UNICAST_GLOBAL, 'fc00::' => self::PRIVATE_USE | self::UNIQUE_LOCAL | self::UNICAST_OTHER, 'fdff:ffff::' => self::PRIVATE_USE | self::UNIQUE_LOCAL | self::UNICAST_OTHER, 'fe80:ffff::' => self::LINK_LOCAL, @@ -279,38 +279,38 @@ public static function getCategorizedIpAddresses() 'febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff' => self::LINK_LOCAL, 'fe80::ffff:ffff:ffff:ffff' => self::LINK_LOCAL, 'fe80:0:0:1::' => self::LINK_LOCAL, - 'fec0::' => self::PUBLIC_USE_V6 | self::UNICAST_GLOBAL, + 'fec0::' => self::GLOBALLY_REACHABLE_V6 | self::UNICAST_GLOBAL, 'ff01::' => self::MULTICAST_INTERFACE_LOCAL, 'ff02::' => self::MULTICAST_LINK_LOCAL, 'ff03::' => self::MULTICAST_REALM_LOCAL, 'ff04::' => self::MULTICAST_ADMIN_LOCAL, 'ff05::' => self::MULTICAST_SITE_LOCAL, 'ff08::' => self::MULTICAST_ORGANIZATION_LOCAL, - 'ff0e::' => self::PUBLIC_USE_V6 | self::MULTICAST_GLOBAL, + 'ff0e::' => self::GLOBALLY_REACHABLE_V6 | self::MULTICAST_GLOBAL, '2001:db8:85a3::8a2e:370:7334' => self::DOCUMENTATION | self::UNICAST_OTHER, - '2001:2::ac32:23ff:21' => self::PUBLIC_USE_V6 | self::BENCHMARKING | self::UNICAST_GLOBAL, - '102:304:506:708:90a:b0c:d0e:f10' => self::PUBLIC_USE_V6 | self::UNICAST_GLOBAL, + '2001:2::ac32:23ff:21' => self::GLOBALLY_REACHABLE_V6 | self::BENCHMARKING | self::UNICAST_GLOBAL, + '102:304:506:708:90a:b0c:d0e:f10' => self::GLOBALLY_REACHABLE_V6 | self::UNICAST_GLOBAL, 'fd00::' => self::PRIVATE_USE | self::UNIQUE_LOCAL | self::UNICAST_OTHER, 'fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff' => self::PRIVATE_USE | self::UNIQUE_LOCAL | self::UNICAST_OTHER, 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff' => self::MULTICAST_OTHER, - '::ffff:1:0' => self::PUBLIC_USE_V6 | self::UNICAST_GLOBAL | self::MAPPED, - '::ffff:7f00:1' => self::PUBLIC_USE_V6 | self::UNICAST_GLOBAL | self::MAPPED | self::LOOPBACK_MAPPED, - '::ffff:1234:5678' => self::PUBLIC_USE_V6 | self::UNICAST_GLOBAL | self::MAPPED, - '0000:0000:0000:0000:0000:ffff:7f00:a001' => self::PUBLIC_USE_V6 | self::UNICAST_GLOBAL | self::MAPPED | self::LOOPBACK_MAPPED, - '2002::' => self::PUBLIC_USE_V6 | self::UNICAST_GLOBAL | self::DERIVED, - '2002:7f00:1::' => self::PUBLIC_USE_V6 | self::UNICAST_GLOBAL | self::DERIVED | self::LOOPBACK_DERIVED, - '2002:1234:4321:0:00:000:0000::' => self::PUBLIC_USE_V6 | self::UNICAST_GLOBAL | self::DERIVED, - '::7f00:1' => self::PUBLIC_USE_V6 | self::UNICAST_GLOBAL | self::COMPATIBLE | self::LOOPBACK_COMPATIBLE, - '::12.34.56.78' => self::PUBLIC_USE_V6 | self::UNICAST_GLOBAL | self::COMPATIBLE, - '0::000:0000:b12:cab' => self::PUBLIC_USE_V6 | self::UNICAST_GLOBAL | self::COMPATIBLE, - '1cc9:7d7f:2a9f:cabd:9186:2be5:bef1:6a54' => self::PUBLIC_USE_V6 | self::UNICAST_GLOBAL, - 'b638:cc70:716:c4d4:f69c:4ee3:6c65:a0b2' => self::PUBLIC_USE_V6 | self::UNICAST_GLOBAL, - '140c:12f1:6e6f:c0bb:980e:3816:3e52:1193' => self::PUBLIC_USE_V6 | self::UNICAST_GLOBAL, - '7a30:bf4:4c6c:8dc1:e340:774d:6487:3822' => self::PUBLIC_USE_V6 | self::UNICAST_GLOBAL, - '6af8:1ceb:eaae:104a:829c:e76e:5802:13f8' => self::PUBLIC_USE_V6 | self::UNICAST_GLOBAL, - '3e48:c9fd:c569:f5dd:ee36:8075:691b:8234' => self::PUBLIC_USE_V6 | self::UNICAST_GLOBAL, - 'cab2:4f27:790f:cf03:5241:9eff:aba5:bb5c' => self::PUBLIC_USE_V6 | self::UNICAST_GLOBAL, - 'e896:8866:872b:bd4f:6d60:7aa8:ebe5:36f1' => self::PUBLIC_USE_V6 | self::UNICAST_GLOBAL, + '::ffff:1:0' => self::GLOBALLY_REACHABLE_V6 | self::UNICAST_GLOBAL | self::MAPPED, + '::ffff:7f00:1' => self::GLOBALLY_REACHABLE_V6 | self::UNICAST_GLOBAL | self::MAPPED | self::LOOPBACK_MAPPED, + '::ffff:1234:5678' => self::GLOBALLY_REACHABLE_V6 | self::UNICAST_GLOBAL | self::MAPPED, + '0000:0000:0000:0000:0000:ffff:7f00:a001' => self::GLOBALLY_REACHABLE_V6 | self::UNICAST_GLOBAL | self::MAPPED | self::LOOPBACK_MAPPED, + '2002::' => self::GLOBALLY_REACHABLE_V6 | self::UNICAST_GLOBAL | self::DERIVED, + '2002:7f00:1::' => self::GLOBALLY_REACHABLE_V6 | self::UNICAST_GLOBAL | self::DERIVED | self::LOOPBACK_DERIVED, + '2002:1234:4321:0:00:000:0000::' => self::GLOBALLY_REACHABLE_V6 | self::UNICAST_GLOBAL | self::DERIVED, + '::7f00:1' => self::GLOBALLY_REACHABLE_V6 | self::UNICAST_GLOBAL | self::COMPATIBLE | self::LOOPBACK_COMPATIBLE, + '::12.34.56.78' => self::GLOBALLY_REACHABLE_V6 | self::UNICAST_GLOBAL | self::COMPATIBLE, + '0::000:0000:b12:cab' => self::GLOBALLY_REACHABLE_V6 | self::UNICAST_GLOBAL | self::COMPATIBLE, + '1cc9:7d7f:2a9f:cabd:9186:2be5:bef1:6a54' => self::GLOBALLY_REACHABLE_V6 | self::UNICAST_GLOBAL, + 'b638:cc70:716:c4d4:f69c:4ee3:6c65:a0b2' => self::GLOBALLY_REACHABLE_V6 | self::UNICAST_GLOBAL, + '140c:12f1:6e6f:c0bb:980e:3816:3e52:1193' => self::GLOBALLY_REACHABLE_V6 | self::UNICAST_GLOBAL, + '7a30:bf4:4c6c:8dc1:e340:774d:6487:3822' => self::GLOBALLY_REACHABLE_V6 | self::UNICAST_GLOBAL, + '6af8:1ceb:eaae:104a:829c:e76e:5802:13f8' => self::GLOBALLY_REACHABLE_V6 | self::UNICAST_GLOBAL, + '3e48:c9fd:c569:f5dd:ee36:8075:691b:8234' => self::GLOBALLY_REACHABLE_V6 | self::UNICAST_GLOBAL, + 'cab2:4f27:790f:cf03:5241:9eff:aba5:bb5c' => self::GLOBALLY_REACHABLE_V6 | self::UNICAST_GLOBAL, + 'e896:8866:872b:bd4f:6d60:7aa8:ebe5:36f1' => self::GLOBALLY_REACHABLE_V6 | self::UNICAST_GLOBAL, ]; } diff --git a/tests/DataProvider/IpDataProviderInterface.php b/tests/DataProvider/IpDataProviderInterface.php index 1480f39..b780628 100644 --- a/tests/DataProvider/IpDataProviderInterface.php +++ b/tests/DataProvider/IpDataProviderInterface.php @@ -16,13 +16,13 @@ interface IpDataProviderInterface public const MULTICAST_IPV4 = 1 << 6; // IPv4 - public const PUBLIC_USE_V4 = 1 << 7; + public const GLOBALLY_REACHABLE_V4 = 1 << 7; public const BROADCAST = 1 << 8; public const SHARED = 1 << 9; public const FUTURE_RESERVED = 1 << 10; // IPv6 - public const PUBLIC_USE_V6 = 1 << 11; + public const GLOBALLY_REACHABLE_V6 = 1 << 11; public const MULTICAST_INTERFACE_LOCAL = 1 << 12; public const MULTICAST_LINK_LOCAL = 1 << 13; public const MULTICAST_REALM_LOCAL = 1 << 14; @@ -42,9 +42,9 @@ interface IpDataProviderInterface public const LOOPBACK_DERIVED = 1 << 28; // Combinations - public const PUBLIC_USE = 0 - | self::PUBLIC_USE_V4 - | self::PUBLIC_USE_V6; + public const GLOBALLY_REACHABLE = 0 + | self::GLOBALLY_REACHABLE_V4 + | self::GLOBALLY_REACHABLE_V6; public const LOOPBACK_EMBEDDED = 0 | self::LOOPBACK_MAPPED | self::LOOPBACK_COMPATIBLE diff --git a/tests/DataProvider/Multi.php b/tests/DataProvider/Multi.php index a0ef8fe..4bd1238 100644 --- a/tests/DataProvider/Multi.php +++ b/tests/DataProvider/Multi.php @@ -270,9 +270,9 @@ public static function getDocumentationIpAddresses() } /** @return list */ - public static function getPublicUseIpAddresses() + public static function getGloballyReachableIpAddresses() { - return array_merge(IPv4::getPublicUseIpAddresses(), IPv6::getPublicUseIpAddressesExcludingMapped()); + return array_merge(IPv4::getGloballyReachableIpAddresses(), IPv6::getGloballyReachableIpAddressesExcludingMapped()); } /** @return list */ diff --git a/tests/Version/IPv4Test.php b/tests/Version/IPv4Test.php index a271766..adaf2aa 100644 --- a/tests/Version/IPv4Test.php +++ b/tests/Version/IPv4Test.php @@ -415,14 +415,14 @@ public function testIsDocumentation(string $value, bool $isDocumentation): void /** * @test - * @dataProvider \Darsyn\IP\Tests\DataProvider\IPv4::getPublicUseIpAddresses() + * @dataProvider \Darsyn\IP\Tests\DataProvider\IPv4::getGloballyReachableIpAddresses() */ #[PHPUnit\Test] - #[PHPUnit\DataProviderExternal(IPv4DataProvider::class, 'getPublicUseIpAddresses')] - public function testIsPublicUse(string $value, bool $isPublicUse): void + #[PHPUnit\DataProviderExternal(IPv4DataProvider::class, 'getGloballyReachableIpAddresses')] + public function testIsGloballyReachable(string $value, bool $isGloballyReachable): void { $ip = IP::factory($value); - $this->assertSame($isPublicUse, $ip->isPublicUse()); + $this->assertSame($isGloballyReachable, $ip->isGloballyReachable()); } /** diff --git a/tests/Version/IPv6Test.php b/tests/Version/IPv6Test.php index 58a30bf..3faf668 100644 --- a/tests/Version/IPv6Test.php +++ b/tests/Version/IPv6Test.php @@ -457,14 +457,14 @@ public function testIsDocumentation(string $value, bool $isDocumentation): void /** * @test - * @dataProvider \Darsyn\IP\Tests\DataProvider\IPv6::getPublicUseIpAddresses() + * @dataProvider \Darsyn\IP\Tests\DataProvider\IPv6::getGloballyReachableIpAddresses() */ #[PHPUnit\Test] - #[PHPUnit\DataProviderExternal(IPv6DataProvider::class, 'getPublicUseIpAddresses')] - public function testIsPublicUse(string $value, bool $isPublicUse): void + #[PHPUnit\DataProviderExternal(IPv6DataProvider::class, 'getGloballyReachableIpAddresses')] + public function testIsGloballyReachable(string $value, bool $isGloballyReachable): void { $ip = IP::factory($value); - $this->assertSame($isPublicUse, $ip->isPublicUse()); + $this->assertSame($isGloballyReachable, $ip->isGloballyReachable()); } /** diff --git a/tests/Version/MultiTest.php b/tests/Version/MultiTest.php index c3f5324..00ca253 100644 --- a/tests/Version/MultiTest.php +++ b/tests/Version/MultiTest.php @@ -390,14 +390,14 @@ public function testIsDocumentation(string $value, bool $isDocumentation): void /** * @test - * @dataProvider \Darsyn\IP\Tests\DataProvider\Multi::getPublicUseIpAddresses() + * @dataProvider \Darsyn\IP\Tests\DataProvider\Multi::getGloballyReachableIpAddresses() */ #[PHPUnit\Test] - #[PHPUnit\DataProviderExternal(MultiDataProvider::class, 'getPublicUseIpAddresses')] - public function testIsPublicUse(string $value, bool $isPublicUse): void + #[PHPUnit\DataProviderExternal(MultiDataProvider::class, 'getGloballyReachableIpAddresses')] + public function testIsGloballyReachable(string $value, bool $isGloballyReachable): void { $ip = IP::factory($value, new Strategy\Mapped()); - $this->assertSame($isPublicUse, $ip->isPublicUse()); + $this->assertSame($isGloballyReachable, $ip->isGloballyReachable()); } /**