1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-11-26 19:39:53 +03:00

Add TAP devices support for FreeBSD and OpenBSD

Thanks to @kennylam777 for the first implementation: https://github.com/kennylam777/SoftEtherVPN/commits/FreeBSD-TAP
This commit is contained in:
Davide Beatrici 2018-08-23 10:56:30 +02:00
parent 0e5d432ae4
commit 3ff5c061d7
5 changed files with 73 additions and 28 deletions

View File

@ -50,13 +50,13 @@ if(UNIX)
endif() endif()
if(${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") if(${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
add_definitions(-DUNIX_BSD -DBRIDGE_BPF -DNO_VLAN) add_definitions(-DUNIX_BSD -DBRIDGE_BPF)
include_directories(SYSTEM /usr/local/include) include_directories(SYSTEM /usr/local/include)
link_directories(SYSTEM /usr/local/lib) link_directories(SYSTEM /usr/local/lib)
endif() endif()
if(${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD") if(${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD")
add_definitions(-DUNIX_BSD -DNO_VLAN) add_definitions(-DUNIX_BSD -DUNIX_OPENBSD)
include_directories(SYSTEM /usr/local/include) include_directories(SYSTEM /usr/local/include)
link_directories(SYSTEM /usr/local/lib) link_directories(SYSTEM /usr/local/lib)
endif() endif()
@ -66,7 +66,7 @@ if(UNIX)
endif() endif()
if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
add_definitions(-DUNIX_MACOS -DBRIDGE_PCAP) add_definitions(-DUNIX_BSD -DUNIX_MACOS -DBRIDGE_PCAP)
endif() endif()
endif() endif()

View File

@ -1491,12 +1491,52 @@ ETH *OpenEthBpf(char *name, bool local, bool tapmode, char *tapaddr)
} }
#endif // BRIDGE_BPF #endif // BRIDGE_BPF
#ifdef UNIX_BSD
ETH *OpenEthBSD(name, local, tapmode, tapaddr)
{
if (tapmode)
{
#ifndef NO_VLAN
// In tap mode
VLAN *v = NewTap(name, tapaddr, true);
if (v == NULL)
{
return NULL;
}
ETH *e;
e = ZeroMalloc(sizeof(ETH));
e->Name = CopyStr(name);
e->Title = CopyStr(name);
e->Cancel = VLanGetCancel(v);
e->IfIndex = 0;
e->Socket = INVALID_SOCKET;
e->Tap = v;
return e;
#else // NO_VLAN
return NULL:
#endif // NO_VLAN
}
#if defined(BRIDGE_BPF)
return OpenEthBpf(name, local, tapmode, tapaddr);
#elif defined(BRIDGE_PCAP)
return OpenEthPcap(name, local, tapmode, tapaddr);
#else
return NULL;
#endif
}
#endif // UNIX_BSD
// Open Ethernet adapter // Open Ethernet adapter
ETH *OpenEth(char *name, bool local, bool tapmode, char *tapaddr) ETH *OpenEth(char *name, bool local, bool tapmode, char *tapaddr)
{ {
#if defined(UNIX_LINUX) #if defined(UNIX_LINUX)
return OpenEthLinux(name, local, tapmode, tapaddr); return OpenEthLinux(name, local, tapmode, tapaddr);
#elif defined(UNIX_BSD)
return OpenEthBSD(name, local, tapmode, tapaddr);
#elif defined(UNIX_SOLARIS) #elif defined(UNIX_SOLARIS)
return OpenEthSolaris(name, local, tapmode, tapaddr); return OpenEthSolaris(name, local, tapmode, tapaddr);
#elif defined(BRIDGE_PCAP) #elif defined(BRIDGE_PCAP)

View File

@ -746,14 +746,14 @@
#define TAP_FILENAME_1 "/dev/net/tun" #define TAP_FILENAME_1 "/dev/net/tun"
#define TAP_FILENAME_2 "/dev/tun" #define TAP_FILENAME_2 "/dev/tun"
#ifdef UNIX_MACOS #ifdef UNIX_BSD
#ifdef NO_VLAN #ifdef NO_VLAN
#define TAP_MACOS_FILENAME "/dev/tap0" #define TAP_BSD_FILENAME "/dev/tap0"
#else // NO_VLAN #else // NO_VLAN
#define TAP_MACOS_FILENAME "tap" #define TAP_BSD_FILENAME "tap"
#endif // NO_VLAN #endif // NO_VLAN
#define TAP_MACOS_DIR "/dev/" #define TAP_BSD_DIR "/dev/"
#define TAP_MACOS_NUMBER (16) #define TAP_BSD_NUMBER (16)
#endif // UNIX_MACOS #endif // UNIX_MACOS

View File

@ -1616,8 +1616,9 @@ void GetServerCapsMain(SERVER *s, CAPSLIST *t)
if (IsBridgeSupported()) if (IsBridgeSupported())
{ {
// Tun / tap device is available (only Linux) // TUN / TAP device availability (Linux and BSD)
AddCapsBool(t, "b_tap_supported", GetOsInfo()->OsType == OSTYPE_LINUX ? true : false); const UINT OsType = GetOsInfo()->OsType;
AddCapsBool(t, "b_tap_supported", OsType == OSTYPE_LINUX || OsType == OSTYPE_BSD);
} }
// Cascade connection // Cascade connection

View File

@ -126,9 +126,13 @@
#include <errno.h> #include <errno.h>
#include <Mayaqua/Mayaqua.h> #include <Mayaqua/Mayaqua.h>
#include <Cedar/Cedar.h> #include <Cedar/Cedar.h>
#ifdef UNIX_MACOS #ifdef UNIX_BSD
#ifdef UNIX_OPENBSD
#include <netinet/if_ether.h>
#else // UNIX_OPENBSD
#include <net/ethernet.h> #include <net/ethernet.h>
#endif #endif // UNIX_OPENBSD
#endif // UNIX_BSD
#ifdef OS_UNIX #ifdef OS_UNIX
@ -445,8 +449,8 @@ int UnixCreateTapDeviceEx(char *name, char *prefix, UCHAR *mac_address, bool cre
struct sockaddr sa; struct sockaddr sa;
char *tap_name = TAP_FILENAME_1; char *tap_name = TAP_FILENAME_1;
int s; int s;
#ifdef UNIX_MACOS #ifdef UNIX_BSD
char tap_macos_name[256] = TAP_MACOS_DIR TAP_MACOS_FILENAME; char tap_bsd_name[256] = TAP_BSD_DIR TAP_BSD_FILENAME;
#endif #endif
// Validate arguments // Validate arguments
if (name == NULL) if (name == NULL)
@ -457,7 +461,7 @@ int UnixCreateTapDeviceEx(char *name, char *prefix, UCHAR *mac_address, bool cre
GenerateTunName(name, prefix, eth_name, sizeof(eth_name)); GenerateTunName(name, prefix, eth_name, sizeof(eth_name));
// Open the tun / tap // Open the tun / tap
#ifndef UNIX_MACOS #ifndef UNIX_BSD
if (GetOsInfo()->OsType == OSTYPE_LINUX) if (GetOsInfo()->OsType == OSTYPE_LINUX)
{ {
// Linux // Linux
@ -472,7 +476,7 @@ int UnixCreateTapDeviceEx(char *name, char *prefix, UCHAR *mac_address, bool cre
Run("chmod", tmp, true, true); Run("chmod", tmp, true, true);
} }
} }
// Other than MacOS X
fd = open(TAP_FILENAME_1, O_RDWR); fd = open(TAP_FILENAME_1, O_RDWR);
if (fd == -1) if (fd == -1)
{ {
@ -484,16 +488,16 @@ int UnixCreateTapDeviceEx(char *name, char *prefix, UCHAR *mac_address, bool cre
} }
tap_name = TAP_FILENAME_2; tap_name = TAP_FILENAME_2;
} }
#else // UNIX_MACOS #else // UNIX_BSD
{ {
int i; int i;
fd = -1; fd = -1;
for (i = 0; i < TAP_MACOS_NUMBER; i++) { for (i = 0; i < TAP_BSD_NUMBER; i++) {
sprintf(tap_macos_name + strlen(TAP_MACOS_DIR TAP_MACOS_FILENAME), "%d", i); sprintf(tap_bsd_name + strlen(TAP_BSD_DIR TAP_BSD_FILENAME), "%d", i);
fd = open(tap_macos_name, O_RDWR); fd = open(tap_bsd_name, O_RDWR);
if (fd != -1) if (fd != -1)
{ {
tap_name = tap_macos_name; tap_name = tap_bsd_name;
break; break;
} }
} }
@ -502,7 +506,7 @@ int UnixCreateTapDeviceEx(char *name, char *prefix, UCHAR *mac_address, bool cre
return -1; return -1;
} }
} }
#endif // UNIX_MACOS #endif // UNIX_BSD
#ifdef UNIX_LINUX #ifdef UNIX_LINUX
// Create a tap for Linux // Create a tap for Linux
@ -547,18 +551,18 @@ int UnixCreateTapDeviceEx(char *name, char *prefix, UCHAR *mac_address, bool cre
} }
#else // UNIX_LINUX #else // UNIX_LINUX
#ifdef UNIX_MACOS #ifdef UNIX_BSD
// MAC address setting // MAC address setting
s = socket(AF_INET, SOCK_DGRAM, 0); s = socket(AF_INET, SOCK_DGRAM, 0);
if (s != -1) if (s != -1)
{ {
char *macos_eth_name; char *bsd_eth_name;
macos_eth_name = tap_macos_name + strlen(TAP_MACOS_DIR); bsd_eth_name = tap_bsd_name + strlen(TAP_BSD_DIR);
if (mac_address != NULL) if (mac_address != NULL)
{ {
Zero(&ifr, sizeof(ifr)); Zero(&ifr, sizeof(ifr));
StrCpy(ifr.ifr_name, sizeof(ifr.ifr_name), macos_eth_name); StrCpy(ifr.ifr_name, sizeof(ifr.ifr_name), bsd_eth_name);
ifr.ifr_addr.sa_len = ETHER_ADDR_LEN; ifr.ifr_addr.sa_len = ETHER_ADDR_LEN;
ifr.ifr_addr.sa_family = AF_LINK; ifr.ifr_addr.sa_family = AF_LINK;
Copy(&ifr.ifr_addr.sa_data, mac_address, ETHER_ADDR_LEN); Copy(&ifr.ifr_addr.sa_data, mac_address, ETHER_ADDR_LEN);
@ -566,7 +570,7 @@ int UnixCreateTapDeviceEx(char *name, char *prefix, UCHAR *mac_address, bool cre
} }
Zero(&ifr, sizeof(ifr)); Zero(&ifr, sizeof(ifr));
StrCpy(ifr.ifr_name, sizeof(ifr.ifr_name), macos_eth_name); StrCpy(ifr.ifr_name, sizeof(ifr.ifr_name), bsd_eth_name);
ioctl(s, SIOCGIFFLAGS, &ifr); ioctl(s, SIOCGIFFLAGS, &ifr);
if (create_up) if (create_up)
@ -577,7 +581,7 @@ int UnixCreateTapDeviceEx(char *name, char *prefix, UCHAR *mac_address, bool cre
close(s); close(s);
} }
#endif // UNIX_MACOS #endif // UNIX_BSD
#ifdef UNIX_SOLARIS #ifdef UNIX_SOLARIS
// Create a tap for Solaris // Create a tap for Solaris
{ {