Pārlūkot izejas kodu

merge upstream v4.19-9582-beta

Mykhaylo Yehorov 10 gadi atpakaļ
vecāks
revīzija
7aaf3d8fd3
100 mainītis faili ar 4350 papildinājumiem un 219 dzēšanām
  1. 6 1
      src/BuildUtil/BuildUtilCommands.cs
  2. 7 4
      src/BuildUtil/CodeSign.cs
  3. 6 6
      src/BuildUtil/Win32BuildUtil.cs
  4. 10 0
      src/Cedar/Bridge.c
  5. 4 0
      src/Cedar/Bridge.h
  6. 791 3
      src/Cedar/BridgeUnix.c
  7. 23 1
      src/Cedar/BridgeUnix.h
  8. 8 3
      src/Cedar/BridgeWin32.c
  9. 7 1
      src/Cedar/BridgeWin32.h
  10. 28 0
      src/Cedar/Cedar.c
  11. 7 6
      src/Cedar/Cedar.h
  12. 12 0
      src/Cedar/CedarType.h
  13. 1 0
      src/Cedar/Command.c
  14. 101 0
      src/Cedar/Hub.c
  15. 5 0
      src/Cedar/Hub.h
  16. 1 1
      src/Cedar/IPsec_EtherIP.c
  17. 15 1
      src/Cedar/IPsec_IKE.c
  18. 21 5
      src/Cedar/IPsec_IPC.c
  19. 2 1
      src/Cedar/IPsec_IPC.h
  20. 192 38
      src/Cedar/IPsec_L2TP.c
  21. 5 1
      src/Cedar/IPsec_L2TP.h
  22. 132 10
      src/Cedar/IPsec_PPP.c
  23. 6 1
      src/Cedar/IPsec_PPP.h
  24. 1 0
      src/Cedar/NM.c
  25. 3 1
      src/Cedar/Nat.c
  26. 1 0
      src/Cedar/Nat.h
  27. 564 6
      src/Cedar/NativeStack.c
  28. 46 0
      src/Cedar/NativeStack.h
  29. 33 2
      src/Cedar/Protocol.c
  30. 1588 0
      src/Cedar/Radius.c
  31. 247 2
      src/Cedar/Radius.h
  32. 8 0
      src/Cedar/Sam.c
  33. 14 0
      src/Cedar/Server.c
  34. 130 16
      src/Cedar/Virtual.c
  35. 8 3
      src/Cedar/Virtual.h
  36. 4 4
      src/CurrentBuild.txt
  37. 0 24
      src/Makefile64
  38. 1 0
      src/Mayaqua/MayaType.h
  39. 135 0
      src/Mayaqua/Memory.c
  40. 16 0
      src/Mayaqua/Memory.h
  41. 63 0
      src/Mayaqua/Network.c
  42. 4 0
      src/Mayaqua/Network.h
  43. 1 0
      src/Mayaqua/TcpIp.c
  44. 3 2
      src/Mayaqua/Tick64.c
  45. 1 1
      src/Mayaqua/Tick64.h
  46. 2 2
      src/Neo/Neo.vcproj
  47. 6 6
      src/Neo6/Neo6.vcproj
  48. 6 6
      src/SeLow/SeLow.vcproj
  49. 1 1
      src/SeLow/SeLowCommon.h
  50. 2 2
      src/See/See.vcproj
  51. 15 1
      src/Wfp/Wfp.c
  52. 6 6
      src/Wfp/Wfp.vcproj
  53. 3 3
      src/bin/hamcore/DriverPackages/Neo/x64/Neo_x64.inf
  54. BIN
      src/bin/hamcore/DriverPackages/Neo/x64/Neo_x64.sys
  55. 3 3
      src/bin/hamcore/DriverPackages/Neo/x86/Neo_x86.inf
  56. BIN
      src/bin/hamcore/DriverPackages/Neo/x86/Neo_x86.sys
  57. 3 3
      src/bin/hamcore/DriverPackages/Neo6/x64/Neo6_x64.inf
  58. BIN
      src/bin/hamcore/DriverPackages/Neo6/x64/Neo6_x64.sys
  59. 3 3
      src/bin/hamcore/DriverPackages/Neo6/x86/Neo6_x86.inf
  60. BIN
      src/bin/hamcore/DriverPackages/Neo6/x86/Neo6_x86.sys
  61. BIN
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN.cat
  62. 3 3
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN.inf
  63. BIN
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN.sys
  64. BIN
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN10.cat
  65. 3 3
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN10.inf
  66. BIN
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN10.sys
  67. BIN
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN100.cat
  68. 3 3
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN100.inf
  69. BIN
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN100.sys
  70. BIN
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN101.cat
  71. 3 3
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN101.inf
  72. BIN
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN101.sys
  73. BIN
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN102.cat
  74. 3 3
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN102.inf
  75. BIN
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN102.sys
  76. BIN
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN103.cat
  77. 3 3
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN103.inf
  78. BIN
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN103.sys
  79. BIN
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN104.cat
  80. 3 3
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN104.inf
  81. BIN
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN104.sys
  82. BIN
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN105.cat
  83. 3 3
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN105.inf
  84. BIN
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN105.sys
  85. BIN
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN106.cat
  86. 3 3
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN106.inf
  87. BIN
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN106.sys
  88. BIN
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN107.cat
  89. 3 3
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN107.inf
  90. BIN
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN107.sys
  91. BIN
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN108.cat
  92. 3 3
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN108.inf
  93. BIN
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN108.sys
  94. BIN
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN109.cat
  95. 3 3
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN109.inf
  96. BIN
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN109.sys
  97. BIN
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN11.cat
  98. 3 3
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN11.inf
  99. BIN
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN11.sys
  100. BIN
      src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN110.cat

+ 6 - 1
src/BuildUtil/BuildUtilCommands.cs

@@ -1322,6 +1322,8 @@ namespace BuildUtil
 				new ConsoleParam("DEST"),
 				new ConsoleParam("COMMENT", ConsoleService.Prompt, "Comment: ", ConsoleService.EvalNotEmpty, null),
 				new ConsoleParam("KERNEL"),
+				new ConsoleParam("CERTID"),
+				new ConsoleParam("SHAMODE"),
 			};
 			ConsoleParamValueList vl = c.ParseCommandList(cmdName, str, args);
 
@@ -1334,7 +1336,10 @@ namespace BuildUtil
 			string comment = vl["COMMENT"].StrValue;
 			bool kernel = vl["KERNEL"].BoolValue;
 
-			CodeSign.SignFile(destFileName, srcFileName, comment, kernel);
+			int certid = vl["CERTID"].IntValue;
+			int shamode = vl["SHAMODE"].IntValue;
+
+			CodeSign.SignFile(destFileName, srcFileName, comment, kernel, certid, shamode);
 
 			return 0;
 		}

+ 7 - 4
src/BuildUtil/CodeSign.cs

@@ -260,16 +260,19 @@ namespace BuildUtil
 		{
 			int cert_id = UsingCertId;
 
-			SignFile(destFileName, srcFileName, comment, kernelModeDriver, cert_id);
+			SignFile(destFileName, srcFileName, comment, kernelModeDriver, cert_id, 0);
 		}
-		public static void SignFile(string destFileName, string srcFileName, string comment, bool kernelModeDriver, int cert_id)
+		public static void SignFile(string destFileName, string srcFileName, string comment, bool kernelModeDriver, int cert_id, int sha_mode)
 		{
 #if	!BU_OSS
+			if (cert_id == 0)
+			{
+				cert_id = UsingCertId;
+			}
+
 			Con.WriteLine("Signing for '{0}'...", Path.GetFileName(destFileName));
 			byte[] srcData = File.ReadAllBytes(srcFileName);
 
-			int sha_mode = 0;
-
 			if (srcFileName.EndsWith(".msi", StringComparison.InvariantCultureIgnoreCase))
 			{
 				sha_mode = 1;

+ 6 - 6
src/BuildUtil/Win32BuildUtil.cs

@@ -1249,7 +1249,7 @@ namespace BuildUtil
 				IO.WriteAllTextWithEncoding(Path.Combine(dst_dir, @"Neo6_Win10\x86\Neo6_x86_" + name + ".inf"),
 					process_inf_file(IO.ReadAllTextWithAutoGetEncoding(Path.Combine(src_dir, @"Neo6\x86\Neo6_x86.inf")), build, version, date, sys_name, name, string.Format("Neo6_x86_{0}.cat", name), true), Str.ShiftJisEncoding, false);
 				cat_src_filename.Add("Neo6_x86_" + name + ".inf");
-				IO.FileCopy(Path.Combine(src_dir, @"Neo6\x86\Neo6_x86.sys"), Path.Combine(dst_dir, @"Neo6_Win10\x86\Neo6_x86_" + name + ".sys"));
+				IO.FileCopy(Path.Combine(src_dir, @"Neo6\x86\Neo6_x86_win10.sys"), Path.Combine(dst_dir, @"Neo6_Win10\x86\Neo6_x86_" + name + ".sys"));
 				make_cat_file(Path.Combine(dst_dir, @"Neo6_Win10\x86"), cat_src_filename.ToArray(), "Neo6_x86_" + name + ".cat", true, true);
 			}
 
@@ -1268,7 +1268,7 @@ namespace BuildUtil
 				IO.WriteAllTextWithEncoding(Path.Combine(dst_dir, @"Neo6_Win10\x64\Neo6_x64_" + name + ".inf"),
 					process_inf_file(IO.ReadAllTextWithAutoGetEncoding(Path.Combine(src_dir, @"Neo6\x64\Neo6_x64.inf")), build, version, date, sys_name, name, string.Format("Neo6_x64_{0}.cat", name), true), Str.ShiftJisEncoding, false);
 				cat_src_filename.Add("Neo6_x64_" + name + ".inf");
-				IO.FileCopy(Path.Combine(src_dir, @"Neo6\x64\Neo6_x64.sys"), Path.Combine(dst_dir, @"Neo6_Win10\x64\Neo6_x64_" + name + ".sys"));
+				IO.FileCopy(Path.Combine(src_dir, @"Neo6\x64\Neo6_x64_win10.sys"), Path.Combine(dst_dir, @"Neo6_Win10\x64\Neo6_x64_" + name + ".sys"));
 				make_cat_file(Path.Combine(dst_dir, @"Neo6_Win10\x64"), cat_src_filename.ToArray(), "Neo6_x64_" + name + ".cat", true, true);
 			}
 
@@ -1303,7 +1303,7 @@ namespace BuildUtil
 			cat_src_filename.Add("SeLow_x86.inf");
 			IO.WriteAllTextWithEncoding(Path.Combine(dst_dir, @"SeLow_Win10\x86\SeLow_x86.inf"),
 				process_inf_file(IO.ReadAllTextWithAutoGetEncoding(Path.Combine(src_dir, @"SeLow\x86\SeLow_x86.inf")), build, version, date, null, null, "SeLow_Win10_x86.cat", false), Str.ShiftJisEncoding, false);
-			IO.FileCopy(Path.Combine(src_dir, @"SeLow\x86\SeLow_x86.sys"), Path.Combine(dst_dir, @"SeLow_Win10\x86\SeLow_x86.sys"));
+			IO.FileCopy(Path.Combine(src_dir, @"SeLow\x86\SeLow_x86_win10.sys"), Path.Combine(dst_dir, @"SeLow_Win10\x86\SeLow_x86.sys"));
 			make_cat_file(Path.Combine(dst_dir, @"SeLow_Win10\x86"), cat_src_filename.ToArray(), "SeLow_Win10_x86.cat", true, false);
 
 			// SeLow x64 for Windows 10
@@ -1313,7 +1313,7 @@ namespace BuildUtil
 			cat_src_filename.Add("SeLow_x64.inf");
 			IO.WriteAllTextWithEncoding(Path.Combine(dst_dir, @"SeLow_Win10\x64\SeLow_x64.inf"),
 				process_inf_file(IO.ReadAllTextWithAutoGetEncoding(Path.Combine(src_dir, @"SeLow\x64\SeLow_x64.inf")), build, version, date, null, null, "SeLow_Win10_x64.cat", false), Str.ShiftJisEncoding, false);
-			IO.FileCopy(Path.Combine(src_dir, @"SeLow\x64\SeLow_x64.sys"), Path.Combine(dst_dir, @"SeLow_Win10\x64\SeLow_x64.sys"));
+			IO.FileCopy(Path.Combine(src_dir, @"SeLow\x64\SeLow_x64_win10.sys"), Path.Combine(dst_dir, @"SeLow_Win10\x64\SeLow_x64.sys"));
 			make_cat_file(Path.Combine(dst_dir, @"SeLow_Win10\x64"), cat_src_filename.ToArray(), "SeLow_Win10_x64.cat", true, false);
 
 			// Wfp x86
@@ -1345,7 +1345,7 @@ namespace BuildUtil
 			cat_src_filename.Add("pxwfp_x86.inf");
 			IO.WriteAllTextWithEncoding(Path.Combine(dst_dir, @"Wfp_Win10\x86\pxwfp_x86.inf"),
 				process_inf_file(IO.ReadAllTextWithAutoGetEncoding(Path.Combine(src_dir, @"Wfp\x86\pxwfp_x86.inf")), build, version, date, null, null, "pxwfp_Win10_x86.cat", false), Str.ShiftJisEncoding, false);
-			IO.FileCopy(Path.Combine(src_dir, @"Wfp\x86\pxwfp_x86.sys"), Path.Combine(dst_dir, @"Wfp_Win10\x86\pxwfp_x86.sys"));
+			IO.FileCopy(Path.Combine(src_dir, @"Wfp\x86\pxwfp_x86_win10.sys"), Path.Combine(dst_dir, @"Wfp_Win10\x86\pxwfp_x86.sys"));
 			make_cat_file(Path.Combine(dst_dir, @"Wfp_Win10\x86"), cat_src_filename.ToArray(), "pxwfp_Win10_x86.cat", true, false);
 
 			// Wfp x64 for Windows 10
@@ -1355,7 +1355,7 @@ namespace BuildUtil
 			cat_src_filename.Add("pxwfp_x64.inf");
 			IO.WriteAllTextWithEncoding(Path.Combine(dst_dir, @"Wfp_Win10\x64\pxwfp_x64.inf"),
 				process_inf_file(IO.ReadAllTextWithAutoGetEncoding(Path.Combine(src_dir, @"Wfp\x64\pxwfp_x64.inf")), build, version, date, null, null, "pxwfp_Win10_x64.cat", false), Str.ShiftJisEncoding, false);
-			IO.FileCopy(Path.Combine(src_dir, @"Wfp\x64\pxwfp_x64.sys"), Path.Combine(dst_dir, @"Wfp_Win10\x64\pxwfp_x64.sys"));
+			IO.FileCopy(Path.Combine(src_dir, @"Wfp\x64\pxwfp_x64_win10.sys"), Path.Combine(dst_dir, @"Wfp_Win10\x64\pxwfp_x64.sys"));
 			make_cat_file(Path.Combine(dst_dir, @"Wfp_Win10\x64"), cat_src_filename.ToArray(), "pxwfp_Win10_x64.cat", true, false);
 
 			string tmp_body = IO.ReadAllTextWithAutoGetEncoding(Path.Combine(src_dir, "make_whql_submission.cm_"));

+ 10 - 0
src/Cedar/Bridge.c

@@ -556,6 +556,16 @@ BRIDGE *BrNewBridge(HUB *h, char *name, POLICY *p, bool local, bool monitor, boo
 	return b;
 }
 
+// Raw IP bridge is supported only on Linux
+bool IsRawIpBridgeSupported()
+{
+#ifdef	UNIX_LINUX
+	return true;
+#else	// UNIX_LINUX
+	return false;
+#endif	// UNIX_LINUX
+}
+
 
 // Developed by SoftEther VPN Project at University of Tsukuba in Japan.
 // Department of Computer Science has dozens of overly-enthusiastic geeks.

+ 4 - 0
src/Cedar/Bridge.h

@@ -126,6 +126,9 @@
 
 #endif	// OS_WIN32
 
+// Constants
+#define	BRIDGE_SPECIAL_IPRAW_NAME		"ipv4_rawsocket_virtual_router"
+
 // Bridge
 struct BRIDGE
 {
@@ -171,6 +174,7 @@ bool DeleteLocalBridge(CEDAR *c, char *hubname, char *devicename);
 bool IsBridgeSupported();
 bool IsNeedWinPcap();
 UINT GetEthDeviceHash();
+bool IsRawIpBridgeSupported();
 
 #endif	// BRIDGE_H
 

+ 791 - 3
src/Cedar/BridgeUnix.c

@@ -374,7 +374,7 @@ TOKEN_LIST *GetEthListSolaris()
 
 #ifdef	UNIX_LINUX
 // Get Ethernet device list on Linux
-TOKEN_LIST *GetEthListLinux()
+TOKEN_LIST *GetEthListLinux(bool enum_normal, bool enum_rawip)
 {
 	struct ifreq ifr;
 	TOKEN_LIST *t;
@@ -383,6 +383,11 @@ TOKEN_LIST *GetEthListLinux()
 	LIST *o;
 	char name[MAX_SIZE];
 
+	if (enum_normal == false && enum_rawip)
+	{
+		return ParseToken(BRIDGE_SPECIAL_IPRAW_NAME, NULL);
+	}
+
 	o = NewListFast(CompareStr);
 
 	s = UnixEthOpenRawSocket();
@@ -431,7 +436,7 @@ TOKEN_LIST *GetEthListLinux()
 	Sort(o);
 
 	t = ZeroMalloc(sizeof(TOKEN_LIST));
-	t->NumTokens = LIST_NUM(o);
+	t->NumTokens = LIST_NUM(o) + (enum_rawip ? 1 : 0);
 	t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);
 
 	for (i = 0;i < LIST_NUM(o);i++)
@@ -440,6 +445,11 @@ TOKEN_LIST *GetEthListLinux()
 		t->Token[i] = name;
 	}
 
+	if (enum_rawip)
+	{
+		t->Token[t->NumTokens - 1] = CopyStr(BRIDGE_SPECIAL_IPRAW_NAME);
+	}
+
 	ReleaseList(o);
 
 	return t;
@@ -542,11 +552,15 @@ TOKEN_LIST *GetEthListBpf()
 
 // Enumerate Ethernet devices
 TOKEN_LIST *GetEthList()
+{
+	return GetEthListEx(NULL, true, false);
+}
+TOKEN_LIST *GetEthListEx(UINT *total_num_including_hidden, bool enum_normal, bool enum_rawip)
 {
 	TOKEN_LIST *t = NULL;
 
 #if	defined(UNIX_LINUX)
-	t = GetEthListLinux();
+	t = GetEthListLinux(enum_normal, enum_rawip);
 #elif	defined(UNIX_SOLARIS)
 	t = GetEthListSolaris();
 #elif	defined(BRIDGE_PCAP)
@@ -575,6 +589,11 @@ ETH *OpenEthLinux(char *name, bool local, bool tapmode, char *tapaddr)
 		return NULL;
 	}
 
+	if (StrCmpi(name, BRIDGE_SPECIAL_IPRAW_NAME) == 0)
+	{
+		return OpenEthLinuxIpRaw();
+	}
+
 	if (tapmode)
 	{
 #ifndef	NO_VLAN
@@ -732,6 +751,10 @@ UINT EthGetMtu(ETH *e)
 	{
 		return 0;
 	}
+	if (e->IsRawIpMode)
+	{
+		return 0;
+	}
 
 	if (e->CurrentMtu != 0)
 	{
@@ -802,6 +825,10 @@ bool EthSetMtu(ETH *e, UINT mtu)
 	{
 		return false;
 	}
+	if (e->IsRawIpMode)
+	{
+		return false;
+	}
 
 	if (mtu == 0)
 	{
@@ -865,6 +892,11 @@ bool EthIsChangeMtuSupported(ETH *e)
 		return false;
 	}
 
+	if (e->IsRawIpMode)
+	{
+		return false;
+	}
+
 	return true;
 #else	// defined(UNIX_LINUX) || defined(UNIX_BSD) || defined(UNIX_SOLARIS)
 	return false;
@@ -1526,6 +1558,13 @@ void CloseEth(ETH *e)
 		return;
 	}
 
+	if (e->IsRawIpMode)
+	{
+		CloseEthLinuxIpRaw(e);
+
+		return;
+	}
+
 	if (e->Tap != NULL)
 	{
 #ifndef	NO_VLAN
@@ -1647,6 +1686,11 @@ UINT EthGetPacketLinux(ETH *e, void **data)
 		return INFINITE;
 	}
 
+	if (e->IsRawIpMode)
+	{
+		return EthGetPacketLinuxIpRaw(e, data);
+	}
+
 	if (e->Tap != NULL)
 	{
 #ifndef	NO_VLAN
@@ -1949,6 +1993,11 @@ void EthPutPacket(ETH *e, void *data, UINT size)
 	{
 		return;
 	}
+	if (e->IsRawIpMode)
+	{
+		EthPutPacketLinuxIpRaw(e, data, size);
+		return;
+	}
 	if (size < 14 || size > MAX_PACKET_SIZE)
 	{
 		Free(data);
@@ -2017,6 +2066,745 @@ void EthPutPacket(ETH *e, void *data, UINT size)
 	Free(data);
 }
 
+
+
+
+// Open ETH by using IP raw packets
+ETH *OpenEthLinuxIpRaw()
+{
+	ETH *e;
+
+	if (IsRawIpBridgeSupported() == false)
+	{
+		return NULL;
+	}
+
+	e = ZeroMalloc(sizeof(ETH));
+
+	e->IsRawIpMode = true;
+
+	e->RawTcp = NewUDP4(MAKE_SPECIAL_PORT(IPPROTO_TCP), NULL);
+	e->RawUdp = NewUDP4(MAKE_SPECIAL_PORT(IPPROTO_UDP), NULL);
+	e->RawIcmp = NewUDP4(MAKE_SPECIAL_PORT(IPPROTO_ICMP), NULL);
+
+	if (e->RawTcp == NULL || e->RawUdp == NULL || e->RawIcmp == NULL)
+	{
+		ReleaseSock(e->RawTcp);
+		ReleaseSock(e->RawUdp);
+		ReleaseSock(e->RawIcmp);
+
+		Free(e);
+		return NULL;
+	}
+
+	ClearSockDfBit(e->RawTcp);
+	ClearSockDfBit(e->RawUdp);
+	ClearSockDfBit(e->RawIcmp);
+
+	SetRawSockHeaderIncludeOption(e->RawTcp, true);
+	SetRawSockHeaderIncludeOption(e->RawUdp, true);
+	SetRawSockHeaderIncludeOption(e->RawIcmp, true);
+
+	e->Name = CopyStr(BRIDGE_SPECIAL_IPRAW_NAME);
+	e->Title = CopyStr(BRIDGE_SPECIAL_IPRAW_NAME);
+	e->Cancel = NewCancel();
+
+	UnixDeletePipe(e->Cancel->pipe_read, e->Cancel->pipe_write);
+	e->Cancel->pipe_read = e->Cancel->pipe_write = -1;
+
+	UnixSetSocketNonBlockingMode(e->RawTcp->socket, true);
+	UnixSetSocketNonBlockingMode(e->RawUdp->socket, true);
+	UnixSetSocketNonBlockingMode(e->RawIcmp->socket, true);
+
+	e->Cancel->SpecialFlag = true;
+	e->Cancel->pipe_read = e->RawTcp->socket;
+	e->Cancel->pipe_special_read2 = e->RawUdp->socket;
+	e->Cancel->pipe_special_read3 = e->RawIcmp->socket;
+
+	e->RawIpMyMacAddr[2] = 0x01;
+	e->RawIpMyMacAddr[5] = 0x01;
+
+	SetIP(&e->MyIP, 10, 171, 7, 253);
+	SetIP(&e->YourIP, 10, 171, 7, 254);
+
+	e->RawIpSendQueue = NewQueueFast();
+
+	e->RawIP_TmpBufferSize = 67000;
+	e->RawIP_TmpBuffer = Malloc(e->RawIP_TmpBufferSize);
+
+	return e;
+}
+
+// Close ETH by using IP raw packets
+void CloseEthLinuxIpRaw(ETH *e)
+{
+	if (e == NULL)
+	{
+		return;
+	}
+
+	while (true)
+	{
+		BUF *buf = GetNext(e->RawIpSendQueue);
+		if (buf == NULL)
+		{
+			break;
+		}
+
+		FreeBuf(buf);
+	}
+	ReleaseQueue(e->RawIpSendQueue);
+
+	Free(e->Name);
+	Free(e->Title);
+
+	ReleaseSock(e->RawTcp);
+	ReleaseSock(e->RawUdp);
+	ReleaseSock(e->RawIcmp);
+
+	ReleaseCancel(e->Cancel);
+
+	Free(e->RawIP_TmpBuffer);
+
+	Free(e);
+}
+
+// Receive an IP raw packet
+UINT EthGetPacketLinuxIpRaw(ETH *e, void **data)
+{
+	UINT r;
+	BUF *b;
+	// Validate arguments
+	if (e == NULL || data == NULL)
+	{
+		return INFINITE;
+	}
+	if (e->RawIp_HasError)
+	{
+		return INFINITE;
+	}
+
+	b = GetNext(e->RawIpSendQueue);
+	if (b != NULL)
+	{
+		UINT size;
+
+		*data = b->Buf;
+		size = b->Size;
+
+		Free(b);
+
+		return size;
+	}
+
+	r = EthGetPacketLinuxIpRawForSock(e, data, e->RawTcp, IP_PROTO_TCP);
+	if (r == 0)
+	{
+		r = EthGetPacketLinuxIpRawForSock(e, data, e->RawUdp, IP_PROTO_UDP);
+		if (r == 0)
+		{
+			r = EthGetPacketLinuxIpRawForSock(e, data, e->RawIcmp, IP_PROTO_ICMPV4);
+		}
+	}
+
+	if (r == INFINITE)
+	{
+		e->RawIp_HasError = true;
+	}
+
+	return r;
+}
+
+// Receive an IP raw packet for the specified socket
+UINT EthGetPacketLinuxIpRawForSock(ETH *e, void **data, SOCK *s, UINT proto)
+{
+	UCHAR *tmp;
+	UINT r;
+	IP src_addr;
+	UINT src_port;
+	UINT ret = INFINITE;
+	UCHAR *retbuf;
+	PKT *p;
+	bool ok = false;
+	// Validate arguments
+	if (e == NULL || data == NULL)
+	{
+		return INFINITE;
+	}
+
+	tmp = e->RawIP_TmpBuffer;
+
+LABEL_RETRY:
+	*data = NULL;
+
+	r = RecvFrom(s, &src_addr, &src_port, tmp, e->RawIP_TmpBufferSize);
+	if (r == SOCK_LATER)
+	{
+		return 0;
+	}
+
+	if (r == 0)
+	{
+		if (s->IgnoreRecvErr)
+		{
+			return 0;
+		}
+		else
+		{
+			return INFINITE;
+		}
+	}
+
+	ret = 14 + r;
+	retbuf = Malloc(ret);
+	*data = retbuf;
+
+	Copy(retbuf, e->RawIpYourMacAddr, 6);
+	Copy(retbuf + 6, e->RawIpMyMacAddr, 6);
+	retbuf[12] = 0x08;
+	retbuf[13] = 0x00;
+	Copy(retbuf + 14, tmp, r);
+
+	// Mangle packet
+	p = ParsePacket(retbuf, ret);
+	if (p != NULL)
+	{
+		if (p->TypeL3 == L3_IPV4)
+		{
+			IPV4_HEADER *ip;
+			IP original_dest_ip;
+
+			ip = p->L3.IPv4Header;
+
+			UINTToIP(&original_dest_ip, ip->DstIP);
+
+			if (IsZeroIP(&e->MyPhysicalIPForce) == false && CmpIpAddr(&e->MyPhysicalIPForce, &original_dest_ip) == 0 ||
+				(IsIPMyHost(&original_dest_ip) && IsLocalHostIP(&original_dest_ip) == false && IsHostIPAddress4(&original_dest_ip)))
+			{
+				if (IsZeroIP(&e->MyPhysicalIPForce) && CmpIpAddr(&e->MyPhysicalIP, &original_dest_ip) != 0)
+				{
+					// Update MyPhysicalIP
+					Copy(&e->MyPhysicalIP, &original_dest_ip, sizeof(IP));
+//					Debug("e->MyPhysicalIP = %r\n", &e->MyPhysicalIP);
+				}
+
+				if (IsZeroIP(&e->MyPhysicalIPForce) == false)
+				{
+					Copy(&e->MyPhysicalIP, &e->MyPhysicalIPForce, sizeof(IP));
+				}
+
+				ip->DstIP = IPToUINT(&e->YourIP);
+				ip->Checksum = 0;
+				ip->Checksum = IpChecksum(ip, IPV4_GET_HEADER_LEN(ip) * 5);
+
+				if (p->TypeL4 == L4_TCP)
+				{
+					TCP_HEADER *tcp = p->L4.TCPHeader;
+/*
+					if (Endian16(tcp->SrcPort) == 80)
+					{
+						IP a, b;
+						UINTToIP(&a, ip->SrcIP);
+						UINTToIP(&b, ip->DstIP);
+						Debug("%r %r %u %u\n", &a, &b, Endian16(tcp->SrcPort), Endian16(tcp->DstPort));
+					}*/
+
+					ok = true;
+				}
+				else if (p->TypeL4 == L4_UDP)
+				{
+					UDP_HEADER *udp = p->L4.UDPHeader;
+
+					udp->Checksum = 0;
+
+					ok = true;
+				}
+				else if (p->TypeL4 == L4_ICMPV4)
+				{
+					ICMP_HEADER *icmp = p->L4.ICMPHeader;
+
+					if (icmp->Type == ICMP_TYPE_DESTINATION_UNREACHABLE || icmp->Type == ICMP_TYPE_TIME_EXCEEDED)
+					{
+						// Rewrite the Src IP of the IPv4 header of the ICMP response packet
+						UINT size = p->PacketSize - ((UCHAR *)icmp - (UCHAR *)p->PacketData);
+						UCHAR *data = (UCHAR *)icmp;
+						IPV4_HEADER *orig_ipv4 = (IPV4_HEADER *)(((UCHAR *)data) + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO));
+						UINT orig_ipv4_size = size - (sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO));
+
+						UINT orig_ipv4_header_size = GetIpHeaderSize((UCHAR *)orig_ipv4, orig_ipv4_size);
+
+						if (orig_ipv4_header_size >= sizeof(IPV4_HEADER) && orig_ipv4_size >= orig_ipv4_header_size)
+						{
+							if (orig_ipv4->Protocol == IP_PROTO_ICMPV4)
+							{
+								// Search the inner ICMP header
+								UINT inner_icmp_size = orig_ipv4_size - orig_ipv4_header_size;
+
+								if (inner_icmp_size >= (sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO)))
+								{
+									ICMP_HEADER *inner_icmp = (ICMP_HEADER *)(((UCHAR *)data) +
+										sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO) + orig_ipv4_header_size);
+
+									if (inner_icmp->Type == ICMP_TYPE_ECHO_REQUEST)
+									{
+										ICMP_ECHO *inner_echo = (ICMP_ECHO *)(((UCHAR *)inner_icmp) + sizeof(ICMP_HEADER));
+
+										inner_icmp->Checksum = 0;
+										orig_ipv4->SrcIP = IPToUINT(&e->YourIP);
+										orig_ipv4->Checksum = 0;
+										orig_ipv4->Checksum = IpChecksum(orig_ipv4, orig_ipv4_header_size);
+
+										// Rewrite the outer ICMP header
+										if (true)
+										{
+											UCHAR *payload;
+											UINT payload_size;
+											ICMP_ECHO *echo;
+
+											// Echo Response
+											echo = (ICMP_ECHO *)(((UCHAR *)data) + sizeof(ICMP_HEADER));
+
+											if (size >= (sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO)))
+											{
+												payload = ((UCHAR *)data) + sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO);
+												payload_size = size - (sizeof(ICMP_HEADER) + sizeof(ICMP_ECHO));
+
+												// Rewrite the header
+												icmp->Checksum = 0;
+												icmp->Checksum = IpChecksum(icmp, size);
+											}
+										}
+									}
+								}
+							}
+						}
+					}
+
+					icmp->Checksum = 0;
+					icmp->Checksum = IpChecksum(icmp, p->PayloadSize);
+
+					ok = true;
+				}
+				else if (p->TypeL4 == L4_FRAGMENT)
+				{
+					ok = true;
+				}
+			}
+		}
+
+		FreePacket(p);
+	}
+
+	if (ok == false)
+	{
+		Free(*data);
+		*data = NULL;
+
+		goto LABEL_RETRY;
+	}
+
+	return ret;
+}
+
+// Send internal IP packet (insert into the send queue)
+void EthSendIpPacketInnerIpRaw(ETH *e, void *data, UINT size, USHORT protocol)
+{
+	BUF *b;
+	if (e == NULL || data == NULL || size == 0)
+	{
+		return;
+	}
+
+	if (e->RawIpSendQueue->num_item >= 1024)
+	{
+		return;
+	}
+
+	b = NewBuf();
+	WriteBuf(b, e->RawIpYourMacAddr, 6);
+	WriteBuf(b, e->RawIpMyMacAddr, 6);
+	WriteBufShort(b, protocol);
+	WriteBuf(b, data, size);
+	SeekBufToBegin(b);
+
+	InsertQueue(e->RawIpSendQueue, b);
+}
+
+// Process the packet internal if necessary
+bool EthProcessIpPacketInnerIpRaw(ETH *e, PKT *p)
+{
+	bool ret = false;
+	if (e == NULL || p == NULL)
+	{
+		return false;
+	}
+
+	if (p->TypeL3 == L3_ARPV4)
+	{
+		// ARP processing
+		ARPV4_HEADER *arp = p->L3.ARPv4Header;
+
+		if (Endian16(arp->HardwareType) == ARP_HARDWARE_TYPE_ETHERNET &&
+			Endian16(arp->ProtocolType) == MAC_PROTO_IPV4 &&
+			arp->HardwareSize == 6 && arp->ProtocolType == 4)
+		{
+			if (IPToUINT(&e->MyIP) == arp->TargetIP)
+			{
+				if (Endian16(arp->Operation) == ARP_OPERATION_REQUEST)
+				{
+					ARPV4_HEADER r;
+
+					Zero(&r, sizeof(r));
+					r.HardwareType = Endian16(ARP_HARDWARE_TYPE_ETHERNET);
+					r.ProtocolType = Endian16(MAC_PROTO_IPV4);
+					r.HardwareSize = 6;
+					r.ProtocolSize = 4;
+					r.Operation = Endian16(ARP_OPERATION_RESPONSE);
+					Copy(r.SrcAddress, e->RawIpMyMacAddr, 6);
+					Copy(r.TargetAddress, arp->SrcAddress, 6);
+					r.SrcIP = IPToUINT(&e->MyIP);
+					r.TargetIP = arp->SrcIP;
+
+					EthSendIpPacketInnerIpRaw(e, &r, sizeof(ARPV4_HEADER), MAC_PROTO_ARPV4);
+				}
+			}
+		}
+	}
+	else if (p->TypeL3 == L3_IPV4 && p->TypeL4 == L4_UDP && p->TypeL7 == L7_DHCPV4)
+	{
+		// DHCP processing
+		DHCPV4_HEADER *dhcp;
+		UCHAR *data;
+		UINT size;
+		UINT dhcp_header_size;
+		UINT dhcp_data_offset;
+		UINT tran_id;
+		UINT magic_cookie = Endian32(DHCP_MAGIC_COOKIE);
+		bool ok;
+		DHCP_OPTION_LIST *opt;
+
+		dhcp = p->L7.DHCPv4Header;
+		tran_id = Endian32(dhcp->TransactionId);
+
+		// Get the DHCP data and size
+		dhcp_header_size = sizeof(DHCPV4_HEADER);
+		dhcp_data_offset = (UINT)(((UCHAR *)p->L7.DHCPv4Header) - ((UCHAR *)p->MacHeader) + dhcp_header_size);
+		data = ((UCHAR *)dhcp) + dhcp_header_size;
+		size = p->PacketSize - dhcp_data_offset;
+		if (dhcp_header_size < 5)
+		{
+			// Data size is invalid
+			return false;
+		}
+
+		// Search for Magic Cookie
+		ok = false;
+		while (size >= 5)
+		{
+			if (Cmp(data, &magic_cookie, sizeof(magic_cookie)) == 0)
+			{
+				// Found
+				data += 4;
+				size -= 4;
+				ok = true;
+				break;
+			}
+			data++;
+			size--;
+		}
+
+		if (ok == false)
+		{
+			// The packet is invalid
+			return false;
+		}
+
+		// Parse DHCP options list
+		opt = ParseDhcpOptionList(data, size);
+		if (opt == NULL)
+		{
+			// The packet is invalid
+			return false;
+		}
+
+		if (dhcp->OpCode == 1 && (opt->Opcode == DHCP_DISCOVER || opt->Opcode == DHCP_REQUEST || opt->Opcode == DHCP_INFORM))
+		{
+			// Operate as the server
+			UINT ip = IPToUINT(&e->YourIP);
+			if (ip != 0 || opt->Opcode == DHCP_INFORM)
+			{
+				// Respond if there is providable IP address
+				DHCP_OPTION_LIST ret;
+				LIST *o;
+				UINT hw_type;
+				UINT hw_addr_size;
+				UINT new_ip = ip;
+				IP default_dns;
+
+				Zero(&default_dns, sizeof(default_dns));
+
+				Zero(&ret, sizeof(ret));
+
+				ret.Opcode = (opt->Opcode == DHCP_DISCOVER ? DHCP_OFFER : DHCP_ACK);
+				ret.ServerAddress = IPToUINT(&e->MyIP);
+				ret.LeaseTime = 3600;
+				if (opt->Opcode == DHCP_INFORM)
+				{
+					ret.LeaseTime = 0;
+				}
+
+				ret.SubnetMask = SetIP32(255, 255, 255, 252);
+
+				if (UnixGetDefaultDns(&default_dns) && IsZeroIp(&default_dns) == false)
+				{
+					ret.DnsServer = IPToUINT(&default_dns);
+					ret.DnsServer2 = SetIP32(8, 8, 8, 8);
+				}
+				else
+				{
+					ret.DnsServer = SetIP32(8, 8, 8, 8);
+					ret.DnsServer2 = SetIP32(8, 8, 4, 4);
+				}
+
+				ret.Gateway = IPToUINT(&e->MyIP);
+
+				if (opt->Opcode != DHCP_INFORM)
+				{
+					char client_mac[MAX_SIZE];
+					char client_ip[64];
+					IP ips;
+					BinToStr(client_mac, sizeof(client_mac), p->MacAddressSrc, 6);
+					UINTToIP(&ips, ip);
+					IPToStr(client_ip, sizeof(client_ip), &ips);
+					Debug("IP_RAW: DHCP %s : %s given %s\n",
+						ret.Opcode == DHCP_OFFER ? "DHCP_OFFER" : "DHCP_ACK",
+						client_mac, client_ip);
+				}
+
+				// Build a DHCP option
+				o = BuildDhcpOption(&ret);
+				if (o != NULL)
+				{
+					BUF *b = BuildDhcpOptionsBuf(o);
+					if (b != NULL)
+					{
+						UINT dest_ip = p->L3.IPv4Header->SrcIP;
+						UINT blank_size = 128 + 64;
+						UINT dhcp_packet_size;
+						UINT magic = Endian32(DHCP_MAGIC_COOKIE);
+						DHCPV4_HEADER *dhcp;
+						void *magic_cookie_addr;
+						void *buffer_addr;
+
+						if (dest_ip == 0)
+						{
+							dest_ip = 0xffffffff;
+						}
+
+						// Calculate the DHCP packet size
+						dhcp_packet_size = blank_size + sizeof(DHCPV4_HEADER) + sizeof(magic) + b->Size;
+
+						if (dhcp_packet_size < DHCP_MIN_SIZE)
+						{
+							// Padding
+							dhcp_packet_size = DHCP_MIN_SIZE;
+						}
+
+						// Create a header
+						dhcp = ZeroMalloc(dhcp_packet_size);
+
+						dhcp->OpCode = 2;
+						dhcp->HardwareType = hw_type;
+						dhcp->HardwareAddressSize = hw_addr_size;
+						dhcp->Hops = 0;
+						dhcp->TransactionId = Endian32(tran_id);
+						dhcp->Seconds = 0;
+						dhcp->Flags = 0;
+						dhcp->YourIP = new_ip;
+						dhcp->ServerIP = IPToUINT(&e->MyIP);
+						Copy(dhcp->ClientMacAddress, p->MacAddressSrc, 6);
+
+						// Calculate the address
+						magic_cookie_addr = (((UCHAR *)dhcp) + sizeof(DHCPV4_HEADER) + blank_size);
+						buffer_addr = ((UCHAR *)magic_cookie_addr) + sizeof(magic);
+
+						// Magic Cookie
+						Copy(magic_cookie_addr, &magic, sizeof(magic));
+
+						// Buffer
+						Copy(buffer_addr, b->Buf, b->Size);
+
+						if (true)
+						{
+							UCHAR *data = ZeroMalloc(sizeof(IPV4_HEADER) + sizeof(UDP_HEADER) + dhcp_packet_size);
+							IPV4_HEADER *ipv4 = (IPV4_HEADER *)(data);
+							UDP_HEADER *udp = (UDP_HEADER *)(data + sizeof(IPV4_HEADER));
+
+							Copy(data + sizeof(IPV4_HEADER) + sizeof(UDP_HEADER), dhcp, dhcp_packet_size);
+
+							IPV4_SET_VERSION(ipv4, 4);
+							IPV4_SET_HEADER_LEN(ipv4, 5);
+							ipv4->TotalLength = Endian16(sizeof(IPV4_HEADER) + sizeof(UDP_HEADER) + dhcp_packet_size);
+							ipv4->TimeToLive = 63;
+							ipv4->Protocol = IP_PROTO_UDP;
+							ipv4->SrcIP = IPToUINT(&e->MyIP);
+							ipv4->DstIP = dest_ip;
+							ipv4->Checksum = IpChecksum(ipv4, sizeof(IPV4_HEADER));
+
+							udp->SrcPort = Endian16(NAT_DHCP_SERVER_PORT);
+							udp->DstPort = Endian16(NAT_DHCP_CLIENT_PORT);
+							udp->PacketLength = Endian16(sizeof(UDP_HEADER) + dhcp_packet_size);
+							udp->Checksum = CalcChecksumForIPv4(ipv4->SrcIP, ipv4->DstIP, IP_PROTO_UDP,
+								dhcp, dhcp_packet_size, 0);
+							if (udp->Checksum == 0)
+							{
+								udp->Checksum = 0xffff;
+							}
+
+							EthSendIpPacketInnerIpRaw(e, data, sizeof(IPV4_HEADER) + sizeof(UDP_HEADER) + dhcp_packet_size, MAC_PROTO_IPV4);
+
+							Free(data);
+						}
+
+						// Release the memory
+						Free(dhcp);
+						FreeBuf(b);
+					}
+					FreeDhcpOptions(o);
+				}
+			}
+		}
+
+		Free(opt);
+	}
+
+	return ret;
+}
+
+// Send an IP raw packet
+void EthPutPacketLinuxIpRaw(ETH *e, void *data, UINT size)
+{
+	PKT *p;
+	// Validate arguments
+	if (e == NULL || data == NULL)
+	{
+		return;
+	}
+	if (size < 14 || size > MAX_PACKET_SIZE || e->RawIp_HasError)
+	{
+		Free(data);
+		return;
+	}
+
+	p = ParsePacket(data, size);
+
+	if (p->BroadcastPacket || Cmp(p->MacAddressDest, e->RawIpMyMacAddr, 6) == 0)
+	{
+		if (IsValidUnicastMacAddress(p->MacAddressSrc))
+		{
+			Copy(e->RawIpYourMacAddr, p->MacAddressSrc, 6);
+		}
+	}
+
+	if (IsZero(e->RawIpYourMacAddr, 6) || IsValidUnicastMacAddress(p->MacAddressSrc) == false ||
+		(p->BroadcastPacket == false && Cmp(p->MacAddressDest, e->RawIpMyMacAddr, 6) != 0))
+	{
+		Free(data);
+		FreePacket(p);
+		return;
+	}
+
+	if (p != NULL)
+	{
+		SOCK *s = NULL;
+
+		if (p->TypeL3 == L3_IPV4)
+		{
+			if (p->TypeL4 == L4_TCP)
+			{
+				if (IsZeroIP(&e->MyPhysicalIP) == false)
+				{
+					s = e->RawTcp;
+				}
+			}
+			else if (p->TypeL4 == L4_UDP)
+			{
+				if (EthProcessIpPacketInnerIpRaw(e, p) == false)
+				{
+					s = e->RawUdp;
+				}
+			}
+			else if (p->TypeL4 == L4_ICMPV4)
+			{
+				if (IsZeroIP(&e->MyPhysicalIP) == false)
+				{
+					s = e->RawIcmp;
+				}
+			}
+			else if (p->TypeL4 == L4_FRAGMENT)
+			{
+				if (IsZeroIP(&e->MyPhysicalIP) == false)
+				{
+					s = e->RawIcmp;
+				}
+			}
+		}
+		else if (p->TypeL3 == L3_ARPV4)
+		{
+			EthProcessIpPacketInnerIpRaw(e, p);
+		}
+
+		if (s != NULL && p->L3.IPv4Header->DstIP != 0xffffffff && p->BroadcastPacket == false &&
+			p->L3.IPv4Header->SrcIP == IPToUINT(&e->YourIP))
+		{
+			UCHAR *send_data = p->IPv4PayloadData;
+			UCHAR *head = p->PacketData;
+			UINT remove_header_size = (UINT)(send_data - head);
+
+			if (p->PacketSize > remove_header_size)
+			{
+				IP dest;
+				UINT send_data_size = p->PacketSize - remove_header_size;
+
+				// checksum
+				if (p->TypeL4 == L4_UDP)
+				{
+					p->L4.UDPHeader->Checksum = 0;
+				}
+				else if (p->TypeL4 == L4_TCP)
+				{
+					p->L4.TCPHeader->Checksum = 0;
+					p->L4.TCPHeader->Checksum = CalcChecksumForIPv4(IPToUINT(&e->MyPhysicalIP),
+						p->L3.IPv4Header->DstIP, IP_PROTO_TCP,
+						p->L4.TCPHeader, p->IPv4PayloadSize, 0);
+				}
+
+				UINTToIP(&dest, p->L3.IPv4Header->DstIP);
+
+				if (s->RawIP_HeaderIncludeFlag == false)
+				{
+					SendTo(s, &dest, 0, send_data, send_data_size);
+				}
+				else
+				{
+					IPV4_HEADER *ip = p->L3.IPv4Header;
+
+					ip->SrcIP = IPToUINT(&e->MyPhysicalIP);
+					ip->Checksum = 0;
+					ip->Checksum = IpChecksum(ip, IPV4_GET_HEADER_LEN(ip) * 4);
+
+					SendTo(s, &dest, 0, ip, ((UCHAR *)p->PacketData - (UCHAR *)ip) + p->PacketSize);
+				}
+			}
+		}
+
+		FreePacket(p);
+	}
+
+	Free(data);
+}
+
+
 #endif	// BRIDGE_C
 
 

+ 23 - 1
src/Cedar/BridgeUnix.h

@@ -162,6 +162,19 @@ struct ETH
 
 	VLAN *Tap;					// tap
 	bool Linux_IsAuxDataSupported;	// Is PACKET_AUXDATA supported
+
+	bool IsRawIpMode;			// RAW IP mode
+	SOCK *RawTcp, *RawUdp, *RawIcmp;	// RAW sockets
+	bool RawIp_HasError;
+	UCHAR RawIpMyMacAddr[6];
+	UCHAR RawIpYourMacAddr[6];
+	IP MyIP;
+	IP YourIP;
+	QUEUE *RawIpSendQueue;
+	IP MyPhysicalIP;
+	IP MyPhysicalIPForce;
+	UCHAR *RawIP_TmpBuffer;
+	UINT RawIP_TmpBufferSize;
 };
 
 #if defined( BRIDGE_BPF ) || defined( BRIDGE_PCAP )
@@ -180,7 +193,8 @@ bool IsEthSupportedLinux();
 bool IsEthSupportedSolaris();
 bool IsEthSupportedPcap();
 TOKEN_LIST *GetEthList();
-TOKEN_LIST *GetEthListLinux();
+TOKEN_LIST *GetEthListEx(UINT *total_num_including_hidden, bool enum_normal, bool enum_rawip);
+TOKEN_LIST *GetEthListLinux(bool enum_normal, bool enum_rawip);
 TOKEN_LIST *GetEthListSolaris();
 TOKEN_LIST *GetEthListPcap();
 ETH *OpenEth(char *name, bool local, bool tapmode, char *tapaddr);
@@ -203,6 +217,14 @@ bool EthIsChangeMtuSupported(ETH *e);
 bool EthGetInterfaceDescriptionUnix(char *name, char *str, UINT size);
 bool EthIsInterfaceDescriptionSupportedUnix();
 
+ETH *OpenEthLinuxIpRaw();
+void CloseEthLinuxIpRaw(ETH *e);
+UINT EthGetPacketLinuxIpRaw(ETH *e, void **data);
+UINT EthGetPacketLinuxIpRawForSock(ETH *e, void **data, SOCK *s, UINT proto);
+void EthPutPacketLinuxIpRaw(ETH *e, void *data, UINT size);
+bool EthProcessIpPacketInnerIpRaw(ETH *e, PKT *p);
+void EthSendIpPacketInnerIpRaw(ETH *e, void *data, UINT size, USHORT protocol);
+
 #ifdef	UNIX_SOLARIS
 // Function prototype for Solaris
 bool DlipAttatchRequest(int fd, UINT devid);

+ 8 - 3
src/Cedar/BridgeWin32.c

@@ -1356,9 +1356,9 @@ TOKEN_LIST *GetEthList()
 {
 	UINT v;
 
-	return GetEthListEx(&v);
+	return GetEthListEx(&v, true, false);
 }
-TOKEN_LIST *GetEthListEx(UINT *total_num_including_hidden)
+TOKEN_LIST *GetEthListEx(UINT *total_num_including_hidden, bool enum_normal, bool enum_rawip)
 {
 	TOKEN_LIST *ret;
 	UINT i;
@@ -1371,6 +1371,11 @@ TOKEN_LIST *GetEthListEx(UINT *total_num_including_hidden)
 		return NULL;
 	}
 
+	if (enum_normal == false)
+	{
+		return NullToken();
+	}
+
 	if (total_num_including_hidden == NULL)
 	{
 		total_num_including_hidden = &dummy_int;
@@ -2139,7 +2144,7 @@ RELEASE:
 		return false;
 	}
 
-	o = GetEthListEx(&total_num);
+	o = GetEthListEx(&total_num, true, false);
 	if (o == NULL || total_num == 0)
 	{
 		FreeToken(o);

+ 7 - 1
src/Cedar/BridgeWin32.h

@@ -213,6 +213,12 @@ struct ETH
 
 	SU *Su;						// SeLow handle
 	SU_ADAPTER *SuAdapter;		// SeLow adapter handle
+
+	// Unused
+	bool IsRawIpMode;			// RAW IP mode
+	UCHAR RawIpMyMacAddr[6];
+	UCHAR RawIpYourMacAddr[6];
+	IP MyPhysicalIPForce;
 };
 
 // Function prototype
@@ -221,7 +227,7 @@ void FreeEth();
 bool IsEthSupported();
 bool IsEthSupportedInner();
 TOKEN_LIST *GetEthList();
-TOKEN_LIST *GetEthListEx(UINT *total_num_including_hidden);
+TOKEN_LIST *GetEthListEx(UINT *total_num_including_hidden, bool enum_normal, bool enum_rawip);
 ETH *OpenEth(char *name, bool local, bool tapmode, char *tapaddr);
 ETH *OpenEthInternal(char *name, bool local, bool tapmode, char *tapaddr);
 void CloseEth(ETH *e);

+ 28 - 0
src/Cedar/Cedar.c

@@ -118,6 +118,34 @@ static UINT init_cedar_counter = 0;
 static REF *cedar_log_ref = NULL;
 static LOG *cedar_log;
 
+// Check whether there is any EAP-enabled RADIUS configuration
+bool CedarIsThereAnyEapEnabledRadiusConfig(CEDAR *c)
+{
+	bool ret = false;
+	UINT i;
+	if (c == NULL)
+	{
+		return false;
+	}
+
+	LockHubList(c);
+	{
+		for (i = 0;i < LIST_NUM(c->HubList);i++)
+		{
+			HUB *hub = LIST_DATA(c->HubList, i);
+
+			if (hub->RadiusConvertAllMsChapv2AuthRequestToEap)
+			{
+				ret = true;
+				break;
+			}
+		}
+	}
+	UnlockHubList(c);
+
+	return ret;
+}
+
 // Get build date of current code
 UINT64 GetCurrentBuildDate()
 {

+ 7 - 6
src/Cedar/Cedar.h

@@ -135,10 +135,10 @@
 
 
 // Version number
-#define	CEDAR_VER					418
+#define	CEDAR_VER					419
 
 // Build Number
-#define	CEDAR_BUILD					9570
+#define	CEDAR_BUILD					9582
 
 // Beta number
 //#define	BETA_NUMBER					3
@@ -158,11 +158,11 @@
 
 // Specifies the build date
 #define	BUILD_DATE_Y		2015
-#define	BUILD_DATE_M		7
-#define	BUILD_DATE_D		26
+#define	BUILD_DATE_M		10
+#define	BUILD_DATE_D		6
 #define	BUILD_DATE_HO		14
-#define	BUILD_DATE_MI		59
-#define	BUILD_DATE_SE		55
+#define	BUILD_DATE_MI		56
+#define	BUILD_DATE_SE		30
 
 // Tolerable time difference
 #define	ALLOW_TIMESTAMP_DIFF		(UINT64)(3 * 24 * 60 * 60 * 1000)
@@ -1259,6 +1259,7 @@ UINT CedarGetQueueBudgetConsuming(CEDAR *c);
 UINT CedarGetFifoBudgetConsuming(CEDAR *c);
 UINT CedarGetQueueBudgetBalance(CEDAR *c);
 UINT CedarGetFifoBudgetBalance(CEDAR *c);
+bool CedarIsThereAnyEapEnabledRadiusConfig(CEDAR *c);
 
 
 

+ 12 - 0
src/Cedar/CedarType.h

@@ -142,6 +142,16 @@ typedef struct AUTHNT AUTHNT;
 // ==============================================================
 
 typedef struct RADIUS_LOGIN_OPTION RADIUS_LOGIN_OPTION;
+typedef struct RADIUS_PACKET RADIUS_PACKET;
+typedef struct RADIUS_AVP RADIUS_AVP;
+typedef struct EAP_CLIENT EAP_CLIENT;
+typedef struct EAP_MESSAGE EAP_MESSAGE;
+typedef struct EAP_MSCHAPV2_GENERAL EAP_MSCHAPV2_GENERAL;
+typedef struct EAP_MSCHAPV2_CHALLENGE EAP_MSCHAPV2_CHALLENGE;
+typedef struct EAP_MSCHAPV2_RESPONSE EAP_MSCHAPV2_RESPONSE;
+typedef struct EAP_MSCHAPV2_SUCCESS_SERVER EAP_MSCHAPV2_SUCCESS_SERVER;
+typedef struct EAP_MSCHAPV2_SUCCESS_CLIENT EAP_MSCHAPV2_SUCCESS_CLIENT;
+typedef struct EAP_PEAP EAP_PEAP;
 
 
 // ==============================================================
@@ -738,6 +748,8 @@ typedef struct MIRROR_SERVER MIRROR_SERVER;
 // ==============================================================
 
 typedef struct NATIVE_STACK NATIVE_STACK;
+typedef struct IPTABLES_STATE IPTABLES_STATE;
+typedef struct IPTABLES_ENTRY IPTABLES_ENTRY;
 
 
 // ==============================================================

+ 1 - 0
src/Cedar/Command.c

@@ -18309,6 +18309,7 @@ UINT PsSecureNatStatusGet(CONSOLE *c, char *cmd_name, wchar_t *str, void *param)
 		CtInsert(ct, _UU("NM_STATUS_DHCP"), tmp);
 
 		CtInsert(ct, _UU("SM_SNAT_IS_KERNEL"), t.IsKernelMode ? _UU("SEC_YES") : _UU("SEC_NO"));
+		CtInsert(ct, _UU("SM_SNAT_IS_RAW"), t.IsRawIpMode ? _UU("SEC_YES") : _UU("SEC_NO"));
 
 		CtFree(ct, c);
 	}

+ 101 - 0
src/Cedar/Hub.c

@@ -166,6 +166,103 @@ ADMIN_OPTION admin_options[] =
 
 UINT num_admin_options = sizeof(admin_options) / sizeof(ADMIN_OPTION);
 
+
+// Create an EAP client for the specified Virtual Hub
+EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, char *username)
+{
+	HUB *hub = NULL;
+	EAP_CLIENT *ret = NULL;
+	char radius_servers[MAX_PATH] = {0};
+	UINT radius_port = 0;
+	UINT radius_retry_interval = 0;
+	char radius_secret[MAX_PATH] = {0};
+	char radius_suffix_filter[MAX_PATH] = {0};
+	if (cedar == NULL || hubname == NULL || client_ip_str == NULL || username == NULL)
+	{
+		return NULL;
+	}
+
+	// Find the Virtual Hub
+	LockHubList(cedar);
+	{
+		hub = GetHub(cedar, hubname);
+	}
+	UnlockHubList(cedar);
+
+	if (hub != NULL)
+	{
+		if (GetRadiusServerEx2(hub, radius_servers, sizeof(radius_servers), &radius_port, radius_secret,
+			sizeof(radius_secret), &radius_retry_interval, radius_suffix_filter, sizeof(radius_suffix_filter)))
+		{
+			bool use_peap = hub->RadiusUsePeapInsteadOfEap;
+
+			if (IsEmptyStr(radius_suffix_filter) || EndWith(username, radius_suffix_filter))
+			{
+				TOKEN_LIST *radius_servers_list = ParseToken(radius_servers, " ,;\t");
+
+				if (radius_servers_list != NULL && radius_servers_list->NumTokens >= 1)
+				{
+					// Try for each of RADIUS servers
+					UINT i;
+					bool finish = false;
+
+					for (i = 0;i < radius_servers_list->NumTokens;i++)
+					{
+						EAP_CLIENT *eap;
+						IP ip;
+
+						if (GetIP(&ip, radius_servers_list->Token[i]))
+						{
+							eap = NewEapClient(&ip, radius_port, radius_secret, radius_retry_interval,
+								RADIUS_INITIAL_EAP_TIMEOUT, client_ip_str, username);
+
+							if (eap != NULL)
+							{
+								if (use_peap == false)
+								{
+									// EAP
+									if (EapClientSendMsChapv2AuthRequest(eap))
+									{
+										eap->GiveupTimeout = RADIUS_RETRY_TIMEOUT;
+										ret = eap;
+										finish = true;
+									}
+								}
+								else
+								{
+									// PEAP
+									if (PeapClientSendMsChapv2AuthRequest(eap))
+									{
+										eap->GiveupTimeout = RADIUS_RETRY_TIMEOUT;
+										ret = eap;
+										finish = true;
+									}
+								}
+
+								if (finish == false)
+								{
+									ReleaseEapClient(eap);
+								}
+							}
+						}
+
+						if (finish)
+						{
+							break;
+						}
+					}
+				}
+
+				FreeToken(radius_servers_list);
+			}
+		}
+	}
+
+	ReleaseHub(hub);
+
+	return ret;
+}
+
 // Create a user list
 LIST *NewUserList()
 {
@@ -587,6 +684,7 @@ void DataToHubOptionStruct(HUB_OPTION *o, RPC_ADMIN_OPTION *ao)
 	GetHubAdminOptionDataAndSet(ao, "SecureNAT_MaxIcmpSessionsPerIp", &o->SecureNAT_MaxIcmpSessionsPerIp);
 	GetHubAdminOptionDataAndSet(ao, "AccessListIncludeFileCacheLifetime", &o->AccessListIncludeFileCacheLifetime);
 	GetHubAdminOptionDataAndSet(ao, "DisableKernelModeSecureNAT", &o->DisableKernelModeSecureNAT);
+	GetHubAdminOptionDataAndSet(ao, "DisableIpRawModeSecureNAT", &o->DisableIpRawModeSecureNAT);
 	GetHubAdminOptionDataAndSet(ao, "DisableUserModeSecureNAT", &o->DisableUserModeSecureNAT);
 	GetHubAdminOptionDataAndSet(ao, "DisableCheckMacOnLocalBridge", &o->DisableCheckMacOnLocalBridge);
 	GetHubAdminOptionDataAndSet(ao, "DisableCorrectIpOffloadChecksum", &o->DisableCorrectIpOffloadChecksum);
@@ -598,6 +696,7 @@ void DataToHubOptionStruct(HUB_OPTION *o, RPC_ADMIN_OPTION *ao)
 	GetHubAdminOptionDataAndSet(ao, "SuppressClientUpdateNotification", &o->SuppressClientUpdateNotification);
 	GetHubAdminOptionDataAndSet(ao, "FloodingSendQueueBufferQuota", &o->FloodingSendQueueBufferQuota);
 	GetHubAdminOptionDataAndSet(ao, "AssignVLanIdByRadiusAttribute", &o->AssignVLanIdByRadiusAttribute);
+	GetHubAdminOptionDataAndSet(ao, "DenyAllRadiusLoginWithNoVlanAssign", &o->DenyAllRadiusLoginWithNoVlanAssign);
 	GetHubAdminOptionDataAndSet(ao, "SecureNAT_RandomizeAssignIp", &o->SecureNAT_RandomizeAssignIp);
 	GetHubAdminOptionDataAndSet(ao, "DetectDormantSessionInterval", &o->DetectDormantSessionInterval);
 	GetHubAdminOptionDataAndSet(ao, "NoPhysicalIPOnPacketLog", &o->NoPhysicalIPOnPacketLog);
@@ -658,6 +757,7 @@ void HubOptionStructToData(RPC_ADMIN_OPTION *ao, HUB_OPTION *o, char *hub_name)
 	Add(aol, NewAdminOption("SecureNAT_MaxIcmpSessionsPerIp", o->SecureNAT_MaxIcmpSessionsPerIp));
 	Add(aol, NewAdminOption("AccessListIncludeFileCacheLifetime", o->AccessListIncludeFileCacheLifetime));
 	Add(aol, NewAdminOption("DisableKernelModeSecureNAT", o->DisableKernelModeSecureNAT));
+	Add(aol, NewAdminOption("DisableIpRawModeSecureNAT", o->DisableIpRawModeSecureNAT));
 	Add(aol, NewAdminOption("DisableUserModeSecureNAT", o->DisableUserModeSecureNAT));
 	Add(aol, NewAdminOption("DisableCheckMacOnLocalBridge", o->DisableCheckMacOnLocalBridge));
 	Add(aol, NewAdminOption("DisableCorrectIpOffloadChecksum", o->DisableCorrectIpOffloadChecksum));
@@ -669,6 +769,7 @@ void HubOptionStructToData(RPC_ADMIN_OPTION *ao, HUB_OPTION *o, char *hub_name)
 	Add(aol, NewAdminOption("SuppressClientUpdateNotification", o->SuppressClientUpdateNotification));
 	Add(aol, NewAdminOption("FloodingSendQueueBufferQuota", o->FloodingSendQueueBufferQuota));
 	Add(aol, NewAdminOption("AssignVLanIdByRadiusAttribute", o->AssignVLanIdByRadiusAttribute));
+	Add(aol, NewAdminOption("DenyAllRadiusLoginWithNoVlanAssign", o->DenyAllRadiusLoginWithNoVlanAssign));
 	Add(aol, NewAdminOption("SecureNAT_RandomizeAssignIp", o->SecureNAT_RandomizeAssignIp));
 	Add(aol, NewAdminOption("DetectDormantSessionInterval", o->DetectDormantSessionInterval));
 	Add(aol, NewAdminOption("NoPhysicalIPOnPacketLog", o->NoPhysicalIPOnPacketLog));

+ 5 - 0
src/Cedar/Hub.h

@@ -265,6 +265,7 @@ struct HUB_OPTION
 	UINT SecureNAT_MaxIcmpSessionsPerIp;	// Maximum number of ICMP sessions per IP address
 	UINT AccessListIncludeFileCacheLifetime;	// Expiration of the access list external file (in seconds)
 	bool DisableKernelModeSecureNAT;			// Disable the kernel mode NAT
+	bool DisableIpRawModeSecureNAT;			// Disable the IP Raw Mode NAT
 	bool DisableUserModeSecureNAT;			// Disable the user mode NAT
 	bool DisableCheckMacOnLocalBridge;	// Disable the MAC address verification in local bridge
 	bool DisableCorrectIpOffloadChecksum;	// Disable the correction of checksum that is IP-Offloaded
@@ -276,6 +277,7 @@ struct HUB_OPTION
 	bool SuppressClientUpdateNotification;	// Suppress the update notification function on the VPN Client
 	UINT FloodingSendQueueBufferQuota;	// The global quota of send queues of flooding packets
 	bool AssignVLanIdByRadiusAttribute;	// Assign the VLAN ID for the VPN session, by the attribute value of RADIUS
+	bool DenyAllRadiusLoginWithNoVlanAssign;	// Deny all RADIUS login with no VLAN ID assigned
 	bool SecureNAT_RandomizeAssignIp;	// Randomize the assignment IP address for new DHCP client
 	UINT DetectDormantSessionInterval;	// Interval (seconds) threshold to detect a dormant VPN session
 	bool NoPhysicalIPOnPacketLog;		// Disable saving physical IP address on the packet log
@@ -436,6 +438,8 @@ struct HUB
 	UINT RadiusRetryInterval;			// Radius retry interval
 	BUF *RadiusSecret;					// Radius shared key
 	char RadiusSuffixFilter[MAX_SIZE];	// Radius suffix filter
+	bool RadiusConvertAllMsChapv2AuthRequestToEap;	// Convert all MS-CHAPv2 auth request to EAP
+	bool RadiusUsePeapInsteadOfEap;			// Use PEAP instead of EAP
 	volatile bool Halt;					// Halting flag
 	bool Offline;						// Offline
 	bool BeingOffline;					// Be Doing Offline
@@ -638,6 +642,7 @@ void CalcTrafficDiff(TRAFFIC *diff, TRAFFIC *old, TRAFFIC *current);
 bool CheckMaxLoggedPacketsPerMinute(SESSION *s, UINT max_packets, UINT64 now);
 void VgsSetUserAgentValue(char *str);
 void VgsSetEmbTag(bool b);
+EAP_CLIENT *HubNewEapClient(CEDAR *cedar, char *hubname, char *client_ip_str, char *username);
 
 #endif	// HUB_H
 

+ 1 - 1
src/Cedar/IPsec_EtherIP.c

@@ -170,7 +170,7 @@ void EtherIPIpcConnectThread(THREAD *t, void *p)
 			&s->ClientIP, s->ClientPort,
 			&s->ServerIP, s->ServerPort,
 			tmp,
-			s->CryptName, true, mss);
+			s->CryptName, true, mss, NULL);
 
 		if (ipc != NULL)
 		{

+ 15 - 1
src/Cedar/IPsec_IKE.c

@@ -113,6 +113,7 @@
 
 #include "CedarPch.h"
 
+//#define	RAW_DEBUG
 
 // Processing of IKE received packet
 void ProcIKEPacketRecv(IKE_SERVER *ike, UDPPACKET *p)
@@ -753,7 +754,7 @@ void ProcIPsecEspPacketRecv(IKE_SERVER *ike, UDPPACKET *p)
 				// Transport mode
 				if (next_header == IP_PROTO_UDP)
 				{
-					if (ike->IPsec->Services.L2TP_IPsec)
+					if (ike->IPsec->Services.L2TP_IPsec || ike->IPsec->Services.EtherIP_IPsec)
 					{
 						// An UDP packet has been received
 						ProcIPsecUdpPacketRecv(ike, c, dec_data, dec_size);
@@ -791,6 +792,19 @@ void ProcIPsecEspPacketRecv(IKE_SERVER *ike, UDPPACKET *p)
 		if (ipsec_sa->PairIPsecSa != NULL)
 		{
 			c->CurrentIpSecSaSend = ipsec_sa->PairIPsecSa;
+
+			if (p->DestPort == IPSEC_PORT_IPSEC_ESP_UDP)
+			{
+				IPSECSA *send_sa = c->CurrentIpSecSaSend;
+				if (send_sa->TransformSetting.CapsuleMode == IKE_P2_CAPSULE_TUNNEL)
+				{
+					send_sa->TransformSetting.CapsuleMode = IKE_P2_CAPSULE_NAT_TUNNEL_1;
+				}
+				else if (send_sa->TransformSetting.CapsuleMode == IKE_P2_CAPSULE_TRANSPORT)
+				{
+					send_sa->TransformSetting.CapsuleMode = IKE_P2_CAPSULE_NAT_TRANSPORT_1;
+				}
+			}
 		}
 		c->LastCommTick = ike->Now;
 		ipsec_sa->LastCommTick = ike->Now;

+ 21 - 5
src/Cedar/IPsec_IPC.c

@@ -133,20 +133,27 @@ bool ParseAndExtractMsChapV2InfoFromPassword(IPC_MSCHAP_V2_AUTHINFO *d, char *pa
 
 	t = ParseTokenWithNullStr(password, ":");
 
-	if (t->NumTokens == 5)
+	if (t->NumTokens == 6)
 	{
-		BUF *b1, *b2, *b3;
+		BUF *b1, *b2, *b3, *b4;
 
 		b1 = StrToBin(t->Token[2]);
 		b2 = StrToBin(t->Token[3]);
 		b3 = StrToBin(t->Token[4]);
+		b4 = StrToBin(t->Token[5]);
 
-		if (IsEmptyStr(t->Token[1]) == false && b1->Size == 16 && b2->Size == 16 && b3->Size == 24)
+		if (IsEmptyStr(t->Token[1]) == false && b1->Size == 16 && b2->Size == 16 && b3->Size == 24
+			 && b4->Size == 8)
 		{
+			UINT64 eap_client_ptr = 0;
+
 			StrCpy(d->MsChapV2_PPPUsername, sizeof(d->MsChapV2_PPPUsername), t->Token[1]);
 			Copy(d->MsChapV2_ServerChallenge, b1->Buf, 16);
 			Copy(d->MsChapV2_ClientChallenge, b2->Buf, 16);
 			Copy(d->MsChapV2_ClientResponse, b3->Buf, 24);
+			Copy(&eap_client_ptr, b4->Buf, 8);
+
+			d->MsChapV2_EapClient = (EAP_CLIENT *)eap_client_ptr;
 
 			ret = true;
 		}
@@ -154,6 +161,7 @@ bool ParseAndExtractMsChapV2InfoFromPassword(IPC_MSCHAP_V2_AUTHINFO *d, char *pa
 		FreeBuf(b1);
 		FreeBuf(b2);
 		FreeBuf(b3);
+		FreeBuf(b4);
 	}
 
 	FreeToken(t);
@@ -315,7 +323,7 @@ IPC *NewIPCByParam(CEDAR *cedar, IPC_PARAM *param, UINT *error_code)
 		param->UserName, param->Password, error_code, &param->ClientIp,
 		param->ClientPort, &param->ServerIp, param->ServerPort,
 		param->ClientHostname, param->CryptName,
-		param->BridgeMode, param->Mss);
+		param->BridgeMode, param->Mss, NULL);
 
 	return ipc;
 }
@@ -324,7 +332,7 @@ IPC *NewIPCByParam(CEDAR *cedar, IPC_PARAM *param, UINT *error_code)
 IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char *username, char *password,
 			UINT *error_code, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port,
 			char *client_hostname, char *crypt_name,
-			bool bridge_mode, UINT mss)
+			bool bridge_mode, UINT mss, EAP_CLIENT *eap_client)
 {
 	IPC *ipc;
 	UINT dummy_int = 0;
@@ -431,6 +439,14 @@ IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char
 	PackAddBool(p, "require_monitor_mode", false);
 	PackAddBool(p, "qos", false);
 
+	if (eap_client != NULL)
+	{
+		UINT64 ptr = (UINT64)eap_client;
+		PackAddInt64(p, "release_me_eap_client", ptr);
+
+		AddRef(eap_client->Ref);
+	}
+
 	// Unique ID is determined by the sum of the connecting client IP address and the client_name
 	b = NewBuf();
 	WriteBuf(b, client_ip, sizeof(IP));

+ 2 - 1
src/Cedar/IPsec_IPC.h

@@ -218,12 +218,13 @@ struct IPC_MSCHAP_V2_AUTHINFO
 	UCHAR MsChapV2_ServerChallenge[16];	// MS-CHAPv2 Server Challenge
 	UCHAR MsChapV2_ClientChallenge[16];	// MS-CHAPv2 Client Challenge
 	UCHAR MsChapV2_ClientResponse[24];	// MS-CHAPv2 Client Response
+	EAP_CLIENT *MsChapV2_EapClient;		// EAP client
 };
 
 IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char *username, char *password,
 			UINT *error_code, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port,
 			char *client_hostname, char *crypt_name,
-			bool bridge_mode, UINT mss);
+			bool bridge_mode, UINT mss, EAP_CLIENT *eap_client);
 IPC *NewIPCByParam(CEDAR *cedar, IPC_PARAM *param, UINT *error_code);
 IPC *NewIPCBySock(CEDAR *cedar, SOCK *s, void *mac_address);
 void FreeIPC(IPC *ipc);

+ 192 - 38
src/Cedar/IPsec_L2TP.c

@@ -180,7 +180,7 @@ void SendL2TPControlPacket(L2TP_SERVER *l2tp, L2TP_TUNNEL *t, UINT session_id, L
 
 	p->Nr = t->LastNr + 1;
 
-	buf = BuildL2TPPacketData(p);
+	buf = BuildL2TPPacketData(p, t);
 
 	q = ZeroMalloc(sizeof(L2TP_QUEUE));
 	q->Buf = buf;
@@ -239,15 +239,33 @@ void SendL2TPDataPacket(L2TP_SERVER *l2tp, L2TP_TUNNEL *t, L2TP_SESSION *s, void
 	else
 	{
 		// L2TPv3
-		buf_size = 4 + size;
-		buf = Malloc(buf_size);
+		if (t->IsYamahaV3 == false)
+		{
+			buf_size = 4 + size;
+			buf = Malloc(buf_size);
 
-		WRITE_UINT(buf, s->SessionId1);
+			WRITE_UINT(buf, s->SessionId1);
 
-		Copy(buf + 4, data, size);
+			Copy(buf + 4, data, size);
 
-		// Transmission
-		p = NewUdpPacket(&t->ServerIp, IPSEC_PORT_L2TPV3_VIRTUAL, &t->ClientIp, IPSEC_PORT_L2TPV3_VIRTUAL, buf, buf_size);
+			// Transmission
+			p = NewUdpPacket(&t->ServerIp, IPSEC_PORT_L2TPV3_VIRTUAL, &t->ClientIp, IPSEC_PORT_L2TPV3_VIRTUAL, buf, buf_size);
+		}
+		else
+		{
+			UINT header = 0x00030000;
+
+			buf_size = 8 + size;
+			buf = Malloc(buf_size);
+
+			WRITE_UINT(buf, header);
+			WRITE_UINT(buf + 4, s->SessionId1);
+
+			Copy(buf + 8, data, size);
+
+			// Transmission
+			p = NewUdpPacket(&t->ServerIp, t->ServerPort, &t->ClientIp, t->ClientPort, buf, buf_size);
+		}
 	}
 
 	L2TPSendUDP(l2tp, p);
@@ -285,14 +303,14 @@ void L2TPSendUDP(L2TP_SERVER *l2tp, UDPPACKET *p)
 }
 
 // Build a L2TP packet
-BUF *BuildL2TPPacketData(L2TP_PACKET *pp)
+BUF *BuildL2TPPacketData(L2TP_PACKET *pp, L2TP_TUNNEL *t)
 {
 	BUF *ret;
 	UCHAR c;
 	USHORT us;
 	UINT ui;
 	// Validate arguments
-	if (pp == NULL)
+	if (pp == NULL || t == NULL)
 	{
 		return NULL;
 	}
@@ -322,9 +340,12 @@ BUF *BuildL2TPPacketData(L2TP_PACKET *pp)
 
 	if (pp->Ver == 3)
 	{
-		// Zero as Session ID
-		ui = 0;
-		WriteBuf(ret, &ui, sizeof(UINT));
+		if (t->IsYamahaV3 == false)
+		{
+			// Zero as Session ID
+			ui = 0;
+			WriteBuf(ret, &ui, sizeof(UINT));
+		}
 	}
 
 	// Flags
@@ -339,6 +360,11 @@ BUF *BuildL2TPPacketData(L2TP_PACKET *pp)
 		c |= L2TP_HEADER_BIT_OFFSET;
 	}
 
+	if (pp->IsControl == false && pp->Ver == 3 && t->IsYamahaV3)
+	{
+		c = 0;
+	}
+
 	WriteBuf(ret, &c, 1);
 
 	// Ver
@@ -356,6 +382,13 @@ BUF *BuildL2TPPacketData(L2TP_PACKET *pp)
 		WriteBuf(ret, &us, sizeof(USHORT));
 	}
 
+	// Reserved
+	if (pp->IsControl == false && pp->Ver == 3 && t->IsYamahaV3)
+	{
+		us = 0;
+		WriteBuf(ret, &us, sizeof(USHORT));
+	}
+
 	// Tunnel ID
 	if (pp->Ver != 3)
 	{
@@ -387,9 +420,12 @@ BUF *BuildL2TPPacketData(L2TP_PACKET *pp)
 	}
 	else
 	{
-		// Offset Size = 0
-		us = 0;
-		WriteBuf(ret, &us, sizeof(USHORT));
+		if (!(pp->IsControl == false && pp->Ver == 3 && t->IsYamahaV3))
+		{
+			// Offset Size = 0
+			us = 0;
+			WriteBuf(ret, &us, sizeof(USHORT));
+		}
 	}
 
 	if (pp->IsControl)
@@ -431,7 +467,8 @@ BUF *BuildL2TPPacketData(L2TP_PACKET *pp)
 	if (pp->IsControl)
 	{
 		// Update Length
-		WRITE_USHORT(((UCHAR *)ret->Buf) + 2 + (pp->Ver == 3 ? sizeof(UINT) : 0), (USHORT)(ret->Size - (pp->Ver == 3 ? sizeof(UINT) : 0)));
+		bool l2tpv3_non_yamaha = ((pp->Ver == 3) && (t->IsYamahaV3 == false));
+		WRITE_USHORT(((UCHAR *)ret->Buf) + 2 + (l2tpv3_non_yamaha ? sizeof(UINT) : 0), (USHORT)(ret->Size - (l2tpv3_non_yamaha ? sizeof(UINT) : 0)));
 	}
 
 	SeekBuf(ret, 0, 0);
@@ -446,6 +483,7 @@ L2TP_PACKET *ParseL2TPPacket(UDPPACKET *p)
 	UCHAR *buf;
 	UINT size;
 	bool is_l2tpv3 = false;
+	bool is_l2tpv3_yamaha = false;
 	// Validate arguments
 	if (p == NULL)
 	{
@@ -456,17 +494,27 @@ L2TP_PACKET *ParseL2TPPacket(UDPPACKET *p)
 
 	if (p->SrcPort == IPSEC_PORT_L2TPV3_VIRTUAL)
 	{
-		// It is L2TPv3
+		// L2TPv3 (Cisco)
 		is_l2tpv3 = true;
 	}
 
 	buf = p->Data;
 	size = p->Size;
 
-	if (is_l2tpv3)
+	if (size >= 2 && ((buf[1] & L2TP_HEADER_BIT_VER) == 3))
 	{
+		if (p->SrcPort != IPSEC_PORT_L2TPV3_VIRTUAL)
+		{
+			// L2TPv3 (YAMAHA)
+			is_l2tpv3 = true;
+			is_l2tpv3_yamaha = true;
+		}
+	}
+
+	if (is_l2tpv3 && (is_l2tpv3_yamaha == false))
+	{
+		// L2TPv3 (Cisco)
 		UINT session_id;
-		// In the case of L2TPv3
 		if (size < 4)
 		{
 			goto LABEL_ERROR;
@@ -590,6 +638,24 @@ L2TP_PACKET *ParseL2TPPacket(UDPPACKET *p)
 		size = ret->Length - 4;
 	}
 
+	if (is_l2tpv3)
+	{
+		if (p->SrcPort != IPSEC_PORT_L2TPV3_VIRTUAL)
+		{
+			if (ret->IsControl == false)
+			{
+				// Reserved
+				if (size < 2)
+				{
+					goto LABEL_ERROR;
+				}
+
+				buf += 2;
+				size -= 2;
+			}
+		}
+	}
+
 	// Tunnel ID, Session ID
 	if (size < 4)
 	{
@@ -616,6 +682,11 @@ L2TP_PACKET *ParseL2TPPacket(UDPPACKET *p)
 
 		// The session ID is not written in the header
 		ret->SessionId = 0;
+
+		if (ret->IsControl == false)
+		{
+			ret->SessionId = ret->TunnelId;
+		}
 	}
 
 	if (ret->HasSequence)
@@ -742,7 +813,7 @@ L2TP_PACKET *ParseL2TPPacket(UDPPACKET *p)
 		ret->MessageType = READ_USHORT(a->Data);
 	}
 
-	if (ret->Ver == 3)
+	if (ret->Ver == 3 && ret->IsControl)
 	{
 		// Get the Remote Session ID in the case of L2TPv3
 		L2TP_AVP *a = GetAVPValue(ret, L2TP_AVP_TYPE_V3_SESSION_ID_REMOTE);
@@ -752,6 +823,8 @@ L2TP_PACKET *ParseL2TPPacket(UDPPACKET *p)
 		}
 	}
 
+	ret->IsYamahaV3 = is_l2tpv3_yamaha;
+
 	return ret;
 
 LABEL_ERROR:
@@ -783,6 +856,22 @@ L2TP_AVP *GetAVPValueEx(L2TP_PACKET *p, UINT type, UINT vendor_id)
 		}
 	}
 
+	if (vendor_id == 0)
+	{
+		if (type == L2TP_AVP_TYPE_V3_TUNNEL_ID)
+		{
+			return GetAVPValueEx(p, L2TPV3_CISCO_AVP_TUNNEL_ID, L2TP_AVP_VENDOR_ID_CISCO);
+		}
+		else if (type == L2TP_AVP_TYPE_V3_SESSION_ID_LOCAL)
+		{
+			return GetAVPValueEx(p, L2TPV3_CISCO_AVP_SESSION_ID_LOCAL, L2TP_AVP_VENDOR_ID_CISCO);
+		}
+		else if (type == L2TP_AVP_TYPE_V3_SESSION_ID_REMOTE)
+		{
+			return GetAVPValueEx(p, L2TPV3_CISCO_AVP_SESSION_ID_REMOTE, L2TP_AVP_VENDOR_ID_CISCO);
+		}
+	}
+
 	return NULL;
 }
 
@@ -899,6 +988,9 @@ L2TP_TUNNEL *NewL2TPTunnel(L2TP_SERVER *l2tp, L2TP_PACKET *p, UDPPACKET *udp)
 		{
 			t->IsCiscoV3 = true;
 		}
+
+		// L2TPv3 on YAMAHA
+		t->IsYamahaV3 = p->IsYamahaV3;
 	}
 
 	// Transmission queue
@@ -965,6 +1057,30 @@ L2TP_TUNNEL *GetTunnelFromIdOfAssignedByClient(L2TP_SERVER *l2tp, IP *client_ip,
 
 	return NULL;
 }
+L2TP_TUNNEL *GetTunnelFromIdOfAssignedByClientEx(L2TP_SERVER *l2tp, IP *client_ip, UINT tunnel_id, bool is_v3)
+{
+	UINT i;
+	// Validate arguments
+	if (l2tp == NULL || client_ip == 0 || tunnel_id == 0)
+	{
+		return NULL;
+	}
+
+	for (i = 0;i < LIST_NUM(l2tp->TunnelList);i++)
+	{
+		L2TP_TUNNEL *t = LIST_DATA(l2tp->TunnelList, i);
+
+		if (t->TunnelId1 == tunnel_id && CmpIpAddr(&t->ClientIp, client_ip) == 0)
+		{
+			if (EQUAL_BOOL(t->IsV3, is_v3))
+			{
+				return t;
+			}
+		}
+	}
+
+	return NULL;
+}
 
 // Create a new tunnel ID
 UINT GenerateNewTunnelId(L2TP_SERVER *l2tp, IP *client_ip)
@@ -1179,14 +1295,23 @@ void L2TPProcessRecvControlPacket(L2TP_SERVER *l2tp, L2TP_TUNNEL *t, L2TP_PACKET
 
 							if (s->IsV3)
 							{
-								// Pseudowire AVP
-								us = Endian16(s->PseudowireType);
-								Add(pp->AvpList, NewAVP(L2TP_AVP_TYPE_V3_PW_TYPE, true, 0, &us, sizeof(USHORT)));
+								if (t->IsYamahaV3 == false)
+								{
+									// Pseudowire AVP
+									us = Endian16(s->PseudowireType);
+									Add(pp->AvpList, NewAVP(L2TP_AVP_TYPE_V3_PW_TYPE, true, 0, &us, sizeof(USHORT)));
+								}
 
 								if (s->IsCiscoV3)
 								{
 									Add(pp->AvpList, NewAVP(L2TPV3_CISCO_AVP_PW_TYPE, true, L2TP_AVP_VENDOR_ID_CISCO, &us, sizeof(USHORT)));
 								}
+
+								if (t->IsYamahaV3)
+								{
+									us = Endian16(0x0003);
+									Add(pp->AvpList, NewAVP(L2TP_AVP_TYPE_V3_CIRCUIT_STATUS, true, 0, &us, sizeof(USHORT)));
+								}
 							}
 
 							SendL2TPControlPacket(l2tp, t, session_id, pp);
@@ -1563,18 +1688,21 @@ void ProcL2TPPacketRecv(L2TP_SERVER *l2tp, UDPPACKET *p)
 							// Respond with SCCEP to SCCRQ
 							pp2 = NewL2TPControlPacket(L2TP_MESSAGE_TYPE_SCCRP, t->IsV3);
 
-							// Protocol Version
-							protocol_version[0] = 1;
-							protocol_version[1] = 0;
-							Add(pp2->AvpList, NewAVP(L2TP_AVP_TYPE_PROTOCOL_VERSION, true, 0, protocol_version, sizeof(protocol_version)));
-
-							// Framing Capabilities
-							Zero(caps_data, sizeof(caps_data));
-							if (t->IsV3 == false)
+							if (t->IsYamahaV3 == false)
 							{
-								caps_data[3] = 3;
+								// Protocol Version
+								protocol_version[0] = 1;
+								protocol_version[1] = 0;
+								Add(pp2->AvpList, NewAVP(L2TP_AVP_TYPE_PROTOCOL_VERSION, true, 0, protocol_version, sizeof(protocol_version)));
+
+								// Framing Capabilities
+								Zero(caps_data, sizeof(caps_data));
+								if (t->IsV3 == false)
+								{
+									caps_data[3] = 3;
+								}
+								Add(pp2->AvpList, NewAVP(L2TP_AVP_TYPE_FRAME_CAP, false, 0, caps_data, sizeof(caps_data)));
 							}
-							Add(pp2->AvpList, NewAVP(L2TP_AVP_TYPE_FRAME_CAP, false, 0, caps_data, sizeof(caps_data)));
 
 							if (t->IsV3 == false)
 							{
@@ -1593,7 +1721,21 @@ void ProcL2TPPacketRecv(L2TP_SERVER *l2tp, UDPPACKET *p)
 							Add(pp2->AvpList, NewAVP(L2TP_AVP_TYPE_HOST_NAME, true, 0, hostname, StrLen(hostname)));
 
 							// Vendor Name
-							Add(pp2->AvpList, NewAVP(L2TP_AVP_TYPE_VENDOR_NAME, false, 0, L2TP_VENDOR_NAME, StrLen(L2TP_VENDOR_NAME)));
+							if (t->IsYamahaV3 == false)
+							{
+								Add(pp2->AvpList, NewAVP(L2TP_AVP_TYPE_VENDOR_NAME, false, 0, L2TP_VENDOR_NAME, StrLen(L2TP_VENDOR_NAME)));
+							}
+							else
+							{
+								char *yamaha_str = "YAMAHA Corporation";
+								Add(pp2->AvpList, NewAVP(L2TP_AVP_TYPE_VENDOR_NAME, false, 0, yamaha_str, StrLen(yamaha_str)));
+							}
+
+							if (t->IsYamahaV3)
+							{
+								UINT zero = 0;
+								Add(pp2->AvpList, NewAVP(L2TP_AVP_TYPE_V3_ROUTER_ID, true, 0, &zero, sizeof(UINT)));
+							}
 
 							// Assigned Tunnel ID
 							if (t->IsV3 == false)
@@ -1635,8 +1777,11 @@ void ProcL2TPPacketRecv(L2TP_SERVER *l2tp, UDPPACKET *p)
 							}
 
 							// Recv Window Size
-							us = Endian16(L2TP_WINDOW_SIZE);
-							Add(pp2->AvpList, NewAVP(L2TP_AVP_TYPE_RECV_WINDOW_SIZE, false, 0, &us, sizeof(USHORT)));
+							if (t->IsYamahaV3 == false)
+							{
+								us = Endian16(L2TP_WINDOW_SIZE);
+								Add(pp2->AvpList, NewAVP(L2TP_AVP_TYPE_RECV_WINDOW_SIZE, false, 0, &us, sizeof(USHORT)));
+							}
 
 							SendL2TPControlPacket(l2tp, t, 0, pp2);
 
@@ -1654,7 +1799,7 @@ void ProcL2TPPacketRecv(L2TP_SERVER *l2tp, UDPPACKET *p)
 		L2TP_TUNNEL *t = NULL;
 		L2TP_SESSION *l2tpv3_session = NULL;
 
-		if (pp->Ver != 3 || pp->IsControl)
+		if (pp->IsControl || pp->Ver != 3)
 		{
 			t = GetTunnelFromId(l2tp, &p->SrcIP, pp->TunnelId, pp->Ver == 3);
 		}
@@ -1767,6 +1912,15 @@ void ProcL2TPPacketRecv(L2TP_SERVER *l2tp, UDPPACKET *p)
 						}
 					}
 				}
+				else
+				{
+					// Reply ACK for already-received packets
+					if (pp->IsZLB == false)
+					{
+						// The packet other than ZLB is treated
+						t->StateChanged = true;
+					}
+				}
 			}
 			else
 			{
@@ -2373,7 +2527,7 @@ void L2TPProcessInterrupts(L2TP_SERVER *l2tp)
 
 				pp->TunnelId = t->TunnelId1;
 				pp->Ns = t->NextNs;
-				q->Buf = BuildL2TPPacketData(pp);
+				q->Buf = BuildL2TPPacketData(pp, t);
 
 				SendL2TPControlPacketMain(l2tp, t, q);
 

+ 5 - 1
src/Cedar/IPsec_L2TP.h

@@ -189,6 +189,7 @@
 #define	L2TP_AVP_TYPE_V3_SESSION_ID_LOCAL	63	// Local Session ID
 #define	L2TP_AVP_TYPE_V3_SESSION_ID_REMOTE	64	// Remote Session ID
 #define	L2TP_AVP_TYPE_V3_PW_TYPE		68		// Pseudowire Type
+#define	L2TP_AVP_TYPE_V3_CIRCUIT_STATUS	71
 
 // Message Type value
 #define	L2TP_MESSAGE_TYPE_SCCRQ			1		// Start-Control-Connection-Request
@@ -247,6 +248,7 @@ struct L2TP_PACKET
 	bool HasOffset;								// Whether there is offset bit
 	bool IsPriority;							// Whether priority packet
 	bool IsZLB;									// Zero Length Bit
+	bool IsYamahaV3;							// L2TPv3 on YAMAHA
 	UINT Ver;									// Version
 	UINT Length;								// Length
 	UINT TunnelId;								// Tunnel ID
@@ -284,6 +286,7 @@ struct L2TP_TUNNEL
 {
 	bool IsV3;									// L2TPv3
 	bool IsCiscoV3;								// L2TPv3 for Cisco
+	bool IsYamahaV3;							// L2TPv3 for YAMAHA
 	IP ClientIp;								// Client IP address
 	UINT ClientPort;							// Client port number
 	IP ServerIp;								// Server IP address
@@ -339,7 +342,7 @@ void FreeL2TPServer(L2TP_SERVER *l2tp);
 void StopL2TPServer(L2TP_SERVER *l2tp, bool no_wait);
 void ProcL2TPPacketRecv(L2TP_SERVER *l2tp, UDPPACKET *p);
 L2TP_PACKET *ParseL2TPPacket(UDPPACKET *p);
-BUF *BuildL2TPPacketData(L2TP_PACKET *pp);
+BUF *BuildL2TPPacketData(L2TP_PACKET *pp, L2TP_TUNNEL *t);
 L2TP_AVP *GetAVPValue(L2TP_PACKET *p, UINT type);
 L2TP_AVP *GetAVPValueEx(L2TP_PACKET *p, UINT type, UINT vendor_id);
 L2TP_TUNNEL *NewL2TPTunnel(L2TP_SERVER *l2tp, L2TP_PACKET *p, UDPPACKET *udp);
@@ -348,6 +351,7 @@ UINT GenerateNewTunnelIdEx(L2TP_SERVER *l2tp, IP *client_ip, bool is_32bit);
 void FreeL2TPTunnel(L2TP_TUNNEL *t);
 L2TP_TUNNEL *GetTunnelFromId(L2TP_SERVER *l2tp, IP *client_ip, UINT tunnel_id, bool is_v3);
 L2TP_TUNNEL *GetTunnelFromIdOfAssignedByClient(L2TP_SERVER *l2tp, IP *client_ip, UINT tunnel_id);
+L2TP_TUNNEL *GetTunnelFromIdOfAssignedByClientEx(L2TP_SERVER *l2tp, IP *client_ip, UINT tunnel_id, bool is_v3);
 void SendL2TPControlPacket(L2TP_SERVER *l2tp, L2TP_TUNNEL *t, UINT session_id, L2TP_PACKET *p);
 void SendL2TPControlPacketMain(L2TP_SERVER *l2tp, L2TP_TUNNEL *t, L2TP_QUEUE *q);
 void SendL2TPDataPacket(L2TP_SERVER *l2tp, L2TP_TUNNEL *t, L2TP_SESSION *s, void *data, UINT size);

+ 132 - 10
src/Cedar/IPsec_PPP.c

@@ -135,6 +135,8 @@ void PPPThread(THREAD *thread, void *param)
 	p->Mru1 = p->Mru2 = PPP_MRU_DEFAULT;
 	p->RecvPacketList = NewList(NULL);
 
+	p->MsChapV2_UseDoubleMsChapV2 = CedarIsThereAnyEapEnabledRadiusConfig(p->Cedar);
+
 	//// Link establishment phase
 	IPToStr(ipstr1, sizeof(ipstr1), &p->ClientIP);
 	IPToStr(ipstr2, sizeof(ipstr2), &p->ServerIP);
@@ -244,9 +246,96 @@ void PPPThread(THREAD *thread, void *param)
 
 		PPPContinueUntilFinishAllLCPOptionRequestsDetermined(p);
 
+		if (p->MsChapV2_UseDoubleMsChapV2)
+		{
+			// Use the double-MSCHAPv2 technieue
+			GetMachineHostName(machine_name, sizeof(machine_name));
+			MsChapV2Server_GenerateChallenge(p->MsChapV2_ServerChallenge);
+
+			pp = ZeroMalloc(sizeof(PPP_PACKET));
+			pp->Protocol = PPP_PROTOCOL_CHAP;
+			pp->IsControl = true;
+			pp->Lcp = NewPPPLCP(PPP_CHAP_CODE_CHALLENGE, 99);
+
+			b = NewBuf();
+			WriteBufChar(b, 16);
+			WriteBuf(b, p->MsChapV2_ServerChallenge, sizeof(p->MsChapV2_ServerChallenge));
+			WriteBuf(b, machine_name, StrLen(machine_name));
+			pp->Lcp->Data = Clone(b->Buf, b->Size);
+			pp->Lcp->DataSize = b->Size;
+			FreeBuf(b);
+
+			PPPSendPacket(p, pp);
+
+			pp_ret = PPPRecvResponsePacket(p, pp, 0, &pp_ret_protocol, false, true);
+
+			if (pp_ret != NULL)
+			{
+				// Extract the username from the first MS-CHAP v2 packet
+				if (pp_ret->Lcp != NULL && pp_ret->Lcp->DataSize >= 51)
+				{
+					BUF *b;
+
+					b = MemToBuf(pp_ret->Lcp->Data, pp_ret->Lcp->DataSize);
+
+					if (ReadBufChar(b) == 49)
+					{
+						UCHAR client_response_buffer[49];
+						char username_tmp[MAX_SIZE];
+						char id[MAX_SIZE];
+						char hub[MAX_SIZE];
+						char client_ip_tmp[256];
+						EAP_CLIENT *eap;
+						ETHERIP_ID d;
+
+						ReadBuf(b, client_response_buffer, 49);
+
+						Zero(username_tmp, sizeof(username_tmp));
+						ReadBuf(b, username_tmp, sizeof(username_tmp));
+
+						Debug("First MS-CHAPv2: id=%s\n", username_tmp);
+
+						Zero(id, sizeof(id));
+						Zero(hub, sizeof(hub));
+
+						// The user name is divided into the ID and the virtual HUB name
+						Zero(&d, sizeof(d));
+						PPPParseUsername(p->Cedar, username_tmp, &d);
+
+						StrCpy(id, sizeof(id), d.UserName);
+						StrCpy(hub, sizeof(hub), d.HubName);
+						Debug("First MS-CHAPv2: username=%s, hubname=%s\n", id, hub);
+
+						IPToStr(client_ip_tmp, sizeof(client_ip_tmp), &p->ClientIP);
+
+						eap = HubNewEapClient(p->Cedar, hub, client_ip_tmp, id);
+
+						if (eap)
+						{
+							p->EapClient = eap;
+						}
+					}
+
+					FreeBuf(b);
+				}
+
+				FreePPPPacket(pp_ret);
+			}
+
+			FreePPPPacket(pp);
+		}
+
 		// Generate a Server Challenge packet of MS-CHAP v2
 		GetMachineHostName(machine_name, sizeof(machine_name));
-		MsChapV2Server_GenerateChallenge(p->MsChapV2_ServerChallenge);
+
+		if (p->EapClient == NULL)
+		{
+			MsChapV2Server_GenerateChallenge(p->MsChapV2_ServerChallenge);
+		}
+		else
+		{
+			Copy(p->MsChapV2_ServerChallenge, p->EapClient->MsChapV2Challenge.Chap_ChallengeValue, 16);
+		}
 
 		pp = ZeroMalloc(sizeof(PPP_PACKET));
 		pp->Protocol = PPP_PROTOCOL_CHAP;
@@ -264,7 +353,7 @@ void PPPThread(THREAD *thread, void *param)
 		PPPSendPacket(p, pp);
 
 		pp_ret_protocol = 0;
-		pp_ret = PPPRecvResponsePacket(p, pp, 0, &pp_ret_protocol, false);
+		pp_ret = PPPRecvResponsePacket(p, pp, 0, &pp_ret_protocol, false, false);
 
 		if (pp_ret != NULL)
 		{
@@ -565,7 +654,7 @@ bool PPPContinueUntilFinishAllLCPOptionRequestsDetermined(PPP_SESSION *p)
 		return false;
 	}
 
-	PPPRecvResponsePacket(p, NULL, PPP_PROTOCOL_LCP, &received_protocol, true);
+	PPPRecvResponsePacket(p, NULL, PPP_PROTOCOL_LCP, &received_protocol, true, false);
 
 	return p->ClientLCPOptionDetermined;
 }
@@ -580,7 +669,7 @@ USHORT PPPContinueCurrentProtocolRequestListening(PPP_SESSION *p, USHORT protoco
 		return 0;
 	}
 
-	PPPRecvResponsePacket(p, NULL, protocol, &received_protocol, false);
+	PPPRecvResponsePacket(p, NULL, protocol, &received_protocol, false, false);
 
 	return received_protocol;
 }
@@ -634,7 +723,7 @@ bool PPPSendRequest(PPP_SESSION *p, USHORT protocol, PPP_LCP *c)
 	}
 
 	// Receive a corresponding PPP packet
-	pp2 = PPPRecvResponsePacket(p, pp, 0, NULL, false);
+	pp2 = PPPRecvResponsePacket(p, pp, 0, NULL, false, false);
 
 	if (pp2 != NULL)
 	{
@@ -880,8 +969,10 @@ PPP_PACKET *PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *req)
 					char server_challenge_hex[MAX_SIZE];
 					char client_challenge_hex[MAX_SIZE];
 					char client_response_hex[MAX_SIZE];
+					char eap_client_hex[64];
 					ETHERIP_ID d;
 					UINT error_code;
+					UINT64 eap_client_ptr = (UINT64)p->EapClient;
 
 					ReadBuf(b, client_response_buffer, 49);
 
@@ -913,18 +1004,21 @@ PPP_PACKET *PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *req)
 						p->MsChapV2_ClientChallenge, sizeof(p->MsChapV2_ClientChallenge));
 					BinToStr(client_response_hex, sizeof(client_response_hex),
 						p->MsChapV2_ClientResponse, sizeof(p->MsChapV2_ClientResponse));
+					BinToStr(eap_client_hex, sizeof(eap_client_hex),
+						&eap_client_ptr, 8);
 
-					Format(password, sizeof(password), "%s%s:%s:%s:%s",
+					Format(password, sizeof(password), "%s%s:%s:%s:%s:%s",
 						IPC_PASSWORD_MSCHAPV2_TAG,
 						username_tmp,
 						server_challenge_hex,
 						client_challenge_hex,
-						client_response_hex);
+						client_response_hex,
+						eap_client_hex);
 
 					// Attempt to connect with IPC
 					ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, hub, id, password,
 						&error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort,
-						p->ClientHostname, p->CryptName, false, p->AdjustMss);
+						p->ClientHostname, p->CryptName, false, p->AdjustMss, p->EapClient);
 
 					if (ipc != NULL)
 					{
@@ -1057,7 +1151,7 @@ PPP_PACKET *PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *req)
 
 								ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, hub, id, password,
 									&error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort,
-									p->ClientHostname, p->CryptName, false, p->AdjustMss);
+									p->ClientHostname, p->CryptName, false, p->AdjustMss, NULL);
 
 								if (ipc != NULL)
 								{
@@ -1555,7 +1649,8 @@ bool PPPGetIPAddressValueFromLCP(PPP_LCP *c, UINT type, IP *ip)
 // (If req == NULL, process on that protocol while the protocol specified in expected_protocol have received.
 //If other protocols has arrived, without further processing, and then store that packet in the session context once,
 // return NULL by setting the received_protocol.)
-PPP_PACKET *PPPRecvResponsePacket(PPP_SESSION *p, PPP_PACKET *req, USHORT expected_protocol, USHORT *received_protocol, bool finish_when_all_lcp_acked)
+PPP_PACKET *PPPRecvResponsePacket(PPP_SESSION *p, PPP_PACKET *req, USHORT expected_protocol, USHORT *received_protocol, bool finish_when_all_lcp_acked,
+								  bool return_mschapv2_response_with_no_processing)
 {
 	UINT64 giveup_tick = Tick64() + (UINT64)PPP_PACKET_RECV_TIMEOUT;
 	UINT64 next_resend = Tick64() + (UINT64)PPP_PACKET_RESEND_INTERVAL;
@@ -1618,6 +1713,16 @@ PPP_PACKET *PPPRecvResponsePacket(PPP_SESSION *p, PPP_PACKET *req, USHORT expect
 				{
 					return pp;
 				}
+
+				if (return_mschapv2_response_with_no_processing)
+				{
+					// For the double-MSCHAPv2 technique
+					if (pp->IsControl && pp->Protocol == req->Protocol && pp->Lcp->Id == req->Lcp->Id &&
+						pp->Protocol == PPP_PROTOCOL_CHAP && PPP_PAP_CODE_IS_RESPONSE(pp->Lcp->Code))
+					{
+						return pp;
+					}
+				}
 			}
 
 			// Return a response immediately without processing if a protocol other than the expected received
@@ -2357,9 +2462,26 @@ void FreePPPSession(PPP_SESSION *p)
 		FreeIPC(p->Ipc);
 	}
 
+	PPPFreeEapClient(p);
+
 	Free(p);
 }
 
+// Free the associated EAP client
+void PPPFreeEapClient(PPP_SESSION *p)
+{
+	if (p == NULL)
+	{
+		return;
+	}
+
+	if (p->EapClient != NULL)
+	{
+		ReleaseEapClient(p->EapClient);
+		p->EapClient = NULL;
+	}
+}
+
 // Get the option value
 PPP_OPTION *GetOptionValue(PPP_LCP *c, UCHAR type)
 {

+ 6 - 1
src/Cedar/IPsec_PPP.h

@@ -284,6 +284,9 @@ struct PPP_SESSION
 	UCHAR MsChapV2_ClientResponse[24];	// MS-CHAPv2 Client Response
 	UCHAR MsChapV2_ServerResponse[20];	// MS-CHAPv2 Server Response
 	UINT MsChapV2_ErrorCode;			// Authentication failure error code of MS-CHAPv2
+
+	bool MsChapV2_UseDoubleMsChapV2;	// Use the double-MSCHAPv2 technieue
+	EAP_CLIENT *EapClient;				// EAP client
 };
 
 // Function prototype
@@ -316,7 +319,8 @@ bool PPPSetIPAddressValueToLCP(PPP_LCP *c, UINT type, IP *ip, bool only_modify);
 bool PPPSendRequest(PPP_SESSION *p, USHORT protocol, PPP_LCP *c);
 USHORT PPPContinueCurrentProtocolRequestListening(PPP_SESSION *p, USHORT protocol);
 bool PPPContinueUntilFinishAllLCPOptionRequestsDetermined(PPP_SESSION *p);
-PPP_PACKET *PPPRecvResponsePacket(PPP_SESSION *p, PPP_PACKET *req, USHORT expected_protocol, USHORT *received_protocol, bool finish_when_all_lcp_acked);
+PPP_PACKET *PPPRecvResponsePacket(PPP_SESSION *p, PPP_PACKET *req, USHORT expected_protocol, USHORT *received_protocol, bool finish_when_all_lcp_acked,
+								  bool return_mschapv2_response_with_no_processing);
 PPP_PACKET *PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *req);
 void PPPSendEchoRequest(PPP_SESSION *p);
 bool PPPParseUsername(CEDAR *cedar, char *src, ETHERIP_ID *dst);
@@ -331,6 +335,7 @@ void MsChapV2Client_GenerateResponse(UCHAR *dst, UCHAR *challenge8, UCHAR *nt_pa
 void MsChapV2Server_GenerateResponse(UCHAR *dst, UCHAR *nt_password_hash_hash, UCHAR *client_response, UCHAR *challenge8);
 bool MsChapV2VerityPassword(IPC_MSCHAP_V2_AUTHINFO *d, char *password);
 char *MsChapV2DoBruteForce(IPC_MSCHAP_V2_AUTHINFO *d, LIST *password_list);
+void PPPFreeEapClient(PPP_SESSION *p);
 
 #endif	// IPSEC_PPP_H
 

+ 1 - 0
src/Cedar/NM.c

@@ -784,6 +784,7 @@ bool NmStatus(HWND hWnd, SM_SERVER *s, void *param)
 	LvInsertAdd(b, ICO_PROTOCOL_DHCP, NULL, 2, _UU("NM_STATUS_DHCP"), tmp);
 
 	LvInsertAdd(b, ICO_MACHINE, NULL, 2, _UU("SM_SNAT_IS_KERNEL"), t.IsKernelMode ? _UU("SEC_YES") : _UU("SEC_NO"));
+	LvInsertAdd(b, ICO_MACHINE, NULL, 2, _UU("SM_SNAT_IS_RAW"), t.IsRawIpMode ? _UU("SEC_YES") : _UU("SEC_NO"));
 
 	LvInsertEnd(b, hWnd, L_STATUS);
 

+ 3 - 1
src/Cedar/Nat.c

@@ -596,7 +596,7 @@ UINT NtGetStatus(NAT *n, RPC_NAT_STATUS *t)
 
 			t->NumDhcpClients = LIST_NUM(v->DhcpLeaseList);
 
-			t->IsKernelMode = NnIsActive(v);
+			t->IsKernelMode = NnIsActiveEx(v, &t->IsRawIpMode);
 		}
 		UnlockVirtual(v);
 	}
@@ -1063,6 +1063,7 @@ void InRpcNatStatus(RPC_NAT_STATUS *t, PACK *p)
 	t->NumDnsSessions = PackGetInt(p, "NumDnsSessions");
 	t->NumDhcpClients = PackGetInt(p, "NumDhcpClients");
 	t->IsKernelMode = PackGetBool(p, "IsKernelMode");
+	t->IsRawIpMode = PackGetBool(p, "IsRawIpMode");
 	PackGetStr(p, "HubName", t->HubName, sizeof(t->HubName));
 }
 void OutRpcNatStatus(PACK *p, RPC_NAT_STATUS *t)
@@ -1080,6 +1081,7 @@ void OutRpcNatStatus(PACK *p, RPC_NAT_STATUS *t)
 	PackAddInt(p, "NumDnsSessions", t->NumDnsSessions);
 	PackAddInt(p, "NumDhcpClients", t->NumDhcpClients);
 	PackAddBool(p, "IsKernelMode", t->IsKernelMode);
+	PackAddBool(p, "IsRawIpMode", t->IsRawIpMode);
 }
 void FreeRpcNatStatus(RPC_NAT_STATUS *t)
 {

+ 1 - 0
src/Cedar/Nat.h

@@ -168,6 +168,7 @@ struct RPC_NAT_STATUS
 	UINT NumDnsSessions;						// Number of DNS sessions
 	UINT NumDhcpClients;						// Number of DHCP clients
 	bool IsKernelMode;							// Whether kernel mode
+	bool IsRawIpMode;							// Whether raw IP mode
 };
 
 // RPC_NAT_INFO *

+ 564 - 6
src/Cedar/NativeStack.c

@@ -257,6 +257,109 @@ LABEL_RESTART:
 	Disconnect(a->Sock2);
 }
 
+// Start the iptables tracking
+bool NsStartIpTablesTracking(NATIVE_STACK *a)
+{
+	if (a->IpTablesThread != NULL)
+	{
+		return true;
+	}
+
+	a->IpTablesInitOk = false;
+
+	a->IpTablesHalt = false;
+
+	a->IpTablesHaltEvent = NewEvent();
+
+	a->IpTablesThread = NewThread(NsIpTablesThread, a);
+
+	WaitThreadInit(a->IpTablesThread);
+
+	return a->IpTablesInitOk;
+}
+
+// iptables thread
+void NsIpTablesThread(THREAD *thread, void *param)
+{
+	IPTABLES_STATE *state;
+	NATIVE_STACK *s;
+	UINT counter = 0;
+	BUF *seed_buf;
+	char exe_name[MAX_PATH];
+	if (thread == NULL || param == NULL)
+	{
+		return;
+	}
+
+	s = (NATIVE_STACK *)param;
+
+	seed_buf = NewBuf();
+
+	WriteBuf(seed_buf, s->MacAddress, 6);
+
+	GetExeName(exe_name, sizeof(exe_name));
+	WriteBufStr(seed_buf, exe_name);
+
+	state = StartAddIpTablesEntryForNativeStack(seed_buf->Buf, seed_buf->Size);
+
+	FreeBuf(seed_buf);
+
+	if (state == NULL)
+	{
+		NoticeThreadInit(thread);
+		return;
+	}
+
+	s->IpTablesInitOk = true;
+	NoticeThreadInit(thread);
+
+	while (true)
+	{
+		UINT wait_interval;
+
+		if (s->IpTablesHalt)
+		{
+			break;
+		}
+
+		if (MaintainAddIpTablesEntryForNativeStack(state))
+		{
+			counter = 0;
+		}
+
+		counter++;
+		wait_interval = NS_CHECK_IPTABLES_INTERVAL_INIT * counter;
+		wait_interval = MIN(wait_interval, NS_CHECK_IPTABLES_INTERVAL_MAX);
+
+		//Debug("NsIpTablesThread: wait for %u\n", wait_interval);
+		Wait(s->IpTablesHaltEvent, wait_interval);
+	}
+
+	EndAddIpTablesEntryForNativeStack(state);
+}
+
+// Stop the iptables tracking
+void NsStopIpTablesTracking(NATIVE_STACK *a)
+{
+	if (a->IpTablesThread == NULL)
+	{
+		return;
+	}
+
+	a->IpTablesHalt = true;
+	Set(a->IpTablesHaltEvent);
+
+	WaitThread(a->IpTablesThread, INFINITE);
+
+	ReleaseThread(a->IpTablesThread);
+	ReleaseEvent(a->IpTablesHaltEvent);
+
+	a->IpTablesThread = NULL;
+	a->IpTablesHaltEvent = NULL;
+	a->IpTablesInitOk = false;
+	a->IpTablesHalt = false;
+}
+
 // Release the stack
 void FreeNativeStack(NATIVE_STACK *a)
 {
@@ -288,6 +391,8 @@ void FreeNativeStack(NATIVE_STACK *a)
 	CloseEth(a->Eth);
 	FreeIPC(a->Ipc);
 
+	NsStopIpTablesTracking(a);
+
 	ReleaseCancel(a->Cancel);
 
 	ReleaseSock(a->Sock1);
@@ -312,12 +417,6 @@ NATIVE_STACK *NewNativeStack(CEDAR *cedar, char *device_name, char *mac_address_
 		return NULL;
 	}
 
-	if (cedar == NULL)
-	{
-		cedar = NewCedar(NULL, NULL);
-		release_cedar = true;
-	}
-
 	GetLocalHostIP4(&localhost);
 
 	// Open the Eth device
@@ -327,6 +426,12 @@ NATIVE_STACK *NewNativeStack(CEDAR *cedar, char *device_name, char *mac_address_
 		return NULL;
 	}
 
+	if (cedar == NULL)
+	{
+		cedar = NewCedar(NULL, NULL);
+		release_cedar = true;
+	}
+
 	a = ZeroMalloc(sizeof(NATIVE_STACK));
 
 	NewSocketPair(&a->Sock1, &a->Sock2, &localhost, 1, &localhost, 1);
@@ -353,6 +458,8 @@ NATIVE_STACK *NewNativeStack(CEDAR *cedar, char *device_name, char *mac_address_
 		ReleaseCedar(cedar);
 	}
 
+	a->IsIpRawMode = a->Eth->IsRawIpMode;
+
 	return a;
 }
 
@@ -440,6 +547,457 @@ void NsGenMacAddress(void *dest, char *mac_address_seed, char *device_name)
 	Copy(dest, mac, 6);
 }
 
+// Add the iptables entries for native stack
+IPTABLES_STATE *StartAddIpTablesEntryForNativeStack(void *seed, UINT seed_size)
+{
+	IPTABLES_STATE *ret = NULL;
+	bool ok = false;
+
+	if (IsIpTablesSupported())
+	{
+		IPTABLES_ENTRY *e;
+		UINT i;
+
+		ret = ZeroMalloc(sizeof(IPTABLES_STATE));
+
+		ret->EntryList = NewListFast(NULL);
+
+		HashSha1(ret->SeedHash, seed, seed_size);
+
+		// Create a pair of entry
+		e = ZeroMalloc(sizeof(IPTABLES_ENTRY));
+		GenerateDummyIpAndMark(ret->SeedHash, e, 0);
+		StrCpy(e->Chain, sizeof(e->Chain), "OUTPUT");
+		Format(e->ConditionAndArgs, sizeof(e->ConditionAndArgs),
+			"-p tcp --tcp-flags RST RST --sport %u:%u ! -s %r/32 ! -d %r/32 -m connmark ! --mark 0x%x -j DROP",
+			NN_RAW_IP_PORT_START, NN_RAW_IP_PORT_END,
+			&e->DummySrcIp, &e->DummyDestIP, e->DummyMark);
+		Add(ret->EntryList, e);
+
+		e = ZeroMalloc(sizeof(IPTABLES_ENTRY));
+		GenerateDummyIpAndMark(ret->SeedHash, e, 1);
+		StrCpy(e->Chain, sizeof(e->Chain), "OUTPUT");
+		Format(e->ConditionAndArgs, sizeof(e->ConditionAndArgs),
+			"-p icmp --icmp-type 3/3 ! -s %r/32 ! -d %r/32 -m connmark ! --mark 0x%x -j DROP",
+			&e->DummySrcIp, &e->DummyDestIP, e->DummyMark);
+		Add(ret->EntryList, e);
+
+		ok = true;
+
+		// Insert entries if not exists
+		for (i = 0; i < LIST_NUM(ret->EntryList);i++)
+		{
+			UINT j;
+			IPTABLES_ENTRY *e = LIST_DATA(ret->EntryList, i);
+
+			for (j = 0;j < 100;j++)
+			{
+				if (GetCurrentIpTableLineNumber(e->Chain, &e->DummySrcIp, &e->DummyDestIP, e->DummyMark) != 0)
+				{
+					char cmdline[MAX_PATH];
+
+					Format(cmdline, sizeof(cmdline),
+						"iptables -D %s %s",
+						e->Chain, e->ConditionAndArgs);
+
+					system(cmdline);
+				}
+				else
+				{
+					break;
+				}
+			}
+
+			if (GetCurrentIpTableLineNumber(e->Chain, &e->DummySrcIp, &e->DummyDestIP, e->DummyMark) == 0)
+			{
+				char cmdline[MAX_PATH];
+
+				Format(cmdline, sizeof(cmdline),
+					"iptables -I %s %s",
+					e->Chain, e->ConditionAndArgs);
+
+				system(cmdline);
+
+				if (GetCurrentIpTableLineNumber(e->Chain, &e->DummySrcIp, &e->DummyDestIP, e->DummyMark) == 0)
+				{
+					Debug("Run \"%s\" failed.\n", cmdline);
+					ok = false;
+					break;
+				}
+				else
+				{
+					Debug("Run \"%s\" ok.\n", cmdline);
+				}
+			}
+		}
+	}
+
+	if (ok == false)
+	{
+		EndAddIpTablesEntryForNativeStack(ret);
+		ret = NULL;
+	}
+
+	return ret;
+}
+
+// Maintain the iptables
+bool MaintainAddIpTablesEntryForNativeStack(IPTABLES_STATE *s)
+{
+	UINT i;
+	bool ret = false;
+	if (s == NULL)
+	{
+		return false;
+	}
+
+	if (s->HasError)
+	{
+		return false;
+	}
+
+	// Insert entries if not exists
+	for (i = 0; i < LIST_NUM(s->EntryList);i++)
+	{
+		IPTABLES_ENTRY *e = LIST_DATA(s->EntryList, i);
+
+		if (GetCurrentIpTableLineNumber(e->Chain, &e->DummySrcIp, &e->DummyDestIP, e->DummyMark) == 0)
+		{
+			char cmdline[MAX_PATH];
+
+			Format(cmdline, sizeof(cmdline),
+				"iptables -I %s %s",
+				e->Chain, e->ConditionAndArgs);
+
+			system(cmdline);
+
+			if (GetCurrentIpTableLineNumber(e->Chain, &e->DummySrcIp, &e->DummyDestIP, e->DummyMark) == 0)
+			{
+				Debug("Run \"%s\" failed.\n", cmdline);
+				s->HasError = true;
+				break;
+			}
+			else
+			{
+				Debug("Run \"%s\" ok.\n", cmdline);
+				ret = true;
+			}
+		}
+	}
+
+	return ret;
+}
+
+// Stop the iptables management
+void EndAddIpTablesEntryForNativeStack(IPTABLES_STATE *s)
+{
+	UINT i;
+	if (s == NULL)
+	{
+		return;
+	}
+
+	// Delete entries
+	for (i = 0; i < LIST_NUM(s->EntryList);i++)
+	{
+		IPTABLES_ENTRY *e = LIST_DATA(s->EntryList, i);
+		UINT j;
+
+		for (j = 0;j < 100;j++)
+		{
+			if (GetCurrentIpTableLineNumber(e->Chain, &e->DummySrcIp, &e->DummyDestIP, e->DummyMark) != 0)
+			{
+				char cmdline[MAX_PATH];
+
+				Format(cmdline, sizeof(cmdline),
+					"iptables -D %s %s",
+					e->Chain, e->ConditionAndArgs);
+
+				system(cmdline);
+			}
+			else
+			{
+				break;
+			}
+		}
+	}
+
+	FreeIpTablesState(s);
+}
+
+// Generate a set of dummy IP addresses and mark
+void GenerateDummyIpAndMark(void *hash_seed, IPTABLES_ENTRY *e, UINT id)
+{
+	PRAND *p;
+	BUF *b;
+	if (hash_seed == NULL || e == NULL)
+	{
+		return;
+	}
+
+	b = NewBuf();
+	WriteBufInt(b, id);
+	WriteBuf(b, hash_seed, SHA1_SIZE);
+	WriteBufStr(b, "20151002");
+
+	p = NewPRand(b->Buf, b->Size);
+	FreeBuf(b);
+
+	GenerateDummyIp(p, &e->DummySrcIp);
+	GenerateDummyIp(p, &e->DummyDestIP);
+	e->DummyMark = GenerateDummyMark(p);
+
+	FreePRand(p);
+}
+
+// Generate a dummy iptables mark
+UINT GenerateDummyMark(PRAND *p)
+{
+	UINT i;
+	if (p == NULL)
+	{
+		return 0;
+	}
+
+	while (true)
+	{
+		i = PRandInt(p);
+
+		if (i >= 1000000000 && i <= 0x7FFFFFFE)
+		{
+			return i;
+		}
+	}
+
+	return 0;
+}
+
+// Generate a dummy IP
+void GenerateDummyIp(PRAND *p, IP *ip)
+{
+	UINT i;
+	if (p == NULL || ip == NULL)
+	{
+		return;
+	}
+
+	Zero(ip, sizeof(IP));
+
+	for (i = 1;i < 4;i++)
+	{
+		UINT v = 0;
+		while (true)
+		{
+			v = PRandInt(p) % 256;
+			if (v >= 1 && v <= 254)
+			{
+				break;
+			}
+		}
+
+		ip->addr[i] = (UCHAR)v;
+	}
+
+	ip->addr[0] = 127;
+}
+
+// Search an entry
+IPTABLES_ENTRY *SearchIpTables(IPTABLES_STATE *s, char *chain, IP *src_ip, IP *dest_ip, UINT mark)
+{
+	char ip_str1[64];
+	char ip_str2[64];
+	char mark_str1[64];
+	char mark_str2[64];
+	UINT i;
+	if (s == NULL || chain == NULL || src_ip == NULL || dest_ip == NULL || mark == 0)
+	{
+		return NULL;
+	}
+
+	IPToStr(ip_str1, sizeof(ip_str1), src_ip);
+	IPToStr(ip_str2, sizeof(ip_str2), dest_ip);
+	ToStr(mark_str1, mark);
+	Format(mark_str2, sizeof(mark_str2), "%x", mark);
+
+	for (i = 0;i < LIST_NUM(s->EntryList);i++)
+	{
+		IPTABLES_ENTRY *e = LIST_DATA(s->EntryList, i);
+
+		if (StrCmpi(e->Chain, chain) == 0)
+		{
+			if (InStr(e->ConditionAndArgs, ip_str1) &&
+				InStr(e->ConditionAndArgs, ip_str2) &&
+				(InStr(e->ConditionAndArgs, mark_str1) || InStr(e->ConditionAndArgs, mark_str2)))
+			{
+				return e;
+			}
+		}
+	}
+
+	return NULL;
+}
+
+// Search an entry and get the line number
+UINT GetCurrentIpTableLineNumber(char *chain, IP *src_ip, IP *dest_ip, UINT mark)
+{
+	IPTABLES_STATE *s;
+	IPTABLES_ENTRY *e;
+	UINT ret = 0;
+
+	if (chain == NULL || src_ip == NULL || dest_ip == NULL || mark == 0)
+	{
+		return 0;
+	}
+
+	s = GetCurrentIpTables();
+
+	e = SearchIpTables(s, chain, src_ip, dest_ip, mark);
+
+	if (e != NULL)
+	{
+		ret = e->LineNumber;
+	}
+
+	FreeIpTablesState(s);
+
+	return ret;
+}
+
+// Free the iptables state
+void FreeIpTablesState(IPTABLES_STATE *s)
+{
+	UINT i;
+	if (s == NULL)
+	{
+		return;
+	}
+
+	for (i = 0;i < LIST_NUM(s->EntryList);i++)
+	{
+		IPTABLES_ENTRY *e = LIST_DATA(s->EntryList, i);
+
+		Free(e);
+	}
+
+	ReleaseList(s->EntryList);
+
+	Free(s);
+}
+
+// Get the current iptables state
+IPTABLES_STATE *GetCurrentIpTables()
+{
+	IPTABLES_STATE *ret = NULL;
+	TOKEN_LIST *t = NULL;
+
+#ifdef	OS_UNIX
+	t = UnixExec("iptables -L -x -n --line-numbers");
+#endif	// OS_UNIX
+
+	if (t != NULL)
+	{
+		UINT i;
+		UINT tmp_num = 0;
+
+		for (i = 0;i < t->NumTokens;i++)
+		{
+			char *line = t->Token[i];
+			if (StartWith(line, "Chain INPUT") ||
+				StartWith(line, "Chain FORWARD") ||
+				StartWith(line, "Chain OUTPUT"))
+			{
+				tmp_num++;
+			}
+		}
+
+		if (tmp_num >= 3)
+		{
+			char current_chain[64];
+			UINT mode = 0;
+
+			Zero(current_chain, sizeof(current_chain));
+
+			for (i = 0;i < t->NumTokens;i++)
+			{
+				char *line = t->Token[i];
+
+				if (StartWith(line, "Chain"))
+				{
+					TOKEN_LIST *t2 = ParseToken(line, " \t");
+					if (t2 != NULL)
+					{
+						if (t2->NumTokens >= 4)
+						{
+							StrCpy(current_chain, sizeof(current_chain), t2->Token[1]);
+							mode = 1;
+
+							if (ret == NULL)
+							{
+								ret = ZeroMalloc(sizeof(IPTABLES_STATE));
+								ret->EntryList = NewListFast(NULL);
+							}
+
+						}
+						FreeToken(t2);
+					}
+				}
+
+				if (mode == 1)
+				{
+					if (StartWith(line, "num"))
+					{
+						mode = 2;
+					}
+				}
+				else if (mode == 2)
+				{
+					TOKEN_LIST *t2 = ParseToken(line, " \t");
+					if (t2 != NULL)
+					{
+						if (t2->NumTokens >= 6 && ToInt(t2->Token[0]) != 0)
+						{
+							IPTABLES_ENTRY *e = ZeroMalloc(sizeof(IPTABLES_ENTRY));
+
+							StrCpy(e->Chain, sizeof(e->Chain), current_chain);
+							e->LineNumber = ToInt(t2->Token[0]);
+							StrCpy(e->ConditionAndArgs, sizeof(e->ConditionAndArgs), line);
+
+							Add(ret->EntryList, e);
+						}
+
+						FreeToken(t2);
+					}
+				}
+			}
+		}
+
+		FreeToken(t);
+	}
+
+	return ret;
+}
+
+// Get whether iptables is supported
+bool IsIpTablesSupported()
+{
+#ifdef	UNIX_LINUX
+	IPTABLES_STATE *s = GetCurrentIpTables();
+	if (s != NULL)
+	{
+		FreeIpTablesState(s);
+		return true;
+	}
+	else
+	{
+		return false;
+	}
+#else	// UNIX_LINUX
+	return false;
+#endif	// UNIX_LINUX
+}
+
+
+
 
 
 // Developed by SoftEther VPN Project at University of Tsukuba in Japan.

+ 46 - 0
src/Cedar/NativeStack.h

@@ -117,6 +117,10 @@
 //// Constants
 #define	NS_MAC_ADDRESS_BYTE_1		0xDA		// First byte of the MAC address
 
+#define	NS_CHECK_IPTABLES_INTERVAL_INIT	(1 * 1000)
+
+#define	NS_CHECK_IPTABLES_INTERVAL_MAX	(5 * 60 * 1000)
+
 //// Type
 struct NATIVE_STACK
 {
@@ -132,6 +136,30 @@ struct NATIVE_STACK
 	SOCK *Sock2;					// Sock2 (Used in the IPC side)
 	DHCP_OPTION_LIST CurrentDhcpOptionList;	// Current DHCP options list
 	IP DnsServerIP;					// IP address of the DNS server
+	IP DnsServerIP2;				// IP address of the DNS server #2
+	bool IsIpRawMode;
+	IP MyIP_InCaseOfIpRawMode;		// My IP
+
+	THREAD *IpTablesThread;
+	EVENT *IpTablesHaltEvent;
+	bool IpTablesHalt;
+	bool IpTablesInitOk;
+};
+
+struct IPTABLES_ENTRY
+{
+	char Chain[64];
+	UINT LineNumber;
+	char ConditionAndArgs[MAX_SIZE];
+	IP DummySrcIp, DummyDestIP;
+	UINT DummyMark;
+};
+
+struct IPTABLES_STATE
+{
+	UCHAR SeedHash[SHA1_SIZE];
+	LIST *EntryList;
+	bool HasError;
 };
 
 
@@ -144,6 +172,24 @@ void NsMainThread(THREAD *thread, void *param);
 void NsGenMacAddressSignatureForMachine(UCHAR *dst_last_2, UCHAR *src_mac_addr_4);
 bool NsIsMacAddressOnLocalhost(UCHAR *mac);
 
+bool NsStartIpTablesTracking(NATIVE_STACK *a);
+void NsStopIpTablesTracking(NATIVE_STACK *a);
+void NsIpTablesThread(THREAD *thread, void *param);
+
+IPTABLES_STATE *GetCurrentIpTables();
+void FreeIpTablesState(IPTABLES_STATE *s);
+bool IsIpTablesSupported();
+IPTABLES_ENTRY *SearchIpTables(IPTABLES_STATE *s, char *chain, IP *src_ip, IP *dest_ip, UINT mark);
+UINT GetCurrentIpTableLineNumber(char *chain, IP *src_ip, IP *dest_ip, UINT mark);
+
+IPTABLES_STATE *StartAddIpTablesEntryForNativeStack(void *seed, UINT seed_size);
+void EndAddIpTablesEntryForNativeStack(IPTABLES_STATE *s);
+bool MaintainAddIpTablesEntryForNativeStack(IPTABLES_STATE *s);
+
+void GenerateDummyIpAndMark(void *hash_seed, IPTABLES_ENTRY *e, UINT id);
+UINT GenerateDummyMark(PRAND *p);
+void GenerateDummyIp(PRAND *p, IP *ip);
+
 #endif	// NATIVESTACK_H
 
 

+ 33 - 2
src/Cedar/Protocol.c

@@ -1324,6 +1324,7 @@ bool ServerAccept(CONNECTION *c)
 	char *error_detail = NULL;
 	char *error_detail_2 = NULL;
 	char ctoken_hash_str[64];
+	EAP_CLIENT *release_me_eap_client = NULL;
 
 	// Validate arguments
 	if (c == NULL)
@@ -1653,6 +1654,7 @@ bool ServerAccept(CONNECTION *c)
 			if (hub->Option != NULL)
 			{
 				radius_login_opt.In_CheckVLanId = hub->Option->AssignVLanIdByRadiusAttribute;
+				radius_login_opt.In_DenyNoVlanId = hub->Option->DenyAllRadiusLoginWithNoVlanAssign;
 				if (hub->Option->UseHubNameAsRadiusNasId == true)
 				{
 					StrCpy(radius_login_opt.NasId, sizeof(radius_login_opt.NasId), hubname);
@@ -1678,6 +1680,14 @@ bool ServerAccept(CONNECTION *c)
 			if (c->IsInProc)
 			{
 				char tmp[MAX_SIZE];
+				UINT64 ptr;
+
+				ptr = PackGetInt64(p, "release_me_eap_client");
+				if (ptr != 0)
+				{
+					release_me_eap_client = (EAP_CLIENT *)ptr;
+				}
+
 				PackGetStr(p, "inproc_postfix", c->InProcPrefix, sizeof(c->InProcPrefix));
 				Zero(tmp, sizeof(tmp));
 				PackGetStr(p, "inproc_cryptname", tmp, sizeof(tmp));
@@ -2207,9 +2217,25 @@ bool ServerAccept(CONNECTION *c)
 			FreePack(p);
 
 			// Check the assigned VLAN ID
-			if (radius_login_opt.Out_VLanId != 0)
+			if (radius_login_opt.Out_IsRadiusLogin)
 			{
-				assigned_vlan_id = radius_login_opt.Out_VLanId;
+				if (radius_login_opt.In_CheckVLanId)
+				{
+					if (radius_login_opt.Out_VLanId != 0)
+					{
+						assigned_vlan_id = radius_login_opt.Out_VLanId;
+					}
+
+					if (radius_login_opt.In_DenyNoVlanId && assigned_vlan_id == 0 || assigned_vlan_id >= 4096)
+					{
+						// Deny this session
+						Unlock(hub->lock);
+						ReleaseHub(hub);
+						c->Err = ERR_ACCESS_DENIED;
+						error_detail = "In_DenyNoVlanId";
+						goto CLEANUP;
+					}
+				}
 			}
 
 			if (StrCmpi(username, ADMINISTRATOR_USERNAME) != 0)
@@ -3811,6 +3837,11 @@ CLEANUP:
 
 	SLog(c->Cedar, "LS_CONNECTION_ERROR", c->Name, GetUniErrorStr(c->Err), c->Err);
 
+	if (release_me_eap_client != NULL)
+	{
+		ReleaseEapClient(release_me_eap_client);
+	}
+
 	return ret;
 }
 

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1588 - 0
src/Cedar/Radius.c


+ 247 - 2
src/Cedar/Radius.h

@@ -117,16 +117,261 @@
 #define	RADIUS_DEFAULT_PORT		1812			// The default port number
 #define	RADIUS_RETRY_INTERVAL	500				// Retransmission interval
 #define	RADIUS_RETRY_TIMEOUT	(10 * 1000)		// Time-out period
+#define	RADIUS_INITIAL_EAP_TIMEOUT	1600		// Initial timeout for EAP
 
 
 // RADIUS attributes
-#define	RADIUS_ATTRIBUTE_VLAN_ID	81
-#define RADIUS_MAX_NAS_ID_LEN		253
+#define	RADIUS_ATTRIBUTE_USER_NAME					1
+#define	RADIUS_ATTRIBUTE_NAS_IP						4
+#define	RADIUS_ATTRIBUTE_NAS_PORT					5
+#define	RADIUS_ATTRIBUTE_SERVICE_TYPE				6
+#define	RADIUS_ATTRIBUTE_FRAMED_PROTOCOL			7
+#define	RADIUS_ATTRIBUTE_FRAMED_MTU					12
+#define	RADIUS_ATTRIBUTE_STATE						24
+#define	RADIUS_ATTRIBUTE_VENDOR_SPECIFIC			26
+#define	RADIUS_ATTRIBUTE_CALLED_STATION_ID			30
+#define	RADIUS_ATTRIBUTE_CALLING_STATION_ID			31
+#define	RADIUS_ATTRIBUTE_NAS_ID						32
+#define	RADIUS_ATTRIBUTE_PROXY_STATE				33
+#define	RADIUS_ATTRIBUTE_ACCT_SESSION_ID			44
+#define	RADIUS_ATTRIBUTE_NAS_PORT_TYPE				61
+#define	RADIUS_ATTRIBUTE_TUNNEL_TYPE				64
+#define	RADIUS_ATTRIBUTE_TUNNEL_MEDIUM_TYPE			65
+#define	RADIUS_ATTRIBUTE_TUNNEL_CLIENT_ENDPOINT		66
+#define	RADIUS_ATTRIBUTE_TUNNEL_SERVER_ENDPOINT		67
+#define	RADIUS_ATTRIBUTE_EAP_MESSAGE				79
+#define	RADIUS_ATTRIBUTE_EAP_AUTHENTICATOR			80
+#define	RADIUS_ATTRIBUTE_VLAN_ID					81
+#define	RADIUS_MAX_NAS_ID_LEN						253
 
+// RADIUS codes
+#define	RADIUS_CODE_ACCESS_REQUEST					1
+#define	RADIUS_CODE_ACCESS_ACCEPT					2
+#define	RADIUS_CODE_ACCESS_REJECT					3
+#define	RADIUS_CODE_ACCESS_CHALLENGE				11
+
+// RADIUS vendor ID
+#define	RADIUS_VENDOR_MICROSOFT						311
+
+// RADIUS MS attributes
+#define	RADIUS_MS_RAS_VENDOR						9
+#define	RADIUS_MS_CHAP_CHALLENGE					11
+#define	RADIUS_MS_VERSION							18
+#define	RADIUS_MS_CHAP2_RESPONSE					25
+#define	RADIUS_MS_RAS_CLIENT_NAME					34
+#define	RADIUS_MS_RAS_CLIENT_VERSION				35
+#define	RADIUS_MS_NETWORK_ACCESS_SERVER_TYPE		47
+#define	RADIUS_MS_RAS_CORRELATION					56
+
+// EAP code
+#define	EAP_CODE_REQUEST							1
+#define	EAP_CODE_RESPONSE							2
+#define	EAP_CODE_SUCCESS							3
+#define	EAP_CODE_FAILURE							4
+
+// EAP type
+#define	EAP_TYPE_IDENTITY							1
+#define	EAP_TYPE_LEGACY_NAK							3
+#define	EAP_TYPE_PEAP								25
+#define	EAP_TYPE_MS_AUTH							26
+
+// MS-CHAPv2 opcodes
+#define	EAP_MSCHAPV2_OP_CHALLENGE					1
+#define	EAP_MSCHAPV2_OP_RESPONSE					2
+#define	EAP_MSCHAPV2_OP_SUCCESS						3
+
+// EAP-TLS flags
+#define	EAP_TLS_FLAGS_LEN							0x80
+#define	EAP_TLS_FLAGS_MORE_FRAGMENTS				0x40
+#define	EAP_TLS_FLAGS_START							0x20
+
+
+////////// Modern implementation
+
+#ifdef	OS_WIN32
+#pragma pack(push, 1)
+#endif	// OS_WIN32
+
+struct EAP_MESSAGE
+{
+	UCHAR Code;
+	UCHAR Id;
+	USHORT Len;		// = sizeof(Data) + 5
+	UCHAR Type;
+	UCHAR Data[1500];
+} GCC_PACKED;
+
+struct EAP_MSCHAPV2_GENERAL
+{
+	UCHAR Code;
+	UCHAR Id;
+	USHORT Len;		// = sizeof(Data) + 5
+	UCHAR Type;
+	UCHAR Chap_Opcode;
+} GCC_PACKED;
+
+struct EAP_MSCHAPV2_CHALLENGE
+{
+	UCHAR Code;
+	UCHAR Id;
+	USHORT Len;		// = sizeof(Data) + 5
+	UCHAR Type;
+	UCHAR Chap_Opcode;
+	UCHAR Chap_Id;
+	USHORT Chap_Len;
+	UCHAR Chap_ValueSize;	// = 16
+	UCHAR Chap_ChallengeValue[16];
+	char Chap_Name[256];
+} GCC_PACKED;
+
+struct EAP_MSCHAPV2_RESPONSE
+{
+	UCHAR Code;
+	UCHAR Id;
+	USHORT Len;		// = sizeof(Data) + 5
+	UCHAR Type;
+	UCHAR Chap_Opcode;
+	UCHAR Chap_Id;
+	USHORT Chap_Len;
+	UCHAR Chap_ValueSize;	// = 49
+	UCHAR Chap_PeerChallange[16];
+	UCHAR Chap_Reserved[8];
+	UCHAR Chap_NtResponse[24];
+	UCHAR Chap_Flags;
+	char Chap_Name[256];
+} GCC_PACKED;
+
+struct EAP_MSCHAPV2_SUCCESS_SERVER
+{
+	UCHAR Code;
+	UCHAR Id;
+	USHORT Len;		// = sizeof(Data) + 5
+	UCHAR Type;
+	UCHAR Chap_Opcode;
+	UCHAR Chap_Id;
+	USHORT Chap_Len;
+	char Message[256];
+} GCC_PACKED;
+
+struct EAP_MSCHAPV2_SUCCESS_CLIENT
+{
+	UCHAR Code;
+	UCHAR Id;
+	USHORT Len;		// = sizeof(Data) + 5
+	UCHAR Type;
+	UCHAR Chap_Opcode;
+} GCC_PACKED;
+
+struct EAP_PEAP
+{
+	UCHAR Code;
+	UCHAR Id;
+	USHORT Len;		// = sizeof(Data) + 5
+	UCHAR Type;
+	UCHAR TlsFlags;
+} GCC_PACKED;
+
+#ifdef	OS_WIN32
+#pragma pack(pop)
+#endif	// OS_WIN32
+
+struct RADIUS_PACKET
+{
+	UCHAR Code;
+	UCHAR PacketId;
+	LIST *AvpList;
+	UCHAR Authenticator[16];
+
+	UINT Parse_EapAuthMessagePos;
+	UINT Parse_AuthenticatorPos;
+
+	EAP_MESSAGE *Parse_EapMessage;
+	UINT Parse_EapMessage_DataSize;
+
+	UINT Parse_StateSize;
+	UCHAR Parse_State[256];
+};
+
+struct RADIUS_AVP
+{
+	UCHAR Type;
+	UINT VendorId;
+	UCHAR VendorCode;
+	UCHAR Padding[3];
+	UCHAR DataSize;
+	UCHAR Data[256];
+};
+
+struct EAP_CLIENT
+{
+	REF *Ref;
+
+	SOCK *UdpSock;
+	IP ServerIp;
+	UINT ServerPort;
+	char SharedSecret[MAX_SIZE];
+	char ClientIpStr[256];
+	char Username[MAX_USERNAME_LEN + 1];
+	UINT ResendTimeout;
+	UINT GiveupTimeout;
+	UCHAR TmpBuffer[4096];
+	UCHAR NextEapId;
+	UCHAR LastRecvEapId;
+
+	bool PeapMode;
+
+	UCHAR LastState[256];
+	UINT LastStateSize;
+
+	EAP_MSCHAPV2_CHALLENGE MsChapV2Challenge;
+	EAP_MSCHAPV2_SUCCESS_SERVER MsChapV2Success;
+	UCHAR ServerResponse[20];
+
+	SSL_PIPE *SslPipe;
+	UCHAR NextRadiusPacketId;
+
+	BUF *PEAP_CurrentReceivingMsg;
+	UINT PEAP_CurrentReceivingTotalSize;
+	UCHAR RecvLastCode;
+
+	UINT LastRecvVLanId;
+};
+
+void FreeRadiusPacket(RADIUS_PACKET *p);
+BUF *GenerateRadiusPacket(RADIUS_PACKET *p, char *shared_secret);
+RADIUS_PACKET *ParseRadiusPacket(void *data, UINT size);
+RADIUS_PACKET *NewRadiusPacket(UCHAR code, UCHAR packet_id);
+RADIUS_AVP *NewRadiusAvp(UCHAR type, UINT vendor_id, UCHAR vendor_code, void *data, UINT size);
+RADIUS_AVP *GetRadiusAvp(RADIUS_PACKET *p, UCHAR type);
+void RadiusTest();
+
+
+EAP_CLIENT *NewEapClient(IP *server_ip, UINT server_port, char *shared_secret, UINT resend_timeout, UINT giveup_timeout, char *client_ip_str, char *username);
+void ReleaseEapClient(EAP_CLIENT *e);
+void CleanupEapClient(EAP_CLIENT *e);
+bool EapClientSendMsChapv2AuthRequest(EAP_CLIENT *e);
+bool EapClientSendMsChapv2AuthClientResponse(EAP_CLIENT *e, UCHAR *client_response, UCHAR *client_challenge);
+void EapSetRadiusGeneralAttributes(RADIUS_PACKET *r, EAP_CLIENT *e);
+bool EapSendPacket(EAP_CLIENT *e, RADIUS_PACKET *r);
+RADIUS_PACKET *EapSendPacketAndRecvResponse(EAP_CLIENT *e, RADIUS_PACKET *r);
+
+bool PeapClientSendMsChapv2AuthRequest(EAP_CLIENT *eap);
+bool PeapClientSendMsChapv2AuthClientResponse(EAP_CLIENT *e, UCHAR *client_response, UCHAR *client_challenge);
+
+bool StartPeapClient(EAP_CLIENT *e);
+bool StartPeapSslClient(EAP_CLIENT *e);
+bool SendPeapRawPacket(EAP_CLIENT *e, UCHAR *peap_data, UINT peap_size);
+bool SendPeapPacket(EAP_CLIENT *e, void *msg, UINT msg_size);
+bool GetRecvPeapMessage(EAP_CLIENT *e, EAP_MESSAGE *msg);
+
+
+////////// Classical implementation
 struct RADIUS_LOGIN_OPTION
 {
 	bool In_CheckVLanId;
+	bool In_DenyNoVlanId;
 	UINT Out_VLanId;
+	bool Out_IsRadiusLogin;
 	char NasId[RADIUS_MAX_NAS_ID_LEN + 1];	// NAS-Identifier
 };
 

+ 8 - 0
src/Cedar/Sam.c

@@ -268,6 +268,14 @@ bool SamAuthUserByPlainPassword(CONNECTION *c, HUB *hub, char *username, char *p
 					b = RadiusLogin(c, radius_server_addr, radius_server_port,
 						radius_secret, StrLen(radius_secret),
 						name, password, interval, mschap_v2_server_response_20, opt);
+
+					if (b)
+					{
+						if (opt != NULL)
+						{
+							opt->Out_IsRadiusLogin = true;
+						}
+					}
 				}
 
 				Lock(hub->lock);

+ 14 - 0
src/Cedar/Server.c

@@ -4098,11 +4098,13 @@ void SiLoadHubOptionCfg(FOLDER *f, HUB_OPTION *o)
 	}
 
 	o->DisableKernelModeSecureNAT = CfgGetBool(f, "DisableKernelModeSecureNAT");
+	o->DisableIpRawModeSecureNAT = CfgGetBool(f, "DisableIpRawModeSecureNAT");
 	o->DisableUserModeSecureNAT = CfgGetBool(f, "DisableUserModeSecureNAT");
 	o->DisableCheckMacOnLocalBridge = CfgGetBool(f, "DisableCheckMacOnLocalBridge");
 	o->DisableCorrectIpOffloadChecksum = CfgGetBool(f, "DisableCorrectIpOffloadChecksum");
 	o->SuppressClientUpdateNotification = CfgGetBool(f, "SuppressClientUpdateNotification");
 	o->AssignVLanIdByRadiusAttribute = CfgGetBool(f, "AssignVLanIdByRadiusAttribute");
+	o->DenyAllRadiusLoginWithNoVlanAssign = CfgGetBool(f, "DenyAllRadiusLoginWithNoVlanAssign");
 	o->SecureNAT_RandomizeAssignIp = CfgGetBool(f, "SecureNAT_RandomizeAssignIp");
 	o->DetectDormantSessionInterval = CfgGetInt(f, "DetectDormantSessionInterval");
 	o->NoPhysicalIPOnPacketLog = CfgGetBool(f, "NoPhysicalIPOnPacketLog");
@@ -4184,6 +4186,7 @@ void SiWriteHubOptionCfg(FOLDER *f, HUB_OPTION *o)
 	CfgAddBool(f, "DropArpInPrivacyFilterMode", o->DropArpInPrivacyFilterMode);
 	CfgAddBool(f, "SuppressClientUpdateNotification", o->SuppressClientUpdateNotification);
 	CfgAddBool(f, "AssignVLanIdByRadiusAttribute", o->AssignVLanIdByRadiusAttribute);
+	CfgAddBool(f, "DenyAllRadiusLoginWithNoVlanAssign", o->DenyAllRadiusLoginWithNoVlanAssign);
 	CfgAddBool(f, "SecureNAT_RandomizeAssignIp", o->SecureNAT_RandomizeAssignIp);
 	CfgAddBool(f, "NoPhysicalIPOnPacketLog", o->NoPhysicalIPOnPacketLog);
 	CfgAddInt(f, "DetectDormantSessionInterval", o->DetectDormantSessionInterval);
@@ -4203,6 +4206,7 @@ void SiWriteHubOptionCfg(FOLDER *f, HUB_OPTION *o)
 	CfgAddInt(f, "SecureNAT_MaxIcmpSessionsPerIp", o->SecureNAT_MaxIcmpSessionsPerIp);
 	CfgAddInt(f, "AccessListIncludeFileCacheLifetime", o->AccessListIncludeFileCacheLifetime);
 	CfgAddBool(f, "DisableKernelModeSecureNAT", o->DisableKernelModeSecureNAT);
+	CfgAddBool(f, "DisableIpRawModeSecureNAT", o->DisableIpRawModeSecureNAT);
 	CfgAddBool(f, "DisableUserModeSecureNAT", o->DisableUserModeSecureNAT);
 	CfgAddBool(f, "DisableCheckMacOnLocalBridge", o->DisableCheckMacOnLocalBridge);
 	CfgAddBool(f, "DisableCorrectIpOffloadChecksum", o->DisableCorrectIpOffloadChecksum);
@@ -5009,6 +5013,9 @@ void SiWriteHubCfg(FOLDER *f, HUB *h)
 		CfgAddInt(f, "RadiusServerPort", h->RadiusServerPort);
 		CfgAddInt(f, "RadiusRetryInterval", h->RadiusRetryInterval);
 		CfgAddStr(f, "RadiusSuffixFilter", h->RadiusSuffixFilter);
+
+		CfgAddBool(f, "RadiusConvertAllMsChapv2AuthRequestToEap", h->RadiusConvertAllMsChapv2AuthRequestToEap);
+		CfgAddBool(f, "RadiusUsePeapInsteadOfEap", h->RadiusUsePeapInsteadOfEap);
 	}
 	Unlock(h->RadiusOptionLock);
 
@@ -5175,6 +5182,9 @@ void SiLoadHubCfg(SERVER *s, FOLDER *f, char *name)
 
 			CfgGetStr(f, "RadiusSuffixFilter", h->RadiusSuffixFilter, sizeof(h->RadiusSuffixFilter));
 
+			h->RadiusConvertAllMsChapv2AuthRequestToEap = CfgGetBool(f, "RadiusConvertAllMsChapv2AuthRequestToEap");
+			h->RadiusUsePeapInsteadOfEap = CfgGetBool(f, "RadiusUsePeapInsteadOfEap");
+
 			if (interval == 0)
 			{
 				interval = RADIUS_RETRY_INTERVAL;
@@ -7490,6 +7500,7 @@ void SiCalledUpdateHub(SERVER *s, PACK *p)
 	o.DropArpInPrivacyFilterMode = PackGetBool(p, "DropArpInPrivacyFilterMode");
 	o.SuppressClientUpdateNotification = PackGetBool(p, "SuppressClientUpdateNotification");
 	o.AssignVLanIdByRadiusAttribute = PackGetBool(p, "AssignVLanIdByRadiusAttribute");
+	o.DenyAllRadiusLoginWithNoVlanAssign = PackGetBool(p, "DenyAllRadiusLoginWithNoVlanAssign");
 	o.SecureNAT_RandomizeAssignIp = PackGetBool(p, "SecureNAT_RandomizeAssignIp");
 	o.DetectDormantSessionInterval = PackGetInt(p, "DetectDormantSessionInterval");
 	o.VlanTypeId = PackGetInt(p, "VlanTypeId");
@@ -7531,6 +7542,7 @@ void SiCalledUpdateHub(SERVER *s, PACK *p)
 		o.AccessListIncludeFileCacheLifetime = ACCESS_LIST_INCLUDE_FILE_CACHE_LIFETIME;
 	}
 	o.DisableKernelModeSecureNAT = PackGetBool(p, "DisableKernelModeSecureNAT");
+	o.DisableIpRawModeSecureNAT = PackGetBool(p, "DisableIpRawModeSecureNAT");
 	o.DisableUserModeSecureNAT = PackGetBool(p, "DisableUserModeSecureNAT");
 	o.DisableCheckMacOnLocalBridge = PackGetBool(p, "DisableCheckMacOnLocalBridge");
 	o.DisableCorrectIpOffloadChecksum = PackGetBool(p, "DisableCorrectIpOffloadChecksum");
@@ -9335,6 +9347,7 @@ void SiPackAddCreateHub(PACK *p, HUB *h)
 	PackAddBool(p, "DropArpInPrivacyFilterMode", h->Option->DropArpInPrivacyFilterMode);
 	PackAddBool(p, "SuppressClientUpdateNotification", h->Option->SuppressClientUpdateNotification);
 	PackAddBool(p, "AssignVLanIdByRadiusAttribute", h->Option->AssignVLanIdByRadiusAttribute);
+	PackAddBool(p, "DenyAllRadiusLoginWithNoVlanAssign", h->Option->DenyAllRadiusLoginWithNoVlanAssign);
 	PackAddInt(p, "ClientMinimumRequiredBuild", h->Option->ClientMinimumRequiredBuild);
 	PackAddBool(p, "SecureNAT_RandomizeAssignIp", h->Option->SecureNAT_RandomizeAssignIp);
 	PackAddBool(p, "NoPhysicalIPOnPacketLog", h->Option->NoPhysicalIPOnPacketLog);
@@ -9372,6 +9385,7 @@ void SiPackAddCreateHub(PACK *p, HUB *h)
 	PackAddInt(p, "SecureNAT_MaxIcmpSessionsPerIp", h->Option->SecureNAT_MaxIcmpSessionsPerIp);
 	PackAddInt(p, "AccessListIncludeFileCacheLifetime", h->Option->AccessListIncludeFileCacheLifetime);
 	PackAddBool(p, "DisableKernelModeSecureNAT", h->Option->DisableKernelModeSecureNAT);
+	PackAddBool(p, "DisableIpRawModeSecureNAT", h->Option->DisableIpRawModeSecureNAT);
 	PackAddBool(p, "DisableUserModeSecureNAT", h->Option->DisableUserModeSecureNAT);
 	PackAddBool(p, "DisableCheckMacOnLocalBridge", h->Option->DisableCheckMacOnLocalBridge);
 	PackAddBool(p, "DisableCorrectIpOffloadChecksum", h->Option->DisableCorrectIpOffloadChecksum);

+ 130 - 16
src/Cedar/Virtual.c

@@ -329,7 +329,7 @@ void NnDeleteSession(NATIVE_NAT *t, NATIVE_NAT_ENTRY *e)
 		break;
 
 	case NAT_ICMP:
-		Debug("NAT ICMP %u Deleted.", e->Id);
+		Debug("NAT ICMP %u Deleted.\n", e->Id);
 		break;
 	}
 
@@ -509,6 +509,7 @@ void NnCombineIp(NATIVE_NAT *t, IP_COMBINE *c, UINT offset, void *data, UINT siz
 		if (total_size == c->Size)
 		{
 			// Received whole of the IP packet
+			//Debug("Combine: %u\n", total_size);
 			NnIpReceived(t, c->SrcIP, c->DestIP, c->Protocol, c->Data, c->Size, c->Ttl,
 				c->HeadIpHeaderData, c->HeadIpHeaderDataSize, c->MaxL3Size);
 
@@ -1651,24 +1652,32 @@ UINT NnMapNewPublicPort(NATIVE_NAT *t, UINT protocol, UINT dest_ip, UINT dest_po
 {
 	UINT i;
 	UINT base_port;
+	UINT port_start = 1025;
+	UINT port_end = 65500;
 	// Validate arguments
 	if (t == NULL)
 	{
 		return 0;
 	}
 
-	base_port = Rand32() % (65500 - 1025) + 1025;
+	if (t->IsRawIpMode)
+	{
+		port_start = NN_RAW_IP_PORT_START;
+		port_end = NN_RAW_IP_PORT_END;
+	}
 
-	for (i = 0;i < (65500 - 1025);i++)
+	base_port = Rand32() % (port_end - port_start) + port_start;
+
+	for (i = 0;i < (port_end - port_start);i++)
 	{
 		UINT port;
 		NATIVE_NAT_ENTRY tt;
 		NATIVE_NAT *e;
 
 		port = base_port + i;
-		if (port > 65500)
+		if (port > port_end)
 		{
-			port = port - 65500 + 1025;
+			port = port - port_end + port_start;
 		}
 
 		// Is this port vacant?
@@ -1688,6 +1697,10 @@ UINT NnMapNewPublicPort(NATIVE_NAT *t, UINT protocol, UINT dest_ip, UINT dest_po
 
 // Examine whether the native NAT is available
 bool NnIsActive(VH *v)
+{
+	return NnIsActiveEx(v, NULL);
+}
+bool NnIsActiveEx(VH *v, bool *is_ipraw_mode)
 {
 	// Validate arguments
 	if (v == NULL)
@@ -1705,6 +1718,14 @@ bool NnIsActive(VH *v)
 		return false;
 	}
 
+	if (v->NativeNat->Active)
+	{
+		if (is_ipraw_mode != NULL)
+		{
+			*is_ipraw_mode = v->NativeNat->IsRawIpMode;
+		}
+	}
+
 	return v->NativeNat->Active;
 }
 
@@ -1745,7 +1766,7 @@ void NnMainLoop(NATIVE_NAT *t, NATIVE_STACK *a)
 	ipc = a->Ipc;
 
 	tubes[num_tubes++] = ipc->Sock->RecvTube;
-	tubes[num_tubes++] = ipc->Sock->SendTube;
+	//tubes[num_tubes++] = ipc->Sock->SendTube;	// bug 2015.10.01 remove
 	tubes[num_tubes++] = t->HaltTube;
 
 	Zero(&yahoo_ip, sizeof(yahoo_ip));
@@ -1757,13 +1778,25 @@ void NnMainLoop(NATIVE_NAT *t, NATIVE_STACK *a)
 	next_dhcp_renew_tick = Tick64() + (UINT64)dhcp_renew_interval;
 	AddInterrupt(interrupt, next_dhcp_renew_tick);
 
-	while (t->Halt == false && t->v->UseNat && ((t->v->HubOption == NULL) || (t->v->HubOption->DisableKernelModeSecureNAT == false)))
+	while (t->Halt == false && t->v->UseNat)
 	{
 		UINT64 now = Tick64();
 		bool call_cancel = false;
 		bool state_changed = false;
 		UINT wait_interval;
 
+		if (t->v->HubOption != NULL)
+		{
+			if (t->IsRawIpMode == false && t->v->HubOption->DisableKernelModeSecureNAT)
+			{
+				break;
+			}
+			if (t->IsRawIpMode && t->v->HubOption->DisableIpRawModeSecureNAT)
+			{
+				break;
+			}
+		}
+
 		IPCFlushArpTable(ipc);
 		call_cancel = false;
 
@@ -1774,7 +1807,7 @@ LABEL_RESTART:
 		{
 			BUF *dns_query;
 
-			dns_src_port = NnGenSrcPort();
+			dns_src_port = NnGenSrcPort(a->IsIpRawMode);
 			dns_tran_id = Rand16();
 
 			// Start a connectivity check periodically
@@ -1877,7 +1910,7 @@ LABEL_RESTART:
 										// DNS response has been received
 										no_store = true;
 
-										tcp_src_port = NnGenSrcPort();
+										tcp_src_port = NnGenSrcPort(a->IsIpRawMode);
 
 										// Generate a TCP connection attempt packet
 										tcp_seq = Rand32();
@@ -2347,22 +2380,47 @@ LABEL_CLEANUP:
 bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube)
 {
 	BUF *dns_query;
+	BUF *dns_query2;
 	bool ok = false;
 	USHORT dns_tran_id = Rand16();
 	UINT64 next_send_tick = 0;
 	UINT64 giveup_time;
 	IPC *ipc;
-	UINT src_port = NnGenSrcPort();
+	UINT src_port = NnGenSrcPort(a->IsIpRawMode);
 	INTERRUPT_MANAGER *interrupt;
 	TUBE *tubes[3];
 	UINT num_tubes = 0;
 	IP yahoo_ip;
+	IP my_priv_ip;
+	UINT num_send_dns = 0;
+	IP using_dns;
 	// Validate arguments
 	if (a == NULL)
 	{
 		return false;
 	}
 
+	Copy(&using_dns, &a->DnsServerIP, sizeof(IP));
+
+	// Get my physical IP
+	if (a->IsIpRawMode)
+	{
+		if (GetMyPrivateIP(&my_priv_ip, false) == false)
+		{
+			Debug("NnTestConnectivity: GetMyPrivateIP failed.\n");
+			return false;
+		}
+		else
+		{
+			Debug("NnTestConnectivity: GetMyPrivateIP ok: %r\n", &my_priv_ip);
+
+			if (a->Eth != NULL)
+			{
+				Copy(&a->Eth->MyPhysicalIPForce, &my_priv_ip, sizeof(IP));
+			}
+		}
+	}
+
 	ipc = a->Ipc;
 	interrupt = NewInterruptManager();
 
@@ -2381,6 +2439,10 @@ bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube)
 		IPToUINT(&ipc->ClientIPAddress), src_port, IPToUINT(&a->DnsServerIP), 53),
 		IPToUINT(&ipc->ClientIPAddress), IPToUINT(&a->DnsServerIP), IP_PROTO_UDP, 0);
 
+	dns_query2 = NnBuildIpPacket(NnBuildUdpPacket(NnBuildDnsQueryPacket(NN_CHECK_HOSTNAME, dns_tran_id),
+		IPToUINT(&ipc->ClientIPAddress), src_port, IPToUINT(&a->DnsServerIP), 53),
+		IPToUINT(&ipc->ClientIPAddress), IPToUINT(&a->DnsServerIP2), IP_PROTO_UDP, 0);
+
 	giveup_time = Tick64() + NN_CHECK_CONNECTIVITY_TIMEOUT;
 	AddInterrupt(interrupt, giveup_time);
 	while (true)
@@ -2401,7 +2463,16 @@ bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube)
 
 			AddInterrupt(interrupt, next_send_tick);
 
-			IPCSendIPv4(ipc, dns_query->Buf, dns_query->Size);
+			if ((num_send_dns % 2) == 0)
+			{
+				IPCSendIPv4(ipc, dns_query->Buf, dns_query->Size);
+			}
+			else
+			{
+				IPCSendIPv4(ipc, dns_query2->Buf, dns_query2->Size);
+			}
+
+			num_send_dns++;
 		}
 
 		// Happy processing
@@ -2424,7 +2495,8 @@ bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube)
 			if (pkt != NULL)
 			{
 				if (pkt->TypeL3 == L3_IPV4 && pkt->TypeL4 == L4_UDP &&
-					pkt->L3.IPv4Header->SrcIP == IPToUINT(&a->DnsServerIP) &&
+					(pkt->L3.IPv4Header->SrcIP == IPToUINT(&a->DnsServerIP) ||
+					 pkt->L3.IPv4Header->SrcIP == IPToUINT(&a->DnsServerIP2)) &&
 					pkt->L3.IPv4Header->DstIP == IPToUINT(&ipc->ClientIPAddress) &&
 					pkt->L4.UDPHeader->SrcPort == Endian16(53) && pkt->L4.UDPHeader->DstPort == Endian16(src_port))
 				{
@@ -2437,6 +2509,9 @@ bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube)
 
 							if (NnParseDnsResponsePacket(pkt->Payload, pkt->PayloadSize, &ret_ip))
 							{
+								UINTToIP(&using_dns, pkt->L3.IPv4Header->SrcIP);
+								Debug("NativeStack: Using DNS: %r\n", &using_dns);
+
 								Copy(&yahoo_ip, &ret_ip, sizeof(IP));
 							}
 						}
@@ -2466,6 +2541,7 @@ bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube)
 	}
 
 	FreeBuf(dns_query);
+	FreeBuf(dns_query2);
 
 	if (IsZeroIP(&yahoo_ip) == false)
 	{
@@ -2589,13 +2665,37 @@ bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube)
 
 	FreeInterruptManager(interrupt);
 
+	if (ok)
+	{
+		if (IsZeroIP(&using_dns) == false)
+		{
+			Copy(&a->DnsServerIP, &using_dns, sizeof(IP));
+		}
+
+		if (a->IsIpRawMode)
+		{
+			if (NsStartIpTablesTracking(a) == false)
+			{
+				Debug("NsStartIpTablesTracking failed.\n");
+				ok = false;
+			}
+		}
+	}
+
 	return ok;
 }
 
 // Generate source port number by a random number
-UINT NnGenSrcPort()
+UINT NnGenSrcPort(bool raw_ip_mode)
 {
-	return 1025 + Rand32() % (65500 - 1025);
+	if (raw_ip_mode == false)
+	{
+		return 1025 + Rand32() % (65500 - 1025);
+	}
+	else
+	{
+		return NN_RAW_IP_PORT_START + Rand32() % (NN_RAW_IP_PORT_END - NN_RAW_IP_PORT_START);
+	}
 }
 
 // Get a next good interface for the native NAT
@@ -2617,7 +2717,9 @@ NATIVE_STACK *NnGetNextInterface(NATIVE_NAT *t)
 	t->NextWaitTimeForRetry = NN_NEXT_WAIT_TIME_FOR_DEVICE_ENUM * MIN((t->FailedCount + 1), NN_NEXT_WAIT_TIME_MAX_FAIL_COUNT);
 
 	// Get the device list
-	device_list = GetEthList();
+	device_list = GetEthListEx(NULL,
+		!(t->v->HubOption != NULL && t->v->HubOption->DisableKernelModeSecureNAT),
+		!(t->v->HubOption != NULL && t->v->HubOption->DisableIpRawModeSecureNAT));
 
 	if (device_list == NULL || device_list->NumTokens == 0)
 	{
@@ -2720,11 +2822,17 @@ NATIVE_STACK *NnGetNextInterface(NATIVE_NAT *t)
 
 				// Determine the DNS server to use
 				UINTToIP(&ret->DnsServerIP, opt.DnsServer);
+				UINTToIP(&ret->DnsServerIP2, opt.DnsServer2);
 				if (IsZeroIP(&ret->DnsServerIP))
 				{
 					// Use 8.8.8.8 instead If the DNS is not assigned from the DHCP server
 					SetIP(&ret->DnsServerIP, 8, 8, 8, 8);
 				}
+				if (IsZeroIP(&ret->DnsServerIP2))
+				{
+					// Use 8.8.4.4 instead If the DNS is not assigned from the DHCP server
+					SetIP(&ret->DnsServerIP2, 8, 8, 4, 4);
+				}
 
 				// Connectivity test
 				// (always fail if the default gateway is not set)
@@ -2773,7 +2881,7 @@ void NativeNatThread(THREAD *thread, void *param)
 	{
 		NATIVE_STACK *a;
 
-		while (t->v->UseNat == false || (t->v->HubOption != NULL && t->v->HubOption->DisableKernelModeSecureNAT))
+		while (t->v->UseNat == false || t->v->HubOption == NULL || (t->v->HubOption->DisableKernelModeSecureNAT && t->v->HubOption->DisableIpRawModeSecureNAT))
 		{
 			if (t->Halt)
 			{
@@ -2802,6 +2910,8 @@ void NativeNatThread(THREAD *thread, void *param)
 			// Acquisition success
 			Debug("NnGetNextInterface Ok: %s\n", a->DeviceName);
 
+			t->IsRawIpMode = a->IsIpRawMode;
+
 			Lock(t->Lock);
 			{
 				if (a->Sock1 != NULL)
@@ -2830,6 +2940,8 @@ void NativeNatThread(THREAD *thread, void *param)
 			NnMainLoop(t, a);
 			Debug("NnMainLoop End.\n");
 
+			t->IsRawIpMode = false;
+
 			t->Active = false;
 			t->PublicIP = 0;
 
@@ -7425,6 +7537,8 @@ void VirtualIcmpEchoRequestReceived(VH *v, UINT src_ip, UINT dst_ip, void *data,
 		return;
 	}
 
+	//Debug("ICMP: %u\n", size);
+
 	if (NnIsActive(v))
 	{
 		// Process by the Native NAT

+ 8 - 3
src/Cedar/Virtual.h

@@ -115,10 +115,13 @@
 #define	VIRTUAL_H
 
 
+#define	NN_RAW_IP_PORT_START			61001
+#define	NN_RAW_IP_PORT_END				65535
+
 #define	VIRTUAL_TCP_SEND_TIMEOUT		(21 * 1000)
 
-#define	NN_NEXT_WAIT_TIME_FOR_DEVICE_ENUM	(60 * 1000)
-#define	NN_NEXT_WAIT_TIME_MAX_FAIL_COUNT	15
+#define	NN_NEXT_WAIT_TIME_FOR_DEVICE_ENUM	(30 * 1000)
+#define	NN_NEXT_WAIT_TIME_MAX_FAIL_COUNT	30
 
 #define	NN_HOSTNAME_FORMAT				"securenat-%s"
 #define	NN_HOSTNAME_STARTWITH			"securenat-"
@@ -191,6 +194,7 @@ struct NATIVE_NAT
 	LIST *IpCombine;				// IP combining list
 	UINT CurrentIpQuota;			// Current IP combining quota
 	UCHAR CurrentMacAddress[6];		// Current MAC address
+	bool IsRawIpMode;				// Is RAW_IP mode
 };
 
 // ARP entry
@@ -643,7 +647,7 @@ BUF *NnBuildDnsQueryPacket(char *hostname, USHORT tran_id);
 BUF *NnBuildUdpPacket(BUF *payload, UINT src_ip, USHORT src_port, UINT dst_ip, USHORT dst_port);
 BUF *NnBuildTcpPacket(BUF *payload, UINT src_ip, USHORT src_port, UINT dst_ip, USHORT dst_port, UINT seq, UINT ack, UINT flag, UINT window_size, UINT mss);
 BUF *NnBuildIpPacket(BUF *payload, UINT src_ip, UINT dst_ip, UCHAR protocol, UCHAR ttl);
-UINT NnGenSrcPort();
+UINT NnGenSrcPort(bool raw_ip_mode);
 bool NnParseDnsResponsePacket(UCHAR *data, UINT size, IP *ret_ip);
 BUF *NnReadDnsRecord(BUF *buf, bool answer, USHORT *ret_type, USHORT *ret_class);
 bool NnReadDnsLabel(BUF *buf);
@@ -656,6 +660,7 @@ UINT GetHashNativeNatTableForRecv(void *p);
 void NnSetNat(NATIVE_NAT_ENTRY *e, UINT protocol, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, UINT pub_ip, UINT pub_port);
 
 bool NnIsActive(VH *v);
+bool NnIsActiveEx(VH *v, bool *is_ipraw_mode);
 void NnUdpRecvForInternet(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, void *data, UINT size, UINT max_l3_size);
 void NnTcpRecvForInternet(VH *v, UINT src_ip, UINT src_port, UINT dest_ip, UINT dest_port, TCP_HEADER *old_tcp, void *data, UINT size, UINT max_l3_size);
 void NnIcmpEchoRecvForInternet(VH *v, UINT src_ip, UINT dest_ip, void *data, UINT size, UCHAR ttl, void *icmp_data, UINT icmp_size, UCHAR *ip_header, UINT ip_header_size, UINT max_l3_size);

+ 4 - 4
src/CurrentBuild.txt

@@ -1,4 +1,4 @@
-BUILD_NUMBER 9570
-VERSION 418
-BUILD_NAME rtm
-BUILD_DATE 20150726_145955
+BUILD_NUMBER 9582
+VERSION 419
+BUILD_NAME beta
+BUILD_DATE 20151006_145630

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 0 - 24
src/Makefile64


+ 1 - 0
src/Mayaqua/MayaType.h

@@ -423,6 +423,7 @@ typedef struct STRMAP_ENTRY STRMAP_ENTRY;
 typedef struct SHARED_BUFFER SHARED_BUFFER;
 typedef struct HASH_LIST HASH_LIST;
 typedef struct HASH_ENTRY HASH_ENTRY;
+typedef struct PRAND PRAND;
 
 // Str.h
 typedef struct TOKEN_LIST TOKEN_LIST;

+ 135 - 0
src/Mayaqua/Memory.c

@@ -134,6 +134,70 @@
 
 static UINT fifo_current_realloc_mem_size = FIFO_REALLOC_MEM_SIZE;
 
+// New PRand
+PRAND *NewPRand(void *key, UINT key_size)
+{
+	PRAND *r;
+	UCHAR dummy[256];
+	if (key == NULL || key_size == 0)
+	{
+		key = "DUMMY";
+		key_size = 5;
+	}
+
+	r = ZeroMalloc(sizeof(PRAND));
+
+	HashSha1(r->Key, key, key_size);
+
+	r->Rc4 = NewCrypt(key, key_size);
+
+	Zero(dummy, sizeof(dummy));
+
+	Encrypt(r->Rc4, dummy, dummy, 256);
+
+	return r;
+}
+
+// Free PRand
+void FreePRand(PRAND *r)
+{
+	if (r == NULL)
+	{
+		return;
+	}
+
+	FreeCrypt(r->Rc4);
+
+	Free(r);
+}
+
+// Generate PRand
+void PRand(PRAND *p, void *data, UINT size)
+{
+	if (p == NULL)
+	{
+		return;
+	}
+
+	Zero(data, size);
+
+	Encrypt(p->Rc4, data, data, size);
+}
+
+// Generate UINT PRand
+UINT PRandInt(PRAND *p)
+{
+	UINT r;
+	if (p == NULL)
+	{
+		return 0;
+	}
+
+	PRand(p, &r, sizeof(UINT));
+
+	return r;
+}
+
 // Check whether the specified key item is in the hash list
 bool IsInHashListKey(HASH_LIST *h, UINT key)
 {
@@ -2368,6 +2432,28 @@ UINT PeekFifo(FIFO *f, void *p, UINT size)
 	return read_size;
 }
 
+// Read all data from FIFO
+BUF *ReadFifoAll(FIFO *f)
+{
+	BUF *buf;
+	UCHAR *tmp;
+	UINT size;
+	if (f == NULL)
+	{
+		return NewBuf();
+	}
+
+	size = FifoSize(f);
+	tmp = Malloc(size);
+	ReadFifo(f, tmp, size);
+
+	buf = MemToBuf(tmp, size);
+
+	Free(tmp);
+
+	return buf;
+}
+
 // Read from the FIFO
 UINT ReadFifo(FIFO *f, void *p, UINT size)
 {
@@ -3128,6 +3214,21 @@ bool WriteBufInt(BUF *b, UINT value)
 	return true;
 }
 
+// Write a short integer in the the buffer
+bool WriteBufShort(BUF *b, USHORT value)
+{
+	// Validate arguments
+	if (b == NULL)
+	{
+		return false;
+	}
+
+	value = Endian16(value);
+
+	WriteBuf(b, &value, sizeof(USHORT));
+	return true;
+}
+
 // Write a UCHAR to the buffer
 bool WriteBufChar(BUF *b, UCHAR uc)
 {
@@ -3194,6 +3295,23 @@ UINT ReadBufInt(BUF *b)
 	return Endian32(value);
 }
 
+// Read a short integer from the buffer
+USHORT ReadBufShort(BUF *b)
+{
+	USHORT value;
+	// Validate arguments
+	if (b == NULL)
+	{
+		return 0;
+	}
+
+	if (ReadBuf(b, &value, sizeof(USHORT)) != sizeof(USHORT))
+	{
+		return 0;
+	}
+	return Endian16(value);
+}
+
 // Write the buffer to a buffer
 void WriteBufBuf(BUF *b, BUF *bb)
 {
@@ -3459,6 +3577,23 @@ BUF *ReadRemainBuf(BUF *b)
 	return ReadBufFromBuf(b, size);
 }
 
+// Get the length of the rest
+UINT ReadBufRemainSize(BUF *b)
+{
+	// Validate arguments
+	if (b == NULL)
+	{
+		return 0;
+	}
+
+	if (b->Size < b->Current)
+	{
+		return 0;
+	}
+
+	return b->Size - b->Current;
+}
+
 // Clone the buffer
 BUF *CloneBuf(BUF *b)
 {

+ 16 - 0
src/Mayaqua/Memory.h

@@ -236,6 +236,13 @@ struct HASH_LIST
 	LIST *AllList;
 };
 
+// PRAND
+struct PRAND
+{
+	UCHAR Key[20];
+	CRYPT *Rc4;
+};
+
 // Function prototype
 HASH_LIST *NewHashList(GET_HASH *get_hash_proc, COMPARE *compare_proc, UINT bits, bool make_list);
 void ReleaseHashList(HASH_LIST *h);
@@ -250,6 +257,11 @@ void UnlockHashList(HASH_LIST *h);
 bool IsInHashListKey(HASH_LIST *h, UINT key);
 void *HashListKeyToPointer(HASH_LIST *h, UINT key);
 
+PRAND *NewPRand(void *key, UINT key_size);
+void FreePRand(PRAND *r);
+void PRand(PRAND *p, void *data, UINT size);
+UINT PRandInt(PRAND *p);
+
 LIST *NewCandidateList();
 void FreeCandidateList(LIST *o);
 int ComapreCandidate(void *p1, void *p2);
@@ -310,11 +322,13 @@ void FreeBuf(BUF *b);
 bool BufToFile(IO *o, BUF *b);
 BUF *FileToBuf(IO *o);
 UINT ReadBufInt(BUF *b);
+USHORT ReadBufShort(BUF *b);
 UINT64 ReadBufInt64(BUF *b);
 UCHAR ReadBufChar(BUF *b);
 bool WriteBufInt(BUF *b, UINT value);
 bool WriteBufInt64(BUF *b, UINT64 value);
 bool WriteBufChar(BUF *b, UCHAR uc);
+bool WriteBufShort(BUF *b, USHORT value);
 bool ReadBufStr(BUF *b, char *str, UINT size);
 bool WriteBufStr(BUF *b, char *str);
 void WriteBufLine(BUF *b, char *str);
@@ -332,10 +346,12 @@ BUF *CloneBuf(BUF *b);
 BUF *MemToBuf(void *data, UINT size);
 BUF *RandBuf(UINT size);
 BUF *ReadRemainBuf(BUF *b);
+UINT ReadBufRemainSize(BUF *b);
 bool CompareBuf(BUF *b1, BUF *b2);
 
 UINT PeekFifo(FIFO *f, void *p, UINT size);
 UINT ReadFifo(FIFO *f, void *p, UINT size);
+BUF *ReadFifoAll(FIFO *f);
 void ShrinkFifoMemory(FIFO *f);
 UCHAR *GetFifoPointer(FIFO *f);
 UCHAR *FifoPtr(FIFO *f);

+ 63 - 0
src/Mayaqua/Network.c

@@ -5842,6 +5842,11 @@ SSL_PIPE *NewSslPipe(bool server_mode, X *x, K *k, DH_CTX *dh)
 			SSL_CTX_set_options(ssl_ctx, SSL_OP_SINGLE_DH_USE);
 		}
 
+		if (server_mode == false)
+		{
+			SSL_CTX_set_options(ssl_ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
+		}
+
 		ssl = SSL_new(ssl_ctx);
 	}
 	Unlock(openssl_lock);
@@ -8907,10 +8912,36 @@ void UnixSelect(SOCKSET *set, UINT timeout, CANCEL *c1, CANCEL *c2)
 	if (c1 != NULL)
 	{
 		reads[num_read++] = p1 = c1->pipe_read;
+
+		if (c1->SpecialFlag)
+		{
+			if (c1->pipe_special_read2 != -1 && c1->pipe_special_read2 != 0)
+			{
+				reads[num_read++] = c1->pipe_special_read2;
+			}
+
+			if (c1->pipe_special_read3 != -1 && c1->pipe_special_read3 != 0)
+			{
+				reads[num_read++] = c1->pipe_special_read3;
+			}
+		}
 	}
 	if (c2 != NULL)
 	{
 		reads[num_read++] = p2 = c2->pipe_read;
+
+		if (c2->SpecialFlag)
+		{
+			if (c2->pipe_special_read2 != -1 && c2->pipe_special_read2 != 0)
+			{
+				reads[num_read++] = c2->pipe_special_read2;
+			}
+
+			if (c2->pipe_special_read3 != -1 && c2->pipe_special_read3 != 0)
+			{
+				reads[num_read++] = c2->pipe_special_read3;
+			}
+		}
 	}
 
 	// Call the select
@@ -8991,6 +9022,8 @@ CANCEL *UnixNewCancel()
 
 	UnixNewPipe(&c->pipe_read, &c->pipe_write);
 
+	c->pipe_special_read2 = c->pipe_special_read3 = -1;
+
 	return c;
 }
 
@@ -12307,6 +12340,36 @@ SOCK *NewUDPEx2RandMachineAndExePath(bool ipv6, IP *ip, UINT num_retry, UCHAR ra
 	return NewUDPEx2Rand(ipv6, ip, hash, sizeof(hash), num_retry);
 }
 
+// Set the DF bit of the socket
+void ClearSockDfBit(SOCK *s)
+{
+#ifdef	IP_PMTUDISC_DONT
+#ifdef	IP_MTU_DISCOVER
+	UINT value = IP_PMTUDISC_DONT;
+	if (s == NULL)
+	{
+		return;
+	}
+
+	setsockopt(s->socket, IPPROTO_IP, IP_MTU_DISCOVER, (char *)&value, sizeof(value));
+#endif	// IP_MTU_DISCOVER
+#endif	// IP_PMTUDISC_DONT
+}
+
+// Set the header-include option
+void SetRawSockHeaderIncludeOption(SOCK *s, bool enable)
+{
+	UINT value = BOOL_TO_INT(enable);
+	if (s == NULL || s->IsRawSocket == false)
+	{
+		return;
+	}
+
+	setsockopt(s->socket, IPPROTO_IP, IP_HDRINCL, (char *)&value, sizeof(value));
+
+	s->RawIP_HeaderIncludeFlag = enable;
+}
+
 // Create and initialize the UDP socket
 // If port is specified as 0, system assigns a certain port.
 SOCK *NewUDP(UINT port)

+ 4 - 0
src/Mayaqua/Network.h

@@ -313,6 +313,7 @@ struct SOCK
 	UINT Reverse_MyServerPort;		// Self port number when using the reverse socket
 	UCHAR Ssl_Init_Async_SendAlert[2];	// Initial state of SSL send_alert
 	bool AcceptOnlyTls;			// Accept only TLS (disable SSLv3)
+	bool RawIP_HeaderIncludeFlag;
 
 #ifdef	ENABLE_SSL_LOGGING
 	// SSL Logging (for debug)
@@ -371,6 +372,7 @@ struct CANCEL
 	void *hEvent;					// Pointer to a Win32 event handle
 #else	// OS_WIN32
 	int pipe_read, pipe_write;		// Pipe
+	int pipe_special_read2, pipe_special_read3;
 #endif	// OS_WIN32
 };
 
@@ -1323,6 +1325,8 @@ SOCK *NewUDP4(UINT port, IP *ip);
 SOCK *NewUDP6(UINT port, IP *ip);
 SOCK *NewUDPEx2Rand(bool ipv6, IP *ip, void *rand_seed, UINT rand_seed_size, UINT num_retry);
 SOCK *NewUDPEx2RandMachineAndExePath(bool ipv6, IP *ip, UINT num_retry, UCHAR rand_port_id);
+void ClearSockDfBit(SOCK *s);
+void SetRawSockHeaderIncludeOption(SOCK *s, bool enable);
 UINT GetNewAvailableUdpPortRand();
 UINT NewRandPortByMachineAndExePath(UINT start_port, UINT end_port, UINT additional_int);
 void DisableUDPChecksum(SOCK *s);

+ 1 - 0
src/Mayaqua/TcpIp.c

@@ -2874,6 +2874,7 @@ bool ParsePacketIPv4(PKT *p, UCHAR *buf, UINT size)
 	{
 		// Quit analysing since this is fragmented
 		p->TypeL4 = L4_FRAGMENT;
+
 		return true;
 	}
 

+ 3 - 2
src/Mayaqua/Tick64.c

@@ -158,13 +158,14 @@ UINT64 Tick64ToTime64(UINT64 tick)
 	}
 	LockList(tk64->AdjustTime);
 	{
-		UINT i;
-		for (i = 0;i < LIST_NUM(tk64->AdjustTime);i++)
+		INT i;
+		for (i = ((INT)LIST_NUM(tk64->AdjustTime) - 1); i >= 0; i--)
 		{
 			ADJUST_TIME *t = LIST_DATA(tk64->AdjustTime, i);
 			if (t->Tick <= tick)
 			{
 				ret = t->Time + (tick - t->Tick);
+				break;
 			}
 		}
 	}

+ 1 - 1
src/Mayaqua/Tick64.h

@@ -115,7 +115,7 @@
 #define	TICK64_H
 
 // Maximum number of correction list entries
-#define	MAX_ADJUST_TIME				5000
+#define	MAX_ADJUST_TIME				1024
 
 // Correction list entry
 struct ADJUST_TIME

+ 2 - 2
src/Neo/Neo.vcproj

@@ -77,7 +77,7 @@
 			<Tool
 				Name="VCLinkerTool"
 				IgnoreImportLibrary="true"
-				AdditionalOptions="/driver /subsystem:native,5.00 /FULLBUILD /align:0x80 /osversion:5.00 /STACK:0x40000,0x1000 /MERGE:_PAGE=PAGE /MERGE:_TEXT=.text /NODEFAULTLIB /stub:C:\WINDDK\7600.16385.0\lib\wnet\stub512.com"
+				AdditionalOptions="/driver /subsystem:native,5.00 /FULLBUILD /align:0x80 /osversion:5.00 /STACK:0x40000,0x1000 /MERGE:_PAGE=PAGE /MERGE:_TEXT=.text /NODEFAULTLIB /stub:C:\WINDDK\7600.16385.0\lib\wnet\stub512.com /ALIGN:4096"
 				AdditionalDependencies="wdm.lib ndis.lib wdmsec.lib &quot;$(SolutionDir)tmp\VersionResources\$(ProjectName)_$(PlatformName).res&quot;"
 				OutputFile="$(OutDir)\Neo_x86.sys"
 				LinkIncremental="1"
@@ -182,7 +182,7 @@
 			<Tool
 				Name="VCLinkerTool"
 				IgnoreImportLibrary="true"
-				AdditionalOptions="/driver /subsystem:native /FULLBUILD /align:0x80 /osversion:5.00 /STACK:0x40000,0x1000 /MERGE:_PAGE=PAGE /MERGE:_TEXT=.text /NODEFAULTLIB /stub:C:\WINDDK\7600.16385.0\lib\wnet\stub512.com"
+				AdditionalOptions="/driver /subsystem:native /FULLBUILD /align:0x80 /osversion:5.00 /STACK:0x40000,0x1000 /MERGE:_PAGE=PAGE /MERGE:_TEXT=.text /NODEFAULTLIB /stub:C:\WINDDK\7600.16385.0\lib\wnet\stub512.com /ALIGN:4096"
 				AdditionalDependencies="wdm.lib ndis.lib wdmsec.lib &quot;$(SolutionDir)tmp\VersionResources\$(ProjectName)_$(PlatformName).res&quot;"
 				OutputFile="$(OutDir)\Neo_x64.sys"
 				LinkIncremental="1"

+ 6 - 6
src/Neo6/Neo6.vcproj

@@ -78,9 +78,9 @@
 				Name="VCLinkerTool"
 				IgnoreImportLibrary="true"
 				LinkLibraryDependencies="false"
-				AdditionalOptions="/driver /subsystem:native,5.00 /FULLBUILD /align:0x80 /osversion:5.00 /STACK:0x40000,0x1000 /MERGE:_PAGE=PAGE /MERGE:_TEXT=.text /NODEFAULTLIB /stub:C:\WINDDK\7600.16385.0\lib\win7\stub512.com"
+				AdditionalOptions="/driver /subsystem:native,5.00 /FULLBUILD /align:0x80 /osversion:5.00 /STACK:0x40000,0x1000 /MERGE:_PAGE=PAGE /MERGE:_TEXT=.text /NODEFAULTLIB /stub:C:\WINDDK\7600.16385.0\lib\win7\stub512.com /ALIGN:4096"
 				AdditionalDependencies="wdm.lib ndis.lib ntoskrnl.lib fwpkclnt.lib &quot;$(SolutionDir)tmp\VersionResources\$(ProjectName)_$(PlatformName).res&quot;"
-				OutputFile="$(OutDir)\Neo6_x86.sys"
+				OutputFile="$(OutDir)\Neo6_x86_unsigned.sys"
 				LinkIncremental="1"
 				AdditionalLibraryDirectories="C:\WINDDK\7600.16385.0\lib\win7\i386"
 				GenerateManifest="false"
@@ -121,7 +121,7 @@
 			/>
 			<Tool
 				Name="VCPostBuildEventTool"
-				CommandLine="$(SolutionDir)bin\BuildUtil.exe /CMD:SignCode &quot;$(TargetPath)&quot; /COMMENT:&quot;VPN Software&quot; /KERNEL:yes&#x0D;&#x0A;"
+				CommandLine="$(SolutionDir)bin\BuildUtil.exe /CMD:SignCode &quot;$(TargetPath)&quot; /DEST:&quot;$(TargetDir)Neo6_x86.sys&quot; /COMMENT:&quot;VPN Software&quot; /KERNEL:yes /CERTID:0 /SHAMODE:0&#x0D;&#x0A;$(SolutionDir)bin\BuildUtil.exe /CMD:SignCode &quot;$(TargetPath)&quot; /DEST:&quot;$(TargetDir)Neo6_x86_win10.sys&quot; /COMMENT:&quot;VPN Software&quot; /KERNEL:yes /CERTID:0 /SHAMODE:2"
 			/>
 		</Configuration>
 		<Configuration
@@ -184,9 +184,9 @@
 				Name="VCLinkerTool"
 				IgnoreImportLibrary="true"
 				LinkLibraryDependencies="false"
-				AdditionalOptions="/driver /subsystem:native /FULLBUILD /align:0x80 /osversion:5.00 /STACK:0x40000,0x1000 /MERGE:_PAGE=PAGE /MERGE:_TEXT=.text /NODEFAULTLIB /stub:C:\WINDDK\7600.16385.0\lib\win7\stub512.com"
+				AdditionalOptions="/driver /subsystem:native /FULLBUILD /align:0x80 /osversion:5.00 /STACK:0x40000,0x1000 /MERGE:_PAGE=PAGE /MERGE:_TEXT=.text /NODEFAULTLIB /stub:C:\WINDDK\7600.16385.0\lib\win7\stub512.com /ALIGN:4096"
 				AdditionalDependencies="wdm.lib ndis.lib wdmsec.lib ntoskrnl.lib fwpkclnt.lib &quot;$(SolutionDir)tmp\VersionResources\$(ProjectName)_$(PlatformName).res&quot;"
-				OutputFile="$(OutDir)\Neo6_x64.sys"
+				OutputFile="$(OutDir)\Neo6_x64_unsigned.sys"
 				LinkIncremental="1"
 				AdditionalLibraryDirectories="C:\WINDDK\7600.16385.0\lib\win7\amd64"
 				GenerateManifest="false"
@@ -227,7 +227,7 @@
 			/>
 			<Tool
 				Name="VCPostBuildEventTool"
-				CommandLine="$(SolutionDir)bin\BuildUtil.exe /CMD:SignCode &quot;$(TargetPath)&quot; /COMMENT:&quot;VPN Software&quot; /KERNEL:yes&#x0D;&#x0A;"
+				CommandLine="$(SolutionDir)bin\BuildUtil.exe /CMD:SignCode &quot;$(TargetPath)&quot; /DEST:&quot;$(TargetDir)Neo6_x64.sys&quot; /COMMENT:&quot;VPN Software&quot; /KERNEL:yes /CERTID:0 /SHAMODE:0&#x0D;&#x0A;$(SolutionDir)bin\BuildUtil.exe /CMD:SignCode &quot;$(TargetPath)&quot; /DEST:&quot;$(TargetDir)Neo6_x64_win10.sys&quot; /COMMENT:&quot;VPN Software&quot; /KERNEL:yes /CERTID:0 /SHAMODE:2"
 			/>
 		</Configuration>
 	</Configurations>

+ 6 - 6
src/SeLow/SeLow.vcproj

@@ -78,9 +78,9 @@
 				Name="VCLinkerTool"
 				IgnoreImportLibrary="true"
 				LinkLibraryDependencies="false"
-				AdditionalOptions="/driver /subsystem:native,5.00 /FULLBUILD /align:0x80 /osversion:5.00 /STACK:0x40000,0x1000 /MERGE:_PAGE=PAGE /MERGE:_TEXT=.text /NODEFAULTLIB /stub:C:\WINDDK\7600.16385.0\lib\win7\stub512.com"
+				AdditionalOptions="/driver /subsystem:native,5.00 /FULLBUILD /align:0x80 /osversion:5.00 /STACK:0x40000,0x1000 /MERGE:_PAGE=PAGE /MERGE:_TEXT=.text /NODEFAULTLIB /stub:C:\WINDDK\7600.16385.0\lib\win7\stub512.com /ALIGN:4096"
 				AdditionalDependencies="bufferoverflowK.lib wdm.lib ndis.lib wdmsec.lib ntoskrnl.lib fwpkclnt.lib &quot;$(SolutionDir)tmp\VersionResources\$(ProjectName)_$(PlatformName).res&quot;"
-				OutputFile="$(OutDir)\SeLow_x86.sys"
+				OutputFile="$(OutDir)\SeLow_x86_unsigned.sys"
 				LinkIncremental="1"
 				AdditionalLibraryDirectories="C:\WINDDK\7600.16385.0\lib\win7\i386"
 				GenerateManifest="false"
@@ -121,7 +121,7 @@
 			/>
 			<Tool
 				Name="VCPostBuildEventTool"
-				CommandLine="$(SolutionDir)bin\BuildUtil.exe /CMD:SignCode &quot;$(TargetPath)&quot; /COMMENT:&quot;VPN Software&quot; /KERNEL:yes&#x0D;&#x0A;"
+				CommandLine="$(SolutionDir)bin\BuildUtil.exe /CMD:SignCode &quot;$(TargetPath)&quot; /DEST:&quot;$(TargetDir)SeLow_x86.sys&quot; /COMMENT:&quot;VPN Software&quot; /KERNEL:yes /CERTID:0 /SHAMODE:0&#x0D;&#x0A;$(SolutionDir)bin\BuildUtil.exe /CMD:SignCode &quot;$(TargetPath)&quot; /DEST:&quot;$(TargetDir)SeLow_x86_win10.sys&quot; /COMMENT:&quot;VPN Software&quot; /KERNEL:yes /CERTID:0 /SHAMODE:2"
 			/>
 		</Configuration>
 		<Configuration
@@ -184,9 +184,9 @@
 				Name="VCLinkerTool"
 				IgnoreImportLibrary="true"
 				LinkLibraryDependencies="false"
-				AdditionalOptions="/driver /subsystem:native /FULLBUILD /align:0x80 /osversion:5.00 /STACK:0x40000,0x1000 /MERGE:_PAGE=PAGE /MERGE:_TEXT=.text /NODEFAULTLIB /stub:C:\WINDDK\7600.16385.0\lib\win7\stub512.com"
+				AdditionalOptions="/driver /subsystem:native /FULLBUILD /align:0x80 /osversion:5.00 /STACK:0x40000,0x1000 /MERGE:_PAGE=PAGE /MERGE:_TEXT=.text /NODEFAULTLIB /stub:C:\WINDDK\7600.16385.0\lib\win7\stub512.com /ALIGN:4096"
 				AdditionalDependencies="bufferoverflowK.lib wdm.lib ndis.lib wdmsec.lib ntoskrnl.lib fwpkclnt.lib &quot;$(SolutionDir)tmp\VersionResources\$(ProjectName)_$(PlatformName).res&quot;"
-				OutputFile="$(OutDir)\SeLow_x64.sys"
+				OutputFile="$(OutDir)\SeLow_x64_unsigned.sys"
 				LinkIncremental="1"
 				AdditionalLibraryDirectories="C:\WINDDK\7600.16385.0\lib\win7\amd64"
 				GenerateManifest="false"
@@ -227,7 +227,7 @@
 			/>
 			<Tool
 				Name="VCPostBuildEventTool"
-				CommandLine="$(SolutionDir)bin\BuildUtil.exe /CMD:SignCode &quot;$(TargetPath)&quot; /COMMENT:&quot;VPN Software&quot; /KERNEL:yes&#x0D;&#x0A;"
+				CommandLine="$(SolutionDir)bin\BuildUtil.exe /CMD:SignCode &quot;$(TargetPath)&quot; /DEST:&quot;$(TargetDir)SeLow_x64.sys&quot; /COMMENT:&quot;VPN Software&quot; /KERNEL:yes /CERTID:0 /SHAMODE:0&#x0D;&#x0A;$(SolutionDir)bin\BuildUtil.exe /CMD:SignCode &quot;$(TargetPath)&quot; /DEST:&quot;$(TargetDir)SeLow_x64_win10.sys&quot; /COMMENT:&quot;VPN Software&quot; /KERNEL:yes /CERTID:0 /SHAMODE:2"
 			/>
 		</Configuration>
 	</Configurations>

+ 1 - 1
src/SeLow/SeLowCommon.h

@@ -115,7 +115,7 @@
 // Change this number every time functions are added or modified on the driver.
 // As long as this number does not change, installation of SeLow during the update
 // installation of the VPN Server / VPN Client / VPN Bridge is skipped.
-#define	SL_VER						45
+#define	SL_VER						46
 
 // Constants
 #define	SL_MAX_PACKET_SIZE			1600

+ 2 - 2
src/See/See.vcproj

@@ -75,7 +75,7 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalOptions="/driver /subsystem:native,5.00 /FULLBUILD /align:0x80 /osversion:5.00 /MERGE:_PAGE=PAGE /MERGE:_TEXT=.text /NODEFAULTLIB"
+				AdditionalOptions="/driver /subsystem:native,5.00 /FULLBUILD /align:0x80 /osversion:5.00 /MERGE:_PAGE=PAGE /MERGE:_TEXT=.text /NODEFAULTLIB /ALIGN:4096"
 				AdditionalDependencies="ntoskrnl.lib hal.lib wmilib.lib ndis.lib &quot;$(SolutionDir)tmp\VersionResources\$(ProjectName)_$(PlatformName).res&quot;"
 				OutputFile="$(OutDir)\See_x86.sys"
 				LinkIncremental="1"
@@ -179,7 +179,7 @@
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalOptions="/driver /subsystem:native /FULLBUILD /align:0x80 /osversion:5.00 /MERGE:_PAGE=PAGE /MERGE:_TEXT=.text /NODEFAULTLIB"
+				AdditionalOptions="/driver /subsystem:native /FULLBUILD /align:0x80 /osversion:5.00 /MERGE:_PAGE=PAGE /MERGE:_TEXT=.text /NODEFAULTLIB /ALIGN:4096"
 				AdditionalDependencies="ntoskrnl.lib hal.lib wmilib.lib ndis.lib &quot;$(SolutionDir)tmp\VersionResources\$(ProjectName)_$(PlatformName).res&quot;"
 				OutputFile="$(OutDir)\See_x64.sys"
 				LinkIncremental="1"

+ 15 - 1
src/Wfp/Wfp.c

@@ -119,6 +119,8 @@
 #include "Wfp.h"
 
 static WFP_CTX *wfp = NULL;
+static bool g_is_win8 = false;
+static POOL_TYPE g_pool_type = NonPagedPool;
 
 // Dispatch function
 NTSTATUS DriverDispatch(DEVICE_OBJECT *device_object, IRP *irp)
@@ -780,12 +782,24 @@ NTSTATUS DriverEntry(DRIVER_OBJECT *driver_object, UNICODE_STRING *registry_path
 {
 	NTSTATUS ret;
 	FWPM_SESSION0 t;
+	ULONG os_ver1 = 0, os_ver2 = 0;
 
 	if (wfp != NULL)
 	{
 		return STATUS_UNSUCCESSFUL;
 	}
 
+	g_is_win8 = false;
+	g_pool_type = NonPagedPool;
+
+	PsGetVersion(&os_ver1, &os_ver2, NULL, NULL);
+
+	if ((os_ver1 == 6 && os_ver2 >= 2) || (os_ver1 >= 7))
+	{
+		g_is_win8 = true;
+		g_pool_type = 512;
+	}
+
 	wfp = ZeroMalloc(sizeof(WFP_CTX));
 
 	RtlInitUnicodeString(&wfp->DeviceName, WFP_DEVICE_NAME);
@@ -1049,7 +1063,7 @@ void *Malloc(UINT size)
 {
 	void *p;
 
-	p = ExAllocatePoolWithTag(NonPagedPool, size + sizeof(UINT), MEMPOOL_TAG);
+	p = ExAllocatePoolWithTag(g_pool_type, size + sizeof(UINT), MEMPOOL_TAG);
 	*((UINT *)p) = size;
 
 	return ((UCHAR *)p) + sizeof(UINT);

+ 6 - 6
src/Wfp/Wfp.vcproj

@@ -78,9 +78,9 @@
 			<Tool
 				Name="VCLinkerTool"
 				IgnoreImportLibrary="true"
-				AdditionalOptions="/driver /subsystem:native,6.00 /FULLBUILD /align:0x80 /osversion:6.00 /STACK:0x40000,0x1000 /MERGE:_PAGE=PAGE /MERGE:_TEXT=.text /NODEFAULTLIB /stub:C:\WINDDK\7600.16385.0\lib\wlh\stub512.com"
+				AdditionalOptions="/driver /subsystem:native,6.00 /FULLBUILD /align:0x80 /osversion:6.00 /STACK:0x40000,0x1000 /MERGE:_PAGE=PAGE /MERGE:_TEXT=.text /NODEFAULTLIB /stub:C:\WINDDK\7600.16385.0\lib\wlh\stub512.com /ALIGN:4096"
 				AdditionalDependencies="wdm.lib ndis.lib ntoskrnl.lib fwpkclnt.lib &quot;$(SolutionDir)tmp\VersionResources\$(ProjectName)_$(PlatformName).res&quot;"
-				OutputFile="$(OutDir)\pxwfp_x86.sys"
+				OutputFile="$(OutDir)\pxwfp_x86_unsigned.sys"
 				LinkIncremental="1"
 				AdditionalLibraryDirectories="C:\WINDDK\7600.16385.0\lib\wlh\i386"
 				GenerateManifest="false"
@@ -121,7 +121,7 @@
 			/>
 			<Tool
 				Name="VCPostBuildEventTool"
-				CommandLine="$(SolutionDir)bin\BuildUtil.exe /CMD:SignCode &quot;$(TargetPath)&quot; /COMMENT:&quot;VPN Software&quot; /KERNEL:yes"
+				CommandLine="$(SolutionDir)bin\BuildUtil.exe /CMD:SignCode &quot;$(TargetPath)&quot; /DEST:&quot;$(TargetDir)pxwfp_x86.sys&quot; /COMMENT:&quot;VPN Software&quot; /KERNEL:yes /CERTID:0 /SHAMODE:0&#x0D;&#x0A;$(SolutionDir)bin\BuildUtil.exe /CMD:SignCode &quot;$(TargetPath)&quot; /DEST:&quot;$(TargetDir)pxwfp_x86_win10.sys&quot; /COMMENT:&quot;VPN Software&quot; /KERNEL:yes /CERTID:0 /SHAMODE:2"
 			/>
 		</Configuration>
 		<Configuration
@@ -182,9 +182,9 @@
 			<Tool
 				Name="VCLinkerTool"
 				IgnoreImportLibrary="true"
-				AdditionalOptions="/driver /subsystem:native /FULLBUILD /align:0x80 /osversion:6.00 /STACK:0x40000,0x1000 /MERGE:_PAGE=PAGE /MERGE:_TEXT=.text /NODEFAULTLIB /stub:C:\WINDDK\7600.16385.0\lib\wlh\stub512.com"
+				AdditionalOptions="/driver /subsystem:native /FULLBUILD /align:0x80 /osversion:6.00 /STACK:0x40000,0x1000 /MERGE:_PAGE=PAGE /MERGE:_TEXT=.text /NODEFAULTLIB /stub:C:\WINDDK\7600.16385.0\lib\wlh\stub512.com /ALIGN:4096"
 				AdditionalDependencies="wdm.lib ndis.lib wdmsec.lib ntoskrnl.lib fwpkclnt.lib &quot;$(SolutionDir)tmp\VersionResources\$(ProjectName)_$(PlatformName).res&quot;"
-				OutputFile="$(OutDir)\pxwfp_x64.sys"
+				OutputFile="$(OutDir)\pxwfp_x64_unsigned.sys"
 				LinkIncremental="1"
 				AdditionalLibraryDirectories="C:\WINDDK\7600.16385.0\lib\wlh\amd64"
 				GenerateManifest="false"
@@ -225,7 +225,7 @@
 			/>
 			<Tool
 				Name="VCPostBuildEventTool"
-				CommandLine="$(SolutionDir)bin\BuildUtil.exe /CMD:SignCode &quot;$(TargetPath)&quot; /COMMENT:&quot;VPN Software&quot; /KERNEL:yes"
+				CommandLine="$(SolutionDir)bin\BuildUtil.exe /CMD:SignCode &quot;$(TargetPath)&quot; /DEST:&quot;$(TargetDir)pxwfp_x64.sys&quot; /COMMENT:&quot;VPN Software&quot; /KERNEL:yes /CERTID:0 /SHAMODE:0&#x0D;&#x0A;$(SolutionDir)bin\BuildUtil.exe /CMD:SignCode &quot;$(TargetPath)&quot; /DEST:&quot;$(TargetDir)pxwfp_x64_win10.sys&quot; /COMMENT:&quot;VPN Software&quot; /KERNEL:yes /CERTID:0 /SHAMODE:2"
 			/>
 		</Configuration>
 	</Configurations>

+ 3 - 3
src/bin/hamcore/DriverPackages/Neo/x64/Neo_x64.inf

@@ -3,14 +3,14 @@
 ; Copyright (c) SoftEther Corporation. All Rights Reserved.
 ; http://www.softether.co.jp/
 ;
-; BUILD 9558
+; BUILD 9575
 
 [Version]
 Signature					= "$Windows NT$"
 Class						= Net
 ClassGUID					= {4D36E972-E325-11CE-BFC1-08002BE10318}
 Provider					= %CompanyName%
-DriverVer					= 05/29/2015, 4.16.0.9558
+DriverVer					= 09/09/2015, 4.19.0.9575
 ;CatalogFile.NT				= $CATALOG_FILENAME$
 
 [Manufacturer]
@@ -110,5 +110,5 @@ On							= "On"
 Off							= "Off"
 
 
-; Auto Generated 20150530_023418.134
+; Auto Generated 20150910_193640.387
 

BIN
src/bin/hamcore/DriverPackages/Neo/x64/Neo_x64.sys


+ 3 - 3
src/bin/hamcore/DriverPackages/Neo/x86/Neo_x86.inf

@@ -3,14 +3,14 @@
 ; Copyright (c) SoftEther Corporation. All Rights Reserved.
 ; http://www.softether.co.jp/
 ; 
-; BUILD 9558
+; BUILD 9575
 
 [Version]
 Signature					= "$Windows NT$"
 Class						= Net
 ClassGUID					= {4D36E972-E325-11CE-BFC1-08002BE10318}
 Provider					= %CompanyName%
-DriverVer					= 05/29/2015, 4.16.0.9558
+DriverVer					= 09/09/2015, 4.19.0.9575
 ;CatalogFile.NT				= $CATALOG_FILENAME$
 
 [Manufacturer]
@@ -110,5 +110,5 @@ On							= "On"
 Off							= "Off"
 
 
-; Auto Generated 20150530_023418.131
+; Auto Generated 20150910_193640.383
 

BIN
src/bin/hamcore/DriverPackages/Neo/x86/Neo_x86.sys


+ 3 - 3
src/bin/hamcore/DriverPackages/Neo6/x64/Neo6_x64.inf

@@ -3,14 +3,14 @@
 ; Copyright (c) SoftEther Corporation. All Rights Reserved.
 ; http://www.softether.co.jp/
 ; 
-; BUILD 9558
+; BUILD 9575
 
 [Version]
 Signature					= "$Windows NT$"
 Class						= Net
 ClassGUID					= {4D36E972-E325-11CE-BFC1-08002BE10318}
 Provider					= %CompanyName%
-DriverVer					= 05/29/2015, 4.16.0.9558
+DriverVer					= 09/09/2015, 4.19.0.9575
 ;CatalogFile.NT				= $CATALOG_FILENAME$
 
 [Manufacturer]
@@ -110,5 +110,5 @@ On							= "On"
 Off							= "Off"
 
 
-; Auto Generated 20150530_023418.140
+; Auto Generated 20150910_193640.393
 

BIN
src/bin/hamcore/DriverPackages/Neo6/x64/Neo6_x64.sys


+ 3 - 3
src/bin/hamcore/DriverPackages/Neo6/x86/Neo6_x86.inf

@@ -3,14 +3,14 @@
 ; Copyright (c) SoftEther Corporation. All Rights Reserved.
 ; http://www.softether.co.jp/
 ; 
-; BUILD 9558
+; BUILD 9575
 
 [Version]
 Signature					= "$Windows NT$"
 Class						= Net
 ClassGUID					= {4D36E972-E325-11CE-BFC1-08002BE10318}
 Provider					= %CompanyName%
-DriverVer					= 05/29/2015, 4.16.0.9558
+DriverVer					= 09/09/2015, 4.19.0.9575
 ;CatalogFile.NT				= $CATALOG_FILENAME$
 
 [Manufacturer]
@@ -110,5 +110,5 @@ On							= "On"
 Off							= "Off"
 
 
-; Auto Generated 20150530_023418.137
+; Auto Generated 20150910_193640.390
 

BIN
src/bin/hamcore/DriverPackages/Neo6/x86/Neo6_x86.sys


BIN
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN.cat


+ 3 - 3
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN.inf

@@ -3,14 +3,14 @@
 ; Copyright (c) SoftEther Corporation. All Rights Reserved.
 ; http://www.softether.co.jp/
 ; 
-; BUILD 9558
+; BUILD 9575
 
 [Version]
 Signature					= "$Windows NT$"
 Class						= Net
 ClassGUID					= {4D36E972-E325-11CE-BFC1-08002BE10318}
 Provider					= %CompanyName%
-DriverVer					= 05/29/2015, 4.16.0.9558
+DriverVer					= 09/09/2015, 4.19.0.9575
 CatalogFile.NT				= Neo6_x64_VPN.cat
 
 [Manufacturer]
@@ -110,5 +110,5 @@ On							= "On"
 Off							= "Off"
 
 
-; Auto Generated 20150530_023435.313
+; Auto Generated 20150910_193658.928
 

BIN
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN.sys


BIN
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN10.cat


+ 3 - 3
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN10.inf

@@ -3,14 +3,14 @@
 ; Copyright (c) SoftEther Corporation. All Rights Reserved.
 ; http://www.softether.co.jp/
 ; 
-; BUILD 9558
+; BUILD 9575
 
 [Version]
 Signature					= "$Windows NT$"
 Class						= Net
 ClassGUID					= {4D36E972-E325-11CE-BFC1-08002BE10318}
 Provider					= %CompanyName%
-DriverVer					= 05/29/2015, 4.16.0.9558
+DriverVer					= 09/09/2015, 4.19.0.9575
 CatalogFile.NT				= Neo6_x64_VPN10.cat
 
 [Manufacturer]
@@ -110,5 +110,5 @@ On							= "On"
 Off							= "Off"
 
 
-; Auto Generated 20150530_023436.178
+; Auto Generated 20150910_193659.933
 

BIN
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN10.sys


BIN
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN100.cat


+ 3 - 3
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN100.inf

@@ -3,14 +3,14 @@
 ; Copyright (c) SoftEther Corporation. All Rights Reserved.
 ; http://www.softether.co.jp/
 ; 
-; BUILD 9558
+; BUILD 9575
 
 [Version]
 Signature					= "$Windows NT$"
 Class						= Net
 ClassGUID					= {4D36E972-E325-11CE-BFC1-08002BE10318}
 Provider					= %CompanyName%
-DriverVer					= 05/29/2015, 4.16.0.9558
+DriverVer					= 09/09/2015, 4.19.0.9575
 CatalogFile.NT				= Neo6_x64_VPN100.cat
 
 [Manufacturer]
@@ -110,5 +110,5 @@ On							= "On"
 Off							= "Off"
 
 
-; Auto Generated 20150530_023444.795
+; Auto Generated 20150910_193709.982
 

BIN
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN100.sys


BIN
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN101.cat


+ 3 - 3
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN101.inf

@@ -3,14 +3,14 @@
 ; Copyright (c) SoftEther Corporation. All Rights Reserved.
 ; http://www.softether.co.jp/
 ; 
-; BUILD 9558
+; BUILD 9575
 
 [Version]
 Signature					= "$Windows NT$"
 Class						= Net
 ClassGUID					= {4D36E972-E325-11CE-BFC1-08002BE10318}
 Provider					= %CompanyName%
-DriverVer					= 05/29/2015, 4.16.0.9558
+DriverVer					= 09/09/2015, 4.19.0.9575
 CatalogFile.NT				= Neo6_x64_VPN101.cat
 
 [Manufacturer]
@@ -110,5 +110,5 @@ On							= "On"
 Off							= "Off"
 
 
-; Auto Generated 20150530_023444.890
+; Auto Generated 20150910_193710.086
 

BIN
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN101.sys


BIN
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN102.cat


+ 3 - 3
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN102.inf

@@ -3,14 +3,14 @@
 ; Copyright (c) SoftEther Corporation. All Rights Reserved.
 ; http://www.softether.co.jp/
 ; 
-; BUILD 9558
+; BUILD 9575
 
 [Version]
 Signature					= "$Windows NT$"
 Class						= Net
 ClassGUID					= {4D36E972-E325-11CE-BFC1-08002BE10318}
 Provider					= %CompanyName%
-DriverVer					= 05/29/2015, 4.16.0.9558
+DriverVer					= 09/09/2015, 4.19.0.9575
 CatalogFile.NT				= Neo6_x64_VPN102.cat
 
 [Manufacturer]
@@ -110,5 +110,5 @@ On							= "On"
 Off							= "Off"
 
 
-; Auto Generated 20150530_023444.985
+; Auto Generated 20150910_193710.189
 

BIN
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN102.sys


BIN
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN103.cat


+ 3 - 3
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN103.inf

@@ -3,14 +3,14 @@
 ; Copyright (c) SoftEther Corporation. All Rights Reserved.
 ; http://www.softether.co.jp/
 ; 
-; BUILD 9558
+; BUILD 9575
 
 [Version]
 Signature					= "$Windows NT$"
 Class						= Net
 ClassGUID					= {4D36E972-E325-11CE-BFC1-08002BE10318}
 Provider					= %CompanyName%
-DriverVer					= 05/29/2015, 4.16.0.9558
+DriverVer					= 09/09/2015, 4.19.0.9575
 CatalogFile.NT				= Neo6_x64_VPN103.cat
 
 [Manufacturer]
@@ -110,5 +110,5 @@ On							= "On"
 Off							= "Off"
 
 
-; Auto Generated 20150530_023445.079
+; Auto Generated 20150910_193710.292
 

BIN
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN103.sys


BIN
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN104.cat


+ 3 - 3
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN104.inf

@@ -3,14 +3,14 @@
 ; Copyright (c) SoftEther Corporation. All Rights Reserved.
 ; http://www.softether.co.jp/
 ; 
-; BUILD 9558
+; BUILD 9575
 
 [Version]
 Signature					= "$Windows NT$"
 Class						= Net
 ClassGUID					= {4D36E972-E325-11CE-BFC1-08002BE10318}
 Provider					= %CompanyName%
-DriverVer					= 05/29/2015, 4.16.0.9558
+DriverVer					= 09/09/2015, 4.19.0.9575
 CatalogFile.NT				= Neo6_x64_VPN104.cat
 
 [Manufacturer]
@@ -110,5 +110,5 @@ On							= "On"
 Off							= "Off"
 
 
-; Auto Generated 20150530_023445.174
+; Auto Generated 20150910_193710.395
 

BIN
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN104.sys


BIN
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN105.cat


+ 3 - 3
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN105.inf

@@ -3,14 +3,14 @@
 ; Copyright (c) SoftEther Corporation. All Rights Reserved.
 ; http://www.softether.co.jp/
 ; 
-; BUILD 9558
+; BUILD 9575
 
 [Version]
 Signature					= "$Windows NT$"
 Class						= Net
 ClassGUID					= {4D36E972-E325-11CE-BFC1-08002BE10318}
 Provider					= %CompanyName%
-DriverVer					= 05/29/2015, 4.16.0.9558
+DriverVer					= 09/09/2015, 4.19.0.9575
 CatalogFile.NT				= Neo6_x64_VPN105.cat
 
 [Manufacturer]
@@ -110,5 +110,5 @@ On							= "On"
 Off							= "Off"
 
 
-; Auto Generated 20150530_023445.269
+; Auto Generated 20150910_193710.534
 

BIN
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN105.sys


BIN
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN106.cat


+ 3 - 3
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN106.inf

@@ -3,14 +3,14 @@
 ; Copyright (c) SoftEther Corporation. All Rights Reserved.
 ; http://www.softether.co.jp/
 ; 
-; BUILD 9558
+; BUILD 9575
 
 [Version]
 Signature					= "$Windows NT$"
 Class						= Net
 ClassGUID					= {4D36E972-E325-11CE-BFC1-08002BE10318}
 Provider					= %CompanyName%
-DriverVer					= 05/29/2015, 4.16.0.9558
+DriverVer					= 09/09/2015, 4.19.0.9575
 CatalogFile.NT				= Neo6_x64_VPN106.cat
 
 [Manufacturer]
@@ -110,5 +110,5 @@ On							= "On"
 Off							= "Off"
 
 
-; Auto Generated 20150530_023445.364
+; Auto Generated 20150910_193710.656
 

BIN
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN106.sys


BIN
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN107.cat


+ 3 - 3
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN107.inf

@@ -3,14 +3,14 @@
 ; Copyright (c) SoftEther Corporation. All Rights Reserved.
 ; http://www.softether.co.jp/
 ; 
-; BUILD 9558
+; BUILD 9575
 
 [Version]
 Signature					= "$Windows NT$"
 Class						= Net
 ClassGUID					= {4D36E972-E325-11CE-BFC1-08002BE10318}
 Provider					= %CompanyName%
-DriverVer					= 05/29/2015, 4.16.0.9558
+DriverVer					= 09/09/2015, 4.19.0.9575
 CatalogFile.NT				= Neo6_x64_VPN107.cat
 
 [Manufacturer]
@@ -110,5 +110,5 @@ On							= "On"
 Off							= "Off"
 
 
-; Auto Generated 20150530_023445.459
+; Auto Generated 20150910_193710.977
 

BIN
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN107.sys


BIN
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN108.cat


+ 3 - 3
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN108.inf

@@ -3,14 +3,14 @@
 ; Copyright (c) SoftEther Corporation. All Rights Reserved.
 ; http://www.softether.co.jp/
 ; 
-; BUILD 9558
+; BUILD 9575
 
 [Version]
 Signature					= "$Windows NT$"
 Class						= Net
 ClassGUID					= {4D36E972-E325-11CE-BFC1-08002BE10318}
 Provider					= %CompanyName%
-DriverVer					= 05/29/2015, 4.16.0.9558
+DriverVer					= 09/09/2015, 4.19.0.9575
 CatalogFile.NT				= Neo6_x64_VPN108.cat
 
 [Manufacturer]
@@ -110,5 +110,5 @@ On							= "On"
 Off							= "Off"
 
 
-; Auto Generated 20150530_023445.556
+; Auto Generated 20150910_193711.080
 

BIN
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN108.sys


BIN
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN109.cat


+ 3 - 3
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN109.inf

@@ -3,14 +3,14 @@
 ; Copyright (c) SoftEther Corporation. All Rights Reserved.
 ; http://www.softether.co.jp/
 ; 
-; BUILD 9558
+; BUILD 9575
 
 [Version]
 Signature					= "$Windows NT$"
 Class						= Net
 ClassGUID					= {4D36E972-E325-11CE-BFC1-08002BE10318}
 Provider					= %CompanyName%
-DriverVer					= 05/29/2015, 4.16.0.9558
+DriverVer					= 09/09/2015, 4.19.0.9575
 CatalogFile.NT				= Neo6_x64_VPN109.cat
 
 [Manufacturer]
@@ -110,5 +110,5 @@ On							= "On"
 Off							= "Off"
 
 
-; Auto Generated 20150530_023445.652
+; Auto Generated 20150910_193711.184
 

BIN
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN109.sys


BIN
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN11.cat


+ 3 - 3
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN11.inf

@@ -3,14 +3,14 @@
 ; Copyright (c) SoftEther Corporation. All Rights Reserved.
 ; http://www.softether.co.jp/
 ; 
-; BUILD 9558
+; BUILD 9575
 
 [Version]
 Signature					= "$Windows NT$"
 Class						= Net
 ClassGUID					= {4D36E972-E325-11CE-BFC1-08002BE10318}
 Provider					= %CompanyName%
-DriverVer					= 05/29/2015, 4.16.0.9558
+DriverVer					= 09/09/2015, 4.19.0.9575
 CatalogFile.NT				= Neo6_x64_VPN11.cat
 
 [Manufacturer]
@@ -110,5 +110,5 @@ On							= "On"
 Off							= "Off"
 
 
-; Auto Generated 20150530_023436.274
+; Auto Generated 20150910_193700.037
 

BIN
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN11.sys


BIN
src/bin/hamcore/DriverPackages/Neo6_Win10/x64/Neo6_x64_VPN110.cat


Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels