Support input from files and stdin

This commit is contained in:
2026-02-24 21:47:19 -05:00
parent 020739397c
commit dc5196404f
2 changed files with 25 additions and 267 deletions

View File

@@ -1,7 +1,8 @@
use clap::Parser;
use std::{
fs::File,
path::PathBuf,
io,
path::{Path, PathBuf},
sync::mpsc::{channel, Sender},
thread,
};
@@ -23,7 +24,7 @@ struct KissPkt {
data: Vec<u8>,
}
fn tnc_loop(tx: Sender<KissPkt>, mut stream: TcpStream) -> Result<()> {
fn tnc_loop<T: Read>(tx: Sender<KissPkt>, mut stream: T) -> Result<()> {
let mut buffer = [0_u8; 4096];
let mut frame = vec![];
let mut escaped = false;
@@ -33,6 +34,9 @@ fn tnc_loop(tx: Sender<KissPkt>, mut stream: TcpStream) -> Result<()> {
let mut orig_len = 0;
loop {
let n = stream.read(&mut buffer)?;
if n == 0 {
return Ok(());
}
for byte in buffer[..n].iter() {
orig_len += 1;
if escaped {
@@ -66,23 +70,20 @@ fn tnc_loop(tx: Sender<KissPkt>, mut stream: TcpStream) -> Result<()> {
}
}
}
//Ok(())
}
const DEFAULT_ADDR: &str = "127.0.0.1:8001";
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Arg {
#[arg(short, long, default_value_t = false)]
verbose: bool,
#[arg(short, long)]
file: Option<PathBuf>,
address: Option<String>,
#[arg(short, long, value_name = "FILE")]
output: Option<PathBuf>,
input: String,
}
fn main() -> Result<()> {
let arg = Arg::parse();
let address = arg.address.unwrap_or(DEFAULT_ADDR.to_string());
let mut file = arg.file.map(|path| {
let mut file = arg.output.map(|path| {
//TODO automatically add file extension
let file_out = File::create(path).expect("Error opening file for writing");
let header = PcapHeader {
@@ -91,15 +92,23 @@ fn main() -> Result<()> {
};
PcapWriter::with_header(file_out, header).expect("Error writing file")
});
//println!("file: {:?}", arg.file);
//println!("address: {}", address);
let (tx, rx) = channel();
let stream = TcpStream::connect(address)?;
let q = tx.clone();
let strm = stream.try_clone()?;
thread::spawn(move || tnc_loop(q, strm).unwrap());
match arg.input.as_str() {
"-" => {
let file = io::BufReader::new(io::stdin());
thread::spawn(move || tnc_loop(tx, file).unwrap());
}
s if Path::new(s).exists() => {
let file = io::BufReader::new(File::open(s)?);
thread::spawn(move || tnc_loop(tx, file).unwrap());
}
addr => {
let stream = TcpStream::connect(addr)?;
let strm = stream.try_clone()?;
thread::spawn(move || tnc_loop(tx, strm).unwrap());
}
}
while let Ok(pkt) = rx.recv() {
//let time = SystemTime::now();