@@ -84,13 +84,59 @@ 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.
98+ ///
99+ /// Both types of addresses are not assigned any special meaning by this implementation,
100+ /// other than what the relevant standards prescribe. This means that an address like `::ffff:127.0.0.1`,
101+ /// while representing an IPv4 loopback address, is not itself an IPv6 loopback address; only `::1` is.
102+ /// To handle these so called "IPv4-in-IPv6" addresses, they have to first be converted to their canonical IPv4 address.
103+ ///
104+ /// ### IPv4-Compatible IPv6 Addresses
105+ ///
106+ /// IPv4-compatible IPv6 addresses are defined in [IETF RFC 4291 Section 2.5.5.1], and have been officially deprecated.
107+ /// The RFC describes the format of an "IPv4-Compatible IPv6 address" as follows:
108+ ///
109+ /// ```text
110+ /// | 80 bits | 16 | 32 bits |
111+ /// +--------------------------------------+--------------------------+
112+ /// |0000..............................0000|0000| IPv4 address |
113+ /// +--------------------------------------+----+---------------------+
114+ /// ```
115+ /// So `::a.b.c.d` would be an IPv4-compatible IPv6 address representing the IPv4 address `a.b.c.d`.
116+ ///
117+ /// To convert from an IPv4 address to an IPv4-compatible IPv6 address, use [`Ipv4Addr::to_ipv6_compatible`].
118+ /// Use [`Ipv6Addr::to_ipv4`] to convert an IPv4-compatible IPv6 address to the canonical IPv4 address.
119+ ///
120+ /// [IETF RFC 4291 Section 2.5.5.1]: https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.1
121+ ///
122+ /// ### IPv4-Mapped IPv6 Addresses
123+ ///
124+ /// IPv4-mapped IPv6 addresses are defined in [IETF RFC 4291 Section 2.5.5.2].
125+ /// The RFC describes the format of an "IPv4-Mapped IPv6 address" as follows:
126+ ///
127+ /// ```text
128+ /// | 80 bits | 16 | 32 bits |
129+ /// +--------------------------------------+--------------------------+
130+ /// |0000..............................0000|FFFF| IPv4 address |
131+ /// +--------------------------------------+----+---------------------+
132+ /// ```
133+ /// So `::ffff:a.b.c.d` would be an IPv4-mapped IPv6 address representing the IPv4 address `a.b.c.d`.
134+ ///
135+ /// To convert from an IPv4 address to an IPv4-mapped IPv6 address, use [`Ipv4Addr::to_ipv6_mapped`].
136+ /// Use [`Ipv6Addr::to_ipv4`] to convert an IPv4-mapped IPv6 address to the canonical IPv4 address.
137+ ///
138+ /// [IETF RFC 4291 Section 2.5.5.2]: https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2
139+ ///
94140/// # Textual representation
95141///
96142/// `Ipv6Addr` provides a [`FromStr`] implementation. There are many ways to represent
@@ -758,13 +804,14 @@ impl Ipv4Addr {
758804 }
759805 }
760806
761- /// Converts this address to an IPv4-compatible [`IPv6` address].
807+ /// Converts this address to an [ IPv4-compatible] [`IPv6` address].
762808 ///
763809 /// `a.b.c.d` becomes `::a.b.c.d`
764810 ///
765- /// This isn't typically the method you want; these addresses don't typically
766- /// function on modern systems. Use `to_ipv6_mapped` instead.
811+ /// Note that IPv4-compatible addresses have been officially deprecated.
812+ /// If you don't explicitly need an IPv4-compatible address for legacy reasons, consider using `to_ipv6_mapped` instead.
767813 ///
814+ /// [IPv4-compatible]: Ipv6Addr#ipv4-compatible-ipv6-addresses
768815 /// [`IPv6` address]: Ipv6Addr
769816 ///
770817 /// # Examples
@@ -787,10 +834,11 @@ impl Ipv4Addr {
787834 }
788835 }
789836
790- /// Converts this address to an IPv4-mapped [`IPv6` address].
837+ /// Converts this address to an [ IPv4-mapped] [`IPv6` address].
791838 ///
792839 /// `a.b.c.d` becomes `::ffff:a.b.c.d`
793840 ///
841+ /// [IPv4-mapped]: Ipv6Addr#ipv4-mapped-ipv6-addresses
794842 /// [`IPv6` address]: Ipv6Addr
795843 ///
796844 /// # Examples
@@ -1193,11 +1241,13 @@ impl Ipv6Addr {
11931241 u128:: from_be_bytes ( self . octets ( ) ) == u128:: from_be_bytes ( Ipv6Addr :: UNSPECIFIED . octets ( ) )
11941242 }
11951243
1196- /// Returns [`true`] if this is a loopback address (::1).
1244+ /// Returns [`true`] if this is the [loopback address] (`::1`),
1245+ /// as defined in [IETF RFC 4291 section 2.5.3].
11971246 ///
1198- /// This property is defined in [IETF RFC 4291] .
1247+ /// Contrary to IPv4, in IPv6 there is only one loopback address .
11991248 ///
1200- /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
1249+ /// [loopback address]: Ipv6Addr::LOCALHOST
1250+ /// [IETF RFC 4291 section 2.5.3]: https://tools.ietf.org/html/rfc4291#section-2.5.3
12011251 ///
12021252 /// # Examples
12031253 ///
@@ -1509,13 +1559,14 @@ impl Ipv6Addr {
15091559 ( self . segments ( ) [ 0 ] & 0xff00 ) == 0xff00
15101560 }
15111561
1512- /// Converts this address to an [`IPv4` address] if it's an " IPv4-mapped IPv6 address"
1513- /// defined in [IETF RFC 4291 section 2.5.5.2], otherwise returns [`None`].
1562+ /// Converts this address to an [`IPv4` address] if it's an [ IPv4-mapped] address,
1563+ /// as defined in [IETF RFC 4291 section 2.5.5.2], otherwise returns [`None`].
15141564 ///
15151565 /// `::ffff:a.b.c.d` becomes `a.b.c.d`.
15161566 /// All addresses *not* starting with `::ffff` will return `None`.
15171567 ///
15181568 /// [`IPv4` address]: Ipv4Addr
1569+ /// [IPv4-mapped]: Ipv6Addr
15191570 /// [IETF RFC 4291 section 2.5.5.2]: https://tools.ietf.org/html/rfc4291#section-2.5.5.2
15201571 ///
15211572 /// # Examples
@@ -1542,12 +1593,19 @@ impl Ipv6Addr {
15421593 }
15431594 }
15441595
1545- /// Converts this address to an [`IPv4` address]. Returns [`None`] if this address is
1546- /// neither IPv4-compatible or IPv4-mapped.
1596+ /// Converts this address to an [`IPv4` address] if it is either
1597+ /// an [IPv4-compatible] address as defined in [IETF RFC 4291 section 2.5.5.1],
1598+ /// or an [IPv4-mapped] address as defined in [IETF RFC 4291 section 2.5.5.2],
1599+ /// otherwise returns [`None`].
15471600 ///
15481601 /// `::a.b.c.d` and `::ffff:a.b.c.d` become `a.b.c.d`
1602+ /// All addresses *not* starting with either all zeroes or `::ffff` will return `None`.
15491603 ///
1550- /// [`IPv4` address]: Ipv4Addr
1604+ /// [IPv4 address]: Ipv4Addr
1605+ /// [IPv4-compatible]: Ipv6Addr#ipv4-compatible-ipv6-addresses
1606+ /// [IPv4-mapped]: Ipv6Addr#ipv4-mapped-ipv6-addresses
1607+ /// [IETF RFC 4291 section 2.5.5.1]: https://tools.ietf.org/html/rfc4291#section-2.5.5.1
1608+ /// [IETF RFC 4291 section 2.5.5.2]: https://tools.ietf.org/html/rfc4291#section-2.5.5.2
15511609 ///
15521610 /// # Examples
15531611 ///
0 commit comments