TUN/TAP devices in 5 Minute
In UNIX systems TUN/TAP devices are a mechanism that allows to create a virtual, software based networking devices.
TAP devices are layer 2 devices which means that they act as Ethernet devices. TAP devices are often used for virtualize network connection to VMs physical network.
TUN devices (Tunnel) are layer 3 devices which means they live at the IP level. TUN devices are often used for routing IP packets and creating virtual point-to-point network connections, i.e like in VPN.
How TUN/TAP devices work
OK, so now that we understand what is TUN/TAP devices let’s talk about how it supported by the kernel.
TUN/TAP devices in Linux are supported by the TUN and TAP kernel modules. These modules provide the infrastructure for creating and managing virtual network interfaces used for various networking tasks, including VPNs, network tunneling, and bridging.
When working with TUN/TAP devices, interaction occurs through the /dev/net/tun
device file, which acts as a bridge between user space and the kernel’s TUN/TAP modules.
tun source code
tap source code
/dev/net/tun file
The /dev/net/tun
is usually created automatically by some script or tool in the system, like udev rules, Init scripts, etc..
But if missing this is how you can manually create one.
create the file
mkdir /dev/net (if it doesn't exist already)
sudo mknod /dev/net/tun c 10 200
/dev/net/tun
is the path to the device file you want to create.c
specifies that you are creating a character device.10
is the major device number associated with TUN/TAP devices.200
is a minor device number; you can use any number you like.
set appropriate permissions
chmod 0666 /dev/net/tun
in case that the TUN and TAP modules aren’t loaded you should also run:
sudo modprobe tun
sudo modprobe tap
Creating TUN/TAP device
First of all creating TUN/TAP device requires root privileges or to be more precisely cap_net_admin capability.
To create TUN/TAP device from commandline we can use the ip
command from the iproute2
toolkit which comes with most Linux distros.
TAP Examples
- creating TAP device and connect to a bridge device
# Create a TAP device (e.g., tap0)
sudo ip tuntap add name tap0 mode tap
# Connect the TAP device to a bridge (e.g., br0)
sudo brctl addif br0 tap0
# Enable the TAP device
sudo ifconfig tap0 up
- creating TAP device for packet capture
# Create a TAP device for packet capture (e.g., tap_capture)
sudo ip tuntap add name tap_capture mode tap
# Enable the TAP device
sudo ifconfig tap_capture up
# Use packet capture software (e.g., Wireshark) to capture network traffic on tap_capture
To create TUN/TAP device with code we can use the ioctl
syscall.
Example
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/if.h>
#include <linux/if_tun.h>
int main() {
int tun_fd;
struct ifreq ifr;
// Open the TUN device
if ((tun_fd = open("/dev/net/tun", O_RDWR)) < 0) {
perror("Failed to open TUN device");
exit(1);
}
// Configure the TUN device
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TUN | IFF_NO_PI; // TUN device without packet information
if (ioctl(tun_fd, TUNSETIFF, (void *)&ifr) < 0) {
perror("Failed to configure TUN device");
close(tun_fd);
exit(1);
}
printf("TUN device name: %s\n", ifr.ifr_name);
// You can now use the TUN device (tun_fd) to read and write network packets.
// Remember to close the TUN device when done
close(tun_fd);
return 0;
}