Skip to content

Commit d845f61

Browse files
committed
Make is_global/is_unicast_global special address handling complete
IANA explicitly documents 192.0.0.9/32, 192.0.0.9/32 and 2001:30::/28 as globally reachable[1][2] and the is_global implementations declare following IANA so let's make this happen. In case of 2002::/16 IANA says N/A so I think it's safe to say we shouldn't return true from is_global and is_unicast_global either for addresses in that block. [1] https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml [2] https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
1 parent a96d57b commit d845f61

File tree

2 files changed

+23
-3
lines changed

2 files changed

+23
-3
lines changed

library/core/src/net/ip_addr.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,11 @@ impl Ipv4Addr {
771771
|| self.is_loopback()
772772
|| self.is_link_local()
773773
// addresses reserved for future protocols (`192.0.0.0/24`)
774-
||(self.octets()[0] == 192 && self.octets()[1] == 0 && self.octets()[2] == 0)
774+
// .9 and .10 are documented as globally reachable so they're excluded
775+
|| (
776+
self.octets()[0] == 192 && self.octets()[1] == 0 && self.octets()[2] == 0
777+
&& self.octets()[3] != 9 && self.octets()[3] != 10
778+
)
775779
|| self.is_documentation()
776780
|| self.is_benchmarking()
777781
|| self.is_reserved()
@@ -1515,8 +1519,12 @@ impl Ipv6Addr {
15151519
// AS112-v6 (`2001:4:112::/48`)
15161520
|| matches!(self.segments(), [0x2001, 4, 0x112, _, _, _, _, _])
15171521
// ORCHIDv2 (`2001:20::/28`)
1518-
|| matches!(self.segments(), [0x2001, b, _, _, _, _, _, _] if b >= 0x20 && b <= 0x2F)
1522+
// Drone Remote ID Protocol Entity Tags (DETs) Prefix (`2001:30::/28`)`
1523+
|| matches!(self.segments(), [0x2001, b, _, _, _, _, _, _] if b >= 0x20 && b <= 0x3F)
15191524
))
1525+
// 6to4 (`2002::/16`) – it's not explicitly documented as globally reachable,
1526+
// IANA says N/A.
1527+
|| matches!(self.segments(), [0x2002, _, _, _, _, _, _, _])
15201528
|| self.is_documentation()
15211529
|| self.is_unique_local()
15221530
|| self.is_unicast_link_local())
@@ -1684,6 +1692,7 @@ impl Ipv6Addr {
16841692
/// - unique local addresses
16851693
/// - the unspecified address
16861694
/// - the address range reserved for documentation
1695+
/// - 6to4 addresses
16871696
///
16881697
/// This method returns [`true`] for site-local addresses as per [RFC 4291 section 2.5.7]
16891698
///
@@ -1717,6 +1726,8 @@ impl Ipv6Addr {
17171726
&& !self.is_unspecified()
17181727
&& !self.is_documentation()
17191728
&& !self.is_benchmarking()
1729+
// 6to4 (`2002::/16`), not documented as globally reachable by IANA
1730+
&& self.segments()[0] != 0x2002
17201731
}
17211732

17221733
/// Returns the address's multicast scope if the address is multicast.

library/core/tests/net/ip_addr.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,9 @@ fn ipv4_properties() {
461461
check!("198.18.54.2", benchmarking);
462462
check!("198.19.255.255", benchmarking);
463463
check!("192.0.0.0");
464+
check!("192.0.0.8");
465+
check!("192.0.0.9", global);
466+
check!("192.0.0.10", global);
464467
check!("192.0.0.255");
465468
check!("192.0.0.100");
466469
check!("240.0.0.0", reserved);
@@ -480,6 +483,10 @@ fn ipv6_properties() {
480483
}
481484

482485
macro_rules! check {
486+
($s:expr, &[$($octet:expr),*]) => {
487+
check!($s, &[$($octet),*], 0);
488+
};
489+
483490
($s:expr, &[$($octet:expr),*], $mask:expr) => {
484491
assert_eq!($s, ip!($s).to_string());
485492
let octets = &[$($octet),*];
@@ -657,14 +664,16 @@ fn ipv6_properties() {
657664
global | unicast_global
658665
);
659666

660-
check!("2001:30::", &[0x20, 1, 0, 0x30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unicast_global);
667+
check!("2001:30::", &[0x20, 1, 0, 0x30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], global | unicast_global);
661668

662669
check!(
663670
"2001:200::",
664671
&[0x20, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
665672
global | unicast_global
666673
);
667674

675+
check!("2002::", &[0x20, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
676+
668677
check!("fc00::", &[0xfc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unique_local);
669678

670679
check!(

0 commit comments

Comments
 (0)