Browse Source

freebsd tun: поддержка ручного имени интерфейса (tunX) + автономер (tun)

topo_upd
Evgeny 2 months ago
parent
commit
867f48c125
  1. 39
      src/tun_freebsd.c

39
src/tun_freebsd.c

@ -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) {

Loading…
Cancel
Save