@@ -620,25 +620,31 @@ impl Ipv4Addr {
620
620
matches ! ( self . octets( ) , [ 169 , 254 , ..] )
621
621
}
622
622
623
- /// Returns [`true`] if the address appears to be globally routable.
624
- /// See [iana-ipv4-special-registry][ipv4-sr].
623
+ /// Returns [`true`] if the address appears to be globally reachable
624
+ /// as specified by the [IANA IPv4 Special-Purpose Address Registry].
625
+ /// Whether or not an address is practically reachable will depend on your network configuration.
626
+ ///
627
+ /// Most IPv4 addresses are globally reachable;
628
+ /// unless they are specifically defined as *not* globally reachable.
625
629
///
626
- /// The following return [`false`] :
630
+ /// Non-exhaustive list of notable addresses that are not globally reachable :
627
631
///
628
- /// - private addresses (see [`Ipv4Addr::is_private()`])
629
- /// - the loopback address (see [`Ipv4Addr::is_loopback()`])
630
- /// - the link-local address (see [`Ipv4Addr::is_link_local()`])
631
- /// - the broadcast address (see [`Ipv4Addr::is_broadcast()`])
632
- /// - addresses used for documentation (see [`Ipv4Addr::is_documentation()`])
633
- /// - the unspecified address (see [`Ipv4Addr::is_unspecified()`]), and the whole
634
- /// `0.0.0.0/8` block
635
- /// - addresses reserved for future protocols, except
636
- /// `192.0.0.9/32` and `192.0.0.10/32` which are globally routable
637
- /// - addresses reserved for future use (see [`Ipv4Addr::is_reserved()`]
638
- /// - addresses reserved for networking devices benchmarking (see
639
- /// [`Ipv4Addr::is_benchmarking()`])
632
+ /// - The [unspecified address] ([`is_unspecified`](Ipv4Addr::is_unspecified))
633
+ /// - Addresses reserved for private use ([`is_private`](Ipv4Addr::is_private))
634
+ /// - Addresses in the shared address space ([`is_shared`](Ipv4Addr::is_shared))
635
+ /// - Loopback addresses ([`is_loopback`](Ipv4Addr::is_loopback))
636
+ /// - Link-local addresses ([`is_link_local`](Ipv4Addr::is_link_local))
637
+ /// - Addresses reserved for documentation ([`is_documentation`](Ipv4Addr::is_documentation))
638
+ /// - Addresses reserved for benchmarking ([`is_benchmarking`](Ipv4Addr::is_benchmarking))
639
+ /// - Reserved addresses ([`is_reserved`](Ipv4Addr::is_reserved))
640
+ /// - The [broadcast address] ([`is_broadcast`](Ipv4Addr::is_broadcast))
640
641
///
641
- /// [ipv4-sr]: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
642
+ /// For the complete overview of which addresses are globally reachable, see the table at the [IANA IPv4 Special-Purpose Address Registry].
643
+ ///
644
+ /// [IANA IPv4 Special-Purpose Address Registry]: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
645
+ /// [unspecified address]: Ipv4Addr::UNSPECIFIED
646
+ /// [broadcast address]: Ipv4Addr::BROADCAST
647
+
642
648
///
643
649
/// # Examples
644
650
///
@@ -647,71 +653,61 @@ impl Ipv4Addr {
647
653
///
648
654
/// use std::net::Ipv4Addr;
649
655
///
650
- /// // private addresses are not global
656
+ /// // Most IPv4 addresses are globally reachable:
657
+ /// assert_eq!(Ipv4Addr::new(80, 9, 12, 3).is_global(), true);
658
+ ///
659
+ /// // However some addresses have been assigned a special meaning
660
+ /// // that makes them not globally reachable. Some examples are:
661
+ ///
662
+ /// // The unspecified address (`0.0.0.0`)
663
+ /// assert_eq!(Ipv4Addr::UNSPECIFIED.is_global(), false);
664
+ ///
665
+ /// // Addresses reserved for private use (`10.0.0.0/8`, `172.16.0.0/12`, 192.168.0.0/16)
651
666
/// assert_eq!(Ipv4Addr::new(10, 254, 0, 0).is_global(), false);
652
667
/// assert_eq!(Ipv4Addr::new(192, 168, 10, 65).is_global(), false);
653
668
/// assert_eq!(Ipv4Addr::new(172, 16, 10, 65).is_global(), false);
654
669
///
655
- /// // the 0.0.0.0/8 block is not global
656
- /// assert_eq!(Ipv4Addr::new(0, 1, 2, 3).is_global(), false);
657
- /// // in particular, the unspecified address is not global
658
- /// assert_eq!(Ipv4Addr::new(0, 0, 0, 0).is_global(), false);
670
+ /// // Addresses in the shared address space (`100.64.0.0/10`)
671
+ /// assert_eq!(Ipv4Addr::new(100, 100, 0, 0).is_global(), false);
659
672
///
660
- /// // the loopback address is not global
661
- /// assert_eq!(Ipv4Addr::new(127, 0, 0, 1) .is_global(), false);
673
+ /// // The loopback addresses (`127.0.0.0/8`)
674
+ /// assert_eq!(Ipv4Addr::LOCALHOST .is_global(), false);
662
675
///
663
- /// // link local addresses are not global
676
+ /// // Link- local addresses (`169.254.0.0/16`)
664
677
/// assert_eq!(Ipv4Addr::new(169, 254, 45, 1).is_global(), false);
665
678
///
666
- /// // the broadcast address is not global
667
- /// assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_global(), false);
668
- ///
669
- /// // the address space designated for documentation is not global
679
+ /// // Addresses reserved for documentation (`192.0.2.0/24`, `198.51.100.0/24`, `203.0.113.0/24`)
670
680
/// assert_eq!(Ipv4Addr::new(192, 0, 2, 255).is_global(), false);
671
681
/// assert_eq!(Ipv4Addr::new(198, 51, 100, 65).is_global(), false);
672
682
/// assert_eq!(Ipv4Addr::new(203, 0, 113, 6).is_global(), false);
673
683
///
674
- /// // shared addresses are not global
675
- /// assert_eq!(Ipv4Addr::new(100, 100, 0, 0).is_global(), false);
676
- ///
677
- /// // addresses reserved for protocol assignment are not global
678
- /// assert_eq!(Ipv4Addr::new(192, 0, 0, 0).is_global(), false);
679
- /// assert_eq!(Ipv4Addr::new(192, 0, 0, 255).is_global(), false);
684
+ /// // Addresses reserved for benchmarking (`198.18.0.0/15`)
685
+ /// assert_eq!(Ipv4Addr::new(198, 18, 0, 0).is_global(), false);
680
686
///
681
- /// // addresses reserved for future use are not global
687
+ /// // Reserved addresses (`240.0.0.0/4`)
682
688
/// assert_eq!(Ipv4Addr::new(250, 10, 20, 30).is_global(), false);
683
689
///
684
- /// // addresses reserved for network devices benchmarking are not global
685
- /// assert_eq!(Ipv4Addr::new(198, 18, 0, 0) .is_global(), false);
690
+ /// // The broadcast address (`255.255.255.255`)
691
+ /// assert_eq!(Ipv4Addr::BROADCAST .is_global(), false);
686
692
///
687
- /// // All the other addresses are global
688
- /// assert_eq!(Ipv4Addr::new(1, 1, 1, 1).is_global(), true);
689
- /// assert_eq!(Ipv4Addr::new(80, 9, 12, 3).is_global(), true);
693
+ /// // For a complete overview see the IANA IPv4 Special-Purpose Address Registry.
690
694
/// ```
691
695
#[ rustc_const_unstable( feature = "const_ipv4" , issue = "76205" ) ]
692
696
#[ unstable( feature = "ip" , issue = "27709" ) ]
693
697
#[ must_use]
694
698
#[ inline]
695
699
pub const fn is_global ( & self ) -> bool {
696
- // check if this address is 192.0.0.9 or 192.0.0.10. These addresses are the only two
697
- // globally routable addresses in the 192.0.0.0/24 range.
698
- if u32:: from_be_bytes ( self . octets ( ) ) == 0xc0000009
699
- || u32:: from_be_bytes ( self . octets ( ) ) == 0xc000000a
700
- {
701
- return true ;
702
- }
703
- !self . is_private ( )
704
- && !self . is_loopback ( )
705
- && !self . is_link_local ( )
706
- && !self . is_broadcast ( )
707
- && !self . is_documentation ( )
708
- && !self . is_shared ( )
700
+ !( self . octets ( ) [ 0 ] == 0 // "This network"
701
+ || self . is_private ( )
702
+ || self . is_shared ( )
703
+ || self . is_loopback ( )
704
+ || self . is_link_local ( )
709
705
// addresses reserved for future protocols (`192.0.0.0/24`)
710
- && ! ( self . octets ( ) [ 0 ] == 192 && self . octets ( ) [ 1 ] == 0 && self . octets ( ) [ 2 ] == 0 )
711
- && ! self . is_reserved ( )
712
- && ! self . is_benchmarking ( )
713
- // Make sure the address is not in 0.0.0.0/8
714
- && self . octets ( ) [ 0 ] != 0
706
+ || ( self . octets ( ) [ 0 ] == 192 && self . octets ( ) [ 1 ] == 0 && self . octets ( ) [ 2 ] == 0 )
707
+ || self . is_documentation ( )
708
+ || self . is_benchmarking ( )
709
+ || self . is_reserved ( )
710
+ || self . is_broadcast ( ) )
715
711
}
716
712
717
713
/// Returns [`true`] if this address is part of the Shared Address Space defined in
@@ -1300,13 +1296,33 @@ impl Ipv6Addr {
1300
1296
u128:: from_be_bytes ( self . octets ( ) ) == u128:: from_be_bytes ( Ipv6Addr :: LOCALHOST . octets ( ) )
1301
1297
}
1302
1298
1303
- /// Returns [`true`] if the address appears to be globally routable.
1299
+ /// Returns [`true`] if the address appears to be globally reachable
1300
+ /// as specified by the [IANA IPv6 Special-Purpose Address Registry].
1301
+ /// Whether or not an address is practically reachable will depend on your network configuration.
1304
1302
///
1305
- /// The following return [`false`]:
1303
+ /// Most IPv6 addresses are globally reachable;
1304
+ /// unless they are specifically defined as *not* globally reachable.
1306
1305
///
1307
- /// - the loopback address
1308
- /// - link-local and unique local unicast addresses
1309
- /// - interface-, link-, realm-, admin- and site-local multicast addresses
1306
+ /// Non-exhaustive list of notable addresses that are not globally reachable:
1307
+ /// - The [unspecified address] ([`is_unspecified`](Ipv6Addr::is_unspecified))
1308
+ /// - The [loopback address] ([`is_loopback`](Ipv6Addr::is_loopback))
1309
+ /// - IPv4-mapped addresses
1310
+ /// - Addresses reserved for benchmarking
1311
+ /// - Addresses reserved for documentation ([`is_documentation`](Ipv6Addr::is_documentation))
1312
+ /// - Unique local addresses ([`is_unique_local`](Ipv6Addr::is_unique_local))
1313
+ /// - Unicast addresses with link-local scope ([`is_unicast_link_local`](Ipv6Addr::is_unicast_link_local))
1314
+ ///
1315
+ /// For the complete overview of which addresses are globally reachable, see the table at the [IANA IPv6 Special-Purpose Address Registry].
1316
+ ///
1317
+ /// Note that an address having global scope is not the same as being globally reachable,
1318
+ /// and there is no direct relation between the two concepts: There exist addresses with global scope
1319
+ /// that are not globally reachable (for example unique local addresses),
1320
+ /// and addresses that are globally reachable without having global scope
1321
+ /// (multicast addresses with non-global scope).
1322
+ ///
1323
+ /// [IANA IPv6 Special-Purpose Address Registry]: https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
1324
+ /// [unspecified address]: Ipv6Addr::UNSPECIFIED
1325
+ /// [loopback address]: Ipv6Addr::LOCALHOST
1310
1326
///
1311
1327
/// # Examples
1312
1328
///
@@ -1315,20 +1331,65 @@ impl Ipv6Addr {
1315
1331
///
1316
1332
/// use std::net::Ipv6Addr;
1317
1333
///
1318
- /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_global(), true);
1319
- /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0x1).is_global(), false);
1320
- /// assert_eq!(Ipv6Addr::new(0, 0, 0x1c9, 0, 0, 0xafc8, 0, 0x1).is_global(), true);
1334
+ /// // Most IPv6 addresses are globally reachable:
1335
+ /// assert_eq!(Ipv6Addr::new(0x26, 0, 0x1c9, 0, 0, 0xafc8, 0x10, 0x1).is_global(), true);
1336
+ ///
1337
+ /// // However some addresses have been assigned a special meaning
1338
+ /// // that makes them not globally reachable. Some examples are:
1339
+ ///
1340
+ /// // The unspecified address (`::`)
1341
+ /// assert_eq!(Ipv6Addr::UNSPECIFIED.is_global(), false);
1342
+ ///
1343
+ /// // The loopback address (`::1`)
1344
+ /// assert_eq!(Ipv6Addr::LOCALHOST.is_global(), false);
1345
+ ///
1346
+ /// // IPv4-mapped addresses (`::ffff:0:0/96`)
1347
+ /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_global(), false);
1348
+ ///
1349
+ /// // Addresses reserved for benchmarking (`2001:2::/48`)
1350
+ /// assert_eq!(Ipv6Addr::new(0x2001, 2, 0, 0, 0, 0, 0, 1,).is_global(), false);
1351
+ ///
1352
+ /// // Addresses reserved for documentation (`2001:db8::/32`)
1353
+ /// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1).is_global(), false);
1354
+ ///
1355
+ /// // Unique local addresses (`fc00::/7`)
1356
+ /// assert_eq!(Ipv6Addr::new(0xfc02, 0, 0, 0, 0, 0, 0, 1).is_global(), false);
1357
+ ///
1358
+ /// // Unicast addresses with link-local scope (`fe80::/10`)
1359
+ /// assert_eq!(Ipv6Addr::new(0xfe81, 0, 0, 0, 0, 0, 0, 1).is_global(), false);
1360
+ ///
1361
+ /// // For a complete overview see the IANA IPv6 Special-Purpose Address Registry.
1321
1362
/// ```
1322
1363
#[ rustc_const_unstable( feature = "const_ipv6" , issue = "76205" ) ]
1323
1364
#[ unstable( feature = "ip" , issue = "27709" ) ]
1324
1365
#[ must_use]
1325
1366
#[ inline]
1326
1367
pub const fn is_global ( & self ) -> bool {
1327
- match self . multicast_scope ( ) {
1328
- Some ( Ipv6MulticastScope :: Global ) => true ,
1329
- None => self . is_unicast_global ( ) ,
1330
- _ => false ,
1331
- }
1368
+ !( self . is_unspecified ( )
1369
+ || self . is_loopback ( )
1370
+ // IPv4-mapped Address (`::ffff:0:0/96`)
1371
+ || matches ! ( self . segments( ) , [ 0 , 0 , 0 , 0 , 0 , 0xffff , _, _] )
1372
+ // IPv4-IPv6 Translat. (`64:ff9b:1::/48`)
1373
+ || matches ! ( self . segments( ) , [ 0x64 , 0xff9b , 1 , _, _, _, _, _] )
1374
+ // Discard-Only Address Block (`100::/64`)
1375
+ || matches ! ( self . segments( ) , [ 0x100 , 0 , 0 , 0 , _, _, _, _] )
1376
+ // IETF Protocol Assignments (`2001::/23`)
1377
+ || ( matches ! ( self . segments( ) , [ 0x2001 , b, _, _, _, _, _, _] if b < 0x200 )
1378
+ && !(
1379
+ // Port Control Protocol Anycast (`2001:1::1`)
1380
+ u128:: from_be_bytes ( self . octets ( ) ) == 0x2001_0001_0000_0000_0000_0000_0000_0001
1381
+ // Traversal Using Relays around NAT Anycast (`2001:1::2`)
1382
+ || u128:: from_be_bytes ( self . octets ( ) ) == 0x2001_0001_0000_0000_0000_0000_0000_0002
1383
+ // AMT (`2001:3::/32`)
1384
+ || matches ! ( self . segments( ) , [ 0x2001 , 3 , _, _, _, _, _, _] )
1385
+ // AS112-v6 (`2001:4:112::/48`)
1386
+ || matches ! ( self . segments( ) , [ 0x2001 , 4 , 0x112 , _, _, _, _, _] )
1387
+ // ORCHIDv2 (`2001:20::/28`)
1388
+ || matches ! ( self . segments( ) , [ 0x2001 , b, _, _, _, _, _, _] if b >= 0x20 && b <= 0x2F )
1389
+ ) )
1390
+ || self . is_documentation ( )
1391
+ || self . is_unique_local ( )
1392
+ || self . is_unicast_link_local ( ) )
1332
1393
}
1333
1394
1334
1395
/// Returns [`true`] if this is a unique local address (`fc00::/7`).
@@ -1525,6 +1586,7 @@ impl Ipv6Addr {
1525
1586
&& !self . is_unique_local ( )
1526
1587
&& !self . is_unspecified ( )
1527
1588
&& !self . is_documentation ( )
1589
+ && !self . is_benchmarking ( )
1528
1590
}
1529
1591
1530
1592
/// Returns the address's multicast scope if the address is multicast.
0 commit comments