I've been following the official documentation on creating a TUN device. There's very little documentation, but what even is there does not seem to work. Here's what I have so far:
#include <linux/if.h>
#include <linux/if_tun.h>
#include <sys/fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
int tun_alloc(char *dev)
{
struct ifreq ifr;
int fd, err;
if( (fd = open("/dev/net/tun", O_RDWR)) < 0 )
return 7; // tun_alloc_old(dev); // this does not happen, linux docs don't say what tun_alloc_old is anyway
memset(&ifr, 0, sizeof(ifr));
/* Flags: IFF_TUN - TUN device (no Ethernet headers)
* IFF_TAP - TAP device
*
* IFF_NO_PI - Do not provide packet information
*/
ifr.ifr_flags = IFF_TUN;
if( *dev ) {
printf("setting ifr.ifr_name to \"%s\"\n", dev);
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
}
printf("ifr.ifr_name is \"%s\"\n", ifr.ifr_name);
if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){
perror("ERR");
close(fd);
printf("GOT ERROR: %d\n", err);
return err;
}
printf("past TUNSETIFF error checking\n");
strcpy(dev, ifr.ifr_name);
return fd;
}
int main() {
char name[128];
strcpy(&name, "tun23");
int tun = tun_alloc(name);
printf("tun_alloc: %s id: %d\n", name, tun);
if(tun == -1) return -1;
while(1) {
printf("in loop\n");
char buf[128];
ssize_t readAmount = read(tun, buf, 128);
printf("finished read\n");
if(readAmount == -1) {
printf("read 0 bytes\n");
continue;
}
printf("Read %d: ", readAmount);
for(int i = 0; i < 128; i++) {
printf("%hhx", buf[i]);
}
printf("\n");
}
return tun;
}
Compiler step is gcc -g3 test.c && a.out
.
When ran as non-root, I get this output
setting ifr.ifr_name to "tun23"
ifr.ifr_name is "tun23"
ERR: Operation not permitted
GOT ERROR: -1
tun_alloc: tun23 id: -1
And as root, it successfully gets into the loop, but then the call to read
seems to block.
setting ifr.ifr_name to "tun23"
ifr.ifr_name is "tun23"
past TUNSETIFF error checking
tun_alloc: tun23 id: 3
in loop
(In the event of an XY problem, the reason I'm doing this is to try and make a very simple vpn-like application)
The issue is that while it's blocking in this loop, no TUN devices are created. I am looking in /dev/
. I'm not sure how I would give it any bytes to read.
Edit: added a proper perror
call and the respective output Operation not permitted
, valgrind output, and a couple print statements. Going to try and debug the strcpy error.
Edit: fixed the strcpy error, was pretty simple. Seems to fail in non-root due to a lack of permission to create TUN devices.