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
10pub 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 pub fn new() -> Self {
50 Default::default()
51 }
52
53 pub fn name(mut self, name: &'a str) -> Self {
55 self.name = name;
56 self
57 }
58
59 pub fn tap(mut self, is_tap: bool) -> Self {
61 self.is_tap = is_tap;
62 self
63 }
64
65 pub fn packet_info(mut self, packet_info: bool) -> Self {
67 self.packet_info = packet_info;
68 self
69 }
70
71 pub fn mtu(mut self, mtu: i32) -> Self {
73 self.mtu = Some(mtu);
74 self
75 }
76
77 pub fn owner(mut self, owner: i32) -> Self {
79 self.owner = Some(owner);
80 self
81 }
82
83 pub fn group(mut self, group: i32) -> Self {
85 self.group = Some(group);
86 self
87 }
88
89 pub fn address(mut self, address: Ipv4Addr) -> Self {
91 self.address = Some(address);
92 self
93 }
94
95 pub fn destination(mut self, dst: Ipv4Addr) -> Self {
97 self.destination = Some(dst);
98 self
99 }
100
101 pub fn broadcast(mut self, broadcast: Ipv4Addr) -> Self {
103 self.broadcast = Some(broadcast);
104 self
105 }
106
107 pub fn netmask(mut self, netmask: Ipv4Addr) -> Self {
109 self.netmask = Some(netmask);
110 self
111 }
112
113 pub fn mac(mut self, mac: MacAddress) -> Self {
115 self.mac = Some(mac);
116 self
117 }
118
119 pub fn persist(mut self) -> Self {
121 self.persist = true;
122 self
123 }
124
125 pub fn up(mut self) -> Self {
127 self.up = true;
128 self
129 }
130
131 pub async fn try_build(self) -> Result<Tun> {
133 Tun::new(self.into()).await
134 }
135
136 #[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}