1
1
// SPDX-License-Identifier: MIT OR Apache-2.0
2
2
3
+ use core:: ops:: DerefMut ;
3
4
use uefi:: proto:: network:: snp:: { InterruptStatus , NetworkState , ReceiveFlags , SimpleNetwork } ;
4
5
use uefi:: proto:: network:: MacAddress ;
5
6
use uefi:: { boot, Status } ;
6
7
8
+ const ETHERNET_PROTOCOL_IPV4 : u16 = 0x0800 ;
9
+
10
+ /// Receives the next IPv4 packet and prints corresponding metadata.
11
+ fn receive ( simple_network : & mut SimpleNetwork , buffer : & mut [ u8 ] ) -> uefi:: Result < usize > {
12
+ let mut recv_src_mac = MacAddress ( [ 0 ; 32 ] ) ;
13
+ let mut recv_dst_mac = MacAddress ( [ 0 ; 32 ] ) ;
14
+ let mut recv_ethernet_protocol = 0 ;
15
+
16
+ let res = simple_network. receive (
17
+ buffer,
18
+ None ,
19
+ Some ( & mut recv_src_mac) ,
20
+ Some ( & mut recv_dst_mac) ,
21
+ Some ( & mut recv_ethernet_protocol) ,
22
+ ) ;
23
+
24
+ res. inspect ( |_| {
25
+ debug ! ( "Received:" ) ;
26
+ debug ! ( " src_mac = {:x?}" , recv_src_mac) ;
27
+ debug ! ( " dst_mac = {:x?}" , recv_dst_mac) ;
28
+ debug ! ( " ethernet_proto=0x{:x?}" , recv_ethernet_protocol) ;
29
+
30
+ // Ensure that we do not accidentally get an ARP packet, which we
31
+ // do not expect in this test.
32
+ assert_eq ! ( recv_ethernet_protocol, ETHERNET_PROTOCOL_IPV4 ) ;
33
+ } )
34
+ }
35
+
36
+ /// This test sends a simple UDP/IP packet to the `EchoService` (created by
37
+ /// `cargo xtask run`) and receives its message.
7
38
pub fn test ( ) {
8
39
info ! ( "Testing the simple network protocol" ) ;
9
40
10
41
let handles = boot:: find_handles :: < SimpleNetwork > ( ) . unwrap_or_default ( ) ;
11
42
12
43
for handle in handles {
13
- let Ok ( simple_network) = boot:: open_protocol_exclusive :: < SimpleNetwork > ( handle) else {
44
+ let Ok ( mut simple_network) = boot:: open_protocol_exclusive :: < SimpleNetwork > ( handle) else {
14
45
continue ;
15
46
} ;
16
47
@@ -53,6 +84,12 @@ pub fn test() {
53
84
)
54
85
. expect ( "Failed to set receive filters" ) ;
55
86
87
+ // EthernetFrame(IPv4Packet(UDPPacket(Payload))).
88
+ // The ethernet frame header will be filled by `transmit()`.
89
+ // The UDP packet contains the byte sequence `4, 4, 3, 2, 1`.
90
+ //
91
+ // The packet is sent to the `EchoService` created by
92
+ // `cargo xtask run`. It runs on UDP port 21572.
56
93
let payload = b"\0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \
57
94
\x45 \x00 \
58
95
\x00 \x21 \
@@ -69,7 +106,6 @@ pub fn test() {
69
106
\xa9 \xe4 \
70
107
\x04 \x01 \x02 \x03 \x04 ";
71
108
72
- let dest_addr = MacAddress ( [ 0xffu8 ; 32 ] ) ;
73
109
assert ! ( !simple_network
74
110
. get_interrupt_status( )
75
111
. unwrap( )
@@ -81,8 +117,8 @@ pub fn test() {
81
117
simple_network. mode ( ) . media_header_size as usize ,
82
118
payload,
83
119
None ,
84
- Some ( dest_addr ) ,
85
- Some ( 0x0800 ) ,
120
+ Some ( simple_network . mode ( ) . broadcast_address ) ,
121
+ Some ( ETHERNET_PROTOCOL_IPV4 ) ,
86
122
)
87
123
. expect ( "Failed to transmit frame" ) ;
88
124
@@ -97,16 +133,10 @@ pub fn test() {
97
133
let mut buffer = [ 0u8 ; 1500 ] ;
98
134
99
135
info ! ( "Waiting for the reception" ) ;
100
- if simple_network. receive ( & mut buffer, None , None , None , None )
101
- == Err ( Status :: NOT_READY . into ( ) )
102
- {
103
- boot:: stall ( 1_000_000 ) ;
104
-
105
- simple_network
106
- . receive ( & mut buffer, None , None , None , None )
107
- . unwrap ( ) ;
108
- }
136
+ let n = receive ( simple_network. deref_mut ( ) , & mut buffer) . unwrap ( ) ;
137
+ debug ! ( "Reply has {n} bytes" ) ;
109
138
139
+ // Check payload in UDP packet that was reversed by our EchoService.
110
140
assert_eq ! ( buffer[ 42 ..47 ] , [ 4 , 4 , 3 , 2 , 1 ] ) ;
111
141
112
142
// Get stats
0 commit comments