@@ -84,13 +84,59 @@ 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.
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
+ ///
94
140
/// # Textual representation
95
141
///
96
142
/// `Ipv6Addr` provides a [`FromStr`] implementation. There are many ways to represent
@@ -758,13 +804,14 @@ impl Ipv4Addr {
758
804
}
759
805
}
760
806
761
- /// Converts this address to an IPv4-compatible [`IPv6` address].
807
+ /// Converts this address to an [ IPv4-compatible] [`IPv6` address].
762
808
///
763
809
/// `a.b.c.d` becomes `::a.b.c.d`
764
810
///
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.
767
813
///
814
+ /// [IPv4-compatible]: Ipv6Addr#ipv4-compatible-ipv6-addresses
768
815
/// [`IPv6` address]: Ipv6Addr
769
816
///
770
817
/// # Examples
@@ -787,10 +834,11 @@ impl Ipv4Addr {
787
834
}
788
835
}
789
836
790
- /// Converts this address to an IPv4-mapped [`IPv6` address].
837
+ /// Converts this address to an [ IPv4-mapped] [`IPv6` address].
791
838
///
792
839
/// `a.b.c.d` becomes `::ffff:a.b.c.d`
793
840
///
841
+ /// [IPv4-mapped]: Ipv6Addr#ipv4-mapped-ipv6-addresses
794
842
/// [`IPv6` address]: Ipv6Addr
795
843
///
796
844
/// # Examples
@@ -1193,11 +1241,13 @@ impl Ipv6Addr {
1193
1241
u128:: from_be_bytes ( self . octets ( ) ) == u128:: from_be_bytes ( Ipv6Addr :: UNSPECIFIED . octets ( ) )
1194
1242
}
1195
1243
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].
1197
1246
///
1198
- /// This property is defined in [IETF RFC 4291] .
1247
+ /// Contrary to IPv4, in IPv6 there is only one loopback address .
1199
1248
///
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
1201
1251
///
1202
1252
/// # Examples
1203
1253
///
@@ -1509,13 +1559,14 @@ impl Ipv6Addr {
1509
1559
( self . segments ( ) [ 0 ] & 0xff00 ) == 0xff00
1510
1560
}
1511
1561
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`].
1514
1564
///
1515
1565
/// `::ffff:a.b.c.d` becomes `a.b.c.d`.
1516
1566
/// All addresses *not* starting with `::ffff` will return `None`.
1517
1567
///
1518
1568
/// [`IPv4` address]: Ipv4Addr
1569
+ /// [IPv4-mapped]: Ipv6Addr
1519
1570
/// [IETF RFC 4291 section 2.5.5.2]: https://tools.ietf.org/html/rfc4291#section-2.5.5.2
1520
1571
///
1521
1572
/// # Examples
@@ -1542,12 +1593,19 @@ impl Ipv6Addr {
1542
1593
}
1543
1594
}
1544
1595
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`].
1547
1600
///
1548
1601
/// `::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`.
1549
1603
///
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
1551
1609
///
1552
1610
/// # Examples
1553
1611
///
0 commit comments