pcap_file/pcapng/
parser.rs1use byteorder_slice::{BigEndian, ByteOrder, LittleEndian};
2
3use super::blocks::block_common::{Block, RawBlock};
4use super::blocks::enhanced_packet::EnhancedPacketBlock;
5use super::blocks::interface_description::InterfaceDescriptionBlock;
6use super::blocks::section_header::SectionHeaderBlock;
7use super::blocks::{INTERFACE_DESCRIPTION_BLOCK, SECTION_HEADER_BLOCK};
8use crate::errors::PcapError;
9use crate::Endianness;
10
11
12pub struct PcapNgParser {
47 section: SectionHeaderBlock<'static>,
48 interfaces: Vec<InterfaceDescriptionBlock<'static>>,
49}
50
51impl PcapNgParser {
52 pub fn new(src: &[u8]) -> Result<(&[u8], Self), PcapError> {
56 let (rem, section) = Block::from_slice::<BigEndian>(src)?;
58 let section = match section {
59 Block::SectionHeader(section) => section.into_owned(),
60 _ => return Err(PcapError::InvalidField("PcapNg: SectionHeader invalid or missing")),
61 };
62
63 let parser = PcapNgParser { section, interfaces: vec![] };
64
65 Ok((rem, parser))
66 }
67
68 pub fn next_block<'a>(&mut self, src: &'a [u8]) -> Result<(&'a [u8], Block<'a>), PcapError> {
70 match self.section.endianness {
72 Endianness::Big => {
73 let (rem, raw_block) = self.next_raw_block_inner::<BigEndian>(src)?;
74 let block = raw_block.try_into_block::<BigEndian>()?;
75 Ok((rem, block))
76 },
77 Endianness::Little => {
78 let (rem, raw_block) = self.next_raw_block_inner::<LittleEndian>(src)?;
79 let block = raw_block.try_into_block::<LittleEndian>()?;
80 Ok((rem, block))
81 },
82 }
83 }
84
85 pub fn next_raw_block<'a>(&mut self, src: &'a [u8]) -> Result<(&'a [u8], RawBlock<'a>), PcapError> {
87 match self.section.endianness {
89 Endianness::Big => self.next_raw_block_inner::<BigEndian>(src),
90 Endianness::Little => self.next_raw_block_inner::<LittleEndian>(src),
91 }
92 }
93
94 fn next_raw_block_inner<'a, B: ByteOrder>(&mut self, src: &'a [u8]) -> Result<(&'a [u8], RawBlock<'a>), PcapError> {
96 let (rem, raw_block) = RawBlock::from_slice::<B>(src)?;
97
98 match raw_block.type_ {
99 SECTION_HEADER_BLOCK => {
100 self.section = raw_block.clone().try_into_block::<B>()?.into_owned().into_section_header().unwrap();
101 self.interfaces.clear();
102 },
103 INTERFACE_DESCRIPTION_BLOCK => {
104 let interface = raw_block.clone().try_into_block::<B>()?.into_owned().into_interface_description().unwrap();
105 self.interfaces.push(interface);
106 },
107 _ => {},
108 }
109
110 Ok((rem, raw_block))
111 }
112
113 pub fn section(&self) -> &SectionHeaderBlock<'static> {
115 &self.section
116 }
117
118 pub fn interfaces(&self) -> &[InterfaceDescriptionBlock<'static>] {
120 &self.interfaces[..]
121 }
122
123 pub fn packet_interface(&self, packet: &EnhancedPacketBlock) -> Option<&InterfaceDescriptionBlock> {
125 self.interfaces.get(packet.interface_id as usize)
126 }
127}