diff options
Diffstat (limited to 'yocto/esp32tun')
| -rwxr-xr-x | yocto/esp32tun/Makefile | 15 | ||||
| -rwxr-xr-x | yocto/esp32tun/esp32tun.c | 173 |
2 files changed, 188 insertions, 0 deletions
diff --git a/yocto/esp32tun/Makefile b/yocto/esp32tun/Makefile new file mode 100755 index 0000000..574c480 --- /dev/null +++ b/yocto/esp32tun/Makefile @@ -0,0 +1,15 @@ +#CFLAGS = +LDFLAGS = -pthread -lgpiod +TARGET = esp32tun +obj = esp32tun.o + +all: $(TARGET) + +%.o: %.c %.h + $(CC) $(CFLAGS) -c $< + +$(TARGET): $(obj) + $(CC) $(obj) $(LDFLAGS) -o $@ + +clean: + rm -f $(TARGET) *.o diff --git a/yocto/esp32tun/esp32tun.c b/yocto/esp32tun/esp32tun.c new file mode 100755 index 0000000..8f9e3bd --- /dev/null +++ b/yocto/esp32tun/esp32tun.c @@ -0,0 +1,173 @@ +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <assert.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/ioctl.h> + +#include <linux/if.h> +#include <linux/if_tun.h> + +#include <pthread.h> + +#define TUN_NAME "tun0" + +#define ESP32_MTU 1500 +#define ESP32_FNAMSIZ 64 +#define ESP32_DEVFN "/dev/esp32.?" +#define ESP32_MTYPE_TUN 1 +#define ESP32_MAX_MTYPE 8 + +static pthread_t tun_handler_thd, esp32_handler_thd; + +static int tun_fd, esp32_fd; +static char tun_name[IFNAMSIZ]; + +/* 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.) + */ +int tun_alloc(char *dev, int flags) { + struct ifreq ifr; + int fd, rv; + char *clonedev = "/dev/net/tun"; + + 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 */ + rv = ioctl(fd, TUNSETIFF, (void *) &ifr); + if (rv < 0) { + close(fd); + return rv; + } + + /* 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) { + if (strlen(name) + 1 > sizeof(tun_name)) return -1; + + strcpy(tun_name, name); + tun_fd = tun_alloc(tun_name, IFF_TUN | IFF_NO_PI); + + if (tun_fd < 0) return tun_fd; + return 0; +} + +ssize_t esp32_read(unsigned char *buffer, size_t buf_size) { + return read(esp32_fd, buffer, buf_size); +} + +ssize_t esp32_write(unsigned char *buffer, size_t buf_len) { + return write(esp32_fd, buffer, buf_len); +} + +int esp32_fname(char *fname, int mtype) { + if (mtype >= ESP32_MAX_MTYPE) return -1; + + strcpy(fname, ESP32_DEVFN); + fname[strlen(fname) - 1] = '0' + mtype; + + return 0; +} + +int esp32_init(void) { + char fname[ESP32_FNAMSIZ]; + int rv; + + rv = esp32_fname(fname, ESP32_MTYPE_TUN); + if (rv) return rv; + + esp32_fd = open(fname, O_RDWR); + + if (esp32_fd < 0) return esp32_fd; + return 0; +} + +void *tun_handler(void *arg) { + unsigned char buffer[ESP32_MTU]; + ssize_t len, rv; + + while (1) { + len = tun_read(buffer, ESP32_MTU); + if (len < 0) { + perror("tun read"); + continue; + } + rv = esp32_write(buffer, len); + if (rv < 0) { + perror("esp32 write"); + continue; + } + } + + return NULL; +} + +void *esp32_handler(void *arg) { + unsigned char buffer[ESP32_MTU]; + ssize_t len, rv; + + while (1) { + len = esp32_read(buffer, ESP32_MTU); + if (len < 0) { + perror("esp32 read"); + continue; + } + rv = tun_write(buffer, len); + if (rv < 0) { + perror("tun write"); + continue; + } + } + + return NULL; +} + +int main(int argc, char *argv[]) { + int rv; + + rv = tun_init(TUN_NAME); + assert(rv == 0); + + rv = esp32_init(); + assert(rv == 0); + + rv = pthread_create(&tun_handler_thd, NULL, tun_handler, NULL); + assert(rv == 0); + + rv = pthread_create(&esp32_handler_thd, NULL, esp32_handler, NULL); + assert(rv == 0); + + while(1); +} |
