use std::io::{stdout, Write};
use structopt::StructOpt;
use ethox::managed::{List, Slice};
use ethox::nic::{Device, sys::TapInterface};
use ethox::layer::{arp, eth, ip, icmp};
use ethox::wire::{ip::v4::Cidr, ethernet::Address};
fn main() {
let Config {
name,
host,
hostmac,
gateway,
} = Config::from_args();
let mut eth = eth::Endpoint::new(hostmac);
let mut neighbors = [arp::Neighbor::default(); 1];
let mut routes = [ip::Route::new_ipv4_gateway(gateway.address()); 1];
let mut ip = ip::Endpoint::new(Slice::One(host.into()),
ip::Routes::import(List::new_full(routes.as_mut().into())),
arp::NeighborCache::new(&mut neighbors[..]));
let mut icmp = icmp::Endpoint::new();
let mut interface = TapInterface::new(&name, vec![0; 1 << 14])
.expect("Couldn't initialize interface");
let out = stdout();
let mut out = out.lock();
out.write_all(b"Started icmpv4 endpoint\n").unwrap();
loop {
let rx_ok = interface.rx(1, eth.recv(ip.recv(icmp.answer())));
let tx_ok = interface.tx(1, eth.send(ip.layer_internal()));
let result = rx_ok.and_then(|x| tx_ok.map(|y| x + y));
if let Ok(1) | Ok(2) = result {
out.write_all(b".").unwrap();
out.flush().unwrap();
}
result.unwrap_or_else(|err| {
panic!("Error during receive {:?} {:?}", err, interface.last_err());
});
}
}
#[derive(StructOpt)]
struct Config {
name: String,
host: Cidr,
hostmac: Address,
gateway: Cidr,
}