Skip to content

Commit 020674e

Browse files
Merge pull request #1748 from rust-osdev/core-net-v3
uefi-raw: various small net improvements
2 parents d2d52fa + 2fd32a7 commit 020674e

File tree

2 files changed

+58
-8
lines changed

2 files changed

+58
-8
lines changed

uefi-raw/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
- Added `PciRootBridgeIoProtocol`.
66
- Added `ConfigKeywordHandlerProtocol`.
77
- Added `HiiConfigAccessProtocol`.
8+
- Added `::octets()` for `Ipv4Address`, `Ipv6Address`, and
9+
`MacAddress` to streamline the API with `core::net`.
810

911
## Changed
1012
- The documentation for UEFI protocols has been streamlined and improved.

uefi-raw/src/net.rs

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
// SPDX-License-Identifier: MIT OR Apache-2.0
22

33
//! UEFI network types.
4+
//!
5+
//! The main exports of this module are:
6+
//! - [`MacAddress`]
7+
//! - [`IpAddress`]
8+
//! - [`Ipv4Address`]
9+
//! - [`Ipv6Address`]
410
511
use core::fmt;
612
use core::fmt::{Debug, Formatter};
@@ -10,6 +16,14 @@ use core::fmt::{Debug, Formatter};
1016
#[repr(transparent)]
1117
pub struct Ipv4Address(pub [u8; 4]);
1218

19+
impl Ipv4Address {
20+
/// Returns the octets of the IP address.
21+
#[must_use]
22+
pub const fn octets(self) -> [u8; 4] {
23+
self.0
24+
}
25+
}
26+
1327
impl From<core::net::Ipv4Addr> for Ipv4Address {
1428
fn from(ip: core::net::Ipv4Addr) -> Self {
1529
Self(ip.octets())
@@ -27,6 +41,14 @@ impl From<Ipv4Address> for core::net::Ipv4Addr {
2741
#[repr(transparent)]
2842
pub struct Ipv6Address(pub [u8; 16]);
2943

44+
impl Ipv6Address {
45+
/// Returns the octets of the IP address.
46+
#[must_use]
47+
pub const fn octets(self) -> [u8; 16] {
48+
self.0
49+
}
50+
}
51+
3052
impl From<core::net::Ipv6Addr> for Ipv6Address {
3153
fn from(ip: core::net::Ipv6Addr) -> Self {
3254
Self(ip.octets())
@@ -39,7 +61,7 @@ impl From<Ipv6Address> for core::net::Ipv6Addr {
3961
}
4062
}
4163

42-
/// An IPv4 or IPv6 internet protocol address.
64+
/// An IPv4 or IPv6 internet protocol address that is ABI compatible with EFI.
4365
///
4466
/// Corresponds to the `EFI_IP_ADDRESS` type in the UEFI specification. This
4567
/// type is defined in the same way as edk2 for compatibility with C code. Note
@@ -106,20 +128,32 @@ impl From<core::net::IpAddr> for IpAddress {
106128
}
107129
}
108130

109-
/// A Media Access Control (MAC) address.
131+
/// UEFI Media Access Control (MAC) address.
132+
///
133+
/// UEFI supports multiple network protocols and hardware types, not just
134+
/// Ethernet. Some of them may use MAC addresses longer than 6 bytes. To be
135+
/// protocol-agnostic and future-proof, the UEFI spec chooses a maximum size
136+
/// that can hold any supported media access control address.
137+
///
138+
/// In most cases, this is just a typical `[u8; 6]` Ethernet style MAC
139+
/// address with the rest of the bytes being zero.
110140
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
111141
#[repr(transparent)]
112142
pub struct MacAddress(pub [u8; 32]);
113143

144+
impl MacAddress {
145+
/// Returns the octets of the MAC address.
146+
#[must_use]
147+
pub const fn octets(self) -> [u8; 32] {
148+
self.0
149+
}
150+
}
151+
152+
// Normal/typical MAC addresses, such as in Ethernet.
114153
impl From<[u8; 6]> for MacAddress {
115154
fn from(octets: [u8; 6]) -> Self {
116155
let mut buffer = [0; 32];
117-
buffer[0] = octets[0];
118-
buffer[1] = octets[1];
119-
buffer[2] = octets[2];
120-
buffer[3] = octets[3];
121-
buffer[4] = octets[4];
122-
buffer[5] = octets[5];
156+
buffer[..6].copy_from_slice(&octets);
123157
Self(buffer)
124158
}
125159
}
@@ -168,4 +202,18 @@ mod tests {
168202
let uefi_addr = IpAddress::from(core_addr);
169203
assert_eq!(unsafe { uefi_addr.v6.0 }, TEST_IPV6);
170204
}
205+
206+
// Ensure that our IpAddress type can be put into a packed struct,
207+
// even when it is normally 4 byte aligned.
208+
#[test]
209+
fn test_efi_ip_address_abi() {
210+
#[repr(C, packed)]
211+
struct PackedHelper<T>(T);
212+
213+
assert_eq!(align_of::<IpAddress>(), 4);
214+
assert_eq!(size_of::<IpAddress>(), 16);
215+
216+
assert_eq!(align_of::<PackedHelper<IpAddress>>(), 1);
217+
assert_eq!(size_of::<PackedHelper<IpAddress>>(), 16);
218+
}
171219
}

0 commit comments

Comments
 (0)