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
511use core:: fmt;
612use core:: fmt:: { Debug , Formatter } ;
@@ -10,6 +16,14 @@ use core::fmt::{Debug, Formatter};
1016#[ repr( transparent) ]
1117pub 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+
1327impl 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) ]
2842pub 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+
3052impl 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) ]
112142pub 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.
114153impl 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