use crate::format::{
DataLinkType, PacketHeader, SnoopHeader, MAX_CAPTURE_LEN, SNOOP_HEADER_SIZE, SNOOP_MAGIC,
SNOOP_PACKET_HEADER_SIZE, SNOOP_VERSION,
};
use crate::Error;
#[derive(Debug)]
pub struct Parser;
impl Parser {
#[allow(clippy::missing_panics_doc)]
pub fn parse_header(buf: &[u8; SNOOP_HEADER_SIZE]) -> Result<SnoopHeader, Error> {
if &buf[0..8] != SNOOP_MAGIC {
return Err(Error::UnknownMagic);
}
if &buf[8..12] != SNOOP_VERSION {
return Err(Error::UnknownVersion);
}
Ok(SnoopHeader {
version: u32::from_be_bytes(buf[8..12].try_into().unwrap()),
link_type: DataLinkType::try_from(u32::from_be_bytes(buf[12..16].try_into().unwrap()))
.unwrap(),
})
}
#[allow(clippy::missing_panics_doc)]
#[allow(clippy::cast_possible_truncation)]
pub fn parse_packet_header(
buf: &[u8; SNOOP_PACKET_HEADER_SIZE],
ph: &mut PacketHeader,
) -> Result<(), Error> {
ph.original_length = u32::from_be_bytes(buf[0..4].try_into().unwrap());
ph.included_length = u32::from_be_bytes(buf[4..8].try_into().unwrap());
ph.packet_record_length = u32::from_be_bytes(buf[8..12].try_into().unwrap());
ph.cumulative_drops = u32::from_be_bytes(buf[12..16].try_into().unwrap());
ph.timestamp_seconds = u32::from_be_bytes(buf[16..20].try_into().unwrap());
ph.timestamp_microseconds = u32::from_be_bytes(buf[20..24].try_into().unwrap());
if ph.included_length > ph.original_length {
return Err(Error::OriginalLenExceeded);
}
if ph.included_length > MAX_CAPTURE_LEN {
return Err(Error::CaptureLenExceeded);
}
if ph.packet_record_length < (SNOOP_PACKET_HEADER_SIZE as u32 + ph.original_length) {
return Err(Error::InvalidRecordLength);
}
Ok(())
}
#[must_use]
#[allow(clippy::cast_possible_truncation)]
pub fn pad(ph: &PacketHeader) -> usize {
(ph.packet_record_length - (SNOOP_PACKET_HEADER_SIZE as u32 + ph.included_length)) as usize
}
#[must_use]
#[allow(clippy::cast_possible_truncation)]
pub fn data_len(ph: &PacketHeader) -> usize {
(ph.packet_record_length - SNOOP_PACKET_HEADER_SIZE as u32) as usize
}
}