I'm trying to learn how to TCP works by creating a TCP/IP stack, and as the title says, I'm programmatically creating a TAP device in Rust as follows
pub struct Tap {
fd: i32,
}
#[repr(C)]
struct IFreq {
name: [c_char; IFNAMSIZ],
flags: c_short,
}
impl Tap {
pub fn new(name: &CStr) -> Result<Tap, TapError> {
let fd = unsafe {
let fd = libc::open(b"/dev/net/tun\0".as_ptr() as *const _, libc::O_RDWR);
if fd < 0 {
Err(TapError::OpenFD(std::io::Error::last_os_error()))
} else {
Ok(fd)
}
}?;
let mut ifr = IFreq {
name: [0; IFNAMSIZ],
flags: (libc::IFF_TAP | libc::IFF_NO_PI) as c_short,
};
for (dst, src) in ifr.name[0..IFNAMSIZ - 1]
.iter_mut()
.zip(name.to_bytes().iter())
{
*dst = *src as i8;
}
unsafe {
let err = libc::ioctl(fd, TUNSETIFF, &mut ifr as *mut _);
if err == -1 {
return Err(TapError::IOCTL(std::io::Error::last_os_error()));
}
}
Ok(Tap { fd })
}
}
However, when I bring it up using ip link set dev <tap name> up and started reading ethernet frames I seem to only be getting IPv6 frames (ethertype is 0x86DD). Is this normal? How do I stop this from happening? I'm currently only working on implementing IPv4 and don't want to deal with IPv6 traffic.