netstack_testing_common/
pcap.rs1use fuchsia_async as fasync;
8use net_types::ip::IpAddress;
9use netemul::RealmUdpSocket as _;
10use packet::ParsablePacket as _;
11use packet_formats::ip::IpExt;
12use pcap;
13
14#[derive(Clone, Copy, Debug, PartialEq, Eq)]
16pub struct ExpectedUdpPacket<'a, A> {
17 pub src_ip: A,
19 pub dst_ip: A,
21 pub src_port: u16,
23 pub dst_port: u16,
25 pub payload: &'a [u8],
27}
28
29pub fn assert_udp_packets<A: IpAddress>(
31 packets_iter: pcap::PcapNgPacketIter<'_>,
32 expected_packets: &[ExpectedUdpPacket<'_, A>],
33 force_skip_checksum_validation: bool,
34) where
35 A::Version: IpExt,
36{
37 let actual_packets: Vec<ExpectedUdpPacket<'_, A>> = packets_iter
38 .map(|epb| {
39 let epb = epb.expect("EPB parse error");
40 assert_eq!(epb.interface_id, 0);
41 assert_eq!(usize::try_from(epb.original_length).unwrap(), epb.packet_data.len());
42 assert_eq!(usize::try_from(epb.captured_length).unwrap(), epb.packet_data.len());
43 let buf = &epb.packet_data;
44 let (mut body, _src_mac, _dst_mac, src_ip, dst_ip, proto, _ttl) =
45 packet_formats::testutil::parse_ip_packet_in_ethernet_frame::<A::Version>(
46 &buf,
47 packet_formats::ethernet::EthernetFrameLengthCheck::NoCheck,
48 )
49 .expect("failed to parse IP packet");
50
51 assert_eq!(proto, packet_formats::ip::IpProto::Udp.into());
52 let udp = packet_formats::udp::UdpPacket::parse(
53 &mut body,
54 packet_formats::udp::UdpParseArgs::with_context(
55 src_ip,
56 dst_ip,
57 packet_formats::testutil::ForceSkipChecksumValidation(
58 force_skip_checksum_validation,
59 ),
60 ),
61 )
62 .expect("failed to parse UDP packet");
63
64 ExpectedUdpPacket {
65 src_ip,
66 dst_ip,
67 src_port: udp.src_port().expect("missing src_port").get(),
68 dst_port: udp.dst_port().get(),
69 payload: body,
70 }
71 })
72 .collect();
73
74 pretty_assertions::assert_eq!(&actual_packets[..], expected_packets);
75}
76
77pub async fn send_udp_to_self_and_recv(
80 realm: &netemul::TestRealm<'_>,
81 bind_addr: std::net::SocketAddr,
82 payload: &[u8],
83) {
84 let sock =
85 fasync::net::UdpSocket::bind_in_realm(realm, bind_addr).await.expect("create socket");
86 let sent = sock.send_to(payload, bind_addr).await.expect("send_to failed");
87 assert_eq!(sent, payload.len());
88
89 let mut recv_buf = vec![0u8; payload.len()];
90 let (received, from_addr) = sock.recv_from(&mut recv_buf).await.expect("recv_from failed");
91 assert_eq!(received, payload.len());
92 assert_eq!(recv_buf.as_slice(), payload);
93 assert_eq!(from_addr, bind_addr);
94}