rmr*_*ins 16 c driver tunnel 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 )
Run Code Online (Sandbox Code Playgroud)
返回-1:应用程序以root身份运行,但仍无法打开此隧道设备.可以打开/dev/net/tun,但这似乎不会生成/dev/tunX要使用的新设备.
总而言之 - 如何编写希望使用Linux隧道驱动程序的应用程序?任何见解将不胜感激.
谢谢; 〜罗伯特
eph*_*ent 14
读/usr/src/linux/Documentation/networking/tuntap.txt.
你应该open是/dev/net/tun设备.随后ioctl在open fd上将创建tun0(或任何你想要命名的)网络接口.Linux的网络接口与任何/dev/*设备都不对应.
ece*_*ulm 12
没有/dev/tunX设备文件.而是打开/dev/net/tun并通过ioctl()"指向"来配置它tun0.为了显示基本过程,我将使用命令行工具创建TUN接口ip tun tap,然后显示要从该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
Run Code Online (Sandbox Code Playgroud)
现在我们已经tun0创建了.要从用户空间程序读取/写入此接口的数据包,您需要使用与/dev/net/tun设备文件进行交互ioctl().这是一个示例,它将读取到达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;
}
Run Code Online (Sandbox Code Playgroud)