@@ -84,13 +84,62 @@ pub struct Ipv4Addr {
8484/// IPv6 addresses are defined as 128-bit integers in [IETF RFC 4291].
8585/// They are usually represented as eight 16-bit segments.
8686///
87- /// See [`IpAddr`] for a type encompassing both IPv4 and IPv6 addresses.
88- ///
8987/// The size of an `Ipv6Addr` struct may vary depending on the target operating
9088/// system.
9189///
9290/// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
9391///
92+ /// # Embedding IPv4 Addresses
93+ ///
94+ /// See [`IpAddr`] for a type encompassing both IPv4 and IPv6 addresses.
95+ ///
96+ /// To assist in the transition from IPv4 to IPv6 two types of IPv6 addresses that embed an IPv4 address were defined:
97+ /// IPv4-compatible and IPv4-mapped addresses. Of these IPv4-compatible addresses have been officially deprecated and are only minimally supported.
98+ ///
99+ /// ## IPv4-Compatible IPv6 Addresses
100+ ///
101+ /// IPv4-compatible IPv6 addresses are defined in [IETF RFC 4291 Section 2.5.5.1], and have been officially deprecated.
102+ /// The RFC describes the format of an "IPv4-Compatible IPv6 address" as follows:
103+ ///
104+ /// ```text
105+ /// | 80 bits | 16 | 32 bits |
106+ /// +--------------------------------------+--------------------------+
107+ /// |0000..............................0000|0000| IPv4 address |
108+ /// +--------------------------------------+----+---------------------+
109+ /// ```
110+ /// So `::a.b.c.d` would be an IPv4-compatible IPv6 address representing the IPv4 address `a.b.c.d`.
111+ ///
112+ /// Despite IPv4-compatible IPv6 addresses having been officially deprecated, there is minimal support for handling these addresses:
113+ /// Only converting to and from these addresses is supported, see [`Ipv4Addr::to_ipv6_compatible`] and [`Ipv6Addr::to_ipv4`].
114+ /// No further special meaning is ascribed to these addresses; for example [`is_loopback`](Ipv6Addr::is_loopback) will return `false` for `::127.0.0.1`,
115+ /// even though it represents the IPv4 address `127.0.0.1` (which is a loopback address).
116+ ///
117+ /// [IETF RFC 4291 Section 2.5.5.1]: https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.1
118+ ///
119+ /// ## IPv4-Mapped IPv6 Addresses
120+ ///
121+ /// IPv4-mapped IPv6 addresses are defined in [IETF RFC 4291 Section 2.5.5.2].
122+ /// The RFC describes the format of an "IPv4-Mapped IPv6 address" as follows:
123+ ///
124+ /// ```text
125+ /// | 80 bits | 16 | 32 bits |
126+ /// +--------------------------------------+--------------------------+
127+ /// |0000..............................0000|FFFF| IPv4 address |
128+ /// +--------------------------------------+----+---------------------+
129+ /// ```
130+ /// So `::ffff:a.b.c.d` would be an IPv4-mapped IPv6 address representing the IPv4 address `a.b.c.d`.
131+ ///
132+ /// There is more support for handling these addresses than there is for IPv4-compatible addresses:
133+ /// Converting to and from these addresses is supported, see [`Ipv4Addr::to_ipv6_mapped`] and [`Ipv6Addr::to_ipv4`].
134+ /// There is also rudimentary support for the embedded IPv4 addresses; for example [`is_loopback`](Ipv6Addr::is_loopback) will return `true` for `::ffff:127.0.0.1`,
135+ /// because it represents the IPv4 address `127.0.0.1` (which is a loopback address).
136+ ///
137+ /// Note: Currently `is_loopback` is the only method that is aware of IPv4-mapped addresses.
138+ ///
139+ /// This support for the embedded IPv4 addresses is in line with other languages and the behaviour of many real-world networking hardware.
140+ ///
141+ /// [IETF RFC 4291 Section 2.5.5.2]: https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2
142+ ///
94143/// # Textual representation
95144///
96145/// `Ipv6Addr` provides a [`FromStr`] implementation. There are many ways to represent
@@ -758,13 +807,14 @@ impl Ipv4Addr {
758807 }
759808 }
760809
761- /// Converts this address to an IPv4-compatible [`IPv6` address].
810+ /// Converts this address to an [ IPv4-compatible] [`IPv6` address].
762811 ///
763812 /// `a.b.c.d` becomes `::a.b.c.d`
764813 ///
765- /// This isn't typically the method you want; these addresses don't typically
766- /// function on modern systems. Use `to_ipv6_mapped` instead.
814+ /// Note that IPv4-compatible addresses have been officially deprecated.
815+ /// If you don't explicitly need an IPv4-compatible address for legacy reasons, consider using `to_ipv6_mapped` instead.
767816 ///
817+ /// [IPv4-compatible]: Ipv6Addr#ipv4-compatible-ipv6-addresses
768818 /// [`IPv6` address]: Ipv6Addr
769819 ///
770820 /// # Examples
@@ -787,10 +837,11 @@ impl Ipv4Addr {
787837 }
788838 }
789839
790- /// Converts this address to an IPv4-mapped [`IPv6` address].
840+ /// Converts this address to an [ IPv4-mapped] [`IPv6` address].
791841 ///
792842 /// `a.b.c.d` becomes `::ffff:a.b.c.d`
793843 ///
844+ /// [IPv4-mapped]: Ipv6Addr#ipv4-mapped-ipv6-addresses
794845 /// [`IPv6` address]: Ipv6Addr
795846 ///
796847 /// # Examples
@@ -1195,13 +1246,15 @@ impl Ipv6Addr {
11951246
11961247 /// Returns [`true`] if this is either:
11971248 /// - the [loopback address] as defined in [IETF RFC 4291 section 2.5.3] (`::1`).
1198- /// - an IPv4-mapped address representing an IPv4 loopback address as defined in [IETF RFC 1122] (`::ffff:127.0.0.0/104`).
1249+ /// - an [ IPv4-mapped] address representing an IPv4 loopback address as defined in [IETF RFC 1122] (`::ffff:127.0.0.0/104`).
11991250 ///
1200- /// Note that this returns [`false`] for an IPv4-compatible address representing an IPv4 loopback address (`::127.0.0.0/104`).
1251+ /// Note that this returns [`false`] for an [ IPv4-compatible] address representing an IPv4 loopback address (`::127.0.0.0/104`).
12011252 ///
12021253 /// [loopback address]: Ipv6Addr::LOCALHOST
12031254 /// [IETF RFC 4291 section 2.5.3]: https://tools.ietf.org/html/rfc4291#section-2.5.3
12041255 /// [IETF RFC 1122]: https://tools.ietf.org/html/rfc1122
1256+ /// [IPv4-mapped]: Ipv6Addr#ipv4-mapped-ipv6-addresses
1257+ /// [IPv4-compatible]: Ipv6Addr#ipv4-compatible-ipv6-addresses
12051258 ///
12061259 /// # Examples
12071260 ///
@@ -1529,13 +1582,14 @@ impl Ipv6Addr {
15291582 ( self . segments ( ) [ 0 ] & 0xff00 ) == 0xff00
15301583 }
15311584
1532- /// Converts this address to an [`IPv4` address] if it's an " IPv4-mapped IPv6 address"
1585+ /// Converts this address to an [`IPv4` address] if it's an [ IPv4-mapped] address as
15331586 /// defined in [IETF RFC 4291 section 2.5.5.2], otherwise returns [`None`].
15341587 ///
15351588 /// `::ffff:a.b.c.d` becomes `a.b.c.d`.
15361589 /// All addresses *not* starting with `::ffff` will return `None`.
15371590 ///
15381591 /// [`IPv4` address]: Ipv4Addr
1592+ /// [IPv4-mapped IPv6 address]: Ipv6Addr
15391593 /// [IETF RFC 4291 section 2.5.5.2]: https://tools.ietf.org/html/rfc4291#section-2.5.5.2
15401594 ///
15411595 /// # Examples
@@ -1562,12 +1616,16 @@ impl Ipv6Addr {
15621616 }
15631617 }
15641618
1565- /// Converts this address to an [`IPv4` address]. Returns [`None`] if this address is
1566- /// neither IPv4-compatible or IPv4-mapped.
1619+ /// Converts this address to an [`IPv4` address] if it's an [IPv4-compatible] address as defined in [IETF RFC 4291 section 2.5.5.1]
1620+ /// or an [ IPv4-mapped] address as defined in [IETF RFC 4291 section 2.5.5.2], otherwise returns [`None`] .
15671621 ///
15681622 /// `::a.b.c.d` and `::ffff:a.b.c.d` become `a.b.c.d`
15691623 ///
15701624 /// [`IPv4` address]: Ipv4Addr
1625+ /// [IPv4-compatible]: Ipv6Addr#ipv4-compatible-ipv6-addresses
1626+ /// [IPv4-mapped]: Ipv6Addr#ipv4-mapped-ipv6-addresses
1627+ /// [IETF RFC 4291 section 2.5.5.1]: https://tools.ietf.org/html/rfc4291#section-2.5.5.1
1628+ /// [IETF RFC 4291 section 2.5.5.2]: https://tools.ietf.org/html/rfc4291#section-2.5.5.2
15711629 ///
15721630 /// # Examples
15731631 ///
0 commit comments