| Crates.io | tapd |
| lib.rs | tapd |
| version | 0.1.32 |
| created_at | 2025-10-31 06:53:09.373533+00 |
| updated_at | 2025-12-03 01:26:40.555941+00 |
| description | wrap tun/tap device to tapd app/lib |
| homepage | |
| repository | |
| max_upload_size | |
| id | 1909551 |
| size | 113,563 |
First, add the following to your Cargo.toml:
[dependencies]
tapd = "0.1"
The following example creates and configures a TAP interface and starts reading packets from it.
use anyhow::{Result, bail};
use nix::{
fcntl::{self, FcntlArg},
sys::stat::{self, SFlag},
};
use std::{
env::{self, args},
io::{IsTerminal, stdin, stdout},
os::fd::AsFd,
};
#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<()> {
let mut argv = args();
let app = argv.next().unwrap();
let blocking = env::var_os("TAPD_ASYNC").is_none();
match argv.len() {
2 => {
let tap1 = &argv.next().unwrap();
let tap2 = &argv.next().unwrap();
tapd::new(blocking).pipe_tun(tap1, tap2)?.join_all().await[0]
}
1 => {
let tap1 = &argv.next().unwrap();
if setup_stdio(stdin()) && setup_stdio(stdout()) {
tapd::new(blocking).pipe_std(tap1)?.join_all().await[0]
}
}
_ => {}
}
bail!("Usage: {app:?} [dev1 dev2 | dev]");
}
fn setup_stdio<T: AsFd + IsTerminal>(fd: T) -> bool {
if fd.is_terminal() {
return false;
}
match stat::fstat(fd.as_fd()) {
Ok(stat) => {
if SFlag::from_bits_truncate(stat.st_mode).contains(SFlag::S_IFIFO) {
let _ = fcntl::fcntl(fd.as_fd(), FcntlArg::F_SETPIPE_SZ(1 << 20));
}
true
}
Err(_) => false,
}
}
You will need the tun module to be loaded and root is required to create
interfaces.