rusty_pcap/pcap/sync/
mod.rs1use std::io::Read;
3pub mod writer;
4use crate::{
5 pcap::PcapParseError, pcap::file_header::PcapFileHeader, pcap::packet_header::PacketHeader,
6};
7#[derive(Debug)]
8pub struct SyncPcapReader<R: Read> {
9 reader: R,
10 buffer: Box<[u8]>,
14 header_buffer: [u8; 16],
15 file_header: PcapFileHeader,
16}
17impl<R: Read> SyncPcapReader<R> {
18 pub fn new(mut reader: R) -> Result<Self, PcapParseError> {
24 let file_header = PcapFileHeader::read(&mut reader)?;
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 fn next_packet(&mut self) -> Result<Option<(PacketHeader, &[u8])>, PcapParseError> {
38 if let Err(err) = self.reader.read_exact(&mut self.header_buffer) {
39 if err.kind() == std::io::ErrorKind::UnexpectedEof {
40 return Ok(None); } else {
42 return Err(PcapParseError::IO(err));
43 }
44 }
45 let packet_header = PacketHeader::parse_bytes(
46 &self.header_buffer,
47 self.file_header.magic_number_and_endianness.endianness,
48 &self.file_header.version,
49 )?;
50 if packet_header.include_len > self.file_header.snap_length {
51 return Err(PcapParseError::InvalidPacketLength {
52 snap_length: self.file_header.snap_length,
53 incl_len: packet_header.include_len,
54 });
55 }
56 let mut_buffer: &mut [u8] = &mut self.buffer;
57 self.reader
58 .read_exact(&mut mut_buffer[0..(packet_header.include_len as usize)])?;
59
60 Ok(Some((
61 packet_header,
62 &self.buffer[..(packet_header.include_len as usize)],
63 )))
64 }
65}
66#[cfg(test)]
67mod tests {
68 use etherparse::{NetSlice, SlicedPacket};
69
70 use super::*;
71 #[test]
72 fn read_packets_from_file() {
73 let file = std::fs::File::open("test_data/test.pcap").expect("Failed to open test.pcap");
74 let mut reader = SyncPcapReader::new(file).expect("Failed to create SyncPcapReader");
75
76 while let Ok(Some((header, data))) = reader.next_packet() {
77 println!("Packet Header: {:?}", header);
78 let parse = SlicedPacket::from_ethernet(data).expect("Failed to parse packet");
79 let Some(net_slice) = parse.net else {
80 panic!("Expected a network layer slice, got: {:?}", parse);
81 };
82
83 match net_slice {
84 NetSlice::Ipv4(ipv4) => {
85 println!("IPv4 Packet: {:?}", ipv4.header());
86 println!("IPv4 Destin: {:?}", ipv4.header().destination_addr());
87 println!("IPv4 Source: {:?}", ipv4.header().source_addr());
88 }
89 NetSlice::Ipv6(ipv6) => {
90 println!("IPv6 Packet: {:?}", ipv6.header());
91 }
92 NetSlice::Arp(arp) => {
93 println!("ARP Packet: {:?}", arp);
94 }
95 }
96 }
97 }
98}