use etherparse::{PacketBuilder, TcpOptionElement};
use libslirp;
use std::io;
use std::os::unix::io::RawFd;
use std::time::Instant;
use structopt::StructOpt;
impl libslirp::Handler for App {
type Timer = usize;
fn clock_get_ns(&mut self) -> i64 {
const NANOS_PER_SEC: u64 = 1_000_000_000;
let d = self.start.elapsed();
(d.as_secs() * NANOS_PER_SEC + d.subsec_nanos() as u64) as i64
}
fn timer_new(&mut self, _func: Box<dyn FnMut()>) -> Box<Self::Timer> {
Box::new(0)
}
fn timer_mod(&mut self, _timer: &mut Box<Self::Timer>, _expire_time: i64) {}
fn timer_free(&mut self, timer: Box<Self::Timer>) {
drop(timer);
}
fn send_packet(&mut self, buf: &[u8]) -> io::Result<usize> {
Ok(buf.len())
}
fn guest_error(&mut self, msg: &str) {
eprintln!("guest error: {}", msg);
}
fn register_poll_fd(&mut self, fd: RawFd) {
println!("register_poll_fd: fd={:?}", fd);
}
fn unregister_poll_fd(&mut self, fd: RawFd) {
println!("unregister_poll_fd: fd={:?}", fd);
}
fn notify(&mut self) {
println!("notify");
}
}
struct App {
start: Instant,
}
#[test]
fn ip() {
let opt = libslirp::Opt::from_args();
let app = App {
start: Instant::now(),
};
let ctxt = libslirp::Context::new_with_opt(&opt, app);
{
let builder = PacketBuilder::ethernet2(
[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12], )
.ipv4(
[192, 168, 1, 1], [192, 168, 1, 2], 20, )
.udp(
21, 1234, );
let payload = [1, 2, 3, 4, 5, 6, 7, 8];
let mut buffer = Vec::<u8>::with_capacity(builder.size(payload.len()));
builder.write(&mut buffer, &payload).unwrap();
ctxt.input(&buffer);
}
{
let builder = PacketBuilder::ethernet2(
[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12], )
.ipv4(
[192, 168, 1, 1], [192, 168, 1, 2], 20, )
.tcp(
21, 1234, 1, 26180, )
.ns() .ack(123) .urg(23) .options(&[
TcpOptionElement::Noop,
TcpOptionElement::MaximumSegmentSize(1234),
])
.unwrap();
let payload = [1, 2, 3, 4, 5, 6, 7, 8];
let mut buffer = Vec::<u8>::with_capacity(builder.size(payload.len()));
builder.write(&mut buffer, &payload).unwrap();
ctxt.input(&buffer);
}
}