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

Merge PR #670: Add TAP devices support for FreeBSD and OpenBSD

This commit is contained in:
Davide Beatrici 2018-08-25 14:43:42 +02:00 committed by GitHub
commit e0598d747a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 73 additions and 28 deletions

View File

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

View File

@ -1491,12 +1491,52 @@ ETH *OpenEthBpf(char *name, bool local, bool tapmode, char *tapaddr)
}
#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
ETH *OpenEth(char *name, bool local, bool tapmode, char *tapaddr)
{
#if defined(UNIX_LINUX)
return OpenEthLinux(name, local, tapmode, tapaddr);
#elif defined(UNIX_BSD)
return OpenEthBSD(name, local, tapmode, tapaddr);
#elif defined(UNIX_SOLARIS)
return OpenEthSolaris(name, local, tapmode, tapaddr);
#elif defined(BRIDGE_PCAP)

View File

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

View File

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

View File

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