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