22
33use core:: ops:: DerefMut ;
44use core:: time:: Duration ;
5-
5+ use smoltcp:: wire:: {
6+ ETHERNET_HEADER_LEN , EthernetFrame , IPV4_HEADER_LEN , Ipv4Packet , UDP_HEADER_LEN , UdpPacket ,
7+ } ;
68use uefi:: boot:: ScopedProtocol ;
79use uefi:: proto:: network:: MacAddress ;
810use uefi:: proto:: network:: snp:: { InterruptStatus , ReceiveFlags , SimpleNetwork } ;
@@ -146,27 +148,52 @@ pub fn test() {
146148 )
147149 . expect ( "Failed to set receive filters" ) ;
148150
149- // EthernetFrame(IPv4Packet(UDPPacket(Payload))).
150- // The ethernet frame header will be filled by `transmit()`.
151- // The UDP packet contains the byte sequence `4, 4, 3, 2, 1`.
152- //
153- // The packet is sent to the `EchoService` created by
154- // `cargo xtask run`. It runs on UDP port 21572.
155- let payload = b"\0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \
156- \x45 \x00 \
157- \x00 \x21 \
158- \x00 \x01 \
159- \x00 \x00 \
160- \x10 \
161- \x11 \
162- \x07 \x6a \
163- \xc0 \xa8 \x11 \x0f \
164- \xc0 \xa8 \x11 \x02 \
165- \x54 \x45 \
166- \x54 \x44 \
167- \x00 \x0d \
168- \xa9 \xe4 \
169- \x04 \x01 \x02 \x03 \x04 ";
151+ // High-level payload to send to destination
152+ let payload = [
153+ 4_u8 , /* Number of elements for echo service */
154+ 1 , 2 , 3 , 4 ,
155+ ] ;
156+ let frame = {
157+ // IP that was obtained by PXE test running earlier
158+ // TODO we should make these tests not depend on each other.
159+ let src_ip = smoltcp:: wire:: Ipv4Address :: new ( 192 , 168 , 17 , 15 ) ;
160+ let dst_ip = smoltcp:: wire:: Ipv4Address :: new ( 192 , 168 , 17 , 2 ) ;
161+
162+ let udp_packet_len = UDP_HEADER_LEN + payload. len ( ) ;
163+ let ipv4_packet_len = IPV4_HEADER_LEN + udp_packet_len;
164+ let frame_len = ETHERNET_HEADER_LEN + ipv4_packet_len;
165+
166+ let mut buffer = vec ! [ 0u8 ; frame_len] ;
167+
168+ let mut frame = EthernetFrame :: new_unchecked ( buffer. as_mut_slice ( ) ) ;
169+ // Ethertype, SRC MAC, and DST MAC will be set by SNP's transmit().
170+
171+ let ipv4_packet_buffer = & mut frame. payload_mut ( ) [ 0 ..ipv4_packet_len] ;
172+ let mut ipv4_packet = Ipv4Packet :: new_unchecked ( ipv4_packet_buffer) ;
173+ ipv4_packet. set_header_len ( IPV4_HEADER_LEN as u8 /* no extensions */ ) ;
174+ ipv4_packet. set_total_len ( ipv4_packet_len as u16 ) ;
175+ ipv4_packet. set_hop_limit ( 16 ) ;
176+ ipv4_packet. set_next_header ( smoltcp:: wire:: IpProtocol :: Udp ) ;
177+ ipv4_packet. set_dont_frag ( true ) ;
178+ ipv4_packet. set_ident ( 0x1337 ) ;
179+ ipv4_packet. set_version ( 4 ) ;
180+ ipv4_packet. set_src_addr ( src_ip) ;
181+ ipv4_packet. set_dst_addr ( dst_ip) ;
182+
183+ let mut udp_packet = UdpPacket :: new_unchecked ( ipv4_packet. payload_mut ( ) ) ;
184+ udp_packet. set_len ( udp_packet_len as u16 ) ;
185+ udp_packet. set_src_port ( 21573 ) ;
186+ udp_packet. set_dst_port ( 21572 ) ;
187+ udp_packet. payload_mut ( ) . copy_from_slice ( & payload) ;
188+ assert ! ( udp_packet. check_len( ) . is_ok( ) ) ;
189+
190+ udp_packet. fill_checksum ( & src_ip. into ( ) , & dst_ip. into ( ) ) ;
191+ // Do this last, as it depends on the other checksum.
192+ ipv4_packet. fill_checksum ( ) ;
193+ assert ! ( ipv4_packet. check_len( ) . is_ok( ) ) ;
194+
195+ buffer
196+ } ;
170197
171198 assert ! (
172199 !simple_network
@@ -179,7 +206,7 @@ pub fn test() {
179206 simple_network
180207 . transmit (
181208 simple_network. mode ( ) . media_header_size as usize ,
182- payload ,
209+ & frame ,
183210 None ,
184211 Some ( simple_network. mode ( ) . broadcast_address ) ,
185212 Some ( ETHERNET_PROTOCOL_IPV4 ) ,
@@ -202,9 +229,9 @@ pub fn test() {
202229
203230 // Check payload in UDP packet that was reversed by our EchoService.
204231 {
205- let recv_frame = smoltcp :: wire :: EthernetFrame :: new_checked ( & buffer) . unwrap ( ) ;
206- let recv_ipv4 = smoltcp :: wire :: Ipv4Packet :: new_checked ( recv_frame. payload ( ) ) . unwrap ( ) ;
207- let udp_packet = smoltcp :: wire :: UdpPacket :: new_checked ( recv_ipv4. payload ( ) ) . unwrap ( ) ;
232+ let recv_frame = EthernetFrame :: new_checked ( & buffer) . unwrap ( ) ;
233+ let recv_ipv4 = Ipv4Packet :: new_checked ( recv_frame. payload ( ) ) . unwrap ( ) ;
234+ let udp_packet = UdpPacket :: new_checked ( recv_ipv4. payload ( ) ) . unwrap ( ) ;
208235 assert_eq ! ( udp_packet. payload( ) , & [ 4 , 4 , 3 , 2 , 1 ] ) ;
209236 }
210237
0 commit comments