#include #include #include #include #include #include #include #include #include #include "spi.h" #include "tun.h" static pthread_t read_thd; static int tun_fd; static char tun_name[IFNAMSIZ]; static int tun_alloc(char *dev, int flags) { struct ifreq ifr; int fd, err; char *clonedev = "/dev/net/tun"; /* Arguments taken by the function: * * char *dev: the name of an interface (or '\0'). MUST have enough * space to hold the interface name if '\0' is passed * int flags: interface flags (eg, IFF_TUN etc.) */ fd = open(clonedev, O_RDWR); if (fd < 0) { return fd; } memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = flags; /* IFF_TUN or IFF_TAP, plus maybe IFF_NO_PI */ if (*dev) { /* if a device name was specified, put it in the structure; otherwise, * the kernel will try to allocate the "next" device of the * specified type */ strncpy(ifr.ifr_name, dev, IFNAMSIZ); } /* try to create the device */ err = ioctl(fd, TUNSETIFF, (void *) &ifr); if (err < 0) { close(fd); return err; } /* if the operation was successful, write back the name of the * interface to the variable "dev", so the caller can know * it. Note that the caller MUST reserve space in *dev (see calling * code below) */ strcpy(dev, ifr.ifr_name); /* this is the special file descriptor that the caller will use to talk * with the virtual interface */ return fd; } ssize_t tun_read(unsigned char *buffer, size_t buf_size) { return read(tun_fd, buffer, buf_size); } ssize_t tun_write(unsigned char *buffer, size_t buf_len) { return write(tun_fd, buffer, buf_len); } int tun_init(char *name) { int rv; if (strlen(name) >= sizeof(tun_name) - 1) return -1; strcpy(tun_name, name); tun_fd = tun_alloc(tun_name, IFF_TUN | IFF_NO_PI); if (tun_fd < 0) return -1; return 0; }