11// SPDX-License-Identifier: MIT OR Apache-2.0
22
3+ use core:: ops:: DerefMut ;
34use uefi:: proto:: network:: snp:: { InterruptStatus , NetworkState , ReceiveFlags , SimpleNetwork } ;
45use uefi:: proto:: network:: MacAddress ;
56use uefi:: { boot, Status } ;
67
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+ debug ! (
17+ "InterruptStatus (before receive): {:?}" ,
18+ simple_network. get_interrupt_status( ) ?
19+ ) ;
20+ let res = simple_network. receive (
21+ buffer,
22+ None ,
23+ Some ( & mut recv_src_mac) ,
24+ Some ( & mut recv_dst_mac) ,
25+ Some ( & mut recv_ethernet_protocol) ,
26+ ) ;
27+ debug ! (
28+ "InterruptStatus (after receive) : {:?}" ,
29+ simple_network. get_interrupt_status( ) ?
30+ ) ;
31+
32+ res. inspect ( |_| {
33+ debug ! ( "Received:" ) ;
34+ debug ! ( " src_mac = {:x?}" , recv_src_mac) ;
35+ debug ! ( " dst_mac = {:x?}" , recv_dst_mac) ;
36+ debug ! ( " ethernet_proto=0x{:x?}" , recv_ethernet_protocol) ;
37+
38+ // Ensure that we do not accidentally get an ARP packet, which we
39+ // do not expect in this test.
40+ assert_eq ! ( recv_ethernet_protocol, ETHERNET_PROTOCOL_IPV4 ) ;
41+ } )
42+ }
43+
44+ /// This test sends a simple UDP/IP packet to the `EchoService` (created by
45+ /// `cargo xtask run`) and receives its message.
746pub fn test ( ) {
847 info ! ( "Testing the simple network protocol" ) ;
948
1049 let handles = boot:: find_handles :: < SimpleNetwork > ( ) . unwrap_or_default ( ) ;
1150
1251 for handle in handles {
13- let Ok ( simple_network) = boot:: open_protocol_exclusive :: < SimpleNetwork > ( handle) else {
52+ let Ok ( mut simple_network) = boot:: open_protocol_exclusive :: < SimpleNetwork > ( handle) else {
1453 continue ;
1554 } ;
1655
@@ -53,6 +92,12 @@ pub fn test() {
5392 )
5493 . expect ( "Failed to set receive filters" ) ;
5594
95+ // EthernetFrame(IPv4Packet(UDPPacket(Payload))).
96+ // The ethernet frame header will be filled by `transmit()`.
97+ // The UDP packet contains the byte sequence `4, 4, 3, 2, 1`.
98+ //
99+ // The packet is sent to the `EchoService` created by
100+ // `cargo xtask run`. It runs on UDP port 21572.
56101 let payload = b"\0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \
57102 \x45 \x00 \
58103 \x00 \x21 \
@@ -69,7 +114,6 @@ pub fn test() {
69114 \xa9 \xe4 \
70115 \x04 \x01 \x02 \x03 \x04 ";
71116
72- let dest_addr = MacAddress ( [ 0xffu8 ; 32 ] ) ;
73117 assert ! ( !simple_network
74118 . get_interrupt_status( )
75119 . unwrap( )
@@ -81,8 +125,8 @@ pub fn test() {
81125 simple_network. mode ( ) . media_header_size as usize ,
82126 payload,
83127 None ,
84- Some ( dest_addr ) ,
85- Some ( 0x0800 ) ,
128+ Some ( simple_network . mode ( ) . broadcast_address ) ,
129+ Some ( ETHERNET_PROTOCOL_IPV4 ) ,
86130 )
87131 . expect ( "Failed to transmit frame" ) ;
88132
@@ -97,16 +141,10 @@ pub fn test() {
97141 let mut buffer = [ 0u8 ; 1500 ] ;
98142
99143 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- }
144+ let n = receive ( simple_network. deref_mut ( ) , & mut buffer) . unwrap ( ) ;
145+ debug ! ( "Reply has {n} bytes" ) ;
109146
147+ // Check payload in UDP packet that was reversed by our EchoService.
110148 assert_eq ! ( buffer[ 42 ..47 ] , [ 4 , 4 , 3 , 2 , 1 ] ) ;
111149
112150 // Get stats
0 commit comments