From 9c33605f5ec2ac0cd7d9dfd3c10aec56aaa9c35e Mon Sep 17 00:00:00 2001 From: Koichiro IWAO Date: Tue, 30 May 2023 23:01:37 +0900 Subject: [PATCH 1/6] Cedar: Don't hardcode prefix for UNIX virtual network interface --- src/Cedar/Cedar.h | 2 ++ src/Cedar/SM.c | 3 ++- src/Cedar/VLanUnix.c | 6 +++--- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Cedar/Cedar.h b/src/Cedar/Cedar.h index 2c9fafbf..7e3c88e0 100644 --- a/src/Cedar/Cedar.h +++ b/src/Cedar/Cedar.h @@ -675,6 +675,8 @@ // ////////////////////////////////////////////////////////////////////// +#define UNIX_VLAN_IFACE_PREFIX "vpn" // Prefix of UNIX virual LAN card interface + #ifndef UNIX_BSD #define TAP_FILENAME_1 "/dev/net/tun" #define TAP_FILENAME_2 "/dev/tun" diff --git a/src/Cedar/SM.c b/src/Cedar/SM.c index b0b5f2ae..ce6d49b7 100644 --- a/src/Cedar/SM.c +++ b/src/Cedar/SM.c @@ -7987,7 +7987,8 @@ void SmBridgeDlgOnOk(HWND hWnd, SM_SERVER *s) StrCpy(t.HubName, sizeof(t.HubName), hub); t.TapMode = tapmode; - if (InStrEx(t.DeviceName, "vpn", false) || InStrEx(t.DeviceName, "tun", false) + if (InStrEx(t.DeviceName, UNIX_VLAN_IFACE_PREFIX, false) + || InStrEx(t.DeviceName, "tun", false) || InStrEx(t.DeviceName, "tap", false)) { // Trying to make a local bridge to the VPN device diff --git a/src/Cedar/VLanUnix.c b/src/Cedar/VLanUnix.c index b4ede360..b4ae5f35 100644 --- a/src/Cedar/VLanUnix.c +++ b/src/Cedar/VLanUnix.c @@ -554,7 +554,7 @@ int UnixCreateTapDeviceEx(char *name, char *prefix, UCHAR *mac_address, bool cre } int UnixCreateTapDevice(char *name, UCHAR *mac_address, bool create_up) { - return UnixCreateTapDeviceEx(name, "vpn", mac_address, create_up); + return UnixCreateTapDeviceEx(name, UNIX_VLAN_IFACE_PREFIX, mac_address, create_up); } // Close the tap device @@ -662,7 +662,7 @@ bool UnixVLanCreateEx(char *name, char *prefix, UCHAR *mac_address, bool create_ } bool UnixVLanCreate(char *name, UCHAR *mac_address, bool create_up) { - return UnixVLanCreateEx(name, "vpn", mac_address, create_up); + return UnixVLanCreateEx(name, UNIX_VLAN_IFACE_PREFIX, mac_address, create_up); } // Set a VLAN up/down @@ -689,7 +689,7 @@ bool UnixVLanSetState(char* name, bool state_up) return false; } - GenerateTunName(name, "vpn", eth_name, sizeof(eth_name)); + GenerateTunName(name, UNIX_VLAN_IFACE_PREFIX, eth_name, sizeof(eth_name)); Zero(&ifr, sizeof(ifr)); StrCpy(ifr.ifr_name, sizeof(ifr.ifr_name), eth_name); From 8482a52522b7127912d3c3934786bd1be04fa359 Mon Sep 17 00:00:00 2001 From: Koichiro IWAO Date: Wed, 31 May 2023 11:34:50 +0900 Subject: [PATCH 2/6] Cedar/VLanUnix: Make NicDelete work on FreeBSD In contrast to Linux, FreeBSD's tap devices are still plumbed after fd closed. The tap device must be destroyed in addition to closing fd to delete virtual network interfaces used for VPN connection. NicDelete command now works properly and virtual network interfaces used by vpnclient are cleaned up when shutting down vpnclient. --- src/Cedar/VLanUnix.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/Cedar/VLanUnix.c b/src/Cedar/VLanUnix.c index b4ae5f35..1bc5c73e 100644 --- a/src/Cedar/VLanUnix.c +++ b/src/Cedar/VLanUnix.c @@ -569,12 +569,40 @@ void UnixCloseTapDevice(int fd) close(fd); } +// Destroy the tap device (for FreeBSD) +// FreeBSD tap device is still plumbed after closing fd so need to destroy after close +void UnixDestroyTapDevice(char *name) +{ +#ifdef UNIX_BSD + struct ifreq ifr; + char eth_name[MAX_SIZE]; + int s; + + Zero(&ifr, sizeof(ifr)); + GenerateTunName(name, UNIX_VLAN_IFACE_PREFIX, eth_name, sizeof(eth_name)); + StrCpy(ifr.ifr_name, sizeof(ifr.ifr_name), eth_name); + + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s == -1) + { + return; + } + ioctl(s, SIOCIFDESTROY, &ifr); + + close(s); +#endif // UNIX_BSD +} + #else // NO_VLAN void UnixCloseTapDevice(int fd) { } +void UnixDestroyTapDevice(char *name) +{ +} + int UnixCreateTapDeviceEx(char *name, char *prefix, UCHAR *mac_address, bool create_up) { return -1; @@ -769,6 +797,9 @@ void UnixVLanDelete(char *name) if (t != NULL) { UnixCloseTapDevice(t->fd); +#ifdef UNIX_BSD + UnixDestroyTapDevice(t->Name); +#endif Delete(unix_vlan, t); Free(t); } @@ -815,6 +846,9 @@ void UnixVLanFree() UNIX_VLAN_LIST *t = LIST_DATA(unix_vlan, i); UnixCloseTapDevice(t->fd); +#ifdef UNIX_BSD + UnixDestroyTapDevice(t->Name); +#endif Free(t); } From 0ba7ad392edcd546965d22f6388f92cdf28b5970 Mon Sep 17 00:00:00 2001 From: Koichiro IWAO Date: Mon, 29 May 2023 18:00:46 +0900 Subject: [PATCH 3/6] Cedar/VLanUnix: Enable UnixVLanSetState on FreeBSD --- src/Cedar/VLanUnix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Cedar/VLanUnix.c b/src/Cedar/VLanUnix.c index 1bc5c73e..1095903d 100644 --- a/src/Cedar/VLanUnix.c +++ b/src/Cedar/VLanUnix.c @@ -696,7 +696,7 @@ bool UnixVLanCreate(char *name, UCHAR *mac_address, bool create_up) // Set a VLAN up/down bool UnixVLanSetState(char* name, bool state_up) { -#ifdef UNIX_LINUX +#if defined(UNIX_LINUX) || defined(UNIX_BSD) UNIX_VLAN_LIST *t, tt; struct ifreq ifr; int s; @@ -742,7 +742,7 @@ bool UnixVLanSetState(char* name, bool state_up) close(s); } UnlockList(unix_vlan); -#endif // UNIX_LINUX +#endif // UNIX_LINUX || UNIX_BSD return true; } From 939eb3130ea796b3b96a6c74919900990250da96 Mon Sep 17 00:00:00 2001 From: Koichiro IWAO Date: Wed, 31 May 2023 16:40:34 +0900 Subject: [PATCH 4/6] Cedar/Client: Enable CtVLans{Up,Down} on FreeBSD The same trick also works on FreeBSD. There's no reason to limit it to Linux. --- src/Cedar/Client.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/Cedar/Client.c b/src/Cedar/Client.c index 46b4f1fa..a4175a3c 100644 --- a/src/Cedar/Client.c +++ b/src/Cedar/Client.c @@ -6524,9 +6524,7 @@ bool CtConnect(CLIENT *c, RPC_CLIENT_CONNECT *connect) // Requires account and VLan lists of the CLIENT argument to be already locked bool CtVLansDown(CLIENT *c) { -#ifndef UNIX_LINUX - return true; -#else +#if defined(UNIX_LINUX) || defined(UNIX_BSD) int i; LIST *tmpVLanList; UNIX_VLAN t, *r; @@ -6568,6 +6566,8 @@ bool CtVLansDown(CLIENT *c) ReleaseList(tmpVLanList); return result; +#else + return true; #endif } @@ -6575,9 +6575,7 @@ bool CtVLansDown(CLIENT *c) // Requires VLan list of the CLIENT argument to be already locked bool CtVLansUp(CLIENT *c) { -#ifndef UNIX_LINUX - return true; -#else +#if defined(UNIX_LINUX) || defined(UNIX_BSD) int i; UNIX_VLAN *r; @@ -6591,9 +6589,8 @@ bool CtVLansUp(CLIENT *c) r = LIST_DATA(c->UnixVLanList, i); UnixVLanSetState(r->Name, true); } - - return true; #endif + return true; } // Get the account information From 96b1961d7874ae0de5e5e4ec1fd88bd7e01b0b1a Mon Sep 17 00:00:00 2001 From: Koichiro IWAO Date: Thu, 1 Jun 2023 11:57:50 +0900 Subject: [PATCH 5/6] Cedar/VLanUnix: add UnixDestroyTapDevice prototype declaration --- src/Cedar/VLanUnix.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Cedar/VLanUnix.h b/src/Cedar/VLanUnix.h index 6bd5f44a..714b746a 100644 --- a/src/Cedar/VLanUnix.h +++ b/src/Cedar/VLanUnix.h @@ -60,6 +60,7 @@ struct UNIX_VLAN_LIST int UnixCreateTapDevice(char *name, UCHAR *mac_address, bool create_up); int UnixCreateTapDeviceEx(char *name, char *prefix, UCHAR *mac_address, bool create_up); void UnixCloseTapDevice(int fd); +void UnixDestroyTapDevice(char *name); void UnixVLanInit(); void UnixVLanFree(); bool UnixVLanCreate(char *name, UCHAR *mac_address, bool create_up); From 867c992111334d76008bb6e5149794dcfb246512 Mon Sep 17 00:00:00 2001 From: Koichiro IWAO Date: Thu, 1 Jun 2023 15:07:27 +0900 Subject: [PATCH 6/6] Cedar/VLanUnix: use space after #ifdef --- src/Cedar/VLanUnix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cedar/VLanUnix.c b/src/Cedar/VLanUnix.c index 1095903d..01d09d64 100644 --- a/src/Cedar/VLanUnix.c +++ b/src/Cedar/VLanUnix.c @@ -846,7 +846,7 @@ void UnixVLanFree() UNIX_VLAN_LIST *t = LIST_DATA(unix_vlan, i); UnixCloseTapDevice(t->fd); -#ifdef UNIX_BSD +#ifdef UNIX_BSD UnixDestroyTapDevice(t->Name); #endif Free(t);