Add EthernetTracer, a specialization of Tracer for EthernetFrame.

This makes the loopback example much nicer, #[cfg]-wise.
v0.7.x
whitequark 2017-07-23 06:20:38 +00:00
parent 6dd833f1f7
commit eae7907f60
4 changed files with 19 additions and 26 deletions

View File

@ -3,22 +3,20 @@
#[macro_use]
extern crate log;
extern crate smoltcp;
#[cfg(feature = "std")]
extern crate env_logger;
#[cfg(feature = "std")]
extern crate getopts;
extern crate smoltcp;
#[cfg(feature = "std")]
#[allow(dead_code)]
mod utils;
use smoltcp::Error;
use smoltcp::phy::Loopback;
#[cfg(feature = "std")]
use smoltcp::phy::Tracer;
use smoltcp::phy::EthernetTracer;
use smoltcp::wire::{EthernetAddress, IpAddress};
#[cfg(feature = "std")]
use smoltcp::wire::EthernetFrame;
use smoltcp::iface::{ArpCache, SliceArpCache, EthernetInterface};
use smoltcp::socket::{AsSocket, SocketSet};
use smoltcp::socket::{TcpSocket, TcpSocketBuffer};
@ -35,7 +33,7 @@ mod mock {
Clock(Cell::new(0))
}
pub fn advance(&mut self, millis: u64) {
pub fn advance(&self, millis: u64) {
self.0.set(self.0.get() + millis)
}
@ -79,8 +77,7 @@ fn main() {
}
let mut device = Loopback::new();
#[cfg(feature = "std")]
let mut device = Tracer::<_, EthernetFrame<&'static [u8]>>::new(device, utils::trace_writer);
let mut device = EthernetTracer::new(device, |printer| trace!("{}", printer));
let mut arp_cache_entries: [_; 8] = Default::default();
let mut arp_cache = SliceArpCache::new(&mut arp_cache_entries[..]);

View File

@ -1,16 +1,12 @@
#![allow(dead_code)]
use std::str::{self, FromStr};
use std::env;
use std::time::{Instant, Duration, SystemTime, UNIX_EPOCH};
use std::process;
use log::{LogLevelFilter, LogRecord};
use log::{LogLevel, LogLevelFilter, LogRecord};
use env_logger::LogBuilder;
use getopts;
use smoltcp::phy::{Tracer, FaultInjector, TapInterface};
use smoltcp::wire::EthernetFrame;
use smoltcp::wire::PrettyPrinter;
use smoltcp::phy::{EthernetTracer, FaultInjector, TapInterface};
pub fn setup_logging_with_clock<F>(since_startup: F)
where F: Fn() -> u64 + Send + Sync + 'static {
@ -18,14 +14,14 @@ pub fn setup_logging_with_clock<F>(since_startup: F)
.format(move |record: &LogRecord| {
let elapsed = since_startup();
let timestamp = format!("[{:6}.{:03}s]", elapsed / 1000, elapsed % 1000);
if record.target().ends_with("::utils") {
if record.target().starts_with("smoltcp::") {
format!("\x1b[0m{} ({}): {}\x1b[0m", timestamp,
record.target().replace("smoltcp::", ""), record.args())
} else if record.level() == LogLevel::Trace {
let mut message = format!("{}", record.args());
message.pop();
format!("\x1b[37m{} {}\x1b[0m", timestamp,
message.replace("\n", "\n "))
} else if record.target().starts_with("smoltcp::") {
format!("\x1b[0m{} ({}): {}\x1b[0m", timestamp,
record.target().replace("smoltcp::", ""), record.args())
} else {
format!("\x1b[32m{} ({}): {}\x1b[0m", timestamp,
record.target(), record.args())
@ -44,12 +40,8 @@ pub fn setup_logging() {
})
}
pub fn trace_writer(printer: PrettyPrinter<EthernetFrame<&[u8]>>) {
trace!("{}", printer)
}
pub fn setup_device(more_args: &[&str])
-> (FaultInjector<Tracer<TapInterface, EthernetFrame<&'static [u8]>>>,
-> (FaultInjector<EthernetTracer<TapInterface>>,
Vec<String>) {
let mut opts = getopts::Options::new();
opts.optopt("", "drop-chance", "Chance of dropping a packet (%)", "CHANCE");
@ -86,7 +78,7 @@ pub fn setup_device(more_args: &[&str])
let seed = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().subsec_nanos();
let device = TapInterface::new(&matches.free[0]).unwrap();
let device = Tracer::<_, EthernetFrame<&'static [u8]>>::new(device, trace_writer);
let device = EthernetTracer::new(device, |printer| trace!("{}", printer));
let mut device = FaultInjector::new(device, seed);
device.set_drop_chance(drop_chance);
device.set_corrupt_chance(corrupt_chance);

View File

@ -127,6 +127,9 @@ pub use self::raw_socket::RawSocket;
#[cfg(all(feature = "tap_interface", target_os = "linux"))]
pub use self::tap_interface::TapInterface;
/// A tracer device for Ethernet frames.
pub type EthernetTracer<T> = Tracer<T, super::wire::EthernetFrame<&'static [u8]>>;
/// A description of device limitations.
///
/// Higher-level protocols may achieve higher throughput or lower latency if they consider

View File

@ -4,8 +4,9 @@ use super::{DeviceLimits, Device};
/// A tracer device.
///
/// A tracer is a device that prints all packets traversing it
/// to the standard output, and delegates to another device otherwise.
/// A tracer is a device that pretty prints all packets traversing it
/// using the provided writer function, and then passes them to another
/// device.
pub struct Tracer<T: Device, U: PrettyPrint> {
lower: T,
writer: fn(PrettyPrinter<U>)