pcap_file/pcapng/blocks/
simple_packet.rs

1//! Simple Packet Block (SPB).
2
3use std::borrow::Cow;
4use std::io::{Result as IoResult, Write};
5
6use byteorder_slice::byteorder::WriteBytesExt;
7use byteorder_slice::result::ReadSlice;
8use byteorder_slice::ByteOrder;
9use derive_into_owned::IntoOwned;
10
11use super::block_common::{Block, PcapNgBlock};
12use crate::errors::PcapError;
13
14
15/// The Simple Packet Block (SPB) is a lightweight container for storing the packets coming from the network.
16/// 
17/// Its presence is optional.
18#[derive(Clone, Debug, IntoOwned, Eq, PartialEq)]
19pub struct SimplePacketBlock<'a> {
20    /// Actual length of the packet when it was transmitted on the network.
21    pub original_len: u32,
22
23    /// The data coming from the network, including link-layer headers.
24    pub data: Cow<'a, [u8]>,
25}
26
27impl<'a> PcapNgBlock<'a> for SimplePacketBlock<'a> {
28    fn from_slice<B: ByteOrder>(mut slice: &'a [u8]) -> Result<(&'a [u8], Self), PcapError> {
29        if slice.len() < 4 {
30            return Err(PcapError::InvalidField("SimplePacketBlock: block length < 4"));
31        }
32        let original_len = slice.read_u32::<B>().unwrap();
33
34        let packet = SimplePacketBlock { original_len, data: Cow::Borrowed(slice) };
35
36        Ok((&[], packet))
37    }
38
39    fn write_to<B: ByteOrder, W: Write>(&self, writer: &mut W) -> IoResult<usize> {
40        writer.write_u32::<B>(self.original_len)?;
41        writer.write_all(&self.data)?;
42
43        let pad_len = (4 - (self.data.len() % 4)) % 4;
44        writer.write_all(&[0_u8; 3][..pad_len])?;
45
46        Ok(4 + self.data.len() + pad_len)
47    }
48
49    fn into_block(self) -> Block<'a> {
50        Block::SimplePacket(self)
51    }
52}