diff --git a/Cargo.toml b/Cargo.toml index 414ce4f..2960844 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,3 +28,9 @@ use_collections = ["managed/use_collections"] use_log = ["log"] verbose = [] default = ["use_std", "use_log", "verbose"] + +[[example]] +name = "tcpdump" + +[[example]] +name = "server" diff --git a/examples/server.rs b/examples/server.rs index 25ba308..455e7e8 100644 --- a/examples/server.rs +++ b/examples/server.rs @@ -4,66 +4,21 @@ extern crate env_logger; extern crate getopts; extern crate smoltcp; -use std::str::{self, FromStr}; -use std::env; -use std::time::{Instant, SystemTime, UNIX_EPOCH}; -use log::{LogLevelFilter, LogRecord}; -use env_logger::{LogBuilder}; +mod utils; -use smoltcp::phy::{Tracer, FaultInjector, TapInterface}; -use smoltcp::wire::{EthernetFrame, EthernetAddress, IpAddress}; -use smoltcp::wire::PrettyPrinter; +use std::str; +use std::time::Instant; +use smoltcp::wire::{EthernetAddress, IpAddress}; use smoltcp::iface::{ArpCache, SliceArpCache, EthernetInterface}; use smoltcp::socket::{AsSocket, SocketSet}; use smoltcp::socket::{UdpSocket, UdpSocketBuffer, UdpPacketBuffer}; use smoltcp::socket::{TcpSocket, TcpSocketBuffer}; fn main() { - let mut opts = getopts::Options::new(); - opts.optopt("", "drop-chance", "Chance of dropping a packet (%)", "CHANCE"); - opts.optopt("", "corrupt-chance", "Chance of corrupting a packet (%)", "CHANCE"); - opts.optflag("h", "help", "print this help menu"); - - let matches = opts.parse(env::args().skip(1)).unwrap(); - if matches.opt_present("h") || matches.free.len() != 1 { - let brief = format!("Usage: {} FILE [options]", env::args().nth(0).unwrap()); - print!("{}", opts.usage(&brief)); - return - } - let drop_chance = u8::from_str(&matches.opt_str("drop-chance") - .unwrap_or("0".to_string())).unwrap(); - let corrupt_chance = u8::from_str(&matches.opt_str("corrupt-chance") - .unwrap_or("0".to_string())).unwrap(); - - let seed = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().subsec_nanos(); + utils::setup_logging(); + let device = utils::setup_device(); let startup_time = Instant::now(); - LogBuilder::new() - .format(move |record: &LogRecord| { - let elapsed = Instant::now().duration_since(startup_time); - if record.target().starts_with("smoltcp::") { - format!("\x1b[0m[{:6}.{:03}s] ({}): {}\x1b[0m", - elapsed.as_secs(), elapsed.subsec_nanos() / 1000000, - record.target().replace("smoltcp::", ""), record.args()) - } else { - format!("\x1b[32m[{:6}.{:03}s] ({}): {}\x1b[0m", - elapsed.as_secs(), elapsed.subsec_nanos() / 1000000, - record.target(), record.args()) - } - }) - .filter(None, LogLevelFilter::Trace) - .init() - .unwrap(); - - fn trace_writer(printer: PrettyPrinter>) { - print!("\x1b[37m{}\x1b[0m", printer) - } - - let device = TapInterface::new(&matches.free[0]).unwrap(); - let mut device = FaultInjector::new(device, seed); - device.set_drop_chance(drop_chance); - device.set_corrupt_chance(corrupt_chance); - let device = Tracer::<_, EthernetFrame<&[u8]>>::new(device, trace_writer); let arp_cache = SliceArpCache::new(vec![Default::default(); 8]); diff --git a/examples/utils.rs b/examples/utils.rs new file mode 100644 index 0000000..7baead0 --- /dev/null +++ b/examples/utils.rs @@ -0,0 +1,63 @@ +use std::str::{self, FromStr}; +use std::env; +use std::time::{Instant, SystemTime, UNIX_EPOCH}; +use std::process; +use log::{LogLevelFilter, LogRecord}; +use env_logger::{LogBuilder}; +use getopts; + +use smoltcp::phy::{Tracer, FaultInjector, TapInterface}; +use smoltcp::wire::EthernetFrame; +use smoltcp::wire::PrettyPrinter; + +pub fn setup_logging() { + let startup_time = Instant::now(); + LogBuilder::new() + .format(move |record: &LogRecord| { + let elapsed = Instant::now().duration_since(startup_time); + if record.target().starts_with("smoltcp::") { + format!("\x1b[0m[{:6}.{:03}s] ({}): {}\x1b[0m", + elapsed.as_secs(), elapsed.subsec_nanos() / 1000000, + record.target().replace("smoltcp::", ""), record.args()) + } else { + format!("\x1b[32m[{:6}.{:03}s] ({}): {}\x1b[0m", + elapsed.as_secs(), elapsed.subsec_nanos() / 1000000, + record.target(), record.args()) + } + }) + .filter(None, LogLevelFilter::Trace) + .init() + .unwrap(); +} + +pub fn setup_device() -> Tracer, EthernetFrame<&'static [u8]>> { + let mut opts = getopts::Options::new(); + opts.optopt("", "drop-chance", "Chance of dropping a packet (%)", "CHANCE"); + opts.optopt("", "corrupt-chance", "Chance of corrupting a packet (%)", "CHANCE"); + opts.optflag("h", "help", "print this help menu"); + + let matches = opts.parse(env::args().skip(1)).unwrap(); + if matches.opt_present("h") || matches.free.len() != 1 { + let brief = format!("Usage: {} INTERFACE [options]", env::args().nth(0).unwrap()); + print!("{}", opts.usage(&brief)); + process::exit(if matches.free.len() != 1 { 1 } else { 0 }); + } + let drop_chance = u8::from_str(&matches.opt_str("drop-chance") + .unwrap_or("0".to_string())).unwrap(); + let corrupt_chance = u8::from_str(&matches.opt_str("corrupt-chance") + .unwrap_or("0".to_string())).unwrap(); + + let seed = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().subsec_nanos(); + + fn trace_writer(printer: PrettyPrinter>) { + print!("\x1b[37m{}\x1b[0m", printer) + } + + let device = TapInterface::new(&matches.free[0]).unwrap(); + let mut device = FaultInjector::new(device, seed); + device.set_drop_chance(drop_chance); + device.set_corrupt_chance(corrupt_chance); + let device = Tracer::<_, EthernetFrame<&'static [u8]>>::new(device, trace_writer); + + device +}