我很难解决这个问题 - 我正在尝试编写一个与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

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

其他提示

没有 / dev / tunX 设备文件。而是打开 / dev / net / tun 并通过 ioctl()将其配置为“point”。到 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 <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() */

/* 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;
}

我遇到了一个很好的关于这个

的介绍教程

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

它带有源代码压缩包。

这与Google问题的结果相同。 :-)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top