pcap_parser/pcapng/
process_information.rs

1use nom::error::{ErrorKind, ParseError};
2use nom::{Err, IResult};
3
4use crate::endianness::{PcapBE, PcapEndianness, PcapLE};
5use crate::{opt_parse_options, PcapError, PcapNGOption, PIB_MAGIC};
6
7use super::*;
8
9#[derive(Debug)]
10pub struct ProcessInformationBlock<'a> {
11    pub block_type: u32,
12    pub block_len1: u32,
13    pub process_id: u32,
14    pub options: Vec<PcapNGOption<'a>>,
15    pub block_len2: u32,
16}
17
18impl<'a, En: PcapEndianness> PcapNGBlockParser<'a, En, ProcessInformationBlock<'a>>
19    for ProcessInformationBlock<'a>
20{
21    const MAGIC: u32 = PIB_MAGIC;
22    const HDR_SZ: usize = 4;
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], ProcessInformationBlock<'a>, E> {
30        // caller function already tested header type(magic) and length
31        // read options
32        let (i, process_id) = En::parse_u32(i)?;
33        let (i, options) = opt_parse_options::<En, E>(i, (block_len1 - 4) as usize, 12)?;
34        if block_len2 != block_len1 {
35            return Err(Err::Error(E::from_error_kind(i, ErrorKind::Verify)));
36        }
37        let block = ProcessInformationBlock {
38            block_type,
39            block_len1,
40            process_id,
41            options,
42            block_len2,
43        };
44        Ok((i, block))
45    }
46}
47
48/// Parse a ProcessInformation Block (little-endian)
49#[inline]
50pub fn parse_processinformationblock_le(
51    i: &[u8],
52) -> IResult<&[u8], ProcessInformationBlock<'_>, PcapError<&[u8]>> {
53    ng_block_parser::<ProcessInformationBlock, PcapLE, _, _>()(i)
54}
55
56/// Parse a ProcessInformation Block (big-endian)
57#[inline]
58pub fn parse_processinformationblock_be(
59    i: &[u8],
60) -> IResult<&[u8], ProcessInformationBlock<'_>, PcapError<&[u8]>> {
61    ng_block_parser::<ProcessInformationBlock, PcapBE, _, _>()(i)
62}