use std::io::{stdout, Write};
use structopt::StructOpt;
use ethox::managed::{List, Map, SlotMap, Slice};
use ethox::nic::{Device, sys::RawSocket, Protocol};
use ethox::layer::{arp, eth, ip, tcp};
use ethox::wire::{ip::v4, ethernet};
fn main() {
let Config {
name,
host,
hostmac,
gateway,
server,
server_port,
} = 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 tcp = tcp::Endpoint::new(
Map::Pairs(List::new(Slice::One(Default::default()))),
SlotMap::new(Slice::One(Default::default()), Slice::One(Default::default())),
tcp::IsnGenerator::from_std_hash(),
);
let message = "GET / HTTP/1.0\r\n\r\n";
let mut tcp_client = tcp::Client::new(
v4::Address::from(server).into(), server_port,
tcp::io::RecvInto::new(vec![0; 1 << 20]),
tcp::io::SendFrom::once(message.as_bytes()));
let mut interface = RawSocket::new(&name, vec![0; 1 << 14])
.expect(&format!("Couldn't initialize interface {}", name));
*interface.capabilities_mut().tcp_mut() = Protocol::offloaded().into();
let out = stdout();
let mut out = out.lock();
loop {
let rx = interface.rx(10, eth.recv(ip.recv(tcp.recv(&mut tcp_client)))).unwrap();
let tx = interface.tx(10, eth.send(ip.send(tcp.send(&mut tcp_client)))).unwrap();
if tcp_client.is_closed() {
break;
}
}
let received = tcp_client.recv().received();
let http = String::from_utf8_lossy(received);
let header_end = http.find("\r\n\r\n")
.expect(&format!("Expected http header end in {}", http));
write!(out, "{}", &http[header_end+4..])
.unwrap();
}
#[derive(StructOpt)]
struct Config {
name: String,
host: v4::Cidr,
hostmac: ethernet::Address,
gateway: v4::Cidr,
server: std::net::Ipv4Addr,
server_port: u16,
}