#tun #tunnel #networking #bindings

forky-tun

TUN 设备创建和处理

1 个不稳定版本

0.5.5 2023年4月14日

#20 in #tun

Download history 7/week @ 2024-04-06 42/week @ 2024-04-20 42/week @ 2024-04-27 3/week @ 2024-05-04

每月105次下载
用于 tonel

WTFPL 许可证

89KB
2K SLoC

TUN 接口 Crates.io tun WTFPL

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

用法

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

[dependencies]
tun = "0.5"

接下来,将以下内容添加到您的crate根目录

extern crate tun;

如果您想使用mio/tokio与TUN接口,您需要启用async功能

[dependencies]
tun = { version = "0.5", features = ["async"] }

示例

以下示例创建并配置一个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 rt = tokio::runtime::Runtime::new().unwrap();
    rt.block_on(async {
        let mut cfg = tun::Configuration::default();
        cfg.raw_fd(fd);
        let mut tun = tun::create_as_async(&cfg).unwrap();
        let mut framed = tun.into_framed();
        while let Some(packet) = framed.next().await {
            ...
        }
    });
}

依赖关系

~0.3–9MB
~76K SLoC