use packet::{builder::Builder, icmp, ip, Packet};
use std::io::{Read, Write};
use std::net::Ipv4Addr;
fn main() {
let mut config = tun::Configuration::default();
config
.address((10, 0, 0, 1))
.netmask((255, 255, 255, 0))
.up();
#[cfg(target_os = "linux")]
config.platform(|config| {
config.packet_information(true);
});
let mut dev = tun::create(&config).unwrap();
let mut buf = [0; 4096];
loop {
println!("prepare to read");
let amount = dev.read(&mut buf).unwrap();
//println!("{:?}", &buf[0..amount]);
let read_buf = &buf[4..amount];
match ip::Packet::new(read_buf) {
Ok(ip::Packet::V4(pkt)) => match icmp::Packet::new(pkt.payload()) {
Ok(icmp) => match icmp.echo() {
Ok(icmp) => {
println!("packet comming!!!! src: {}, dest: {}",pkt.source(),pkt.destination());
let reply = ip::v4::Builder::default()
.id(0x42)
.unwrap()
.ttl(64)
.unwrap()
.source(pkt.destination())
.unwrap()
.destination(pkt.source())
.unwrap()
.icmp()
.unwrap()
.echo()
.unwrap()
.reply()
.unwrap()
.identifier(icmp.identifier())
.unwrap()
.sequence(icmp.sequence())
.unwrap()
.payload(icmp.payload())
.unwrap()
.build()
.unwrap();
let r = dev.write(&reply[..]).unwrap();
dev.flush().unwrap();
println!("write {r}");
}
_ => {}
},
_ => {}
},
Err(err) => println!("Received an invalid packet: {:?}", err),
_ => {}
}
}
}
This code is exactly the same as that of https://github.com/meh/rust-tun/blob/master/examples/ping-tun.rs except that the code uses synchronous version API. When running command ping 10.0.0.2, the program can read packet, however, when trying to reply to the ICMP packet, dev.write does not work. I'm not sure what wrong is here.
This code is exactly the same as that of https://github.com/meh/rust-tun/blob/master/examples/ping-tun.rs except that the code uses synchronous version API. When running command
ping 10.0.0.2
, the program can read packet, however, when trying to reply to the ICMP packet,dev.write
does not work. I'm not sure what wrong is here.