1pub mod sys;
15use std::fmt;
16use std::fmt::Display;
17use std::io::Read;
18use std::io::Write;
19use std::net;
20use std::num::ParseIntError;
21use std::os::raw::*;
22use std::str::FromStr;
23
24use base::AsRawDescriptor;
25use base::Error as SysError;
26use base::RawDescriptor;
27use remain::sorted;
28use serde::Deserialize;
29use serde::Deserializer;
30use serde::Serialize;
31use serde::Serializer;
32pub use sys::TapT;
33use thiserror::Error as ThisError;
34
35#[cfg(feature = "slirp")]
36pub mod slirp;
37#[cfg(all(feature = "slirp", windows))]
38pub use slirp::Slirp;
39
40#[sorted]
41#[derive(ThisError, Debug)]
42pub enum Error {
43 #[error("failed to clone tap interface: {0}")]
45 CloneTap(SysError),
46 #[error("failed to create a socket: {0}")]
48 CreateSocket(SysError),
49 #[error("failed to create tap interface: {0}")]
51 CreateTap(SysError),
52 #[error("ioctl failed: {0}")]
54 IoctlError(SysError),
55 #[error("failed to open /dev/net/tun: {0}")]
57 OpenTun(SysError),
58 #[cfg(all(feature = "slirp", windows))]
59 #[error("slirp related error")]
60 Slirp(slirp::SlirpError),
61}
62
63pub type Result<T> = std::result::Result<T, Error>;
64
65impl Error {
66 pub fn sys_error(&self) -> SysError {
67 match self {
68 Error::CreateSocket(e) => *e,
69 Error::OpenTun(e) => *e,
70 Error::CreateTap(e) => *e,
71 Error::CloneTap(e) => *e,
72 Error::IoctlError(e) => *e,
73 #[cfg(all(feature = "slirp", windows))]
74 Error::Slirp(e) => e.sys_error(),
75 }
76 }
77}
78
79#[sorted]
80#[derive(ThisError, Debug, PartialEq, Eq)]
81pub enum MacAddressError {
82 #[error("invalid number of octets: {0}")]
84 InvalidNumOctets(usize),
85 #[error("failed to parse octet: {0}")]
87 ParseOctet(ParseIntError),
88}
89
90#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
92pub struct MacAddress {
93 addr: [u8; 6],
94}
95
96impl MacAddress {
97 pub fn octets(&self) -> [u8; 6] {
98 self.addr
99 }
100}
101
102impl FromStr for MacAddress {
103 type Err = MacAddressError;
104
105 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
106 let octets: Vec<&str> = s.split(':').collect();
107 if octets.len() != 6usize {
108 return Err(MacAddressError::InvalidNumOctets(octets.len()));
109 }
110
111 let mut result = MacAddress::default();
112
113 for (i, octet) in octets.iter().enumerate() {
114 result.addr[i] = u8::from_str_radix(octet, 16).map_err(MacAddressError::ParseOctet)?;
115 }
116
117 Ok(result)
118 }
119}
120
121impl Display for MacAddress {
122 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
123 write!(
124 f,
125 "{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}",
126 self.addr[0], self.addr[1], self.addr[2], self.addr[3], self.addr[4], self.addr[5]
127 )
128 }
129}
130
131impl<'de> Deserialize<'de> for MacAddress {
132 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
133 where
134 D: Deserializer<'de>,
135 {
136 let s = String::deserialize(deserializer)?;
137 FromStr::from_str(&s).map_err(serde::de::Error::custom)
138 }
139}
140
141impl Serialize for MacAddress {
142 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
143 where
144 S: Serializer,
145 {
146 serializer.collect_str(&self)
147 }
148}
149
150pub trait TapTCommon: Read + Write + AsRawDescriptor + Send + Sized {
151 fn new_with_name(name: &[u8], vnet_hdr: bool, multi_vq: bool) -> Result<Self>;
158
159 fn new(vnet_hdr: bool, multi_vq: bool) -> Result<Self>;
163
164 fn into_mq_taps(self, vq_pairs: u16) -> Result<Vec<Self>>;
167
168 fn ip_addr(&self) -> Result<net::Ipv4Addr>;
170
171 fn set_ip_addr(&self, ip_addr: net::Ipv4Addr) -> Result<()>;
173
174 fn netmask(&self) -> Result<net::Ipv4Addr>;
176
177 fn set_netmask(&self, netmask: net::Ipv4Addr) -> Result<()>;
179
180 fn mtu(&self) -> Result<u16>;
182
183 fn set_mtu(&self, mtu: u16) -> Result<()>;
185
186 fn mac_address(&self) -> Result<MacAddress>;
188
189 fn set_mac_address(&self, mac_addr: MacAddress) -> Result<()>;
191
192 fn set_offload(&self, flags: c_uint) -> Result<()>;
194
195 fn enable(&self) -> Result<()>;
197
198 fn try_clone(&self) -> Result<Self>;
200
201 unsafe fn from_raw_descriptor(descriptor: RawDescriptor) -> Result<Self>;
208}
209
210#[cfg(test)]
211mod tests {
212 use serde_json::*;
213
214 use super::*;
215
216 #[test]
217 fn json_serialize_deserialize() {
218 let mac_address = MacAddress {
219 addr: [0x3d, 0x70, 0xeb, 0x61, 0x1a, 0x91],
220 };
221 const SERIALIZED_ADDRESS: &str = "\"3D:70:EB:61:1A:91\"";
222 assert_eq!(to_string(&mac_address).unwrap(), SERIALIZED_ADDRESS);
223 assert_eq!(
224 from_str::<MacAddress>(SERIALIZED_ADDRESS).unwrap(),
225 mac_address
226 );
227 }
228}