#include <fcntl.h>
#include <net/if.h>
#include <linux/if_tun.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
int main()
{
struct ifreq ifr;
int fd = open("/dev/net/tun", O_RDWR);
if(fd < 0)
{
perror("open tun fail");
return -1;
}
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_UP;
// set tap device name
strncpy(ifr.ifr_name, "tap99", IFNAMSIZ);
if(ioctl(fd, TUNSETIFF, (void*)(&ifr)) < 0)
{
perror("ioctl fail");
close(fd);
return -1;
}
printf("TAP device %s created successfully\n", ifr.ifr_name);
close(fd);
return 0;
}
The code executes successfully, but no TAP device is created。
1.Check kernel support for tap and tun
[root@Qwons c_test]# lsmod | grep tun
tun 49152 2
[root@Qwons c_test]# lsmod | grep tap
tap 28672 0
[root@Qwons c_test]# ll /net/dev
total 0
crw-rw-rw- 1 root root 10, 200 Dec 23 23:38 tun
2.using strace to check it
3.After I executed this program, I couldn't find the tap device using ip and ifconfig
[root@Qwons c_test]# ./modify
TAP device tap99 created successfully
[qwons@Qwons c_test]$ ip link set tap99 up
Cannot find device "tap99"
[qwons@Qwons c_test]$ ifconfig | grep tap99
[qwons@Qwons c_test]$
I want to know why this program doesn't work and how can I fix it.
The interface gets automatically destroyed when the file descriptor is closed.
By their design, tun & tap interfaces exist to be 'driven' by a program – any packet "sent" through the interface will be read by the program that created that interface, and vice versa. Without a program that has a file descriptor to that interface, the interface would be inoperative, so it is automatically deleted as soon as the fd is closed.
If you want to avoid this, you can use ioctl(fd, TUNSETPERSIST, 1)
to create a "persistent" interface – or you can use ip tuntap add
to achieve the same thing without writing a custom program.