1use byteorder::{BigEndian, LittleEndian};
2
3use super::RawPcapPacket;
4use crate::errors::*;
5use crate::pcap::{PcapHeader, PcapPacket};
6use crate::Endianness;
7
8#[derive(Debug)]
43pub struct PcapParser {
44 header: PcapHeader,
45}
46
47impl PcapParser {
48 pub fn new(slice: &[u8]) -> PcapResult<(&[u8], PcapParser)> {
52 let (slice, header) = PcapHeader::from_slice(slice)?;
53
54 let parser = PcapParser { header };
55
56 Ok((slice, parser))
57 }
58
59 #[cfg(feature = "tokio")]
63 pub async fn async_new(slice: &[u8]) -> PcapResult<(&[u8], PcapParser)> {
64 let (slice, header) = PcapHeader::async_from_slice(slice).await?;
65
66 let parser = PcapParser { header };
67
68 Ok((slice, parser))
69 }
70
71 pub fn next_packet<'a>(&self, slice: &'a [u8]) -> PcapResult<(&'a [u8], PcapPacket<'a>)> {
73 match self.header.endianness {
74 Endianness::Big => PcapPacket::from_slice::<BigEndian>(slice, self.header.ts_resolution, self.header.snaplen),
75 Endianness::Little => PcapPacket::from_slice::<LittleEndian>(slice, self.header.ts_resolution, self.header.snaplen),
76 }
77 }
78
79 #[cfg(feature = "tokio")]
81 pub async fn async_next_packet<'a>(&self, slice: &'a [u8]) -> PcapResult<(&'a [u8], PcapPacket<'a>)> {
82 match self.header.endianness {
83 Endianness::Big => PcapPacket::async_from_slice::<BigEndian>(slice, self.header.ts_resolution, self.header.snaplen).await,
84 Endianness::Little => PcapPacket::async_from_slice::<LittleEndian>(slice, self.header.ts_resolution, self.header.snaplen).await,
85 }
86 }
87
88 pub fn next_raw_packet<'a>(&self, slice: &'a [u8]) -> PcapResult<(&'a [u8], RawPcapPacket<'a>)> {
90 match self.header.endianness {
91 Endianness::Big => RawPcapPacket::from_slice::<BigEndian>(slice),
92 Endianness::Little => RawPcapPacket::from_slice::<LittleEndian>(slice),
93 }
94 }
95
96 #[cfg(feature = "tokio")]
98 pub async fn async_next_raw_packet<'a>(&self, slice: &'a [u8]) -> PcapResult<(&'a [u8], RawPcapPacket<'a>)> {
99 match self.header.endianness {
100 Endianness::Big => RawPcapPacket::async_from_slice::<BigEndian>(slice).await,
101 Endianness::Little => RawPcapPacket::async_from_slice::<LittleEndian>(slice).await,
102 }
103 }
104
105 pub fn header(&self) -> PcapHeader {
107 self.header
108 }
109}