@@ -631,25 +631,31 @@ impl Ipv4Addr {
631
631
matches ! ( self . octets( ) , [ 169 , 254 , ..] )
632
632
}
633
633
634
- /// Returns [`true`] if the address appears to be globally routable.
635
- /// See [iana-ipv4-special-registry][ipv4-sr].
634
+ /// Returns [`true`] if the address appears to be globally reachable
635
+ /// as specified by the [IANA IPv4 Special-Purpose Address Registry].
636
+ /// Whether or not an address is practically reachable will depend on your network configuration.
637
+ ///
638
+ /// Most IPv4 addresses are globally reachable;
639
+ /// unless they are specifically defined as *not* globally reachable.
640
+ ///
641
+ /// Non-exhaustive list of notable addresses that are not globally reachable:
636
642
///
637
- /// The following return [`false`]:
643
+ /// - The [unspecified address] ([`is_unspecified`](Ipv4Addr::is_unspecified))
644
+ /// - Addresses reserved for private use ([`is_private`](Ipv4Addr::is_private))
645
+ /// - Addresses in the shared address space ([`is_shared`](Ipv4Addr::is_shared))
646
+ /// - Loopback addresses ([`is_loopback`](Ipv4Addr::is_loopback))
647
+ /// - Link-local addresses ([`is_link_local`](Ipv4Addr::is_link_local))
648
+ /// - Addresses reserved for documentation ([`is_documentation`](Ipv4Addr::is_documentation))
649
+ /// - Addresses reserved for benchmarking ([`is_benchmarking`](Ipv4Addr::is_benchmarking))
650
+ /// - Reserved addresses ([`is_reserved`](Ipv4Addr::is_reserved))
651
+ /// - The [broadcast address] ([`is_broadcast`](Ipv4Addr::is_broadcast))
638
652
///
639
- /// - private addresses (see [`Ipv4Addr::is_private()`])
640
- /// - the loopback address (see [`Ipv4Addr::is_loopback()`])
641
- /// - the link-local address (see [`Ipv4Addr::is_link_local()`])
642
- /// - the broadcast address (see [`Ipv4Addr::is_broadcast()`])
643
- /// - addresses used for documentation (see [`Ipv4Addr::is_documentation()`])
644
- /// - the unspecified address (see [`Ipv4Addr::is_unspecified()`]), and the whole
645
- /// `0.0.0.0/8` block
646
- /// - addresses reserved for future protocols, except
647
- /// `192.0.0.9/32` and `192.0.0.10/32` which are globally routable
648
- /// - addresses reserved for future use (see [`Ipv4Addr::is_reserved()`]
649
- /// - addresses reserved for networking devices benchmarking (see
650
- /// [`Ipv4Addr::is_benchmarking()`])
653
+ /// For the complete overview of which addresses are globally reachable, see the table at the [IANA IPv4 Special-Purpose Address Registry].
651
654
///
652
- /// [ipv4-sr]: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
655
+ /// [IANA IPv4 Special-Purpose Address Registry]: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
656
+ /// [unspecified address]: Ipv4Addr::UNSPECIFIED
657
+ /// [broadcast address]: Ipv4Addr::BROADCAST
658
+
653
659
///
654
660
/// # Examples
655
661
///
@@ -658,71 +664,66 @@ impl Ipv4Addr {
658
664
///
659
665
/// use std::net::Ipv4Addr;
660
666
///
661
- /// // private addresses are not global
667
+ /// // Most IPv4 addresses are globally reachable:
668
+ /// assert_eq!(Ipv4Addr::new(80, 9, 12, 3).is_global(), true);
669
+ ///
670
+ /// // However some addresses have been assigned a special meaning
671
+ /// // that makes them not globally reachable. Some examples are:
672
+ ///
673
+ /// // The unspecified address (`0.0.0.0`)
674
+ /// assert_eq!(Ipv4Addr::UNSPECIFIED.is_global(), false);
675
+ ///
676
+ /// // Addresses reserved for private use (`10.0.0.0/8`, `172.16.0.0/12`, 192.168.0.0/16)
662
677
/// assert_eq!(Ipv4Addr::new(10, 254, 0, 0).is_global(), false);
663
678
/// assert_eq!(Ipv4Addr::new(192, 168, 10, 65).is_global(), false);
664
679
/// assert_eq!(Ipv4Addr::new(172, 16, 10, 65).is_global(), false);
665
680
///
666
- /// // the 0.0.0.0/8 block is not global
667
- /// assert_eq!(Ipv4Addr::new(0, 1, 2, 3).is_global(), false);
668
- /// // in particular, the unspecified address is not global
669
- /// assert_eq!(Ipv4Addr::new(0, 0, 0, 0).is_global(), false);
681
+ /// // Addresses in the shared address space (`100.64.0.0/10`)
682
+ /// assert_eq!(Ipv4Addr::new(100, 100, 0, 0).is_global(), false);
670
683
///
671
- /// // the loopback address is not global
672
- /// assert_eq!(Ipv4Addr::new(127, 0, 0, 1) .is_global(), false);
684
+ /// // The loopback addresses (`127.0.0.0/8`)
685
+ /// assert_eq!(Ipv4Addr::LOCALHOST .is_global(), false);
673
686
///
674
- /// // link local addresses are not global
687
+ /// // Link- local addresses (`169.254.0.0/16`)
675
688
/// assert_eq!(Ipv4Addr::new(169, 254, 45, 1).is_global(), false);
676
689
///
677
- /// // the broadcast address is not global
678
- /// assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_global(), false);
679
- ///
680
- /// // the address space designated for documentation is not global
690
+ /// // Addresses reserved for documentation (`192.0.2.0/24`, `198.51.100.0/24`, `203.0.113.0/24`)
681
691
/// assert_eq!(Ipv4Addr::new(192, 0, 2, 255).is_global(), false);
682
692
/// assert_eq!(Ipv4Addr::new(198, 51, 100, 65).is_global(), false);
683
693
/// assert_eq!(Ipv4Addr::new(203, 0, 113, 6).is_global(), false);
684
694
///
685
- /// // shared addresses are not global
686
- /// assert_eq!(Ipv4Addr::new(100, 100, 0, 0).is_global(), false);
687
- ///
688
- /// // addresses reserved for protocol assignment are not global
689
- /// assert_eq!(Ipv4Addr::new(192, 0, 0, 0).is_global(), false);
690
- /// assert_eq!(Ipv4Addr::new(192, 0, 0, 255).is_global(), false);
695
+ /// // Addresses reserved for benchmarking (`198.18.0.0/15`)
696
+ /// assert_eq!(Ipv4Addr::new(198, 18, 0, 0).is_global(), false);
691
697
///
692
- /// // addresses reserved for future use are not global
698
+ /// // Reserved addresses (`240.0.0.0/4`)
693
699
/// assert_eq!(Ipv4Addr::new(250, 10, 20, 30).is_global(), false);
694
700
///
695
- /// // addresses reserved for network devices benchmarking are not global
696
- /// assert_eq!(Ipv4Addr::new(198, 18, 0, 0) .is_global(), false);
701
+ /// // The broadcast address (`255.255.255.255`)
702
+ /// assert_eq!(Ipv4Addr::BROADCAST .is_global(), false);
697
703
///
698
- /// // All the other addresses are global
699
- /// assert_eq!(Ipv4Addr::new(1, 1, 1, 1).is_global(), true);
700
- /// assert_eq!(Ipv4Addr::new(80, 9, 12, 3).is_global(), true);
704
+ /// // For a complete overview see the IANA IPv4 Special-Purpose Address Registry.
701
705
/// ```
702
706
#[ rustc_const_unstable( feature = "const_ipv4" , issue = "76205" ) ]
703
707
#[ unstable( feature = "ip" , issue = "27709" ) ]
704
708
#[ must_use]
705
709
#[ inline]
706
710
pub const fn is_global ( & self ) -> bool {
707
- // check if this address is 192.0.0.9 or 192.0.0.10. These addresses are the only two
708
- // globally routable addresses in the 192.0.0.0/24 range.
709
- if u32:: from_be_bytes ( self . octets ( ) ) == 0xc0000009
710
- || u32:: from_be_bytes ( self . octets ( ) ) == 0xc000000a
711
- {
712
- return true ;
713
- }
714
- !self . is_private ( )
715
- && !self . is_loopback ( )
716
- && !self . is_link_local ( )
717
- && !self . is_broadcast ( )
718
- && !self . is_documentation ( )
719
- && !self . is_shared ( )
720
- // addresses reserved for future protocols (`192.0.0.0/24`)
721
- && !( self . octets ( ) [ 0 ] == 192 && self . octets ( ) [ 1 ] == 0 && self . octets ( ) [ 2 ] == 0 )
722
- && !self . is_reserved ( )
723
- && !self . is_benchmarking ( )
724
- // Make sure the address is not in 0.0.0.0/8
725
- && self . octets ( ) [ 0 ] != 0
711
+ !( self . octets ( ) [ 0 ] == 0 // "This network"
712
+ || self . is_private ( )
713
+ || self . is_shared ( )
714
+ || self . is_loopback ( )
715
+ || self . is_link_local ( )
716
+ || ( self . is_ietf_protocol_assignment ( )
717
+ && !(
718
+ // Port Control Protocol Anycast (`192.0.0.9`)
719
+ u32:: from_be_bytes ( self . octets ( ) ) == 0xc0000009
720
+ // Traversal Using Relays around NAT Anycast (`192.0.0.10`)
721
+ || u32:: from_be_bytes ( self . octets ( ) ) == 0xc000000a
722
+ ) )
723
+ || self . is_documentation ( )
724
+ || self . is_benchmarking ( )
725
+ || self . is_reserved ( )
726
+ || self . is_broadcast ( ) )
726
727
}
727
728
728
729
/// Returns [`true`] if this address is part of the Shared Address Space defined in
0 commit comments