Compare commits

...

3 Commits

Author SHA1 Message Date
200eadf9a1 Forgot to add Ok(()) 2026-03-07 12:36:42 -05:00
f9671f9408 Remove unneeded todo 2026-03-07 11:45:03 -05:00
250dcd8d6f Add support for reading pcap files 2026-03-07 11:40:34 -05:00

View File

@@ -1,7 +1,7 @@
use clap::Parser;
use std::{
fs::File,
io,
io::{self, IsTerminal},
path::{Path, PathBuf},
sync::mpsc::{channel, Sender},
thread,
@@ -10,7 +10,7 @@ use std::{
use anyhow::Result;
use ax25::frame::Ax25Frame;
use pcap_file::{
pcap::{PcapHeader, PcapPacket, PcapWriter},
pcap::{PcapHeader, PcapPacket, PcapReader, PcapWriter},
DataLink,
};
use std::io::Read;
@@ -28,6 +28,18 @@ struct KissPkt {
data: Vec<u8>,
}
fn pcap_loop<T: Read>(tx: Sender<KissPkt>, stream: T) -> Result<()> {
let mut reader = PcapReader::new(stream)?;
while let Some(Ok(pkt)) = reader.next_packet() {
tx.send(KissPkt {
timestamp: pkt.timestamp,
orig_len: pkt.orig_len,
data: pkt.data.into(),
})?;
}
Ok(())
}
fn tnc_loop<T: Read>(tx: Sender<KissPkt>, mut stream: T) -> Result<()> {
let mut buffer = [0_u8; 4096];
let mut frame = vec![];
@@ -110,8 +122,14 @@ fn main() -> Result<()> {
thread::spawn(move || tnc_loop(tx, file).unwrap());
}
path if Path::new(path).exists() => {
let file = io::BufReader::new(File::open(path)?);
thread::spawn(move || tnc_loop(tx, file).unwrap());
let file = File::open(path)?;
let is_tty = file.is_terminal();
let mut filebuf = io::BufReader::new(file);
if !is_tty && has_pcap_magic(&mut filebuf) {
thread::spawn(move || pcap_loop(tx, filebuf).unwrap());
} else {
thread::spawn(move || tnc_loop(tx, filebuf).unwrap());
}
}
addr => {
let stream = TcpStream::connect(addr)?;
@@ -155,3 +173,17 @@ fn main() -> Result<()> {
Ok(())
}
fn has_pcap_magic(filebuf: &mut io::BufReader<File>) -> bool {
const PCAP_MAGIC_MS: u32 = 0xA1B2C3D4;
const PCAP_MAGIC_NS: u32 = 0xA1B23C4D;
match io::BufRead::fill_buf(filebuf) {
Ok(buf) if buf.len() >= 4 => {
let mut tmp = [0_u8; 4];
tmp.copy_from_slice(&buf[..4]);
let be = u32::from_be_bytes(tmp);
let le = u32::from_le_bytes(tmp);
be == PCAP_MAGIC_MS || be == PCAP_MAGIC_NS || le == PCAP_MAGIC_MS || le == PCAP_MAGIC_NS
}
_ => false,
}
}