1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
// (c) Copyright 2021 Christian Saide
// SPDX-License-Identifier: MIT
//! `riptun` is a library for creating, managing, and leveraging TUN/TAP devices.
//!
//! The implementation exposes both a synchronous interface via the [Tun] and [Queue] structs, as well as an
//! asynchronous interface via a set of feature flagged structs. See the [Features](#features) and [Examples](#examples)
//! sections for more information on the async implementations and how to use them.
//!
//! # Getting started
//!
//! The simplest way to get started with riptun is to manage a single queue synchronous TUN device:
//!
//! Lets start by disabling the async support as we won't be using it:
//!
//! ```toml
//! riptun = { version = "0.1", default-features = false, features = [] }
//! ```
//!
//! The following example program will create a new TUN device named `rip%d`, where the `%d`
//! will be replaced with an appropriate value by the OS. The exact device name along with the
//! actual TUN device is then returned for use. We then loop forever reading packets and printing
//! them to stdout:
//!
//! ```no_run
//! use riptun::Tun;
//!
//! // First lets create a new single queue tun.
//! let tun = match Tun::new("rip%d", 1) {
//! Ok(tun) => tun,
//! Err(err) => {
//! println!("[ERROR] => {}", err);
//! return;
//! }
//! };
//!
//! // Lets make sure we print the real name of our new TUN device.
//! println!("[INFO] => Created TUN '{}'!", tun.name());
//!
//! // Create a buffer to read packets into, and setup the queue to receive from.
//! let mut buffer: [u8; 1500] = [0x00; 1500];
//! let queue = 0;
//!
//! // Loop forever reading packets off the queue.
//! loop {
//! // Receive the next packet from the specified queue.
//! let read = match tun.recv_via(queue, &mut buffer) {
//! Ok(read) => read,
//! Err(err) => {
//! println!("[ERROR] => {}", err);
//! return;
//! }
//! };
//!
//! // Print out the amount of data received and the bytes read off the queue.
//! println!(
//! "[INFO] => Received packet data ({}B): {:?}",
//! read,
//! &buffer[..read]
//! );
//! }
//! ```
//!
//! Once the `rip%d` device is created, you will need to add an IP address to it. On Linux this can be
//! done like:
//!
//! ```bash
//! sudo ip addr add 203.0.113.2/24 brd 203.0.113.255 dev rip0
//! sudo ip link set dev rip0 up
//! ```
//!
//! # Examples
//!
//! There is a suite of included examples demonstrating the functionality of `riptun`. Note that the following examples
//! will require elevated privileges to configure and create the actual Tun interface itself. This generally means `root`
//! or `Administrator` privileges across unix and windows platforms.
//!
//! As in the [Getting Started](#getting-started) section above, all the examples will require assigning an IP address to the
//! created interface, you can do so by running:
//!
//! ```bash
//! sudo ip addr add 203.0.113.2/24 brd 203.0.113.255 dev rip0
//! sudo ip link set dev rip0 up
//! ```
//!
//! ## Sync
//!
//! The synchronous mode of operation is detailed in the [sync example](https://github.com/csaide/riptun/blob/master/examples/sync.rs). The
//! implementation leverages a multi-queue [Tun] device. Then creates a new thread for each queue, and loops forever reading packets from
//! each one.
//!
//! You can run this example using the following and get similar output if you have the right permissions:
//!
//! ```bash
//! cargo run --no-default-features --example sync
//! [INFO] => Created new virtual device: rip0
//! ```
//!
//! ## Mio
//!
//! The mio integration allows for registering and deregistering [Queue] instances with a Poll Registry. The [mio example](https://github.com/csaide/riptun/blob/master/examples/mio.rs)
//! shows how to leverage this integration for a multi-threaded async version of the [Sync](#sync) example above.
//!
//! You can run this example using the following and get similar output if you have the right permissions:
//!
//! ```bash
//! cargo run --no-default-features --features mio-impl --example mio
//! [INFO] => Created new virtual device: rip0
//! ```
//!
//! ## Smol and async-std
//!
//! `riptun` exposes an [async-io](https://docs.rs/async-io/1.6.0/async_io/index.html) integration via the [AsyncStdTun] and [AsyncStdQueue] structs. These can be used interchangeably
//! across both [smol](https://github.com/smol-rs/smol) and [async-std](https://docs.rs/async-std/1.10.0/async_std/index.html).
//!
//! The [std example](https://github.com/csaide/riptun/blob/master/examples/std.rs) describes how to leverage a multi-queue device using a single thread of operation. While using the `async-std` runtime.
//!
//! You can run the `std` example using the following and get similar output if you have the right permissions:
//!
//! ```bash
//! cargo run --no-default-features --features async-std-example --example std
//! [INFO] => Created new virtual device: rip0
//! ```
//!
//! The [smol example](https://github.com/csaide/riptun/blob/master/examples/smol.rs) describes how to leverage a multi-queue device using a single thread, but with multiple concurrent tasks. While using the `smol` runtime.
//!
//! You can run the `smol` example using the following and get similar output if you have the right permissions:
//!
//! ```bash
//! cargo run --no-default-features --features smol-example --example smol
//! [INFO] => Created new virtual device: rip0
//! ```
//!
//! ## Tokio
//!
//! The `riptun` tokio integration is exposed via the [TokioTun] and [TokioQueue] structs. The [tokio example](https://github.com/csaide/riptun/blob/master/examples/tokio.rs) demonstrates
//! how to leverage both multi-threaded and concurrent operation simultaneously.
//!
//! You can run this example using the following and get similar output if you have the right permissions:
//!
//! ```bash
//! cargo run --no-default-features --features tokio-example --example tokio
//! [INFO] => Created new virtual device: rip0
//! ```
//!
//! # Features
//!
//! The async support is enabled by default, and `riptun` can be used out of the box across mio, tokio,
//! async-std, and smol. However to reduce library size, you can enable and disable each of the integrations
//! using feature flags:
//! - The `async-std-impl` feature exposes the [AsyncStdQueue]/[AsyncStdTun] structs.
//! - The `tokio-impl` feature exposes the [TokioQueue]/[TokioTun] structs.
//! - The `mio-impl` enables registration of [Queue] structs in a mio poll registry.
//!
//! # Platform support
//!
//! The `riptun` library is designed to be as platform agnostic as possible. Unfortunately each platform requires
//! special handling, so each platform must be implemented manually. The current and planned platform support
//! is detailed bellow.
//!
//! Platform/Architecture support matrix:
//!
//! | Target | Sync Supported | Async Supported |
//! |---------------------------------|:--------------:|:---------------:|
//! | `x86_64-unknown-linux-gnu` | ✅ | ✅ |
//! | `aarch64-unknown-linux-gnu` | ✅ | ✅ |
//! | `armv7-unknown-linux-gnueabihf` | ✅ | ✅ |
//! | `armv7-unknown-linux-gnueabi` | ✅ | ✅ |
//! | `arm-unknown-linux-gnueabihf` | ✅ | ✅ |
//! | `arm-unknown-linux-gnueabi` | ✅ | ✅ |
//! | `x86_64-pc-windows-msvc` | ❌ | ❌ |
//! | `aarch64-pc-windows-msvc` | ❌ | ❌ |
//! | `x86_64-apple-darwin` | ❌ | ❌ |
//! | `aarch64-apple-darwin` | ❌ | ❌ |
//! | `x86_64-unknown-freebsd` | ❌ | ❌ |
//! | `aarch64-unknown-freebsd` | ❌ | ❌ |
//! | `x86_64-unknown-netbsd` | ❌ | ❌ |
//! | `aarch64-unknown-netbsd` | ❌ | ❌ |
//! | `x86_64-unknown-openbsd` | ❌ | ❌ |
//! | `aarch64-unknown-openbsd` | ❌ | ❌ |
//!
use cfg_if;
pub use ;
pub use Queue;
pub use Tun;
cfg_if!
cfg_if!