2
2
3
3
use core:: ops:: DerefMut ;
4
4
use core:: time:: Duration ;
5
-
5
+ use smoltcp:: wire:: {
6
+ ETHERNET_HEADER_LEN , EthernetFrame , IPV4_HEADER_LEN , Ipv4Packet , UDP_HEADER_LEN , UdpPacket ,
7
+ } ;
6
8
use uefi:: boot:: ScopedProtocol ;
7
9
use uefi:: proto:: network:: MacAddress ;
8
10
use uefi:: proto:: network:: snp:: { InterruptStatus , ReceiveFlags , SimpleNetwork } ;
@@ -147,27 +149,52 @@ pub fn test() {
147
149
)
148
150
. expect ( "Failed to set receive filters" ) ;
149
151
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
+ } ;
171
198
172
199
assert ! (
173
200
!simple_network
@@ -180,7 +207,7 @@ pub fn test() {
180
207
simple_network
181
208
. transmit (
182
209
simple_network. mode ( ) . media_header_size as usize ,
183
- payload ,
210
+ & frame ,
184
211
None ,
185
212
Some ( simple_network. mode ( ) . broadcast_address ) ,
186
213
Some ( ETHERNET_PROTOCOL_IPV4 ) ,
@@ -203,9 +230,9 @@ pub fn test() {
203
230
204
231
// Check payload in UDP packet that was reversed by our EchoService.
205
232
{
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 ( ) ;
209
236
assert_eq ! ( udp_packet. payload( ) , & [ 4 , 4 , 3 , 2 , 1 ] ) ;
210
237
}
211
238
0 commit comments