From 867f48c12597a64959ad94dc70f07d8846a2c2b8 Mon Sep 17 00:00:00 2001 From: Evgeny Date: Thu, 13 Aug 2026 16:21:47 +0300 Subject: [PATCH] =?UTF-8?q?freebsd=20tun:=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5?= =?UTF-8?q?=D1=80=D0=B6=D0=BA=D0=B0=20=D1=80=D1=83=D1=87=D0=BD=D0=BE=D0=B3?= =?UTF-8?q?=D0=BE=20=D0=B8=D0=BC=D0=B5=D0=BD=D0=B8=20=D0=B8=D0=BD=D1=82?= =?UTF-8?q?=D0=B5=D1=80=D1=84=D0=B5=D0=B9=D1=81=D0=B0=20(tunX)=20+=20?= =?UTF-8?q?=D0=B0=D0=B2=D1=82=D0=BE=D0=BD=D0=BE=D0=BC=D0=B5=D1=80=20(tun)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/tun_freebsd.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/src/tun_freebsd.c b/src/tun_freebsd.c index 61babfe2..2108820e 100644 --- a/src/tun_freebsd.c +++ b/src/tun_freebsd.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -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) {