如何与Linux tun驱动程序进行交互

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

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

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

获取接口标志时的tun0:ERROR:没有这样的设备。

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

cat:/ dev / net / tun:文件描述符处于错误状态。

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

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

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

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

谢谢; 〜罗伯特

阅读/usr/src/linux/Documentation/networking/tuntap.txt

您应该open /dev/net/tun设备。 open fd上的后续ioctl将创建tun0 (或任何你想要命名的)网络接口。 Linux的网络接口与任何/dev/*设备都不对应。

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

 sudo ip tuntap add mode tun dev tun0 ip addr add 10.0.0.0/24 dev tun0 # give it an ip ip link set dev tun0 up # bring the if up ip route get 10.0.0.2 # check that packets to 10.0.0.x are going through tun0 ping 10.0.0.2 # leave this running in another shell to be able to see the effect of the next example 

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

 #include  /* O_RDWR */ #include  /* memset(), memcpy() */ #include  /* perror(), printf(), fprintf() */ #include  /* exit(), malloc(), free() */ #include  /* ioctl() */ /* includes for struct ifreq, etc */ #include  #include  #include  #include  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; } 

我遇到了一个很好的介绍教程

http://backreference.org/2010/03/26/tuntap-interface-tutorial/

它带有源代码压缩包。

与此问题的Google搜索结果相同。 🙂