Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to interface with the Linux tun driver

Tags:

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

like image 593
rmrobins Avatar asked Jun 16 '09 20:06

rmrobins


People also ask

How does TUN interface work?

TUN, namely network TUNnel, simulates a network layer device and operates in layer 3 carrying IP packets. TAP, namely network TAP, simulates a link layer device and operates in layer 2 carrying Ethernet frames. TUN is used with routing. TAP can be used to create a user space network bridge.

What is TUN interface in Ubuntu?

The tun interface is a software loopback mechanism that can be loosely described as the network interface analog of the pty(4), that is, tun does for network interfaces what the pty(4) driver does for terminals.

What is Linux TAP interface?

Tap interfaces are special software entities which tell the Linux bridge to forward Ethernet frames as it is. In other words, the virtual machines connected to tap interfaces will be able to receive raw Ethernet frames.

What is tun0 interface Linux?

A TUN interface is a virtual IP Point-to-Point interface and a TAP interface is a virtual Ethernet interface. That means the user program can only read/write IP packets from/to a TUN interface and Ethernet frames from/to a TAP interface.


2 Answers

There are no /dev/tunX device files. Instead, you open the /dev/net/tun and configure it via ioctl() to "point" to tun0. To show the basic procedure, I will create the TUN interface using the command line tool ip tun tap and then show the C code to read from that TUN device. So to create the tun interface via commands line:

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 

The tun0 is created and all packets to destination IP address 10.0.3.x will be routed to tun0.

To read / write packets to this interface from an user space program you need to interact with the /dev/net/tun device file using ioctl(). Here is an example that will read the packets arriving at the tun0 interface and print the size:

#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; } 

If you have the ping 10.0.3.1 or ping 10.0.3.40 running, you will see Read 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 shows 10.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

sudo ip link set dev tun0 down sudo ip tuntap del mode tun dev tun0 
like image 95
RubenLaguna Avatar answered Sep 19 '22 10:09

RubenLaguna


Read /usr/src/linux/Documentation/networking/tuntap.rst.

You are supposed to open the /dev/net/tun device. A subsequent ioctl on the open fd will create the tun0 (or whatever you wish to name it) network interface. Linux's network interfaces do not correspond to any /dev/* device.

like image 25
ephemient Avatar answered Sep 21 '22 10:09

ephemient