tun_driver/
lib.rs

1#![doc(
2    html_root_url = "https://docs.rs/tun-tap/0.1.2/tun-tap/",
3    test(attr(deny(warnings), allow(unused_variables)))
4)]
5
6
7//! A TUN/TAP bindings for Rust.
8//!
9//! This is a basic interface to create userspace virtual network adapter.
10//!
11//! For basic usage, create an [`Iface`](struct.Iface.html) object and call the
12//! [`send`](struct.Iface.html#method.send) and [`recv`](struct.Iface.html#method.recv) methods.
13//!
14//! You can also use [`Async`](async/struct.Async.html) if you want to integrate with tokio event
15//! loop. This is configurable by a feature (it is on by default).
16//!
17//! Creating the devices requires `CAP_NETADM` privileges (most commonly done by running as root).
18//!
19//! # Known issues
20//!
21//! * It is tested only on Linux and probably doesn't work anywhere else, even though other systems
22//!   have some TUN/TAP support. Reports that it works (or not) and pull request to add other
23//!   sustem's support are welcome.
24//! * The [`Async`](async/struct.Async.html) interface is very minimal and will require extention
25//!   for further use cases and better performance.
26//! * This doesn't support advanced usage patters, like reusing already created device or creating
27//!   persistent devices. Again, pull requests are welcome.
28//! * There are no automated tests. Any idea how to test this in a reasonable way?
29
30use std::ffi::CStr;
31use std::fs::{File, OpenOptions};
32use std::io::{Error, Read, Result, Write};
33use std::os::raw::{c_char, c_int};
34use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd};
35
36
37pub mod async;
38
39extern "C" {
40    fn tuntap_setup(fd: c_int, name: *mut u8, mode: c_int, packet_info: c_int) -> c_int;
41}
42
43/// The mode in which open the virtual network adapter.
44#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
45pub enum Mode {
46    /// TUN mode
47    ///
48    /// The packets returned are on the IP layer (layer 3), prefixed with 4-byte header (2 bytes
49    /// are flags, 2 bytes are the protocol inside, eg one of
50    /// <https://en.wikipedia.org/wiki/EtherType#Examples>.
51    Tun = 1,
52    /// TAP mode
53    ///
54    /// The packets are on the transport layer (layer 2), and start with ethernet frame header.
55    Tap = 2,
56}
57
58/// The virtual interface.
59///
60/// This is the main structure of the crate, representing the actual virtual interface, either in
61/// TUN or TAP mode.
62#[derive(Debug)]
63pub struct Iface {
64    fd: File,
65    mode: Mode,
66    name: String,
67}
68
69impl Iface {
70    /// Creates a new virtual interface.
71    ///
72    /// # Parameters
73    ///
74    /// * `ifname`: The requested name of the virtual device. If left empty, the kernel will
75    ///   provide some reasonable, currently unused name. It also can contain `%d`, which will be
76    ///   replaced by a number to ensure the name is unused. Even if it isn't empty or doesn't
77    ///   contain `%d`, the actual name may be different (for example truncated to OS-dependent
78    ///   length). Use [`name`](#method.name) to find out the real name.
79    /// * `mode`: In which mode to create the device.
80    ///
81    /// # Errors
82    ///
83    /// This may fail for various OS-dependent reasons. However, two most common are:
84    ///
85    /// * The name is already taken.
86    /// * The process doesn't have the needed privileges (eg. `CAP_NETADM`).
87    ///
88    /// # Examples
89    ///
90    /// ```rust,no_run
91    /// # use tun_tap::*;
92    /// let iface = Iface::new("mytun", Mode::Tun).expect("Failed to create a TUN device");
93    /// let name = iface.name();
94    /// // Configure the device ‒ set IP address on it, bring it up.
95    /// let mut buffer = vec![0; 1504]; // MTU + 4 for the header
96    /// iface.recv(&mut buffer).unwrap();
97    /// ```
98    pub fn new(ifname: &str, mode: Mode) -> Result<Self> {
99        Iface::with_options(ifname, mode, true)
100    }
101    /// Creates a new virtual interface without the prepended packet info.
102    ///
103    /// # Parameters
104    ///
105    /// * `ifname`: The requested name of the virtual device. If left empty, the kernel will
106    ///   provide some reasonable, currently unused name. It also can contain `%d`, which will be
107    ///   replaced by a number to ensure the name is unused. Even if it isn't empty or doesn't
108    ///   contain `%d`, the actual name may be different (for example truncated to OS-dependent
109    ///   length). Use [`name`](#method.name) to find out the real name.
110    /// * `mode`: In which mode to create the device.
111    ///
112    /// # Errors
113    ///
114    /// This may fail for various OS-dependent reasons. However, two most common are:
115    ///
116    /// * The name is already taken.
117    /// * The process doesn't have the needed privileges (eg. `CAP_NETADM`).
118    ///
119    /// # Examples
120    ///
121    /// ```rust,no_run
122    /// # use tun_tap::*;
123    /// let iface = Iface::without_packet_info("mytap", Mode::Tap).expect("Failed to create a TAP device");
124    /// let name = iface.name();
125    /// // Configure the device ‒ set IP address on it, bring it up.
126    /// let mut buffer = vec![0; 1500]; // MTU
127    /// iface.recv(&mut buffer).unwrap();
128    /// ```
129    pub fn without_packet_info(ifname: &str, mode: Mode) -> Result<Self> {
130        Iface::with_options(ifname, mode, false)
131    }
132
133    fn with_options(ifname: &str, mode: Mode, packet_info: bool) -> Result<Self> {
134        let fd = OpenOptions::new()
135            .read(true)
136            .write(true)
137            .open("/dev/net/tun")?;
138        // The buffer is larger than needed, but who cares… it is large enough.
139        let mut name_buffer = Vec::new();
140        name_buffer.extend_from_slice(ifname.as_bytes());
141        name_buffer.extend_from_slice(&[0; 33]);
142        let name_ptr: *mut u8 = name_buffer.as_mut_ptr();
143        let result = unsafe { tuntap_setup(fd.as_raw_fd(), name_ptr, mode as c_int, { if packet_info { 1 } else { 0 } }) };
144        if result < 0 {
145            return Err(Error::last_os_error());
146        }
147        let name = unsafe {
148            CStr::from_ptr(name_ptr as *const c_char)
149                .to_string_lossy()
150                .into_owned()
151        };
152        Ok(Iface {
153            fd,
154            mode,
155            name,
156        })
157    }
158
159    /// Returns the mode of the adapter.
160    ///
161    /// It is always the same as the one passed to [`new`](#method.new).
162    pub fn mode(&self) -> Mode {
163        self.mode
164    }
165    /// Returns the real name of the adapter.
166    ///
167    /// Use this to find out what the real name of the adapter is. The parameter of
168    /// [`new`](#method.new) is more of a wish than hard requirement and the name of the created
169    /// device might be different. Therefore, always create the interface and then find out the
170    /// actual name by this method before proceeding.
171    pub fn name(&self) -> &str {
172        &self.name
173    }
174    /// Receives a packet from the interface.
175    ///
176    /// Blocks until a packet is sent into the virtual interface. At that point, the content of the
177    /// packet is copied into the provided buffer.
178    ///
179    /// Make sure the buffer is large enough. It is MTU of the interface (usually 1500, unless
180    /// reconfigured) + 4 for the header in case that packet info is prepended, MTU + size of ethernet frame (38 bytes,
181    /// unless VLan tags are enabled). If the buffer isn't large enough, the packet gets truncated.
182    ///
183    /// # Result
184    ///
185    /// On successful receive, the number of bytes copied into the buffer is returned.
186    pub fn recv(&self, buf: &mut [u8]) -> Result<usize> {
187        (&self.fd).read(buf)
188    }
189    /// Sends a packet into the interface.
190    ///
191    /// Sends a packet through the interface. The buffer must be valid representation of a packet
192    /// (with appropriate headers).
193    ///
194    /// It is up to the caller to provide only packets that fit MTU.
195    ///
196    /// # Result
197    ///
198    /// On successful send, the number of bytes sent in the packet is returned. Under normal
199    /// circumstances, this should be the size of the packet passed.
200    ///
201    /// # Notes
202    ///
203    /// The TUN/TAP is a network adapter. Therefore, many errors are handled simply by dropping
204    /// packets. If you pass an invalid packet, it'll likely suceed in sending it, but will be
205    /// dropped somewhere in kernel due to failed validation. If you send packets too fast, they
206    /// are likely to get dropped too. If you send a packet for address that is not assigned to any
207    /// interface and not routed anywhere… you get the idea.
208    pub fn send(&self, buf: &[u8]) -> Result<usize> {
209        (&self.fd).write(buf)
210    }
211}
212
213impl AsRawFd for Iface {
214    fn as_raw_fd(&self) -> RawFd {
215        self.fd.as_raw_fd()
216    }
217}
218
219impl IntoRawFd for Iface {
220    fn into_raw_fd(self) -> RawFd {
221        self.fd.into_raw_fd()
222    }
223}