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