Skip to main content

wireforge_app/pcap/
writer.rs

1//! pcap file writer.
2
3use std::io::Write;
4use std::time::Duration;
5
6use super::types::LinkType;
7
8pub struct PcapWriter<W: Write> {
9    writer: W,
10}
11
12impl<W: Write> PcapWriter<W> {
13    pub fn new(mut writer: W, link_type: LinkType) -> Result<Self, std::io::Error> {
14        let net: u32 = match link_type { LinkType::Ethernet => 1, LinkType::Raw => 101, LinkType::Unknown(v) => v };
15        writer.write_all(&0xa1b2c3d4u32.to_be_bytes())?; // magic
16        writer.write_all(&2u16.to_be_bytes())?; // version major
17        writer.write_all(&4u16.to_be_bytes())?; // version minor
18        writer.write_all(&[0u8; 4])?; // thiszone
19        writer.write_all(&[0u8; 4])?; // sigfigs
20        writer.write_all(&65535u32.to_be_bytes())?; // snaplen
21        writer.write_all(&net.to_be_bytes())?; // network
22        Ok(Self { writer })
23    }
24
25    pub fn write(&mut self, ts: Duration, packet: &[u8]) -> Result<(), std::io::Error> {
26        self.writer.write_all(&(ts.as_secs() as u32).to_be_bytes())?;
27        self.writer.write_all(&ts.subsec_micros().to_be_bytes())?;
28        self.writer.write_all(&(packet.len() as u32).to_be_bytes())?;
29        self.writer.write_all(&(packet.len() as u32).to_be_bytes())?;
30        self.writer.write_all(packet)?;
31        self.writer.flush()
32    }
33}