pcap_parser/pcapng/
custom.rs

1use nom::error::{ErrorKind, ParseError};
2use nom::{Err, IResult};
3
4use crate::endianness::{PcapBE, PcapEndianness, PcapLE};
5use crate::{PcapError, CB_MAGIC, DCB_MAGIC};
6
7use super::*;
8
9#[derive(Debug)]
10pub struct CustomBlock<'a> {
11    pub block_type: u32,
12    pub block_len1: u32,
13    // Private Enterprise Number (PEN)
14    pub pen: u32,
15    pub data: &'a [u8],
16    // pub options: &'a [u8],
17    pub block_len2: u32,
18}
19
20impl<'a, En: PcapEndianness> PcapNGBlockParser<'a, En, CustomBlock<'a>> for CustomBlock<'a> {
21    const HDR_SZ: usize = 16;
22    const MAGIC: u32 = CB_MAGIC;
23
24    fn inner_parse<E: ParseError<&'a [u8]>>(
25        block_type: u32,
26        block_len1: u32,
27        i: &'a [u8],
28        block_len2: u32,
29    ) -> IResult<&'a [u8], CustomBlock<'a>, E> {
30        // caller function already tested header type(magic) and length
31        // read end of header
32        let (i, pen) = En::parse_u32(i)?;
33        // there is no way to differentiate custom data and options,
34        // since length of data is not provided
35        let data = i;
36        if block_len2 != block_len1 {
37            return Err(Err::Error(E::from_error_kind(i, ErrorKind::Verify)));
38        }
39        let block = CustomBlock {
40            block_type,
41            block_len1,
42            pen,
43            data,
44            block_len2,
45        };
46        Ok((i, block))
47    }
48}
49
50struct DCBParser;
51impl<'a, En: PcapEndianness> PcapNGBlockParser<'a, En, CustomBlock<'a>> for DCBParser {
52    const HDR_SZ: usize = 16;
53    const MAGIC: u32 = DCB_MAGIC;
54
55    fn inner_parse<E: ParseError<&'a [u8]>>(
56        block_type: u32,
57        block_len1: u32,
58        i: &'a [u8],
59        block_len2: u32,
60    ) -> IResult<&'a [u8], CustomBlock<'a>, E> {
61        <CustomBlock as PcapNGBlockParser<En, CustomBlock<'a>>>::inner_parse::<E>(
62            block_type, block_len1, i, block_len2,
63        )
64    }
65}
66
67impl CustomBlock<'_> {
68    pub fn do_not_copy(&self) -> bool {
69        self.block_type == DCB_MAGIC || self.block_type == DCB_MAGIC.swap_bytes()
70    }
71}
72
73/// Parse a Custom Block (little-endian)
74#[inline]
75pub fn parse_customblock_le(i: &[u8]) -> IResult<&[u8], CustomBlock<'_>, PcapError<&[u8]>> {
76    ng_block_parser::<CustomBlock, PcapLE, _, _>()(i)
77}
78
79/// Parse a Custom Block (big-endian)
80#[inline]
81pub fn parse_customblock_be(i: &[u8]) -> IResult<&[u8], CustomBlock<'_>, PcapError<&[u8]>> {
82    ng_block_parser::<CustomBlock, PcapBE, _, _>()(i)
83}
84
85/// Parse a Do-not-copy Custom Block (little-endian)
86#[inline]
87pub fn parse_dcb_le(i: &[u8]) -> IResult<&[u8], CustomBlock<'_>, PcapError<&[u8]>> {
88    ng_block_parser::<DCBParser, PcapLE, _, _>()(i)
89}
90
91/// Parse a Do-not-copy Custom Block (big-endian)
92#[inline]
93pub fn parse_dcb_be(i: &[u8]) -> IResult<&[u8], CustomBlock<'_>, PcapError<&[u8]>> {
94    ng_block_parser::<DCBParser, PcapBE, _, _>()(i)
95}