#tun #networking #tunnel #bindings #packet

tun-sync

使用 async-std 创建和管理 TUN 设备

2 个版本

0.1.1 2023 年 11 月 17 日
0.1.0 2023 年 11 月 17 日

#1964 in 网络编程


用于 atm0s-sdn-tun-tap

WTFPL 许可证

72KB
1.5K SLoC

TUN 接口 Crates.io tun WTFPL

此crate允许创建和使用TUN接口,目的是使其跨平台。

使用方法

首先,将以下内容添加到您的 Cargo.toml

[dependencies]
tun = "0.5"

然后,将以下内容添加到您的crate根目录

extern crate tun;

如果您想使用异步TUN接口,可以使用 as_raw_fd()

示例

以下示例创建并配置了一个TUN接口,并开始从中读取数据包。

use std::io::Read;

extern crate tun;

fn main() {
	let mut config = tun::Configuration::default();
	config.address((10, 0, 0, 1))
	       .netmask((255, 255, 255, 0))
	       .up();

	#[cfg(target_os = "linux")]
	config.platform(|config| {
		config.packet_information(true);
	});

	let mut dev = tun::create(&config).unwrap();
	let mut buf = [0; 4096];

	loop {
		let amount = dev.read(&mut buf).unwrap();
		println!("{:?}", &buf[0 .. amount]);
	}
}

平台

并非所有平台都受支持。

Linux

您需要加载 tun 模块,并且创建接口需要root权限。

macOS

它只需按原样工作,但您必须手动设置路由。

iOS

您可以将TUN设备的文件描述符传递给 rust-tun 来创建接口。

以下是iOS上创建TUN设备并将 fd 传递给 rust-tun 的示例

// Swift
class PacketTunnelProvider: NEPacketTunnelProvider {
    override func startTunnel(options: [String : NSObject]?, completionHandler: @escaping (Error?) -> Void) {
        let tunnelNetworkSettings = createTunnelSettings() // Configure TUN address, DNS, mtu, routing...
        setTunnelNetworkSettings(tunnelNetworkSettings) { [weak self] error in
            let tunFd = self?.packetFlow.value(forKeyPath: "socket.fileDescriptor") as! Int32
            DispatchQueue.global(qos: .default).async {
                start_tun(tunFd)
            }
            completionHandler(nil)
        }
    }
}
#[no_mangle]
pub extern "C" fn start_tun(fd: std::os::raw::c_int) {
    let mut cfg = tun::Configuration::default();
    cfg.raw_fd(fd);
    let mut tun = tun::create(&cfg).unwrap();
    //TODO process in thread or async
}

依赖项

~0.3–0.8MB
~19K SLoC