pcap_parser/pcapng/
section.rs1use nom::{
2 combinator::complete,
3 error::{make_error, ErrorKind},
4 multi::{many0, many1},
5 Err, IResult, Parser as _,
6};
7
8use crate::{PcapBlock, PcapError};
9
10use super::*;
11
12pub struct Section<'a> {
14 pub blocks: Vec<Block<'a>>,
16 pub big_endian: bool,
18}
19
20impl<'a> Section<'a> {
21 pub fn header(&self) -> Option<&SectionHeaderBlock<'_>> {
23 if let Some(Block::SectionHeader(ref b)) = self.blocks.first() {
24 Some(b)
25 } else {
26 None
27 }
28 }
29
30 pub fn iter(&'a self) -> SectionBlockIterator<'a> {
32 SectionBlockIterator {
33 section: self,
34 index_block: 0,
35 }
36 }
37
38 pub fn iter_interfaces(&'a self) -> InterfaceBlockIterator<'a> {
40 InterfaceBlockIterator {
41 section: self,
42 index_block: 0,
43 }
44 }
45}
46
47pub struct SectionBlockIterator<'a> {
49 section: &'a Section<'a>,
50 index_block: usize,
51}
52
53impl<'a> Iterator for SectionBlockIterator<'a> {
54 type Item = PcapBlock<'a>;
55
56 fn next(&mut self) -> Option<PcapBlock<'a>> {
57 let block = self.section.blocks.get(self.index_block);
58 self.index_block += 1;
59 block.map(PcapBlock::from)
60 }
61}
62
63pub struct InterfaceBlockIterator<'a> {
65 section: &'a Section<'a>,
66 index_block: usize,
67}
68
69impl<'a> Iterator for InterfaceBlockIterator<'a> {
70 type Item = &'a InterfaceDescriptionBlock<'a>;
71
72 fn next(&mut self) -> Option<&'a InterfaceDescriptionBlock<'a>> {
73 if self.index_block >= self.section.blocks.len() {
74 return None;
75 }
76 for block in &self.section.blocks[self.index_block..] {
77 self.index_block += 1;
78 if let Block::InterfaceDescription(ref idb) = block {
79 return Some(idb);
80 }
81 }
82 None
83 }
84}
85
86pub fn parse_section_content_block_le(i: &[u8]) -> IResult<&[u8], Block<'_>, PcapError<&[u8]>> {
88 let (rem, block) = parse_block_le(i)?;
89 match block {
90 Block::SectionHeader(_) => Err(Err::Error(make_error(i, ErrorKind::Tag))),
91 _ => Ok((rem, block)),
92 }
93}
94
95pub fn parse_section_content_block_be(i: &[u8]) -> IResult<&[u8], Block<'_>, PcapError<&[u8]>> {
97 let (rem, block) = parse_block_be(i)?;
98 match block {
99 Block::SectionHeader(_) => Err(Err::Error(make_error(i, ErrorKind::Tag))),
100 _ => Ok((rem, block)),
101 }
102}
103
104pub fn parse_section(i: &[u8]) -> IResult<&[u8], Section<'_>, PcapError<&[u8]>> {
106 let (rem, shb) = parse_sectionheaderblock(i)?;
107 let big_endian = shb.big_endian();
108 let (rem, mut b) = if big_endian {
109 many0(complete(parse_section_content_block_be)).parse(rem)?
110 } else {
111 many0(complete(parse_section_content_block_le)).parse(rem)?
112 };
113 let mut blocks = Vec::with_capacity(b.len() + 1);
114 blocks.push(Block::SectionHeader(shb));
115 blocks.append(&mut b);
116 let section = Section { blocks, big_endian };
117 Ok((rem, section))
118}
119
120#[inline]
122pub fn parse_sections(i: &[u8]) -> IResult<&[u8], Vec<Section<'_>>, PcapError<&[u8]>> {
123 many1(complete(parse_section)).parse(i)
124}