@@ -474,26 +474,30 @@ impl Ipv4Addr {
474474 matches ! ( self . octets( ) , [ 169 , 254 , ..] )
475475 }
476476
477- /// Returns [`true`] if the address appears to be globally routable.
478- /// See [iana-ipv4-special-registry][ipv4-sr].
479- ///
480- /// The following return [`false`]:
481- ///
482- /// - private addresses (see [`Ipv4Addr::is_private()`])
483- /// - the loopback address (see [`Ipv4Addr::is_loopback()`])
484- /// - the link-local address (see [`Ipv4Addr::is_link_local()`])
485- /// - the broadcast address (see [`Ipv4Addr::is_broadcast()`])
486- /// - addresses used for documentation (see [`Ipv4Addr::is_documentation()`])
487- /// - the unspecified address (see [`Ipv4Addr::is_unspecified()`]), and the whole
488- /// `0.0.0.0/8` block
489- /// - addresses reserved for future protocols (see
490- /// [`Ipv4Addr::is_ietf_protocol_assignment()`], except
491- /// `192.0.0.9/32` and `192.0.0.10/32` which are globally routable
492- /// - addresses reserved for future use (see [`Ipv4Addr::is_reserved()`]
493- /// - addresses reserved for networking devices benchmarking (see
494- /// [`Ipv4Addr::is_benchmarking()`])
495- ///
496- /// [ipv4-sr]: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
477+ /// Returns [`true`] if the address appears to be globally reachable
478+ /// as specified by the [IANA IPv4 Special-Purpose Address Registry].
479+ /// Whether or not an address is practically reachable will depend on your network configuration.
480+ ///
481+ /// Most IPv4 addresses are globally reachable;
482+ /// unless they are specifically defined as *not* globally reachable.
483+ ///
484+ /// Non-exhaustive list of notable addresses that are not globally reachable:
485+ ///
486+ /// - The [unspecified address] ([`is_unspecified`](Ipv4Addr::is_unspecified))
487+ /// - Addresses reserved for private use ([`is_private`](Ipv4Addr::is_private))
488+ /// - Addresses in the shared address space ([`is_shared`](Ipv4Addr::is_shared))
489+ /// - Loopback addresses ([`is_loopback`](Ipv4Addr::is_loopback))
490+ /// - Link-local addresses ([`is_link_local`](Ipv4Addr::is_link_local))
491+ /// - Addresses reserved for documentation ([`is_documentation`](Ipv4Addr::is_documentation))
492+ /// - Addresses reserved for benchmarking ([`is_benchmarking`](Ipv4Addr::is_benchmarking))
493+ /// - Reserved addresses ([`is_reserved`](Ipv4Addr::is_reserved))
494+ /// - The [broadcast address] ([`is_broadcast`](Ipv4Addr::is_broadcast))
495+ ///
496+ /// For the complete overview of which addresses are globally reachable, see the table at the [IANA IPv4 Special-Purpose Address Registry].
497+ ///
498+ /// [IANA IPv4 Special-Purpose Address Registry]: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
499+ /// [unspecified address]: Ipv4Addr::UNSPECIFIED
500+ /// [broadcast address]: Ipv4Addr::BROADCAST
497501 ///
498502 /// # Examples
499503 ///
@@ -502,69 +506,65 @@ impl Ipv4Addr {
502506 ///
503507 /// use std::net::Ipv4Addr;
504508 ///
505- /// // private addresses are not global
509+ /// // Most IPv4 addresses are globally reachable:
510+ /// assert_eq!(Ipv4Addr::new(80, 9, 12, 3).is_global(), true);
511+ ///
512+ /// // However some addresses have been assigned a special meaning
513+ /// // that makes them not globally reachable. Some examples are:
514+ ///
515+ /// // The unspecified address (`0.0.0.0`)
516+ /// assert_eq!(Ipv4Addr::UNSPECIFIED.is_global(), false);
517+ ///
518+ /// // Addresses reserved for private use (`10.0.0.0/8`, `172.16.0.0/12`, 192.168.0.0/16)
506519 /// assert_eq!(Ipv4Addr::new(10, 254, 0, 0).is_global(), false);
507520 /// assert_eq!(Ipv4Addr::new(192, 168, 10, 65).is_global(), false);
508521 /// assert_eq!(Ipv4Addr::new(172, 16, 10, 65).is_global(), false);
509522 ///
510- /// // the 0.0.0.0/8 block is not global
511- /// assert_eq!(Ipv4Addr::new(0, 1, 2, 3).is_global(), false);
512- /// // in particular, the unspecified address is not global
513- /// assert_eq!(Ipv4Addr::new(0, 0, 0, 0).is_global(), false);
523+ /// // Addresses in the shared address space (`100.64.0.0/10`)
524+ /// assert_eq!(Ipv4Addr::new(100, 100, 0, 0).is_global(), false);
514525 ///
515- /// // the loopback address is not global
516- /// assert_eq!(Ipv4Addr::new(127, 0, 0, 1) .is_global(), false);
526+ /// // The loopback addresses (`127.0.0.0/8`)
527+ /// assert_eq!(Ipv4Addr::LOCALHOST .is_global(), false);
517528 ///
518- /// // link local addresses are not global
529+ /// // Link- local addresses (`169.254.0.0/16`)
519530 /// assert_eq!(Ipv4Addr::new(169, 254, 45, 1).is_global(), false);
520531 ///
521- /// // the broadcast address is not global
522- /// assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_global(), false);
523- ///
524- /// // the address space designated for documentation is not global
532+ /// // Addresses reserved for documentation (`192.0.2.0/24`, `198.51.100.0/24`, `203.0.113.0/24`)
525533 /// assert_eq!(Ipv4Addr::new(192, 0, 2, 255).is_global(), false);
526534 /// assert_eq!(Ipv4Addr::new(198, 51, 100, 65).is_global(), false);
527535 /// assert_eq!(Ipv4Addr::new(203, 0, 113, 6).is_global(), false);
528536 ///
529- /// // shared addresses are not global
530- /// assert_eq!(Ipv4Addr::new(100, 100, 0, 0).is_global(), false);
531- ///
532- /// // addresses reserved for protocol assignment are not global
533- /// assert_eq!(Ipv4Addr::new(192, 0, 0, 0).is_global(), false);
534- /// assert_eq!(Ipv4Addr::new(192, 0, 0, 255).is_global(), false);
537+ /// // Addresses reserved for benchmarking (`198.18.0.0/15`)
538+ /// assert_eq!(Ipv4Addr::new(198, 18, 0, 0).is_global(), false);
535539 ///
536- /// // addresses reserved for future use are not global
540+ /// // Reserved addresses (`240.0.0.0/4`)
537541 /// assert_eq!(Ipv4Addr::new(250, 10, 20, 30).is_global(), false);
538542 ///
539- /// // addresses reserved for network devices benchmarking are not global
540- /// assert_eq!(Ipv4Addr::new(198, 18, 0, 0) .is_global(), false);
543+ /// // The broadcast address (`255.255.255.255`)
544+ /// assert_eq!(Ipv4Addr::BROADCAST .is_global(), false);
541545 ///
542- /// // All the other addresses are global
543- /// assert_eq!(Ipv4Addr::new(1, 1, 1, 1).is_global(), true);
544- /// assert_eq!(Ipv4Addr::new(80, 9, 12, 3).is_global(), true);
546+ /// // For a complete overview see the IANA IPv4 Special-Purpose Address Registry.
545547 /// ```
546548 #[ rustc_const_unstable( feature = "const_ipv4" , issue = "76205" ) ]
547549 #[ unstable( feature = "ip" , issue = "27709" ) ]
548550 #[ inline]
549551 pub const fn is_global ( & self ) -> bool {
550- // check if this address is 192.0.0.9 or 192.0.0.10. These addresses are the only two
551- // globally routable addresses in the 192.0.0.0/24 range.
552- if u32:: from_be_bytes ( self . octets ( ) ) == 0xc0000009
553- || u32:: from_be_bytes ( self . octets ( ) ) == 0xc000000a
554- {
555- return true ;
556- }
557- !self . is_private ( )
558- && !self . is_loopback ( )
559- && !self . is_link_local ( )
560- && !self . is_broadcast ( )
561- && !self . is_documentation ( )
562- && !self . is_shared ( )
563- && !self . is_ietf_protocol_assignment ( )
564- && !self . is_reserved ( )
565- && !self . is_benchmarking ( )
566- // Make sure the address is not in 0.0.0.0/8
567- && self . octets ( ) [ 0 ] != 0
552+ !( self . octets ( ) [ 0 ] == 0 // "This network"
553+ || self . is_private ( )
554+ || self . is_shared ( )
555+ || self . is_loopback ( )
556+ || self . is_link_local ( )
557+ || ( self . is_ietf_protocol_assignment ( )
558+ && !(
559+ // Port Control Protocol Anycast (`192.0.0.9`)
560+ u32:: from_be_bytes ( self . octets ( ) ) == 0xc0000009
561+ // Traversal Using Relays around NAT Anycast (`192.0.0.10`)
562+ || u32:: from_be_bytes ( self . octets ( ) ) == 0xc000000a
563+ ) )
564+ || self . is_documentation ( )
565+ || self . is_benchmarking ( )
566+ || self . is_reserved ( )
567+ || self . is_broadcast ( ) )
568568 }
569569
570570 /// Returns [`true`] if this address is part of the Shared Address Space defined in
0 commit comments