#[cfg(not(windows))]
mod tests {
use etherparse::{PacketBuilder, PacketHeaders};
use pcap::Capture;
use tun_tap::Iface;
#[test]
#[ignore]
fn conntrack_tap_basic() {
let (cap, iface) = capture_tap_interface();
let mut cap = cap.snaplen(32000).timeout(500).open().unwrap();
let builder1 = PacketBuilder::ethernet2([1, 1, 1, 1, 1, 1], [2, 2, 2, 2, 2, 2])
.ipv4([1, 2, 3, 4], [5, 6, 7, 8], 128)
.tcp(80, 12345, 1, 32000);
let payload1 = [1, 2, 3, 4, 5, 6, 7, 8];
let mut pkt1 = Vec::with_capacity(builder1.size(payload1.len()));
builder1.write(&mut pkt1, &payload1).unwrap();
let send_len = iface.send(&pkt1).unwrap();
assert_eq!(send_len, pkt1.len());
let test_pkt1 = cap.next_packet().unwrap();
assert_eq!(pkt1.len(), test_pkt1.header.caplen as usize);
assert_eq!(&pkt1, test_pkt1.data);
cap.sendpacket(pkt1.clone()).unwrap();
let mut buf = vec![0; pkt1.len() * 2];
let recv_len = iface.recv(&mut buf).unwrap();
let (test_sendpkt, _) = buf.split_at(recv_len);
if recv_len != pkt1.len() {
let weird = PacketHeaders::from_ethernet_slice(test_sendpkt).unwrap();
panic!("weird packet !! {weird:#?}");
}
assert_eq!(pkt1.len(), recv_len);
assert_eq!(pkt1, test_sendpkt);
}
fn capture_tap_interface() -> (Capture<pcap::Inactive>, Iface) {
use tun_tap::Mode;
let iface_result = Iface::without_packet_info("testtap%d", Mode::Tap);
if let Err(e) = iface_result {
if e.kind() == std::io::ErrorKind::PermissionDenied {
println!("Permission denied - needs tp be run as root/sudo!");
panic!("Failed to bind the tap interface: PermissionDenied - please run with root/sudo!");
}
panic!("Failed to bind the tap interface: {e:#?}");
}
let iface = iface_result.unwrap();
if cfg!(target_os = "linux") {
safe_run_command(format!(
"sysctl -w net.ipv6.conf.{}.disable_ipv6=1",
iface.name()
));
safe_run_command(format!("ip link set dev {} up", iface.name()));
}
let device = pcap::Device::from(iface.name());
(Capture::from_device(device).unwrap(), iface)
}
fn safe_run_command(cmd: String) {
use std::process::Command;
let mut split_cmd = cmd.split_ascii_whitespace();
let output = Command::new(split_cmd.next().unwrap())
.args(split_cmd.collect::<Vec<&str>>())
.output()
.unwrap();
if !output.status.success() {
panic!(
"safe_run_command FAILED: '{}' command returned stderr '{:#?}'",
cmd,
String::from_utf8(output.stderr)
);
}
}
}