rusty_pcap/pcap/tokio_impl/
reader.rs1use crate::{
3 pcap::PcapParseError, pcap::file_header::PcapFileHeader, pcap::packet_header::PacketHeader,
4};
5use tokio::io::{AsyncRead, AsyncReadExt};
6#[derive(Debug)]
7pub struct AsyncPcapReader<R: AsyncRead + Unpin> {
8 reader: R,
9 buffer: Box<[u8]>,
11 header_buffer: [u8; 16],
13 file_header: PcapFileHeader,
14}
15impl<R: AsyncRead + Unpin> AsyncPcapReader<R> {
16 pub async fn new(mut reader: R) -> Result<Self, PcapParseError> {
22 let mut file_header = [0u8; 24];
23 reader.read_exact(&mut file_header).await?;
24 let file_header = PcapFileHeader::try_from(&file_header)?;
25 let buffer = vec![0u8; file_header.snap_length as usize].into_boxed_slice();
26 Ok(Self {
27 reader,
28 buffer,
29 file_header,
30 header_buffer: [0; 16],
31 })
32 }
33 pub fn file_header(&self) -> &PcapFileHeader {
35 &self.file_header
36 }
37 pub async fn next_packet(&mut self) -> Result<Option<(PacketHeader, &[u8])>, PcapParseError> {
41 if let Err(err) = self.reader.read_exact(&mut self.header_buffer).await {
42 if err.kind() == std::io::ErrorKind::UnexpectedEof {
43 return Ok(None); } else {
45 return Err(PcapParseError::IO(err));
46 }
47 }
48 let packet_header = PacketHeader::parse_bytes(
49 &self.header_buffer,
50 self.file_header.magic_number_and_endianness.endianness,
51 &self.file_header.version,
52 )?;
53 if packet_header.include_len > self.file_header.snap_length {
56 return Err(PcapParseError::InvalidPacketLength {
57 snap_length: self.file_header.snap_length,
58 incl_len: packet_header.include_len,
59 });
60 }
61 let mut_buffer: &mut [u8] = &mut self.buffer;
62 self.reader
63 .read_exact(&mut mut_buffer[0..(packet_header.include_len as usize)])
64 .await?;
65
66 Ok(Some((
67 packet_header,
68 &self.buffer[..(packet_header.include_len as usize)],
69 )))
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use etherparse::{NetSlice, SlicedPacket};
76
77 use super::*;
78 #[tokio::test]
79 async fn read_packets_from_file() {
80 let file = tokio::fs::File::open("test_data/test.pcap")
81 .await
82 .expect("Failed to open test.pcap");
83 let mut reader = AsyncPcapReader::new(file)
84 .await
85 .expect("Failed to create SyncPcapReader");
86
87 while let Ok(Some((header, data))) = reader.next_packet().await {
88 println!("Packet Header: {:?}", header);
89 let parse = SlicedPacket::from_ethernet(data).expect("Failed to parse packet");
90 if let Some(net_slice) = parse.net {
91 match net_slice {
92 NetSlice::Ipv4(ipv4) => {
93 println!("IPv4 Packet: {:?}", ipv4.header());
94 println!("IPv4 Destin: {:?}", ipv4.header().destination_addr());
95 println!("IPv4 Source: {:?}", ipv4.header().source_addr());
96 }
97 NetSlice::Ipv6(ipv6) => {
98 println!("IPv6 Packet: {:?}", ipv6.header());
99 }
100 NetSlice::Arp(arp) => {
101 println!("ARP Packet: {:?}", arp);
102 }
103 }
104 } else {
105 println!("Non Packet");
106 }
107 }
108 }
109}