use super::result::Result;
use super::tun::Tun;
#[cfg(target_os = "linux")]
use crate::linux::params::Params;
use core::convert::From;
use libc::{IFF_NO_PI, IFF_TAP, IFF_TUN};
use mac_address::MacAddress;
use std::net::Ipv4Addr;
pub struct TunBuilder<'a> {
name: &'a str,
is_tap: bool,
packet_info: bool,
persist: bool,
up: bool,
mtu: Option<i32>,
owner: Option<i32>,
group: Option<i32>,
address: Option<Ipv4Addr>,
destination: Option<Ipv4Addr>,
broadcast: Option<Ipv4Addr>,
netmask: Option<Ipv4Addr>,
mac: Option<MacAddress>,
}
impl<'a> Default for TunBuilder<'a> {
fn default() -> Self {
Self {
name: "",
owner: None,
group: None,
is_tap: false,
persist: false,
up: false,
mtu: None,
packet_info: true,
address: None,
destination: None,
broadcast: None,
netmask: None,
mac: None,
}
}
}
impl<'a> TunBuilder<'a> {
pub fn new() -> Self {
Default::default()
}
pub fn name(mut self, name: &'a str) -> Self {
self.name = name;
self
}
pub fn tap(mut self, is_tap: bool) -> Self {
self.is_tap = is_tap;
self
}
pub fn packet_info(mut self, packet_info: bool) -> Self {
self.packet_info = packet_info;
self
}
pub fn mtu(mut self, mtu: i32) -> Self {
self.mtu = Some(mtu);
self
}
pub fn owner(mut self, owner: i32) -> Self {
self.owner = Some(owner);
self
}
pub fn group(mut self, group: i32) -> Self {
self.group = Some(group);
self
}
pub fn address(mut self, address: Ipv4Addr) -> Self {
self.address = Some(address);
self
}
pub fn destination(mut self, dst: Ipv4Addr) -> Self {
self.destination = Some(dst);
self
}
pub fn broadcast(mut self, broadcast: Ipv4Addr) -> Self {
self.broadcast = Some(broadcast);
self
}
pub fn netmask(mut self, netmask: Ipv4Addr) -> Self {
self.netmask = Some(netmask);
self
}
pub fn mac(mut self, mac: MacAddress) -> Self {
self.mac = Some(mac);
self
}
pub fn persist(mut self) -> Self {
self.persist = true;
self
}
pub fn up(mut self) -> Self {
self.up = true;
self
}
pub async fn try_build(self) -> Result<Tun> {
Tun::new(self.into()).await
}
#[cfg(target_os = "linux")]
pub async fn try_build_mq(self, queues: usize) -> Result<Vec<Tun>> {
Tun::new_mq(self.into(), queues).await
}
}
impl<'a> From<TunBuilder<'a>> for Params {
#[cfg(target_os = "linux")]
fn from(builder: TunBuilder) -> Self {
Params {
name: if builder.name.is_empty() {
None
} else {
Some(builder.name.into())
},
flags: {
let mut flags = if builder.is_tap { IFF_TAP } else { IFF_TUN } as _;
if !builder.packet_info {
flags |= IFF_NO_PI as i16;
}
flags
},
persist: builder.persist,
up: builder.up,
mtu: builder.mtu,
owner: builder.owner,
group: builder.group,
address: builder.address,
destination: builder.destination,
broadcast: builder.broadcast,
netmask: builder.netmask,
mac: builder.mac,
}
}
#[cfg(not(any(target_os = "linux")))]
fn from(builder: TunBuilder) -> Self {
unimplemented!()
}
}