async_tun/
builder.rs

1use super::result::Result;
2use super::tun::Tun;
3#[cfg(target_os = "linux")]
4use crate::linux::params::Params;
5use core::convert::From;
6use libc::{IFF_NO_PI, IFF_TAP, IFF_TUN};
7use mac_address::MacAddress;
8use std::net::Ipv4Addr;
9
10/// Represents a factory to build new instances of [`Tun`](struct.Tun.html).
11pub struct TunBuilder<'a> {
12    name: &'a str,
13    is_tap: bool,
14    packet_info: bool,
15    persist: bool,
16    up: bool,
17    mtu: Option<i32>,
18    owner: Option<i32>,
19    group: Option<i32>,
20    address: Option<Ipv4Addr>,
21    destination: Option<Ipv4Addr>,
22    broadcast: Option<Ipv4Addr>,
23    netmask: Option<Ipv4Addr>,
24    mac: Option<MacAddress>,
25}
26
27impl<'a> Default for TunBuilder<'a> {
28    fn default() -> Self {
29        Self {
30            name: "",
31            owner: None,
32            group: None,
33            is_tap: false,
34            persist: false,
35            up: false,
36            mtu: None,
37            packet_info: true,
38            address: None,
39            destination: None,
40            broadcast: None,
41            netmask: None,
42            mac: None,
43        }
44    }
45}
46
47impl<'a> TunBuilder<'a> {
48    /// Creates a new instance of [`TunBuilder`](struct.TunBuilder.html).
49    pub fn new() -> Self {
50        Default::default()
51    }
52
53    /// Sets the name of device (max length: 16 characters), if it is empty, then device name is set by kernel. Default value is empty.
54    pub fn name(mut self, name: &'a str) -> Self {
55        self.name = name;
56        self
57    }
58
59    /// If `is_tap` is true, a TAP device is allocated, otherwise, a TUN device is created. Default value is `false`.
60    pub fn tap(mut self, is_tap: bool) -> Self {
61        self.is_tap = is_tap;
62        self
63    }
64
65    /// If `packet_info` is false, then `IFF_NO_PI` flag is set. Default value is `true`.
66    pub fn packet_info(mut self, packet_info: bool) -> Self {
67        self.packet_info = packet_info;
68        self
69    }
70
71    /// Sets the MTU of device.
72    pub fn mtu(mut self, mtu: i32) -> Self {
73        self.mtu = Some(mtu);
74        self
75    }
76
77    /// Sets the owner of device.
78    pub fn owner(mut self, owner: i32) -> Self {
79        self.owner = Some(owner);
80        self
81    }
82
83    /// Sets the group of device.
84    pub fn group(mut self, group: i32) -> Self {
85        self.group = Some(group);
86        self
87    }
88
89    /// Sets IPv4 address of device.
90    pub fn address(mut self, address: Ipv4Addr) -> Self {
91        self.address = Some(address);
92        self
93    }
94
95    /// Sets IPv4 destination address of device.
96    pub fn destination(mut self, dst: Ipv4Addr) -> Self {
97        self.destination = Some(dst);
98        self
99    }
100
101    /// Sets IPv4 broadcast address of device.
102    pub fn broadcast(mut self, broadcast: Ipv4Addr) -> Self {
103        self.broadcast = Some(broadcast);
104        self
105    }
106
107    /// Sets IPv4 netmask address of device.
108    pub fn netmask(mut self, netmask: Ipv4Addr) -> Self {
109        self.netmask = Some(netmask);
110        self
111    }
112
113    /// Sets Ethernet MAC address of device (for tap mode).
114    pub fn mac(mut self, mac: MacAddress) -> Self {
115        self.mac = Some(mac);
116        self
117    }
118
119    /// Makes the device persistent.
120    pub fn persist(mut self) -> Self {
121        self.persist = true;
122        self
123    }
124
125    /// Sets up the device.
126    pub fn up(mut self) -> Self {
127        self.up = true;
128        self
129    }
130
131    /// Builds a new instance of [`Tun`](struct.Tun.html).
132    pub async fn try_build(self) -> Result<Tun> {
133        Tun::new(self.into()).await
134    }
135
136    /// Builds multiple instances of [`Tun`](struct.Tun.html) with `IFF_MULTI_QUEUE` flag.
137    #[cfg(target_os = "linux")]
138    pub async fn try_build_mq(self, queues: usize) -> Result<Vec<Tun>> {
139        Tun::new_mq(self.into(), queues).await
140    }
141}
142
143impl<'a> From<TunBuilder<'a>> for Params {
144    #[cfg(target_os = "linux")]
145    fn from(builder: TunBuilder) -> Self {
146        Params {
147            name: if builder.name.is_empty() {
148                None
149            } else {
150                Some(builder.name.into())
151            },
152            flags: {
153                let mut flags = if builder.is_tap { IFF_TAP } else { IFF_TUN } as _;
154                if !builder.packet_info {
155                    flags |= IFF_NO_PI as i16;
156                }
157                flags
158            },
159            persist: builder.persist,
160            up: builder.up,
161            mtu: builder.mtu,
162            owner: builder.owner,
163            group: builder.group,
164            address: builder.address,
165            destination: builder.destination,
166            broadcast: builder.broadcast,
167            netmask: builder.netmask,
168            mac: builder.mac,
169        }
170    }
171
172    #[cfg(not(any(target_os = "linux")))]
173    fn from(builder: TunBuilder) -> Self {
174        unimplemented!()
175    }
176}