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 } ;
@@ -146,27 +148,52 @@ pub fn test() {
146
148
)
147
149
. expect ( "Failed to set receive filters" ) ;
148
150
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
+ } ;
170
197
171
198
assert ! (
172
199
!simple_network
@@ -179,7 +206,7 @@ pub fn test() {
179
206
simple_network
180
207
. transmit (
181
208
simple_network. mode ( ) . media_header_size as usize ,
182
- payload ,
209
+ & frame ,
183
210
None ,
184
211
Some ( simple_network. mode ( ) . broadcast_address ) ,
185
212
Some ( ETHERNET_PROTOCOL_IPV4 ) ,
@@ -202,9 +229,9 @@ pub fn test() {
202
229
203
230
// Check payload in UDP packet that was reversed by our EchoService.
204
231
{
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 ( ) ;
208
235
assert_eq ! ( udp_packet. payload( ) , & [ 4 , 4 , 3 , 2 , 1 ] ) ;
209
236
}
210
237
0 commit comments