1
1
// SPDX-License-Identifier: MIT OR Apache-2.0
2
2
3
3
//! UEFI network types.
4
+ //!
5
+ //! The main exports of this module are:
6
+ //! - [`MacAddress`]
7
+ //! - [`IpAddress`]
8
+ //! - [`Ipv4Address`]
9
+ //! - [`Ipv6Address`]
4
10
5
11
use core:: fmt;
6
12
use core:: fmt:: { Debug , Formatter } ;
@@ -10,6 +16,14 @@ use core::fmt::{Debug, Formatter};
10
16
#[ repr( transparent) ]
11
17
pub struct Ipv4Address ( pub [ u8 ; 4 ] ) ;
12
18
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
+
13
27
impl From < core:: net:: Ipv4Addr > for Ipv4Address {
14
28
fn from ( ip : core:: net:: Ipv4Addr ) -> Self {
15
29
Self ( ip. octets ( ) )
@@ -27,6 +41,14 @@ impl From<Ipv4Address> for core::net::Ipv4Addr {
27
41
#[ repr( transparent) ]
28
42
pub struct Ipv6Address ( pub [ u8 ; 16 ] ) ;
29
43
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
+
30
52
impl From < core:: net:: Ipv6Addr > for Ipv6Address {
31
53
fn from ( ip : core:: net:: Ipv6Addr ) -> Self {
32
54
Self ( ip. octets ( ) )
@@ -39,7 +61,7 @@ impl From<Ipv6Address> for core::net::Ipv6Addr {
39
61
}
40
62
}
41
63
42
- /// An IPv4 or IPv6 internet protocol address.
64
+ /// An IPv4 or IPv6 internet protocol address that is ABI compatible with EFI .
43
65
///
44
66
/// Corresponds to the `EFI_IP_ADDRESS` type in the UEFI specification. This
45
67
/// 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 {
106
128
}
107
129
}
108
130
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.
110
140
#[ derive( Clone , Copy , Debug , Default , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
111
141
#[ repr( transparent) ]
112
142
pub struct MacAddress ( pub [ u8 ; 32 ] ) ;
113
143
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.
114
153
impl From < [ u8 ; 6 ] > for MacAddress {
115
154
fn from ( octets : [ u8 ; 6 ] ) -> Self {
116
155
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) ;
123
157
Self ( buffer)
124
158
}
125
159
}
@@ -168,4 +202,18 @@ mod tests {
168
202
let uefi_addr = IpAddress :: from ( core_addr) ;
169
203
assert_eq ! ( unsafe { uefi_addr. v6. 0 } , TEST_IPV6 ) ;
170
204
}
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
+ }
171
219
}
0 commit comments