use getopts::Options; use smoltcp::phy::{PcapLinkType, PcapSink}; use smoltcp::time::Instant; use std::env; use std::fs::File; use std::io::{self, Read}; use std::path::Path; use std::process::exit; fn convert( packet_filename: &Path, pcap_filename: &Path, link_type: PcapLinkType, ) -> io::Result<()> { let mut packet_file = File::open(packet_filename)?; let mut packet = Vec::new(); packet_file.read_to_end(&mut packet)?; let mut pcap_file = File::create(pcap_filename)?; PcapSink::global_header(&mut pcap_file, link_type); PcapSink::packet(&mut pcap_file, Instant::from_millis(0), &packet[..]); Ok(()) } fn print_usage(program: &str, opts: Options) { let brief = format!("Usage: {} [options] INPUT OUTPUT", program); print!("{}", opts.usage(&brief)); } fn main() { let args: Vec = env::args().collect(); let program = args[0].clone(); let mut opts = Options::new(); opts.optflag("h", "help", "print this help menu"); opts.optopt( "t", "link-type", "set link type (one of: ethernet ip)", "TYPE", ); let matches = match opts.parse(&args[1..]) { Ok(m) => m, Err(e) => { eprintln!("{}", e); return; } }; let link_type = match matches.opt_str("t").as_ref().map(|s| &s[..]) { Some("ethernet") => Some(PcapLinkType::Ethernet), Some("ip") => Some(PcapLinkType::Ip), _ => None, }; if matches.opt_present("h") || matches.free.len() != 2 || link_type.is_none() { print_usage(&program, opts); return; } match convert( Path::new(&matches.free[0]), Path::new(&matches.free[1]), link_type.unwrap(), ) { Ok(()) => (), Err(e) => { eprintln!("Cannot convert packet to pcap: {}", e); exit(1); } } }