use super::{ifreq, Errno, LibcResult, IoctlResult};
use libc;
pub(crate) const ETH_P_ALL: libc::c_short = 0x0003;
pub(crate) trait TunSetIf {
fn tun_set_if(&mut self, fd: libc::c_int, kind: libc::c_int) -> Result<(), Errno>;
fn tun_set_tap(&mut self, fd: libc::c_int) -> Result<(), Errno>;
}
pub(crate) trait NetdeviceMtu {
fn get_mtu(&mut self, fd: libc::c_int) -> Result<libc::c_int, Errno>;
}
pub(crate) trait IfIndex {
fn get_if_index(&mut self, fd: libc::c_int) -> Result<libc::c_int, Errno>;
}
impl ifreq {
pub(crate) const SIOCGIFMTU: libc::c_ulong = 0x8921;
pub(crate) const SIOCGIFINDEX: libc::c_ulong = 0x8933;
pub(crate) const TUNSETIFF: libc::c_ulong = 0x400454CA;
pub(crate) const IFF_TAP: libc::c_int = 0x0002;
pub(crate) const IFF_NO_PI: libc::c_int = 0x1000;
}
impl TunSetIf for ifreq {
fn tun_set_if(&mut self, fd: libc::c_int, kind: libc::c_int) -> Result<(), Errno> {
#[repr(C)]
#[derive(Debug)]
struct Request {
interface: ifreq,
kind: libc::c_int,
}
let mut request = Request {
interface: *self,
kind,
};
let res = unsafe {
libc::ioctl(fd, Self::TUNSETIFF, &mut request as *mut _)
};
IoctlResult(res).errno()?;
Ok(())
}
fn tun_set_tap(&mut self, fd: libc::c_int) -> Result<(), Errno> {
self.tun_set_if(fd, Self::IFF_TAP | Self::IFF_NO_PI)
}
}
impl NetdeviceMtu for ifreq {
fn get_mtu(&mut self, fd: libc::c_int) -> Result<libc::c_int, Errno> {
#[repr(C)]
struct Request {
interface: ifreq,
ifr_mtu: libc::c_int,
}
let mut request = Request {
interface: *self,
ifr_mtu: 0,
};
let res = unsafe {
libc::ioctl(fd, Self::SIOCGIFMTU, &mut request as *mut _)
};
IoctlResult(res).errno()?;
Ok(request.ifr_mtu)
}
}
impl IfIndex for ifreq {
fn get_if_index(&mut self, fd: libc::c_int) -> Result<libc::c_int, Errno> {
#[repr(C)]
struct Request {
interface: ifreq,
ifr_ifindex: libc::c_int,
}
let mut request = Request {
interface: *self,
ifr_ifindex: 0,
};
let res = unsafe {
libc::ioctl(fd, Self::SIOCGIFINDEX, &mut request as *mut _)
};
IoctlResult(res).errno()?;
Ok(request.ifr_ifindex)
}
}