Skip to content

Commit c4b928a

Browse files
uefi-raw: Add IpAddress type
For compatibility with typical C code, the type is defined the same way as in edk2; a union rather than a plain byte buffer.
1 parent d60ce4a commit c4b928a

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

uefi-raw/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# uefi-raw - [Unreleased]
22

33
## Added
4-
- Added `Ipv4Address`, `Ipv6Address`, and `MacAddress` types.
4+
- Added `IpAddress`, `Ipv4Address`, `Ipv6Address`, and `MacAddress` types.
55
- Added `ServiceBindingProtocol`, `Dhcp4Protocol`, `HttpProtocol`,
66
`Ip4Config2Protocol`, `TlsConfigurationProtocol`, and related types.
77

uefi-raw/src/lib.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ pub mod time;
2626
mod status;
2727

2828
use core::ffi::c_void;
29+
use core::fmt::{self, Debug, Formatter};
2930
pub use status::Status;
3031
pub use uguid::{guid, Guid};
3132

@@ -68,6 +69,60 @@ pub struct Ipv4Address(pub [u8; 4]);
6869
#[repr(transparent)]
6970
pub struct Ipv6Address(pub [u8; 16]);
7071

72+
/// An IPv4 or IPv6 internet protocol address.
73+
///
74+
/// Corresponds to the `EFI_IP_ADDRESS` type in the UEFI specification. This
75+
/// type is defined in the same way as edk2 for compatibility with C code. Note
76+
/// that this is an untagged union, so there's no way to tell which type of
77+
/// address an `IpAddress` value contains without additional context.
78+
#[derive(Clone, Copy)]
79+
#[repr(C)]
80+
pub union IpAddress {
81+
/// This member serves to align the whole type to a 4 bytes as required by
82+
/// the spec. Note that this is slightly different from `repr(align(4))`,
83+
/// which would prevent placing this type in a packed structure.
84+
pub addr: [u32; 4],
85+
86+
/// An IPv4 internet protocol address.
87+
pub v4: Ipv4Address,
88+
89+
/// An IPv6 internet protocol address.
90+
pub v6: Ipv6Address,
91+
}
92+
93+
impl IpAddress {
94+
/// Construct a new IPv4 address.
95+
#[must_use]
96+
pub const fn new_v4(ip_addr: [u8; 4]) -> Self {
97+
Self {
98+
v4: Ipv4Address(ip_addr),
99+
}
100+
}
101+
102+
/// Construct a new IPv6 address.
103+
#[must_use]
104+
pub const fn new_v6(ip_addr: [u8; 16]) -> Self {
105+
Self {
106+
v6: Ipv6Address(ip_addr),
107+
}
108+
}
109+
}
110+
111+
impl Debug for IpAddress {
112+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
113+
// The type is an untagged union, so we don't know whether it contains
114+
// an IPv4 or IPv6 address. It's also not safe to just print the whole
115+
// 16 bytes, since they might not all be initialized.
116+
f.debug_struct("IpAddress").finish()
117+
}
118+
}
119+
120+
impl Default for IpAddress {
121+
fn default() -> Self {
122+
Self { addr: [0u32; 4] }
123+
}
124+
}
125+
71126
/// A Media Access Control (MAC) address.
72127
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
73128
#[repr(transparent)]

0 commit comments

Comments
 (0)