第一步 open /dev/net/tun
第二步 ioctl TUNSETIFF
在crates.io里面搜索tun会得到很多结果.让人眼花缭乱.不知道用哪一个好
看了一下 关于tun的第一步 思路都是一致 都是要先open /dev/net/tun" 然后再进行下一步操作
大多数是使用 libc open [ meh /rust-tun] [ csaide /riptun ][ canndrew /netsim ]
也有使用 nix::fcntl::{open [mcginty /mio-utun]
也有使用
OpenOptions::new() .read(true) .write(true) .open("/dev/net/tun") .await?, 这种方式去打开的
[ yaa110 / async-tun] [vorner /tuntap]
/*
- Since the rust ioctl bindings don't have all the structures and constants,
- it's easier to just write the thing in C and link it in. */
that is what [vorner /tuntap] said some years ago.it is still ture today?
let tun_file = fs::OpenOptions::new().read(true).write(true).open(&path).await?;
// nonblock
if unsafe { libc::fcntl(tun_file.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK) == -1 } {
return Err(io::Error::last_os_error());
}
[Totsugekitai /rustic-stack]这个比较简单
基本上都是只支持Linux平台.没有window平台的支持.
some useful links
1.https://backreference.org/2010/03/26/tuntap-interface-tutorial/
2.https://lishiwen4.github.io/network/virtual-network-interface-tun-and-tap
3.https://web.ecs.syr.edu/~wedu/seed/Labs/VPN/files/simpletun.c
4.https://blog.51cto.com/chinesefys/837996
5.https://users.rust-lang.org/t/cant-get-tun-set-iff-ioctl-to-execute-properly/14485/3
评论区
写评论let ifreq = InterfaceRequest::with_name(name); unsafe { match libc::ioctl(tun_file, TUNSETIFF, &ifreq) { -1 => Err(-1), _ => Ok(0), } }
nix::ioctl_write_int!(tun_set_iff, b'T', 202);
let mut ifr = ifreq::from_name(name)?; ifr.set_flags(IFF_TAP as i16 | IFF_NO_PI as i16); unsafe { tun_set_iff(device.fd, &mut ifr as *mut _ as *mut _) }?;
在Linux内核中的代码是这样写的
if (cmd == TUNSETIFF || cmd == TUNSETQUEUE ||
The next step in creating the interface is issuing a special ioctl() system call
What is an ioctl?
ioctls are synchronous system calls and are similar to read and write calls in that regard. They operate on file descriptors and have an identifier that specifies what the ioctl is.
It is common to see ioctls used for the following purposes:
Do whatever else the device driver creator thought made most sense.
Ioctls are synchronous system calls and are similar to read and write calls in that regard.
The prototype for the ioctl system call in libc is as follows:
int ioctl(int fd, unsigned long request, ...);
Typically, an ioctl takes 3 parameters as arguments:
1.An open file descriptor, fd.
2.An device-dependennt request code or operation. This request code is referred to as op in this module.
3.Either a pointer to a location in memory or an integer. This number of pointer may either be used by the kernel or written to by the kernel depending on how the operation is documented to work.
对于“/dev/net/tun”设备来说, 最重要的操作就是 read / write / ioctl了, 其中ioctl用于添加/删除 tun/tap 接口
tun/tap 的添加通过使用ioctl 发送 TUNSETIFF 命令来实现
根据 ioctl 的 TUNSETIFF cmd 附带的IFF_TUN 或者 IFF_TAP flag来添加一个 tun或者tap网络接口, TUNSETIFF 支持如下的flag