@@ -84,13 +84,62 @@ pub struct Ipv4Addr {
84
84
/// IPv6 addresses are defined as 128-bit integers in [IETF RFC 4291].
85
85
/// They are usually represented as eight 16-bit segments.
86
86
///
87
- /// See [`IpAddr`] for a type encompassing both IPv4 and IPv6 addresses.
88
- ///
89
87
/// The size of an `Ipv6Addr` struct may vary depending on the target operating
90
88
/// system.
91
89
///
92
90
/// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
93
91
///
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
+ ///
94
143
/// # Textual representation
95
144
///
96
145
/// `Ipv6Addr` provides a [`FromStr`] implementation. There are many ways to represent
@@ -758,13 +807,14 @@ impl Ipv4Addr {
758
807
}
759
808
}
760
809
761
- /// Converts this address to an IPv4-compatible [`IPv6` address].
810
+ /// Converts this address to an [ IPv4-compatible] [`IPv6` address].
762
811
///
763
812
/// `a.b.c.d` becomes `::a.b.c.d`
764
813
///
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.
767
816
///
817
+ /// [IPv4-compatible]: Ipv6Addr#ipv4-compatible-ipv6-addresses
768
818
/// [`IPv6` address]: Ipv6Addr
769
819
///
770
820
/// # Examples
@@ -787,10 +837,11 @@ impl Ipv4Addr {
787
837
}
788
838
}
789
839
790
- /// Converts this address to an IPv4-mapped [`IPv6` address].
840
+ /// Converts this address to an [ IPv4-mapped] [`IPv6` address].
791
841
///
792
842
/// `a.b.c.d` becomes `::ffff:a.b.c.d`
793
843
///
844
+ /// [IPv4-mapped]: Ipv6Addr#ipv4-mapped-ipv6-addresses
794
845
/// [`IPv6` address]: Ipv6Addr
795
846
///
796
847
/// # Examples
@@ -1195,13 +1246,15 @@ impl Ipv6Addr {
1195
1246
1196
1247
/// Returns [`true`] if this is either:
1197
1248
/// - 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`).
1199
1250
///
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`).
1201
1252
///
1202
1253
/// [loopback address]: Ipv6Addr::LOCALHOST
1203
1254
/// [IETF RFC 4291 section 2.5.3]: https://tools.ietf.org/html/rfc4291#section-2.5.3
1204
1255
/// [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
1205
1258
///
1206
1259
/// # Examples
1207
1260
///
@@ -1529,13 +1582,14 @@ impl Ipv6Addr {
1529
1582
( self . segments ( ) [ 0 ] & 0xff00 ) == 0xff00
1530
1583
}
1531
1584
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
1533
1586
/// defined in [IETF RFC 4291 section 2.5.5.2], otherwise returns [`None`].
1534
1587
///
1535
1588
/// `::ffff:a.b.c.d` becomes `a.b.c.d`.
1536
1589
/// All addresses *not* starting with `::ffff` will return `None`.
1537
1590
///
1538
1591
/// [`IPv4` address]: Ipv4Addr
1592
+ /// [IPv4-mapped IPv6 address]: Ipv6Addr
1539
1593
/// [IETF RFC 4291 section 2.5.5.2]: https://tools.ietf.org/html/rfc4291#section-2.5.5.2
1540
1594
///
1541
1595
/// # Examples
@@ -1562,12 +1616,16 @@ impl Ipv6Addr {
1562
1616
}
1563
1617
}
1564
1618
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`] .
1567
1621
///
1568
1622
/// `::a.b.c.d` and `::ffff:a.b.c.d` become `a.b.c.d`
1569
1623
///
1570
1624
/// [`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
1571
1629
///
1572
1630
/// # Examples
1573
1631
///
0 commit comments