如何与 Linux tun 驱动程序交互
我很难解决这个问题 - 我正在尝试编写一个与 Linux 隧道驱动程序交互的程序。 在非常基础的层面上,我只是想创建一个能够通过网络隧道传输数据的应用程序。 但是,我完全不知道如何正确设置隧道驱动程序以实现此目的。
我正在 Ubuntu 9.04 上进行开发,并且加载了隧道驱动程序内核模块。
存在设备 /dev/net/tun
,但不存在 /dev/tunX
设备。 我无法使用 ifconfig
创建这些设备 - 例如,每当我运行 /sbin/ifconfig tun0 up
时,我都会收到以下错误:
tun0:获取接口标志时出错:没有这样的设备。
如果我尝试查看 /dev/net/tun
设备,则会出现以下错误:
cat: /dev/net/tun: 文件描述符处于错误状态。
尝试通过小程序打开/dev/tunX
,基本上,一个简单的
tun_fd = open( "/dev/tun0", O_RDWR )
返回-1:应用程序以root身份运行,但仍然无法打开这个隧道设备。 可以打开 /dev/net/tun
,但这似乎不会生成新的 /dev/tunX
设备来使用。
那么,总而言之,如何编写一个希望使用 Linux 隧道驱动程序的应用程序呢? 任何见解将不胜感激。
谢谢; 〜罗伯特
I'm having a hard time figuring this problem out - I am trying to write a program that will interact with the Linux tunnel driver. At a very basic level, I simply want to create an application that is able to transfer data over a network tunnel. However, I am completely at a loss as to how to properly set up the tunnel driver in order to accomplish this.
I am developing on Ubuntu 9.04, and I have the tunnel driver kernel module loaded.
There exists the device /dev/net/tun
, however there are no /dev/tunX
devices. I am unable to create these devices using ifconfig
- whenever I run /sbin/ifconfig tun0 up
, for example, I get the following error:
tun0: ERROR while getting interface flags: No such device.
If I attempt to look at the /dev/net/tun
device, the following error is presented:
cat: /dev/net/tun: File descriptor in bad state.
Attempting to open /dev/tunX
via a small program, basically, a simple
tun_fd = open( "/dev/tun0", O_RDWR )
returns -1: the application is running as root and still cannot open this tunnel device. It is possible to open /dev/net/tun
, however this does not appear to generate a new /dev/tunX
device to use instead.
So, in summary - how does one go about writing an application that wishes to use the Linux tunnel driver? Any insights would be greatly appreciated.
Thanks;
~Robert
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
没有
/dev/tunX
设备文件。 相反,您打开/dev/net/tun
并通过ioctl()
将其配置为“指向”tun0
。 为了展示基本过程,我将使用命令行工具ip tun tap
创建 TUN 接口,然后展示从该 TUN 设备读取的 C 代码。 因此,要通过命令行创建 tun 接口:创建
tun0
,并且所有发送到目标 IP 地址 10.0.3.x 的数据包都将路由到tun0
。要从用户空间程序向此接口读取/写入数据包,您需要使用 ioctl() 与 /dev/net/tun 设备文件进行交互。 以下示例将读取到达
tun0
接口的数据包并打印大小:如果您有
ping 10.0.3.1
或ping 10.0.3.40< /code> 运行时,您将看到
定期从 tun0 读取 88 字节
。您还可以使用 netcat UDP 和
nc -u 10.0.3.3 2222
并输入文本 + Enter 进行测试。如果没有打印任何内容,则很可能分配给 tun0 的 id 地址/IP 范围不可访问/可路由/可寻址。 确保
ip route get 10.0.3.4
显示10.0.3.4 dev tun0
表明 Linux 内核知道发往 10.0.3.4 的数据包应发送到 tun0 设备。要删除
tun0
,请执行以下操作There are no
/dev/tunX
device files. Instead, you open the/dev/net/tun
and configure it viaioctl()
to "point" totun0
. To show the basic procedure, I will create the TUN interface using the command line toolip tun tap
and then show the C code to read from that TUN device. So to create the tun interface via commands line:The
tun0
is created and all packets to destination IP address 10.0.3.x will be routed totun0
.To read / write packets to this interface from an user space program you need to interact with the
/dev/net/tun
device file usingioctl()
. Here is an example that will read the packets arriving at thetun0
interface and print the size:If you have the
ping 10.0.3.1
orping 10.0.3.40
running, you will seeRead 88 bytes from tun0
periodically.You can also test using netcat UDP with
nc -u 10.0.3.3 2222
and typing text + Enter.If nothing is being printed is most likely that the id address / ip range assigned to the tun0 is not reachable/routable/addressable. Make sure that the
ip route get 10.0.3.4
shows10.0.3.4 dev tun0
indicating that the linux kernels knows that packets to 10.0.3.4 should be sent to the tun0 device.To delete the
tun0
do阅读
/usr/src/linux/Documentation/networking/tuntap.rst
。您应该
打开
/dev/net/tun
设备。 open fd 上的后续 ioctl 将创建 tun0(或任何您希望命名的名称)网络接口。 Linux 的网络接口不对应于任何/dev/*
设备。Read
/usr/src/linux/Documentation/networking/tuntap.rst
.You are supposed to
open
the/dev/net/tun
device. A subsequentioctl
on the open fd will create thetun0
(or whatever you wish to name it) network interface. Linux's network interfaces do not correspond to any/dev/*
device.我发现了一个关于这个的很好的介绍教程
http://backreference.org/2010 /03/26/tuntap-interface-tutorial/
它带有源 tarball。
它与这个问题在同一组谷歌结果中。 :-)
I came across a nice intro tutorial about this
http://backreference.org/2010/03/26/tuntap-interface-tutorial/
It comes with a source tarball.
It was in the same set of Google results as this question. :-)
另一种实现是在 c11 的
stdio.h
中使用 apifopen
fclose
fread
,而不是unistd 中的 api .h
another implementation using api
fopen
fclose
fread
instdio.h
in c11, instead of api inunistd.h