From 8779e59295b857c38f5f453080a5e87be07c1fc3 Mon Sep 17 00:00:00 2001 From: nattoheaven Date: Tue, 14 Jan 2014 23:19:37 +0900 Subject: [PATCH] Supporting VLAN for Mac OS X using TunTapOSX --- src/Cedar/Cedar.h | 8 +++++ src/Cedar/Client.c | 22 ++++++++++++-- src/Cedar/VLanUnix.c | 56 ++++++++++++++++++++++++++++------- src/Mayaqua/TunTap.h | 17 ++++------- src/Mayaqua/Unix.c | 4 +++ src/makefiles/macos_32bit.mak | 6 ++-- src/makefiles/macos_64bit.mak | 6 ++-- 7 files changed, 91 insertions(+), 28 deletions(-) diff --git a/src/Cedar/Cedar.h b/src/Cedar/Cedar.h index b857a7d6..693e9a36 100644 --- a/src/Cedar/Cedar.h +++ b/src/Cedar/Cedar.h @@ -696,7 +696,15 @@ #define TAP_FILENAME_1 "/dev/net/tun" #define TAP_FILENAME_2 "/dev/tun" +#ifdef UNIX_MACOS +#ifdef NO_VLAN #define TAP_MACOS_FILENAME "/dev/tap0" +#else +#define TAP_MACOS_FILENAME "tap" +#endif +#define TAP_MACOS_DIR "/dev/" +#define TAP_MACOS_NUMBER (16) +#endif diff --git a/src/Cedar/Client.c b/src/Cedar/Client.c index 16062e7f..f85a9c72 100644 --- a/src/Cedar/Client.c +++ b/src/Cedar/Client.c @@ -7446,12 +7446,14 @@ bool CtDisableVLan(CLIENT *c, RPC_CLIENT_CREATE_VLAN *vlan) #ifndef OS_WIN32 +#ifdef NO_VLAN if (GetOsInfo()->OsType == OSTYPE_MACOS_X) { // Can not be added or removed the virtual LAN card in MacOS X CiSetError(c, ERR_NOT_SUPPORTED); return false; } +#endif // Check whether the virtual LAN card with the specified name is not // being used by one or more accounts @@ -7597,12 +7599,14 @@ bool CtEnableVLan(CLIENT *c, RPC_CLIENT_CREATE_VLAN *vlan) #ifndef OS_WIN32 +#ifdef NO_VLAN if (GetOsInfo()->OsType == OSTYPE_MACOS_X) { // Can not be added or removed the virtual LAN card in MacOS X CiSetError(c, ERR_NOT_SUPPORTED); return false; } +#endif // Search the virtual LAN card LockList(c->UnixVLanList); @@ -7693,12 +7697,14 @@ bool CtDeleteVLan(CLIENT *c, RPC_CLIENT_CREATE_VLAN *d) #ifndef OS_WIN32 +#ifdef NO_VLAN if (GetOsInfo()->OsType == OSTYPE_MACOS_X) { // Can not be added or removed the virtual LAN card in MacOS X CiSetError(c, ERR_NOT_SUPPORTED); return false; } +#endif // Check whether the virtual LAN card with the specified name is not // being used by one or more accounts @@ -8265,12 +8271,14 @@ bool CtCreateVLan(CLIENT *c, RPC_CLIENT_CREATE_VLAN *create) #ifndef OS_WIN32 // Non-Win32 +#ifdef NO_VLAN if (GetOsInfo()->OsType == OSTYPE_MACOS_X) { // A virtual LAN card can not be added or removed in MacOS X CiSetError(c, ERR_NOT_SUPPORTED); return false; } +#endif // Check whether the specified name is valid or not if (IsSafeStr(create->DeviceName) == false) @@ -9792,7 +9800,11 @@ bool CiReadSettingFromCfg(CLIENT *c, FOLDER *root) // Eraser c->Eraser = NewEraser(c->Logger, CfgGetInt64(config, "AutoDeleteCheckDiskFreeSpaceMin")); - if (OS_IS_UNIX(GetOsInfo()->OsType) && GetOsInfo()->OsType != OSTYPE_MACOS_X) + if (OS_IS_UNIX(GetOsInfo()->OsType) +#ifdef NO_VLAN + && GetOsInfo()->OsType != OSTYPE_MACOS_X +#endif + ) { // Read the UNIX version virtual LAN card list (except MacOS) vlan = CfgGetFolder(root, "UnixVLan"); @@ -9802,6 +9814,7 @@ bool CiReadSettingFromCfg(CLIENT *c, FOLDER *root) } } +#ifdef NO_VLAN if (GetOsInfo()->OsType == OSTYPE_MACOS_X) { #ifdef OS_UNIX @@ -9822,6 +9835,7 @@ bool CiReadSettingFromCfg(CLIENT *c, FOLDER *root) Add(c->UnixVLanList, uv); #endif // OS_UNIX } +#endif CiLoadAccountDatabase(c, db); @@ -10328,7 +10342,11 @@ void CiWriteSettingToCfg(CLIENT *c, FOLDER *root) CiWriteCAList(c, ca); // VLAN - if (OS_IS_UNIX(GetOsInfo()->OsType) && GetOsInfo()->OsType != OSTYPE_MACOS_X) + if (OS_IS_UNIX(GetOsInfo()->OsType) +#ifdef NO_VLAN + && GetOsInfo()->OsType != OSTYPE_MACOS_X +#endif + ) { vlan = CfgCreateFolder(root, "UnixVLan"); CiWriteVLanList(c, vlan); diff --git a/src/Cedar/VLanUnix.c b/src/Cedar/VLanUnix.c index c3e77d0c..c987f14a 100644 --- a/src/Cedar/VLanUnix.c +++ b/src/Cedar/VLanUnix.c @@ -302,11 +302,7 @@ CANCEL *VLanGetCancel(VLAN *v) fd = v->fd; -#ifndef UNIX_MACOS UnixSetSocketNonBlockingMode(fd, true); -#else // UNIX_MACOS - UnixSetSocketNonBlockingMode(fd, false); -#endif // UNIX_MACOS c->SpecialFlag = true; c->pipe_read = fd; @@ -402,6 +398,9 @@ int UnixCreateTapDeviceEx(char *name, char *prefix, UCHAR *mac_address) 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; +#endif // Validate arguments if (name == NULL) { @@ -445,13 +444,23 @@ int UnixCreateTapDeviceEx(char *name, char *prefix, UCHAR *mac_address) tap_name = TAP_FILENAME_2; } #else // UNIX_MACOS - // MacOS X - fd = open(TAP_MACOS_FILENAME, O_RDWR); - if (fd == -1) { - return -1; + 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); + if (fd != -1) + { + tap_name = tap_macos_name; + break; + } + } + if (fd == -1) + { + return -1; + } } - tap_name = TAP_MACOS_FILENAME; #endif // UNIX_MACOS #ifdef UNIX_LINUX @@ -479,7 +488,7 @@ int UnixCreateTapDeviceEx(char *name, char *prefix, UCHAR *mac_address) Zero(&ifr, sizeof(ifr)); StrCpy(ifr.ifr_name, sizeof(ifr.ifr_name), eth_name); ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; - Copy(&ifr.ifr_hwaddr.sa_data, mac_address, 6); + Copy(&ifr.ifr_addr.sa_data, mac_address, 6); ioctl(s, SIOCSIFHWADDR, &ifr); } @@ -494,6 +503,33 @@ int UnixCreateTapDeviceEx(char *name, char *prefix, UCHAR *mac_address) } #else // UNIX_LINUX +#ifdef UNIX_MACOS + // 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); + + if (mac_address != NULL) + { + uint8_t macos_mac_address[19]; + Zero(&ifr, sizeof(ifr)); + StrCpy(ifr.ifr_name, sizeof(ifr.ifr_name), macos_eth_name); + Copy(&ifr.ifr_addr.sa_data, mac_address, 6); + ioctl(s, SIOCSIFLLADDR, &ifr); + } + + Zero(&ifr, sizeof(ifr)); + StrCpy(ifr.ifr_name, sizeof(ifr.ifr_name), macos_eth_name); + ioctl(s, SIOCGIFFLAGS, &ifr); + + ifr.ifr_flags |= IFF_UP; + ioctl(s, SIOCSIFFLAGS, &ifr); + + close(s); + } +#endif #ifdef UNIX_SOLARIS // Create a tap for Solaris { diff --git a/src/Mayaqua/TunTap.h b/src/Mayaqua/TunTap.h index 5db02c06..872fd5ac 100644 --- a/src/Mayaqua/TunTap.h +++ b/src/Mayaqua/TunTap.h @@ -227,11 +227,14 @@ struct tundladdr { #else // UNIX_SOLARIS -#ifdef UNIX_BSD +#if defined(UNIX_BSD) || (!defined(NO_VLAN) && defined(UNIX_MACOS)) // ----------------------------------------------------------------- // Tap header for FreeBSD // ----------------------------------------------------------------- +// ----------------------------------------------------------------- +// Tap header For MacOS +// ----------------------------------------------------------------- /* $NetBSD: if_tun.h,v 1.5 1994/06/29 06:36:27 cgd Exp $ */ /* @@ -283,17 +286,7 @@ struct tuninfo { #else // UNIX_BSD -#ifdef UNIX_MACOS - -// ----------------------------------------------------------------- -// Tap header For MacOS -// ----------------------------------------------------------------- - -#else // UNIX_MACOS - -#endif // UNIX_MACOS - -#endif // UNIX_BSD +#endif // UNIX_BSD || UNIX_MACOS #endif // UNIX_SOLARIS diff --git a/src/Mayaqua/Unix.c b/src/Mayaqua/Unix.c index fc2cbf32..f637a1b6 100644 --- a/src/Mayaqua/Unix.c +++ b/src/Mayaqua/Unix.c @@ -96,6 +96,7 @@ // Struct statfs for MacOS X #ifdef UNIX_MACOS +#ifdef NO_VLAN typedef struct fsid { int32_t val[2]; } fsid_t; struct statfs { short f_otype; /* TEMPORARY SHADOW COPY OF f_type */ @@ -117,6 +118,9 @@ struct statfs { char f_mntonname[90]; /* directory on which mounted */ char f_mntfromname[90];/* mounted filesystem */ }; +#else +#include +#endif #endif // UNIX_MACOS // Scandir() function for Solaris diff --git a/src/makefiles/macos_32bit.mak b/src/makefiles/macos_32bit.mak index 816f4515..e62eb18c 100644 --- a/src/makefiles/macos_32bit.mak +++ b/src/makefiles/macos_32bit.mak @@ -24,11 +24,13 @@ # Variables CC=gcc -OPTIONS_COMPILE_DEBUG=-D_DEBUG -DDEBUG -DUNIX -DUNIX_MACOS -DBRIDGE_PCAP -DNO_VLAN -D_REENTRANT -DREENTRANT -D_THREAD_SAFE -D_THREADSAFE -DTHREAD_SAFE -DTHREADSAFE -D_FILE_OFFSET_BITS=64 -I./src/ -I./src/Cedar/ -I./src/Mayaqua/ -g -fsigned-char +NO_VLAN?=-DNO_VLAN + +OPTIONS_COMPILE_DEBUG=-D_DEBUG -DDEBUG -DUNIX -DUNIX_MACOS -DBRIDGE_PCAP $(NO_VLAN) -D_REENTRANT -DREENTRANT -D_THREAD_SAFE -D_THREADSAFE -DTHREAD_SAFE -DTHREADSAFE -D_FILE_OFFSET_BITS=64 -I./src/ -I./src/Cedar/ -I./src/Mayaqua/ -g -fsigned-char OPTIONS_LINK_DEBUG=-g -fsigned-char -lm -lpthread -lssl -lcrypto -liconv -lreadline -lncurses -lz -lpcap -OPTIONS_COMPILE_RELEASE=-DNDEBUG -DVPN_SPEED -DUNIX -DUNIX_MACOS -DBRIDGE_PCAP -DNO_VLAN -D_REENTRANT -DREENTRANT -D_THREAD_SAFE -D_THREADSAFE -DTHREAD_SAFE -DTHREADSAFE -D_FILE_OFFSET_BITS=64 -I./src/ -I./src/Cedar/ -I./src/Mayaqua/ -O2 -fsigned-char +OPTIONS_COMPILE_RELEASE=-DNDEBUG -DVPN_SPEED -DUNIX -DUNIX_MACOS -DBRIDGE_PCAP $(NO_VLAN) -D_REENTRANT -DREENTRANT -D_THREAD_SAFE -D_THREADSAFE -DTHREAD_SAFE -DTHREADSAFE -D_FILE_OFFSET_BITS=64 -I./src/ -I./src/Cedar/ -I./src/Mayaqua/ -O2 -fsigned-char OPTIONS_LINK_RELEASE=-O2 -fsigned-char -lm -lpthread -lssl -lcrypto -liconv -lreadline -lncurses -lz -lpcap diff --git a/src/makefiles/macos_64bit.mak b/src/makefiles/macos_64bit.mak index fb0bfbc3..933bc5b7 100644 --- a/src/makefiles/macos_64bit.mak +++ b/src/makefiles/macos_64bit.mak @@ -24,11 +24,13 @@ # Variables CC=gcc -OPTIONS_COMPILE_DEBUG=-D_DEBUG -DDEBUG -DUNIX -DUNIX_MACOS -DBRIDGE_PCAP -DNO_VLAN -DCPU_64 -D_REENTRANT -DREENTRANT -D_THREAD_SAFE -D_THREADSAFE -DTHREAD_SAFE -DTHREADSAFE -D_FILE_OFFSET_BITS=64 -I./src/ -I./src/Cedar/ -I./src/Mayaqua/ -g -fsigned-char -m64 +NO_VLAN?=-DNO_VLAN + +OPTIONS_COMPILE_DEBUG=-D_DEBUG -DDEBUG -DUNIX -DUNIX_MACOS -DBRIDGE_PCAP $(NO_VLAN) -DCPU_64 -D_REENTRANT -DREENTRANT -D_THREAD_SAFE -D_THREADSAFE -DTHREAD_SAFE -DTHREADSAFE -D_FILE_OFFSET_BITS=64 -I./src/ -I./src/Cedar/ -I./src/Mayaqua/ -g -fsigned-char -m64 OPTIONS_LINK_DEBUG=-g -fsigned-char -m64 -lm -lpthread -lssl -lcrypto -liconv -lreadline -lncurses -lz -lpcap -OPTIONS_COMPILE_RELEASE=-DNDEBUG -DVPN_SPEED -DUNIX -DUNIX_MACOS -DBRIDGE_PCAP -DNO_VLAN -DCPU_64 -D_REENTRANT -DREENTRANT -D_THREAD_SAFE -D_THREADSAFE -DTHREAD_SAFE -DTHREADSAFE -D_FILE_OFFSET_BITS=64 -I./src/ -I./src/Cedar/ -I./src/Mayaqua/ -O2 -fsigned-char -m64 +OPTIONS_COMPILE_RELEASE=-DNDEBUG -DVPN_SPEED -DUNIX -DUNIX_MACOS -DBRIDGE_PCAP $(NO_VLAN) -DCPU_64 -D_REENTRANT -DREENTRANT -D_THREAD_SAFE -D_THREADSAFE -DTHREAD_SAFE -DTHREADSAFE -D_FILE_OFFSET_BITS=64 -I./src/ -I./src/Cedar/ -I./src/Mayaqua/ -O2 -fsigned-char -m64 OPTIONS_LINK_RELEASE=-O2 -fsigned-char -m64 -lm -lpthread -lssl -lcrypto -liconv -lreadline -lncurses -lz -lpcap