Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 79 additions & 23 deletions library/core/src/net/ip_addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,15 +177,17 @@ impl Hash for Ipv6Addr {
}
}

/// Scope of an [IPv6 multicast address] as defined in [IETF RFC 7346 section 2].
/// Scope of an [IPv6 multicast address] as defined in [IETF RFC 7346 section 2],
/// which updates [IETF RFC 4291 section 2.7].
///
/// # Stability Guarantees
///
/// Not all possible values for a multicast scope have been assigned.
/// Future RFCs may introduce new scopes, which will be added as variants to this enum;
/// because of this the enum is marked as `#[non_exhaustive]`.
/// Scopes 0 and F are currently reserved by IETF, and may be assigned in the future.
/// For this reason, the enum variants for those two scopes are not currently nameable.
/// You can still check for them in your code using `as` casts.
///
/// # Examples
///
/// ```
/// #![feature(ip)]
///
Expand All @@ -204,32 +206,77 @@ impl Hash for Ipv6Addr {
/// Some(SiteLocal) => println!("Site-Local scope"),
/// Some(OrganizationLocal) => println!("Organization-Local scope"),
/// Some(Global) => println!("Global scope"),
/// Some(_) => println!("Unknown scope"),
/// Some(s) => {
/// let snum = s as u8;
/// if matches!(0x0 | 0xF, snum) {
/// println!("Reserved scope {snum:X}")
/// } else {
/// println!("Unassigned scope {snum:X}")
/// }
/// }
/// None => println!("Not a multicast address!")
/// }
///
/// ```
///
/// [IPv6 multicast address]: Ipv6Addr
/// [IETF RFC 7346 section 2]: https://tools.ietf.org/html/rfc7346#section-2
#[derive(Copy, PartialEq, Eq, Clone, Hash, Debug)]
/// [IETF RFC 4291 section 2.7]: https://datatracker.ietf.org/doc/html/rfc4291#section-2.7
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[unstable(feature = "ip", issue = "27709")]
#[non_exhaustive]
#[repr(u8)]
pub enum Ipv6MulticastScope {
/// Reserved by IETF.
#[doc(hidden)]
#[unstable(
feature = "ip_multicast_reserved",
reason = "not yet assigned by IETF",
issue = "none"
)]
Reserved0 = 0x0,
/// Interface-Local scope.
InterfaceLocal,
InterfaceLocal = 0x1,
/// Link-Local scope.
LinkLocal,
LinkLocal = 0x2,
/// Realm-Local scope.
RealmLocal,
RealmLocal = 0x3,
/// Admin-Local scope.
AdminLocal,
AdminLocal = 0x4,
/// Site-Local scope.
SiteLocal,
SiteLocal = 0x5,

/// Scope 6. Unassigned, available for administrators
/// to define additional multicast regions.
Unassigned6 = 0x6,
/// Scope 7. Unassigned, available for administrators
/// to define additional multicast regions.
Unassigned7 = 0x7,
/// Organization-Local scope.
OrganizationLocal,
OrganizationLocal = 0x8,
/// Scope 9. Unassigned, available for administrators
/// to define additional multicast regions.
Unassigned9 = 0x9,
/// Scope A. Unassigned, available for administrators
/// to define additional multicast regions.
UnassignedA = 0xA,
/// Scope B. Unassigned, available for administrators
/// to define additional multicast regions.
UnassignedB = 0xB,
/// Scope C. Unassigned, available for administrators
/// to define additional multicast regions.
UnassignedC = 0xC,
/// Scope D. Unassigned, available for administrators
/// to define additional multicast regions.
UnassignedD = 0xD,
/// Global scope.
Global,
Global = 0xE,
/// Reserved by IETF.
#[doc(hidden)]
#[unstable(
feature = "ip_multicast_reserved",
reason = "not yet assigned by IETF",
issue = "none"
)]
ReservedF = 0xF,
}

impl IpAddr {
Expand Down Expand Up @@ -1848,14 +1895,23 @@ impl Ipv6Addr {
pub const fn multicast_scope(&self) -> Option<Ipv6MulticastScope> {
if self.is_multicast() {
match self.segments()[0] & 0x000f {
1 => Some(Ipv6MulticastScope::InterfaceLocal),
2 => Some(Ipv6MulticastScope::LinkLocal),
3 => Some(Ipv6MulticastScope::RealmLocal),
4 => Some(Ipv6MulticastScope::AdminLocal),
5 => Some(Ipv6MulticastScope::SiteLocal),
8 => Some(Ipv6MulticastScope::OrganizationLocal),
14 => Some(Ipv6MulticastScope::Global),
_ => None,
0x0 => Some(Ipv6MulticastScope::Reserved0),
0x1 => Some(Ipv6MulticastScope::InterfaceLocal),
0x2 => Some(Ipv6MulticastScope::LinkLocal),
0x3 => Some(Ipv6MulticastScope::RealmLocal),
0x4 => Some(Ipv6MulticastScope::AdminLocal),
0x5 => Some(Ipv6MulticastScope::SiteLocal),
0x6 => Some(Ipv6MulticastScope::Unassigned6),
0x7 => Some(Ipv6MulticastScope::Unassigned7),
0x8 => Some(Ipv6MulticastScope::OrganizationLocal),
0x9 => Some(Ipv6MulticastScope::Unassigned9),
0xA => Some(Ipv6MulticastScope::UnassignedA),
0xB => Some(Ipv6MulticastScope::UnassignedB),
0xC => Some(Ipv6MulticastScope::UnassignedC),
0xD => Some(Ipv6MulticastScope::UnassignedD),
0xE => Some(Ipv6MulticastScope::Global),
0xF => Some(Ipv6MulticastScope::ReservedF),
_ => unreachable!(),
}
} else {
None
Expand Down
Loading