Skip to content

uefi-raw: Add conversions to/from core::net IP address types #1582

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 22, 2025
Merged
Show file tree
Hide file tree
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
3 changes: 3 additions & 0 deletions uefi-raw/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
# uefi-raw - [Unreleased]

## Added
- MSRV increased to 1.77.
- Added `Boolean` type
- Added `protocol::network::pxe` module.
- Added conversions between `MacAddress` and the `[u8; 6]` type that's more commonly used to represent MAC addresses.
- Implemented `From` conversions between the `core::net` and `uefi_raw` IP
address types.
- Added `DiskInfoProtocol`.
- Added `ExtScsiPassThruProtocol`.

Expand Down
2 changes: 1 addition & 1 deletion uefi-raw/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ license.workspace = true
repository.workspace = true
# uefi-raw is much less likely to need the latest bleeding-edge features.
# Hence, it is okay to not use the workspace MSRV.
rust-version = "1.70"
rust-version = "1.77"

[dependencies]
bitflags.workspace = true
Expand Down
72 changes: 72 additions & 0 deletions uefi-raw/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,35 @@ impl From<Boolean> for bool {
#[repr(transparent)]
pub struct Ipv4Address(pub [u8; 4]);

impl From<core::net::Ipv4Addr> for Ipv4Address {
fn from(ip: core::net::Ipv4Addr) -> Self {
Self(ip.octets())
}
}

impl From<Ipv4Address> for core::net::Ipv4Addr {
fn from(ip: Ipv4Address) -> Self {
Self::from(ip.0)
}
}

/// An IPv6 internet protocol address.
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[repr(transparent)]
pub struct Ipv6Address(pub [u8; 16]);

impl From<core::net::Ipv6Addr> for Ipv6Address {
fn from(ip: core::net::Ipv6Addr) -> Self {
Self(ip.octets())
}
}

impl From<Ipv6Address> for core::net::Ipv6Addr {
fn from(ip: Ipv6Address) -> Self {
Self::from(ip.0)
}
}

/// An IPv4 or IPv6 internet protocol address.
///
/// Corresponds to the `EFI_IP_ADDRESS` type in the UEFI specification. This
Expand Down Expand Up @@ -170,6 +194,19 @@ impl Default for IpAddress {
}
}

impl From<core::net::IpAddr> for IpAddress {
fn from(t: core::net::IpAddr) -> Self {
match t {
core::net::IpAddr::V4(ip) => Self {
v4: Ipv4Address::from(ip),
},
core::net::IpAddr::V6(ip) => Self {
v6: Ipv6Address::from(ip),
},
}
}
}

/// A Media Access Control (MAC) address.
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[repr(transparent)]
Expand Down Expand Up @@ -198,6 +235,11 @@ impl From<MacAddress> for [u8; 6] {
mod tests {
use super::*;

const TEST_IPV4: [u8; 4] = [91, 92, 93, 94];
const TEST_IPV6: [u8; 16] = [
101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
];

#[test]
/// Test the properties promised in [0]. This also applies for the other
/// architectures.
Expand All @@ -215,4 +257,34 @@ mod tests {
assert!(bool::from(Boolean(0b11111110)));
assert!(bool::from(Boolean(0b11111111)));
}

/// Test round-trip conversion between `Ipv4Address` and `core::net::Ipv4Addr`.
#[test]
fn test_ip_addr4_conversion() {
let uefi_addr = Ipv4Address(TEST_IPV4);
let core_addr = core::net::Ipv4Addr::from(uefi_addr);
assert_eq!(uefi_addr, Ipv4Address::from(core_addr));
}

/// Test round-trip conversion between `Ipv6Address` and `core::net::Ipv6Addr`.
#[test]
fn test_ip_addr6_conversion() {
let uefi_addr = Ipv6Address(TEST_IPV6);
let core_addr = core::net::Ipv6Addr::from(uefi_addr);
assert_eq!(uefi_addr, Ipv6Address::from(core_addr));
}

/// Test conversion from `core::net::IpAddr` to `IpvAddress`.
///
/// Note that conversion in the other direction is not possible.
#[test]
fn test_ip_addr_conversion() {
let core_addr = core::net::IpAddr::V4(core::net::Ipv4Addr::from(TEST_IPV4));
let uefi_addr = IpAddress::from(core_addr);
assert_eq!(unsafe { uefi_addr.v4.0 }, TEST_IPV4);

let core_addr = core::net::IpAddr::V6(core::net::Ipv6Addr::from(TEST_IPV6));
let uefi_addr = IpAddress::from(core_addr);
assert_eq!(unsafe { uefi_addr.v6.0 }, TEST_IPV6);
}
}
Loading