pcap_parser/pcapng/
section_header.rs1use nom::error::ParseError;
2use nom::number::streaming::{be_i64, be_u16, le_i64, le_u16, le_u32};
3use nom::{Err, IResult};
4
5use crate::endianness::{PcapBE, PcapLE};
6use crate::utils::array_ref4;
7use crate::{opt_parse_options, PcapError, PcapNGOption, SHB_MAGIC};
8
9use super::*;
10
11#[derive(Debug)]
18pub struct SectionHeaderBlock<'a> {
19 pub block_type: u32,
20 pub block_len1: u32,
21 pub bom: u32,
23 pub major_version: u16,
24 pub minor_version: u16,
25 pub section_len: i64,
26 pub options: Vec<PcapNGOption<'a>>,
27 pub block_len2: u32,
28}
29
30impl<'a> SectionHeaderBlock<'a> {
31 pub fn big_endian(&self) -> bool {
32 self.bom != BOM_MAGIC
33 }
34}
35
36impl<'a> PcapNGBlockParser<'a, PcapBE, SectionHeaderBlock<'a>> for SectionHeaderBlock<'a> {
37 const HDR_SZ: usize = 28;
38 const MAGIC: u32 = SHB_MAGIC;
39
40 fn inner_parse<E: ParseError<&'a [u8]>>(
41 block_type: u32,
42 block_len1: u32,
43 i: &'a [u8],
44 block_len2: u32,
45 ) -> IResult<&'a [u8], SectionHeaderBlock<'a>, E> {
46 let (i, bom) = le_u32(i)?;
49 let (i, major_version) = be_u16(i)?;
50 let (i, minor_version) = be_u16(i)?;
51 let (i, section_len) = be_i64(i)?;
52 let (i, options) = opt_parse_options::<PcapBE, E>(i, block_len1 as usize, 28)?;
53 let block = SectionHeaderBlock {
54 block_type,
55 block_len1,
56 bom,
57 major_version,
58 minor_version,
59 section_len,
60 options,
61 block_len2,
62 };
63 Ok((i, block))
64 }
65}
66
67impl<'a> PcapNGBlockParser<'a, PcapLE, SectionHeaderBlock<'a>> for SectionHeaderBlock<'a> {
68 const HDR_SZ: usize = 28;
69 const MAGIC: u32 = SHB_MAGIC;
70
71 fn inner_parse<E: ParseError<&'a [u8]>>(
72 block_type: u32,
73 block_len1: u32,
74 i: &'a [u8],
75 block_len2: u32,
76 ) -> IResult<&'a [u8], SectionHeaderBlock<'a>, E> {
77 let (i, bom) = le_u32(i)?;
80 let (i, major_version) = le_u16(i)?;
81 let (i, minor_version) = le_u16(i)?;
82 let (i, section_len) = le_i64(i)?;
83 let (i, options) = opt_parse_options::<PcapLE, E>(i, block_len1 as usize, 28)?;
84 let block = SectionHeaderBlock {
85 block_type,
86 block_len1,
87 bom,
88 major_version,
89 minor_version,
90 section_len,
91 options,
92 block_len2,
93 };
94 Ok((i, block))
95 }
96}
97
98pub fn parse_sectionheaderblock_le(
100 i: &[u8],
101) -> IResult<&[u8], SectionHeaderBlock, PcapError<&[u8]>> {
102 ng_block_parser::<SectionHeaderBlock, PcapLE, _, _>()(i)
103}
104
105pub fn parse_sectionheaderblock_be(
107 i: &[u8],
108) -> IResult<&[u8], SectionHeaderBlock, PcapError<&[u8]>> {
109 ng_block_parser::<SectionHeaderBlock, PcapBE, _, _>()(i)
110}
111
112pub fn parse_sectionheaderblock(i: &[u8]) -> IResult<&[u8], SectionHeaderBlock, PcapError<&[u8]>> {
114 if i.len() < 12 {
115 return Err(Err::Incomplete(nom::Needed::new(12 - i.len())));
116 }
117 let bom = u32::from_le_bytes(*array_ref4(i, 8));
118 if bom == BOM_MAGIC {
119 parse_sectionheaderblock_le(i)
120 } else if bom == u32::from_be(BOM_MAGIC) {
121 parse_sectionheaderblock_be(i)
122 } else {
123 Err(Err::Error(PcapError::HeaderNotRecognized))
124 }
125}