< 返回我的博客

githik999 发表于 2022-07-06 03:52

Tags:rust tun

第一步 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

评论区

写评论
作者 githik999 2022-07-06 13:13

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 _) }?;

作者 githik999 2022-07-06 13:01

在Linux内核中的代码是这样写的

if (cmd == TUNSETIFF || cmd == TUNSETQUEUE ||

作者 githik999 2022-07-06 12:59

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

IFF_TUN : 创建一个点对点设备, 和 IFF_TAP互斥
IFF_TAP : 创建一个以太网设备, 和 IFF_TUN互斥
IFF_NO_PI : 不包含包信息,默认的每个数据包当传到用户空间时,都将包含一个附加的包头来保存包信息, 可和其它flag组合
IFF_ONE_QUEUE : 采用单一队列模式,即当数据包队列满的时候,由虚拟网络设备自已丢弃以后的数据包直到数据包队列再有空闲, 可和其它flag组合
1 共 3 条评论, 1 页