wireforge_app/pcap/
ng_writer.rs1use std::io::Write;
4use std::time::Duration;
5
6use super::types::LinkType;
7
8pub struct PcapNgWriter<W: Write> {
9 writer: W,
10}
11
12impl<W: Write> PcapNgWriter<W> {
13 pub fn new(mut writer: W, link_type: LinkType) -> Result<Self, std::io::Error> {
14 let shb_body = [0u8; 16]; let shb_len = 28u32; writer.write_all(&0x0A0D0D0Au32.to_be_bytes())?;
18 writer.write_all(&shb_len.to_be_bytes())?;
19 writer.write_all(&shb_body)?;
20 writer.write_all(&shb_len.to_be_bytes())?;
21
22 let lt: u16 = match link_type { LinkType::Ethernet => 1, LinkType::Raw => 101, LinkType::Unknown(v) => v as u16 };
24 let mut idb_body = vec![0u8; 16];
25 idb_body[8..10].copy_from_slice(<.to_le_bytes()); let idb_len = 32u32; writer.write_all(&1u32.to_be_bytes())?;
28 writer.write_all(&idb_len.to_be_bytes())?;
29 writer.write_all(&idb_body)?;
30 writer.write_all(&idb_len.to_be_bytes())?;
31
32 Ok(Self { writer })
33 }
34
35 pub fn write_epb(&mut self, ts: Duration, packet: &[u8]) -> Result<(), std::io::Error> {
36 let padded_len = (packet.len() + 3) & !3;
37 let epb_body_len = 20 + padded_len;
38 let epb_total_len = 12 + epb_body_len; self.writer.write_all(&6u32.to_be_bytes())?;
41 self.writer.write_all(&(epb_total_len as u32).to_be_bytes())?;
42 self.writer.write_all(&0u32.to_be_bytes())?; self.writer.write_all(&(ts.as_secs() as u32).to_be_bytes())?; self.writer.write_all(&ts.subsec_nanos().to_be_bytes())?; self.writer.write_all(&(packet.len() as u32).to_be_bytes())?; self.writer.write_all(&(packet.len() as u32).to_be_bytes())?; self.writer.write_all(packet)?;
48 if padded_len > packet.len() {
50 self.writer.write_all(&vec![0u8; padded_len - packet.len()])?;
51 }
52 self.writer.write_all(&(epb_total_len as u32).to_be_bytes())?;
53 self.writer.flush()
54 }
55}