Skip to content

Commit 1f2480b

Browse files
committed
Document IPv4-mapped and IPv4-compatible addresses.
1 parent c838138 commit 1f2480b

File tree

1 file changed

+72
-14
lines changed

1 file changed

+72
-14
lines changed

library/std/src/net/ip.rs

+72-14
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)