|
|
|
|
@ -7,6 +7,7 @@
|
|
|
|
|
#include <stdio.h> |
|
|
|
|
#include <stdlib.h> |
|
|
|
|
#include <string.h> |
|
|
|
|
#include <ctype.h> |
|
|
|
|
#include <unistd.h> |
|
|
|
|
#include <fcntl.h> |
|
|
|
|
#include <sys/ioctl.h> |
|
|
|
|
@ -56,9 +57,43 @@ static int parse_ip_mask(const char *ip_addr, struct in_addr *ip, struct in_addr
|
|
|
|
|
netmask->s_addr = htonl(mask); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
// Create TUN device using cloning device /dev/tun
|
|
|
|
|
// Create TUN device.
|
|
|
|
|
// Если имя оканчивается на цифру (tun4, tun0) — создаём интерфейс с этим именем
|
|
|
|
|
// через SIOCIFCREATE. Иначе (tun или пусто) — клонирующее устройство /dev/tun,
|
|
|
|
|
// ядро само выдаёт следующий свободный номер.
|
|
|
|
|
static int create_tun_device(char *ifname, size_t ifname_len) { |
|
|
|
|
int fd; |
|
|
|
|
size_t name_len = ifname ? strlen(ifname) : 0; |
|
|
|
|
int manual = name_len > 0 && isdigit((unsigned char)ifname[name_len - 1]); |
|
|
|
|
|
|
|
|
|
if (manual) { |
|
|
|
|
int sock = socket(AF_INET, SOCK_DGRAM, 0); |
|
|
|
|
if (sock < 0) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_TUN, "Failed to create ioctl socket: %s", strerror(errno)); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
struct ifreq ifr; |
|
|
|
|
memset(&ifr, 0, sizeof(ifr)); |
|
|
|
|
strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1); |
|
|
|
|
ifr.ifr_name[IFNAMSIZ - 1] = '\0'; |
|
|
|
|
if (ioctl(sock, SIOCIFCREATE, &ifr) < 0) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_TUN, "SIOCIFCREATE failed for %s: %s", ifname, strerror(errno)); |
|
|
|
|
close(sock); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
close(sock); |
|
|
|
|
|
|
|
|
|
char dev_path[IFNAMSIZ + 6]; |
|
|
|
|
snprintf(dev_path, sizeof(dev_path), "/dev/%s", ifname); |
|
|
|
|
fd = open(dev_path, O_RDWR); |
|
|
|
|
if (fd < 0) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_TUN, "Failed to open %s: %s", dev_path, strerror(errno)); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_TUN, "Opened %s (fd=%d)", dev_path, fd); |
|
|
|
|
return fd; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Открываем cloning device /dev/tun
|
|
|
|
|
fd = open("/dev/tun", O_RDWR); |
|
|
|
|
if (fd < 0) { |
|
|
|
|
@ -245,7 +280,7 @@ static int tun_set_mtu(const char *ifname, int mtu) {
|
|
|
|
|
} |
|
|
|
|
// Platform-specific initialization for FreeBSD
|
|
|
|
|
int tun_platform_init(struct tun_if* tun, const char* ifname, const char* ip_str, int mtu) { |
|
|
|
|
(void)ifname; // FreeBSD выделяет имя автоматически через cloning device
|
|
|
|
|
(void)ifname; // имя уже в tun->ifname, передаётся в create_tun_device
|
|
|
|
|
// Create TUN device
|
|
|
|
|
tun->fd = create_tun_device(tun->ifname, sizeof(tun->ifname)); |
|
|
|
|
if (tun->fd < 0) { |
|
|
|
|
|