gpt4 book ai didi

c - 如何与 Linux tun 驱动程序交互

转载 作者:太空狗 更新时间:2023-10-29 16:33:39 52 4
gpt4 key购买 nike

我很难解决这个问题 - 我正在尝试编写一个程序来与 Linux 隧道驱动程序交互。在最基本的层面上,我只想创建一个能够通过网络隧道传输数据的应用程序。但是,对于如何正确设置隧道驱动程序以实现此目的,我完全不知所措。

我在 Ubuntu 9.04 上开发,我加载了隧道驱动程序内核模块。

存在设备/dev/net/tun,但是没有/dev/tunX设备。我无法使用 ifconfig 创建这些设备 - 例如,每当我运行 /sbin/ifconfig tun0 up 时,我都会收到以下错误:

tun0: ERROR while getting interface flags: No such device.

如果我尝试查看 /dev/net/tun 设备,会出现以下错误:

cat: /dev/net/tun: File descriptor in bad state.

试图通过一个小程序打开/dev/tunX,基本上,一个简单的

tun_fd = open( "/dev/tun0", O_RDWR )

返回 -1:应用程序以 root 身份运行,但仍然无法打开此隧道设备。可以打开 /dev/net/tun,但这似乎不会生成一个新的 /dev/tunX 设备来代替使用。

因此,总而言之 - 如何编写一个希望使用 Linux 隧道驱动程序的应用程序?任何见解将不胜感激。

谢谢;~罗伯特

最佳答案

没有/dev/tunX 设备文件。相反,您打开 /dev/net/tun 并通过 ioctl() 将其配置为“指向”tun0。为了展示基本过程,我将使用命令行工具 ip tun tap 创建 TUN 接口(interface),然后展示要从该 TUN 设备读取的 C 代码。因此,要通过命令行创建 tun 接口(interface):

ip addr show # my eth0 inet address is 10.0.2.15/24 as Im running on a VirtualBox vm with Ubuntu 18.04 guest
sudo ip tuntap add mode tun dev tun0
sudo ip addr add 10.0.3.0/24 dev tun0 # give it an address (that does not conflict with existing IP)
sudo ip link set dev tun0 up # bring the if up
ip route get 10.0.3.50 # check that packets to 10.0.3.x are going through tun0
# 10.0.3.50 dev tun0 src 10.0.3.0 uid 1000
ping 10.0.3.50 # leave this running in another shell to be able to see the effect of the next example, nobody is responding to the ping

tun0 已创建,所有发往目标 IP 地址 10.0.3.x 的数据包都将路由到 tun0

要从用户空间程序向此接口(interface)读取/写入数据包,您需要使用ioctl()/dev/net/tun 设备文件进行交互。下面是一个示例,它将读取到达 tun0 接口(interface)的数据包并打印大小:

#include <fcntl.h>  /* O_RDWR */
#include <string.h> /* memset(), memcpy() */
#include <stdio.h> /* perror(), printf(), fprintf() */
#include <stdlib.h> /* exit(), malloc(), free() */
#include <sys/ioctl.h> /* ioctl() */
#include <unistd.h> /* read(), close() */

/* includes for struct ifreq, etc */
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/if.h>
#include <linux/if_tun.h>

int tun_open(char *devname)
{
struct ifreq ifr;
int fd, err;

if ( (fd = open("/dev/net/tun", O_RDWR)) == -1 ) {
perror("open /dev/net/tun");exit(1);
}
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TUN;
strncpy(ifr.ifr_name, devname, IFNAMSIZ); // devname = "tun0" or "tun1", etc

/* ioctl will use ifr.if_name as the name of TUN
* interface to open: "tun0", etc. */
if ( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) == -1 ) {
perror("ioctl TUNSETIFF");close(fd);exit(1);
}

/* After the ioctl call the fd is "connected" to tun device specified
* by devname ("tun0", "tun1", etc)*/

return fd;
}


int main(int argc, char *argv[])
{
int fd, nbytes;
char buf[1600];

fd = tun_open("tun0"); /* devname = ifr.if_name = "tun0" */
printf("Device tun0 opened\n");
while(1) {
nbytes = read(fd, buf, sizeof(buf));
printf("Read %d bytes from tun0\n", nbytes);
}
return 0;
}

如果您正在运行 ping 10.0.3.1ping 10.0.3.40,您将定期看到 Read 88 bytes from tun0

您还可以通过 nc -u 10.0.3.3 2222 并键入 text + Enter 来测试使用 netcat UDP。

如果未打印任何内容,则很可能是分配给 tun0 的 id 地址/ip 范围不可访问/不可路由/不可寻址。确保 ip route get 10.0.3.4 显示 10.0.3.4 dev tun0 表明 linux 内核知道到 10.0.3.4 的数据包应该发送到 tun0 设备。

删除 tun0

sudo ip link set dev tun0 down
sudo ip tuntap del mode tun dev tun0

关于c - 如何与 Linux tun 驱动程序交互,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1003684/

52 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com