use crate::structures::common::{self, StructureError};
use std::collections::HashMap;
#[derive(Debug, Clone, Default)]
pub struct PcapBlock {
pub block_type: usize,
pub block_size: usize,
}
pub fn parse_pcapng_block(
block_data: &[u8],
endianness: &str,
) -> Result<PcapBlock, StructureError> {
const BLOCK_TYPE_RESERVED_MASK: usize = 0x80000000;
let block_header_structure = vec![("block_type", "u32"), ("block_size", "u32")];
let block_footer_structure = vec![("block_size", "u32")];
let mut result = PcapBlock {
..Default::default()
};
let footer_size = common::size(&block_footer_structure);
if let Ok(block_header) = common::parse(block_data, &block_header_structure, endianness) {
result.block_type = block_header["block_type"];
result.block_size = block_header["block_size"];
if (result.block_type & BLOCK_TYPE_RESERVED_MASK) == 0 {
let block_footer_start = result.block_size - footer_size;
let block_footer_end = block_footer_start + footer_size;
if let Some(block_footer_data) = block_data.get(block_footer_start..block_footer_end) {
if let Ok(block_footer) =
common::parse(block_footer_data, &block_footer_structure, endianness)
{
if block_footer["block_size"] == result.block_size {
return Ok(result);
}
}
}
}
}
Err(StructureError)
}
#[derive(Debug, Default, Clone)]
pub struct PcapSectionBlock {
pub block_size: usize,
pub endianness: String,
}
pub fn parse_pcapng_section_block(block_data: &[u8]) -> Result<PcapSectionBlock, StructureError> {
const SECTION_HEADER_BLOCK_TYPE: usize = 0x0A0D0D0A;
let section_header_structure = vec![
("block_type", "u32"),
("block_size", "u32"),
("endian_magic", "u32"),
("major_version", "u16"),
("minor_version", "u16"),
("section_length", "u32"),
];
let endian_magics: HashMap<usize, &str> =
HashMap::from([(0x1A2B3C4D, "little"), (0x4D3C2B1A, "big")]);
let mut result = PcapSectionBlock {
..Default::default()
};
if let Ok(section_header) = common::parse(block_data, §ion_header_structure, "little") {
if endian_magics.contains_key(§ion_header["endian_magic"]) {
result.endianness = endian_magics[§ion_header["endian_magic"]].to_string();
if let Ok(block_header) = parse_pcapng_block(block_data, &result.endianness) {
if block_header.block_type == SECTION_HEADER_BLOCK_TYPE {
result.block_size = block_header.block_size;
return Ok(result);
}
}
}
}
Err(StructureError)
}