use std::io::BufWriter;
use std::io::Write;
use anyhow::Result;
const MAGIC: [u8; 4] = [0xd4, 0xc3, 0xb2, 0xa1];
const VERSION_MAJOR: u16 = 2;
const VERSION_MINOR: u16 = 4;
const LINKTYPE_AX25: u32 = 3;
fn write_u16(mut w: impl std::io::Write, v: u16) -> Result<()> {
w.write_all(&[(v & 0xff) as u8, ((v >> 8) & 0xFF) as u8])?;
Ok(())
}
fn write_u32(mut w: impl std::io::Write, v: u32) -> Result<()> {
w.write_all(&[
(v & 0xff) as u8,
((v >> 8) & 0xFF) as u8,
((v >> 16) & 0xFF) as u8,
((v >> 24) & 0xFF) as u8,
])?;
Ok(())
}
pub struct PcapWriter {
f: BufWriter<std::fs::File>,
}
impl PcapWriter {
pub fn create(filename: std::path::PathBuf) -> Result<Self> {
let mut f = BufWriter::new(
std::fs::File::options()
.read(false)
.write(true)
.create_new(true)
.open(filename)?,
);
f.write_all(&MAGIC)?;
write_u16(&mut f, VERSION_MAJOR)?;
write_u16(&mut f, VERSION_MINOR)?;
write_u32(&mut f, 0)?;
write_u32(&mut f, 0)?;
write_u32(&mut f, 65535)?;
write_u32(&mut f, LINKTYPE_AX25)?;
Ok(Self { f })
}
pub fn write(&mut self, packet: &[u8]) -> Result<()> {
let len = packet.len() as u32;
let now = std::time::SystemTime::now().duration_since(std::time::SystemTime::UNIX_EPOCH)?;
write_u32(&mut self.f, now.as_secs() as u32)?;
write_u32(&mut self.f, (now.as_micros() % 1000000) as u32)?;
write_u32(&mut self.f, len)?;
write_u32(&mut self.f, len)?;
self.f.write_all(packet)?;
Ok(())
}
}