rusty_pcap/pcap_ng/blocks/
generic.rs

1use std::io::Read;
2
3use crate::{
4    byte_order::{Endianness, ReadExt},
5    pcap_ng::{PcapNgParseError, blocks::BlockHeader},
6};
7/// A Generic Block in the PCAP-NG format
8///
9/// Used for unknown block ids or custom blocks that do not have a specific structure defined in the PCAP-NG specification.
10#[derive(Debug, Clone, PartialEq, Eq)]
11pub struct GenericBlock {
12    /// The block ID
13    pub block_id: u32,
14    /// The length of the block in bytes, including the header
15    pub block_length: u32,
16    /// The data of the block, if any
17    pub data: Option<Vec<u8>>,
18}
19impl GenericBlock {
20    pub fn new(block_id: u32, data: Option<Vec<u8>>) -> Self {
21        let mut block_length = 12; // Minimum size for a block header
22        if let Some(ref data) = data {
23            block_length += data.len() as u32;
24        }
25        Self {
26            block_id,
27            block_length,
28            data,
29        }
30    }
31    pub fn read_with_header<R: Read>(
32        reader: &mut R,
33        header: &BlockHeader,
34        byte_order: Endianness,
35    ) -> Result<Self, PcapNgParseError> {
36        let block_length = header.block_length_as_u32(byte_order);
37        let data = if block_length > 12 {
38            let mut data = vec![0u8; (block_length - 12) as usize];
39            reader.read_exact(&mut data)?;
40            Some(data)
41        } else {
42            None
43        };
44
45        reader.read_bytes::<4>()?;
46        Ok(Self {
47            block_id: header.block_id_as_u32(byte_order),
48            block_length,
49            data,
50        })
51    }
52    pub fn read<R: Read>(reader: &mut R, byte_order: Endianness) -> Result<Self, PcapNgParseError> {
53        let header = BlockHeader::read(reader)?;
54        Self::read_with_header(reader, &header, byte_order)
55    }
56}