From 77bab135465a14d13f7835c7a9c3a53dc04496dd Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Mon, 18 Nov 2013 12:01:33 -0500 Subject: More UI work, reorg Windows stuff... --- ZeroTierOne.sln | 390 --- ZeroTierUI/ZeroTierUI.pro | 3 +- ZeroTierUI/mainwindow.cpp | 30 + ZeroTierUI/mainwindow.ui | 5 +- ZeroTierUI/network.cpp | 13 +- ZeroTierUI/network.h | 9 +- ZeroTierUI/network.ui | 254 +- vsprojects/SelfTest/SelfTest.vcxproj | 231 -- vsprojects/SelfTest/SelfTest.vcxproj.filters | 227 -- vsprojects/SelfTest/targetver.h | 8 - .../TapDriver Package/TapDriver Package.vcxproj | 155 - .../TapDriver Package.vcxproj.filters | 9 - vsprojects/TapDriver/TapDriver.vcxproj | 352 --- vsprojects/TapDriver/TapDriver.vcxproj.filters | 81 - vsprojects/TapDriver/config.h | 12 - vsprojects/TapDriver/constants.h | 52 - vsprojects/TapDriver/dhcp.c | 603 ---- vsprojects/TapDriver/dhcp.h | 168 -- vsprojects/TapDriver/endian.h | 35 - vsprojects/TapDriver/error.c | 387 --- vsprojects/TapDriver/error.h | 88 - vsprojects/TapDriver/instance.c | 241 -- vsprojects/TapDriver/lock.h | 75 - vsprojects/TapDriver/macinfo.c | 154 - vsprojects/TapDriver/macinfo.h | 38 - vsprojects/TapDriver/mem.c | 186 -- vsprojects/TapDriver/proto.h | 224 -- vsprojects/TapDriver/prototypes.h | 260 -- vsprojects/TapDriver/tap-windows.h | 73 - vsprojects/TapDriver/tapdrvr.c | 3173 -------------------- vsprojects/TapDriver/testcert.pfx | Bin 2651 -> 0 bytes vsprojects/TapDriver/types.h | 182 -- vsprojects/TapDriver/ztTap100.inf | 84 - vsprojects/ZeroTierOne/ZeroTierOne.vcxproj | 228 -- vsprojects/ZeroTierOne/ZeroTierOne.vcxproj.filters | 228 -- windows/SelfTest/SelfTest.vcxproj | 231 ++ windows/SelfTest/SelfTest.vcxproj.filters | 227 ++ windows/SelfTest/targetver.h | 8 + .../TapDriver Package/TapDriver Package.vcxproj | 155 + .../TapDriver Package.vcxproj.filters | 9 + windows/TapDriver/TapDriver.vcxproj | 352 +++ windows/TapDriver/TapDriver.vcxproj.filters | 81 + windows/TapDriver/config.h | 12 + windows/TapDriver/constants.h | 52 + windows/TapDriver/dhcp.c | 603 ++++ windows/TapDriver/dhcp.h | 168 ++ windows/TapDriver/endian.h | 35 + windows/TapDriver/error.c | 387 +++ windows/TapDriver/error.h | 88 + windows/TapDriver/instance.c | 241 ++ windows/TapDriver/lock.h | 75 + windows/TapDriver/macinfo.c | 154 + windows/TapDriver/macinfo.h | 38 + windows/TapDriver/mem.c | 186 ++ windows/TapDriver/proto.h | 224 ++ windows/TapDriver/prototypes.h | 260 ++ windows/TapDriver/tap-windows.h | 73 + windows/TapDriver/tapdrvr.c | 3173 ++++++++++++++++++++ windows/TapDriver/testcert.pfx | Bin 0 -> 2651 bytes windows/TapDriver/types.h | 182 ++ windows/TapDriver/ztTap100.inf | 84 + windows/ZeroTierOne.sln | 390 +++ windows/ZeroTierOne/ZeroTierOne.vcxproj | 228 ++ windows/ZeroTierOne/ZeroTierOne.vcxproj.filters | 228 ++ 64 files changed, 8240 insertions(+), 7962 deletions(-) delete mode 100644 ZeroTierOne.sln delete mode 100644 vsprojects/SelfTest/SelfTest.vcxproj delete mode 100644 vsprojects/SelfTest/SelfTest.vcxproj.filters delete mode 100644 vsprojects/SelfTest/targetver.h delete mode 100644 vsprojects/TapDriver Package/TapDriver Package.vcxproj delete mode 100644 vsprojects/TapDriver Package/TapDriver Package.vcxproj.filters delete mode 100644 vsprojects/TapDriver/TapDriver.vcxproj delete mode 100644 vsprojects/TapDriver/TapDriver.vcxproj.filters delete mode 100644 vsprojects/TapDriver/config.h delete mode 100644 vsprojects/TapDriver/constants.h delete mode 100644 vsprojects/TapDriver/dhcp.c delete mode 100644 vsprojects/TapDriver/dhcp.h delete mode 100644 vsprojects/TapDriver/endian.h delete mode 100644 vsprojects/TapDriver/error.c delete mode 100644 vsprojects/TapDriver/error.h delete mode 100644 vsprojects/TapDriver/instance.c delete mode 100644 vsprojects/TapDriver/lock.h delete mode 100644 vsprojects/TapDriver/macinfo.c delete mode 100644 vsprojects/TapDriver/macinfo.h delete mode 100644 vsprojects/TapDriver/mem.c delete mode 100644 vsprojects/TapDriver/proto.h delete mode 100644 vsprojects/TapDriver/prototypes.h delete mode 100644 vsprojects/TapDriver/tap-windows.h delete mode 100644 vsprojects/TapDriver/tapdrvr.c delete mode 100644 vsprojects/TapDriver/testcert.pfx delete mode 100644 vsprojects/TapDriver/types.h delete mode 100644 vsprojects/TapDriver/ztTap100.inf delete mode 100644 vsprojects/ZeroTierOne/ZeroTierOne.vcxproj delete mode 100644 vsprojects/ZeroTierOne/ZeroTierOne.vcxproj.filters create mode 100644 windows/SelfTest/SelfTest.vcxproj create mode 100644 windows/SelfTest/SelfTest.vcxproj.filters create mode 100644 windows/SelfTest/targetver.h create mode 100644 windows/TapDriver Package/TapDriver Package.vcxproj create mode 100644 windows/TapDriver Package/TapDriver Package.vcxproj.filters create mode 100644 windows/TapDriver/TapDriver.vcxproj create mode 100644 windows/TapDriver/TapDriver.vcxproj.filters create mode 100644 windows/TapDriver/config.h create mode 100644 windows/TapDriver/constants.h create mode 100644 windows/TapDriver/dhcp.c create mode 100644 windows/TapDriver/dhcp.h create mode 100644 windows/TapDriver/endian.h create mode 100644 windows/TapDriver/error.c create mode 100644 windows/TapDriver/error.h create mode 100644 windows/TapDriver/instance.c create mode 100644 windows/TapDriver/lock.h create mode 100644 windows/TapDriver/macinfo.c create mode 100644 windows/TapDriver/macinfo.h create mode 100644 windows/TapDriver/mem.c create mode 100644 windows/TapDriver/proto.h create mode 100644 windows/TapDriver/prototypes.h create mode 100644 windows/TapDriver/tap-windows.h create mode 100644 windows/TapDriver/tapdrvr.c create mode 100644 windows/TapDriver/testcert.pfx create mode 100644 windows/TapDriver/types.h create mode 100644 windows/TapDriver/ztTap100.inf create mode 100644 windows/ZeroTierOne.sln create mode 100644 windows/ZeroTierOne/ZeroTierOne.vcxproj create mode 100644 windows/ZeroTierOne/ZeroTierOne.vcxproj.filters diff --git a/ZeroTierOne.sln b/ZeroTierOne.sln deleted file mode 100644 index 90f8243b..00000000 --- a/ZeroTierOne.sln +++ /dev/null @@ -1,390 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SelfTest", "vsprojects\SelfTest\SelfTest.vcxproj", "{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TapDriver", "vsprojects\TapDriver\TapDriver.vcxproj", "{689210B1-467C-4850-BB7D-2E10D5B4A3DA}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TapDriver Package", "vsprojects\TapDriver Package\TapDriver Package.vcxproj", "{FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}" - ProjectSection(ProjectDependencies) = postProject - {689210B1-467C-4850-BB7D-2E10D5B4A3DA} = {689210B1-467C-4850-BB7D-2E10D5B4A3DA} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZeroTierOne", "vsprojects\ZeroTierOne\ZeroTierOne.vcxproj", "{B00A4957-5977-4AC1-9EF4-571DC27EADA2}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|Mixed Platforms = Debug|Mixed Platforms - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Any CPU = Release|Any CPU - Release|Mixed Platforms = Release|Mixed Platforms - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - Vista Debug|Any CPU = Vista Debug|Any CPU - Vista Debug|Mixed Platforms = Vista Debug|Mixed Platforms - Vista Debug|Win32 = Vista Debug|Win32 - Vista Debug|x64 = Vista Debug|x64 - Vista Release|Any CPU = Vista Release|Any CPU - Vista Release|Mixed Platforms = Vista Release|Mixed Platforms - Vista Release|Win32 = Vista Release|Win32 - Vista Release|x64 = Vista Release|x64 - Win7 Debug|Any CPU = Win7 Debug|Any CPU - Win7 Debug|Mixed Platforms = Win7 Debug|Mixed Platforms - Win7 Debug|Win32 = Win7 Debug|Win32 - Win7 Debug|x64 = Win7 Debug|x64 - Win7 Release|Any CPU = Win7 Release|Any CPU - Win7 Release|Mixed Platforms = Win7 Release|Mixed Platforms - Win7 Release|Win32 = Win7 Release|Win32 - Win7 Release|x64 = Win7 Release|x64 - Win8 Debug|Any CPU = Win8 Debug|Any CPU - Win8 Debug|Mixed Platforms = Win8 Debug|Mixed Platforms - Win8 Debug|Win32 = Win8 Debug|Win32 - Win8 Debug|x64 = Win8 Debug|x64 - Win8 Release|Any CPU = Win8 Release|Any CPU - Win8 Release|Mixed Platforms = Win8 Release|Mixed Platforms - Win8 Release|Win32 = Win8 Release|Win32 - Win8 Release|x64 = Win8 Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Debug|Win32.ActiveCfg = Release|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Debug|Win32.Build.0 = Release|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Debug|x64.ActiveCfg = Debug|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Release|Any CPU.ActiveCfg = Release|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Release|Win32.ActiveCfg = Release|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Release|Win32.Build.0 = Release|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Release|x64.ActiveCfg = Release|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Debug|Any CPU.ActiveCfg = Debug|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Debug|Win32.ActiveCfg = Debug|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Debug|Win32.Build.0 = Debug|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Debug|Win32.Deploy.0 = Debug|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Debug|x64.ActiveCfg = Debug|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Release|Any CPU.ActiveCfg = Release|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Release|Mixed Platforms.ActiveCfg = Release|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Release|Win32.ActiveCfg = Release|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Release|Win32.Build.0 = Release|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Release|Win32.Deploy.0 = Release|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Release|x64.ActiveCfg = Release|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Debug|Any CPU.ActiveCfg = Debug|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Debug|Win32.ActiveCfg = Debug|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Debug|Win32.Build.0 = Debug|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Debug|Win32.Deploy.0 = Debug|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Debug|x64.ActiveCfg = Debug|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Release|Any CPU.ActiveCfg = Release|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Release|Mixed Platforms.ActiveCfg = Release|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Release|Win32.ActiveCfg = Release|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Release|Win32.Build.0 = Release|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Release|Win32.Deploy.0 = Release|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Release|x64.ActiveCfg = Release|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Debug|Any CPU.ActiveCfg = Debug|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Debug|Win32.ActiveCfg = Debug|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Debug|Win32.Build.0 = Debug|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Debug|Win32.Deploy.0 = Debug|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Debug|x64.ActiveCfg = Debug|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Release|Any CPU.ActiveCfg = Release|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Release|Mixed Platforms.ActiveCfg = Release|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Release|Win32.ActiveCfg = Release|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Release|Win32.Build.0 = Release|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Release|Win32.Deploy.0 = Release|Win32 - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Release|x64.ActiveCfg = Release|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Debug|Any CPU.ActiveCfg = Win8 Debug|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Debug|Mixed Platforms.ActiveCfg = Win8 Debug|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Debug|Win32.ActiveCfg = Win7 Debug|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Debug|Win32.Build.0 = Win7 Debug|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Debug|Win32.Deploy.0 = Win7 Debug|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Debug|x64.ActiveCfg = Win7 Debug|x64 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Debug|x64.Build.0 = Win7 Debug|x64 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Debug|x64.Deploy.0 = Win7 Debug|x64 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Release|Any CPU.ActiveCfg = Win7 Release|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Release|Mixed Platforms.ActiveCfg = Win7 Release|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Release|Win32.ActiveCfg = Win8 Release|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Release|Win32.Build.0 = Win8 Release|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Release|Win32.Deploy.0 = Win8 Release|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Release|x64.ActiveCfg = Win7 Release|x64 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Release|x64.Build.0 = Win7 Release|x64 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Release|x64.Deploy.0 = Win7 Release|x64 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Debug|Any CPU.ActiveCfg = Vista Debug|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Debug|Mixed Platforms.ActiveCfg = Vista Debug|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Debug|Win32.ActiveCfg = Vista Debug|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Debug|Win32.Build.0 = Vista Debug|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Debug|Win32.Deploy.0 = Vista Debug|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Debug|x64.ActiveCfg = Vista Debug|x64 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Debug|x64.Build.0 = Vista Debug|x64 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Debug|x64.Deploy.0 = Vista Debug|x64 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Release|Any CPU.ActiveCfg = Vista Release|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Release|Mixed Platforms.ActiveCfg = Vista Release|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Release|Win32.ActiveCfg = Vista Release|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Release|Win32.Build.0 = Vista Release|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Release|Win32.Deploy.0 = Vista Release|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Release|x64.ActiveCfg = Vista Release|x64 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Release|x64.Build.0 = Vista Release|x64 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Release|x64.Deploy.0 = Vista Release|x64 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Debug|Any CPU.ActiveCfg = Win7 Debug|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Debug|Mixed Platforms.ActiveCfg = Win7 Debug|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Debug|Win32.ActiveCfg = Win7 Debug|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Debug|Win32.Build.0 = Win7 Debug|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Debug|Win32.Deploy.0 = Win7 Debug|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Debug|x64.ActiveCfg = Win7 Debug|x64 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Debug|x64.Build.0 = Win7 Debug|x64 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Debug|x64.Deploy.0 = Win7 Debug|x64 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Release|Any CPU.ActiveCfg = Win7 Release|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Release|Mixed Platforms.ActiveCfg = Win7 Release|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Release|Win32.ActiveCfg = Win7 Release|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Release|Win32.Build.0 = Win7 Release|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Release|Win32.Deploy.0 = Win7 Release|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Release|x64.ActiveCfg = Win7 Release|x64 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Release|x64.Build.0 = Win7 Release|x64 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Release|x64.Deploy.0 = Win7 Release|x64 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Debug|Any CPU.ActiveCfg = Win8 Debug|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Debug|Mixed Platforms.ActiveCfg = Win8 Debug|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Debug|Win32.ActiveCfg = Win8 Debug|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Debug|Win32.Build.0 = Win8 Debug|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Debug|Win32.Deploy.0 = Win8 Debug|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Debug|x64.ActiveCfg = Win8 Debug|x64 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Debug|x64.Build.0 = Win8 Debug|x64 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Debug|x64.Deploy.0 = Win8 Debug|x64 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Release|Any CPU.ActiveCfg = Win8 Release|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Release|Mixed Platforms.ActiveCfg = Win8 Release|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Release|Win32.ActiveCfg = Win8 Release|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Release|Win32.Build.0 = Win8 Release|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Release|Win32.Deploy.0 = Win8 Release|Win32 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Release|x64.ActiveCfg = Win8 Release|x64 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Release|x64.Build.0 = Win8 Release|x64 - {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Release|x64.Deploy.0 = Win8 Release|x64 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Debug|Any CPU.ActiveCfg = Win8 Debug|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Debug|Mixed Platforms.ActiveCfg = Win8 Debug|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Debug|Win32.ActiveCfg = Win7 Debug|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Debug|Win32.Build.0 = Win7 Debug|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Debug|Win32.Deploy.0 = Win7 Debug|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Debug|x64.ActiveCfg = Win7 Debug|x64 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Debug|x64.Build.0 = Win7 Debug|x64 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Debug|x64.Deploy.0 = Win7 Debug|x64 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Release|Any CPU.ActiveCfg = Win7 Release|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Release|Mixed Platforms.ActiveCfg = Win7 Release|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Release|Win32.ActiveCfg = Win8 Release|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Release|Win32.Build.0 = Win8 Release|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Release|Win32.Deploy.0 = Win8 Release|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Release|x64.ActiveCfg = Win7 Release|x64 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Release|x64.Build.0 = Win7 Release|x64 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Release|x64.Deploy.0 = Win7 Release|x64 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Debug|Any CPU.ActiveCfg = Vista Debug|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Debug|Mixed Platforms.ActiveCfg = Vista Debug|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Debug|Win32.ActiveCfg = Vista Debug|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Debug|Win32.Build.0 = Vista Debug|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Debug|Win32.Deploy.0 = Vista Debug|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Debug|x64.ActiveCfg = Vista Debug|x64 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Debug|x64.Build.0 = Vista Debug|x64 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Debug|x64.Deploy.0 = Vista Debug|x64 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Release|Any CPU.ActiveCfg = Vista Release|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Release|Mixed Platforms.ActiveCfg = Vista Release|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Release|Win32.ActiveCfg = Vista Release|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Release|Win32.Build.0 = Vista Release|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Release|Win32.Deploy.0 = Vista Release|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Release|x64.ActiveCfg = Vista Release|x64 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Release|x64.Build.0 = Vista Release|x64 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Release|x64.Deploy.0 = Vista Release|x64 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Debug|Any CPU.ActiveCfg = Win7 Debug|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Debug|Mixed Platforms.ActiveCfg = Win7 Debug|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Debug|Win32.ActiveCfg = Win7 Debug|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Debug|Win32.Build.0 = Win7 Debug|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Debug|Win32.Deploy.0 = Win7 Debug|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Debug|x64.ActiveCfg = Win7 Debug|x64 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Debug|x64.Build.0 = Win7 Debug|x64 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Debug|x64.Deploy.0 = Win7 Debug|x64 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Release|Any CPU.ActiveCfg = Win7 Release|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Release|Mixed Platforms.ActiveCfg = Win7 Release|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Release|Win32.ActiveCfg = Win7 Release|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Release|Win32.Build.0 = Win7 Release|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Release|Win32.Deploy.0 = Win7 Release|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Release|x64.ActiveCfg = Win7 Release|x64 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Release|x64.Build.0 = Win7 Release|x64 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Release|x64.Deploy.0 = Win7 Release|x64 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Debug|Any CPU.ActiveCfg = Win8 Debug|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Debug|Mixed Platforms.ActiveCfg = Win8 Debug|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Debug|Win32.ActiveCfg = Win8 Debug|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Debug|Win32.Build.0 = Win8 Debug|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Debug|Win32.Deploy.0 = Win8 Debug|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Debug|x64.ActiveCfg = Win8 Debug|x64 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Debug|x64.Build.0 = Win8 Debug|x64 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Debug|x64.Deploy.0 = Win8 Debug|x64 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Release|Any CPU.ActiveCfg = Win8 Release|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Release|Mixed Platforms.ActiveCfg = Win8 Release|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Release|Win32.ActiveCfg = Win8 Release|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Release|Win32.Build.0 = Win8 Release|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Release|Win32.Deploy.0 = Win8 Release|Win32 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Release|x64.ActiveCfg = Win8 Release|x64 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Release|x64.Build.0 = Win8 Release|x64 - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Release|x64.Deploy.0 = Win8 Release|x64 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Debug|Mixed Platforms.Deploy.0 = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Debug|Win32.ActiveCfg = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Debug|Win32.Build.0 = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Debug|Win32.Deploy.0 = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Debug|x64.ActiveCfg = Debug|x64 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Debug|x64.Build.0 = Debug|x64 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Release|Any CPU.ActiveCfg = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Release|Mixed Platforms.Build.0 = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Release|Mixed Platforms.Deploy.0 = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Release|Win32.ActiveCfg = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Release|Win32.Build.0 = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Release|Win32.Deploy.0 = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Release|x64.ActiveCfg = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Debug|Any CPU.ActiveCfg = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Debug|Mixed Platforms.Build.0 = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Debug|Mixed Platforms.Deploy.0 = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Debug|Win32.ActiveCfg = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Debug|Win32.Build.0 = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Debug|Win32.Deploy.0 = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Debug|x64.ActiveCfg = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Release|Any CPU.ActiveCfg = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Release|Mixed Platforms.ActiveCfg = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Release|Mixed Platforms.Build.0 = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Release|Mixed Platforms.Deploy.0 = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Release|Win32.ActiveCfg = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Release|Win32.Build.0 = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Release|Win32.Deploy.0 = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Release|x64.ActiveCfg = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Debug|Any CPU.ActiveCfg = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Debug|Mixed Platforms.Build.0 = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Debug|Mixed Platforms.Deploy.0 = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Debug|Win32.ActiveCfg = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Debug|Win32.Build.0 = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Debug|Win32.Deploy.0 = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Debug|x64.ActiveCfg = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Release|Any CPU.ActiveCfg = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Release|Mixed Platforms.ActiveCfg = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Release|Mixed Platforms.Build.0 = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Release|Mixed Platforms.Deploy.0 = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Release|Win32.ActiveCfg = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Release|Win32.Build.0 = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Release|Win32.Deploy.0 = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Release|x64.ActiveCfg = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Debug|Any CPU.ActiveCfg = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Debug|Mixed Platforms.Build.0 = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Debug|Mixed Platforms.Deploy.0 = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Debug|Win32.ActiveCfg = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Debug|Win32.Build.0 = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Debug|Win32.Deploy.0 = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Debug|x64.ActiveCfg = Debug|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Release|Any CPU.ActiveCfg = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Release|Mixed Platforms.ActiveCfg = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Release|Mixed Platforms.Build.0 = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Release|Mixed Platforms.Deploy.0 = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Release|Win32.ActiveCfg = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Release|Win32.Build.0 = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Release|Win32.Deploy.0 = Release|Win32 - {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Release|x64.ActiveCfg = Release|Win32 - {079E8119-388C-4676-964E-0B8C5324F770}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Debug|Any CPU.Build.0 = Debug|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Debug|Win32.ActiveCfg = Debug|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Debug|x64.ActiveCfg = Debug|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Release|Any CPU.ActiveCfg = Release|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Release|Any CPU.Build.0 = Release|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Release|Win32.ActiveCfg = Release|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Release|x64.ActiveCfg = Release|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Vista Debug|Any CPU.ActiveCfg = Debug|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Vista Debug|Any CPU.Build.0 = Debug|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Vista Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Vista Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Vista Debug|Win32.ActiveCfg = Debug|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Vista Debug|x64.ActiveCfg = Debug|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Vista Release|Any CPU.ActiveCfg = Release|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Vista Release|Any CPU.Build.0 = Release|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Vista Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Vista Release|Mixed Platforms.Build.0 = Release|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Vista Release|Win32.ActiveCfg = Release|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Vista Release|x64.ActiveCfg = Release|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Win7 Debug|Any CPU.ActiveCfg = Debug|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Win7 Debug|Any CPU.Build.0 = Debug|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Win7 Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Win7 Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Win7 Debug|Win32.ActiveCfg = Debug|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Win7 Debug|x64.ActiveCfg = Debug|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Win7 Release|Any CPU.ActiveCfg = Release|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Win7 Release|Any CPU.Build.0 = Release|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Win7 Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Win7 Release|Mixed Platforms.Build.0 = Release|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Win7 Release|Win32.ActiveCfg = Release|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Win7 Release|x64.ActiveCfg = Release|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Win8 Debug|Any CPU.ActiveCfg = Debug|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Win8 Debug|Any CPU.Build.0 = Debug|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Win8 Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Win8 Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Win8 Debug|Win32.ActiveCfg = Debug|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Win8 Debug|x64.ActiveCfg = Debug|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Win8 Release|Any CPU.ActiveCfg = Release|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Win8 Release|Any CPU.Build.0 = Release|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Win8 Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Win8 Release|Mixed Platforms.Build.0 = Release|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Win8 Release|Win32.ActiveCfg = Release|Any CPU - {079E8119-388C-4676-964E-0B8C5324F770}.Win8 Release|x64.ActiveCfg = Release|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Debug|Win32.ActiveCfg = Debug|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Debug|x64.ActiveCfg = Debug|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Release|Any CPU.Build.0 = Release|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Release|Win32.ActiveCfg = Release|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Release|x64.ActiveCfg = Release|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Vista Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Vista Debug|Any CPU.Build.0 = Debug|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Vista Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Vista Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Vista Debug|Win32.ActiveCfg = Debug|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Vista Debug|x64.ActiveCfg = Debug|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Vista Release|Any CPU.ActiveCfg = Release|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Vista Release|Any CPU.Build.0 = Release|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Vista Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Vista Release|Mixed Platforms.Build.0 = Release|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Vista Release|Win32.ActiveCfg = Release|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Vista Release|x64.ActiveCfg = Release|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win7 Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win7 Debug|Any CPU.Build.0 = Debug|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win7 Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win7 Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win7 Debug|Win32.ActiveCfg = Debug|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win7 Debug|x64.ActiveCfg = Debug|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win7 Release|Any CPU.ActiveCfg = Release|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win7 Release|Any CPU.Build.0 = Release|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win7 Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win7 Release|Mixed Platforms.Build.0 = Release|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win7 Release|Win32.ActiveCfg = Release|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win7 Release|x64.ActiveCfg = Release|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win8 Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win8 Debug|Any CPU.Build.0 = Debug|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win8 Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win8 Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win8 Debug|Win32.ActiveCfg = Debug|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win8 Debug|x64.ActiveCfg = Debug|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win8 Release|Any CPU.ActiveCfg = Release|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win8 Release|Any CPU.Build.0 = Release|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win8 Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win8 Release|Mixed Platforms.Build.0 = Release|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win8 Release|Win32.ActiveCfg = Release|Any CPU - {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win8 Release|x64.ActiveCfg = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/ZeroTierUI/ZeroTierUI.pro b/ZeroTierUI/ZeroTierUI.pro index fcdba8ca..7c907c06 100644 --- a/ZeroTierUI/ZeroTierUI.pro +++ b/ZeroTierUI/ZeroTierUI.pro @@ -19,7 +19,8 @@ SOURCES += main.cpp\ HEADERS += mainwindow.h \ network.h \ - aboutwindow.h + aboutwindow.h \ + ../node/Node.hpp FORMS += mainwindow.ui \ network.ui \ diff --git a/ZeroTierUI/mainwindow.cpp b/ZeroTierUI/mainwindow.cpp index 41d94987..bb2c263b 100644 --- a/ZeroTierUI/mainwindow.cpp +++ b/ZeroTierUI/mainwindow.cpp @@ -28,6 +28,7 @@ void MainWindow::on_actionAbout_triggered() void MainWindow::on_actionJoin_Network_triggered() { + // Does the same thing as clicking join button on main UI on_joinNetworkButton_clicked(); } @@ -37,6 +38,35 @@ void MainWindow::on_actionShow_Detailed_Status_triggered() void MainWindow::on_networkIdLineEdit_textChanged(const QString &text) { + QString newText; + for(QString::const_iterator i(text.begin());i!=text.end();++i) { + switch(i->toLatin1()) { + case '0': newText.append('0'); break; + case '1': newText.append('1'); break; + case '2': newText.append('2'); break; + case '3': newText.append('3'); break; + case '4': newText.append('4'); break; + case '5': newText.append('5'); break; + case '6': newText.append('6'); break; + case '7': newText.append('7'); break; + case '8': newText.append('8'); break; + case '9': newText.append('9'); break; + case 'a': newText.append('a'); break; + case 'b': newText.append('b'); break; + case 'c': newText.append('c'); break; + case 'd': newText.append('d'); break; + case 'e': newText.append('e'); break; + case 'f': newText.append('f'); break; + case 'A': newText.append('a'); break; + case 'B': newText.append('b'); break; + case 'C': newText.append('c'); break; + case 'D': newText.append('d'); break; + case 'E': newText.append('e'); break; + case 'F': newText.append('f'); break; + default: break; + } + } + ui->networkIdLineEdit->setText(newText); } void MainWindow::on_statusAndAddressButton_clicked() diff --git a/ZeroTierUI/mainwindow.ui b/ZeroTierUI/mainwindow.ui index c9366ccf..d4824d59 100644 --- a/ZeroTierUI/mainwindow.ui +++ b/ZeroTierUI/mainwindow.ui @@ -64,6 +64,9 @@ + + 0 + 0 @@ -128,7 +131,7 @@ border: 0; - 0000000000 (OFFLINE, 0 peers) + 0000000000 (OFFLINE, 0 peers) Qt::ToolButtonTextOnly diff --git a/ZeroTierUI/network.cpp b/ZeroTierUI/network.cpp index fed644db..3826a8da 100644 --- a/ZeroTierUI/network.cpp +++ b/ZeroTierUI/network.cpp @@ -1,8 +1,10 @@ #include "network.h" #include "ui_network.h" +#include + Network::Network(QWidget *parent) : - QScrollArea(parent), + QWidget(parent), ui(new Ui::Network) { ui->setupUi(this); @@ -12,3 +14,12 @@ Network::~Network() { delete ui; } + +void Network::on_leaveNetworkButton_clicked() +{ +} + +void Network::on_networkIdPushButton_clicked() +{ + QApplication::clipboard()->setText(ui->networkIdPushButton->text()); +} diff --git a/ZeroTierUI/network.h b/ZeroTierUI/network.h index 9c7273a1..730b7982 100644 --- a/ZeroTierUI/network.h +++ b/ZeroTierUI/network.h @@ -1,13 +1,13 @@ #ifndef NETWORK_H #define NETWORK_H -#include +#include namespace Ui { class Network; } -class Network : public QScrollArea +class Network : public QWidget { Q_OBJECT @@ -15,6 +15,11 @@ public: explicit Network(QWidget *parent = 0); ~Network(); +private slots: + void on_leaveNetworkButton_clicked(); + + void on_networkIdPushButton_clicked(); + private: Ui::Network *ui; }; diff --git a/ZeroTierUI/network.ui b/ZeroTierUI/network.ui index cb8a93ca..1f80a4c8 100644 --- a/ZeroTierUI/network.ui +++ b/ZeroTierUI/network.ui @@ -1,31 +1,259 @@ Network - + 0 0 618 - 79 + 93 + + + 0 + 0 + + - ScrollArea + Network - + true - - - - 0 - 0 - 616 - 77 - + + + 6 + + + 6 + + + 0 + + + 6 + + + 0 - + + + + + QFormLayout::ExpandingFieldsGrow + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + Qt::AlignHCenter|Qt::AlignTop + + + 6 + + + 2 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Network ID: + + + Qt::PlainText + + + + + + + + 0 + 0 + + + + + Courier + 13 + 75 + true + + + + Click to Copy to Clipboard + + + border: 0; +padding: 0; +margin: 0; +text-align: left; + + + 0000000000000000 + + + true + + + + + + + Status: + + + Qt::PlainText + + + + + + + + 0 + 0 + + + + + 75 + true + + + + OK + + + Qt::PlainText + + + + + + + Device: + + + Qt::PlainText + + + + + + + + 75 + true + + + + zt0 + + + Qt::PlainText + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 10 + true + + + + padding: 0; margin: 0; + + + Leave Network + + + true + + + + + + + + + + + + + + 0 + 0 + + + + + Courier + 10 + + + + false + + + + diff --git a/vsprojects/SelfTest/SelfTest.vcxproj b/vsprojects/SelfTest/SelfTest.vcxproj deleted file mode 100644 index db4e163f..00000000 --- a/vsprojects/SelfTest/SelfTest.vcxproj +++ /dev/null @@ -1,231 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD} - Win32Proj - SelfTest - - - - Application - true - v110 - Unicode - - - Application - true - v110 - Unicode - - - Application - false - v110 - true - Unicode - - - Application - false - v110 - true - Unicode - - - - - - - - - - - - - - - - - - - true - $(SolutionDir)\Build\$(Configuration)\ - - - true - - - false - $(SolutionDir)\Build\$(Platform)\$(Configuration)\ - - - false - $(SolutionDir)\Build\$(Platform)\$(Configuration)\ - - - - NotUsing - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - $(SolutionDir)\ext\bin\libcrypto\include;%(AdditionalIncludeDirectories) - - - Console - true - $(SolutionDir)\ext\bin\libcrypto\win32-vs2012\libeay32.lib;wsock32.lib;ws2_32.lib;%(AdditionalDependencies) - - - - - NotUsing - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - $(SolutionDir)\ext\bin\libcrypto\include;%(AdditionalIncludeDirectories) - - - Console - true - $(SolutionDir)\ext\bin\libcrypto\win32-vs2012\libeay32.lib;wsock32.lib;ws2_32.lib;%(AdditionalDependencies) - - - - - Level3 - NotUsing - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - $(SolutionDir)\ext\bin\libcrypto\include;%(AdditionalIncludeDirectories) - - - Console - true - true - true - wsock32.lib;ws2_32.lib;iphlpapi.lib;$(SolutionDir)\ext\bin\libcrypto\win32-vs2012\libeay32.lib;%(AdditionalDependencies) - false - - - - - Level3 - NotUsing - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - $(SolutionDir)\ext\bin\libcrypto\include;%(AdditionalIncludeDirectories) - - - Console - true - true - true - wsock32.lib;ws2_32.lib;iphlpapi.lib;$(SolutionDir)\ext\bin\libcrypto\win64-vs2012\libeay32.lib;%(AdditionalDependencies) - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vsprojects/SelfTest/SelfTest.vcxproj.filters b/vsprojects/SelfTest/SelfTest.vcxproj.filters deleted file mode 100644 index fa8c8331..00000000 --- a/vsprojects/SelfTest/SelfTest.vcxproj.filters +++ /dev/null @@ -1,227 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/vsprojects/SelfTest/targetver.h b/vsprojects/SelfTest/targetver.h deleted file mode 100644 index 87c0086d..00000000 --- a/vsprojects/SelfTest/targetver.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -// Including SDKDDKVer.h defines the highest available Windows platform. - -// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and -// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. - -#include diff --git a/vsprojects/TapDriver Package/TapDriver Package.vcxproj b/vsprojects/TapDriver Package/TapDriver Package.vcxproj deleted file mode 100644 index 6ac36e9e..00000000 --- a/vsprojects/TapDriver Package/TapDriver Package.vcxproj +++ /dev/null @@ -1,155 +0,0 @@ - - - - - Win8 Debug - Win32 - - - Win8 Release - Win32 - - - Win7 Debug - Win32 - - - Win7 Release - Win32 - - - Vista Debug - Win32 - - - Vista Release - Win32 - - - Win8 Debug - x64 - - - Win8 Release - x64 - - - Win7 Debug - x64 - - - Win7 Release - x64 - - - Vista Debug - x64 - - - Vista Release - x64 - - - - {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946} - {4605da2c-74a5-4865-98e1-152ef136825f} - v4.5 - 11.0 - Win8 Debug - Win32 - - - TapDriver_Package - $(VCTargetsPath11) - - - WindowsKernelModeDriver8.0 - Utility - Package - true - - - - Windows8 - true - - - Windows8 - false - - - Windows7 - true - - - Windows7 - false - - - Vista - true - - - Vista - false - - - Windows8 - true - - - Windows8 - false - - - Windows7 - true - - - Windows7 - false - - - Vista - true - - - Vista - false - - - - - - - - - - - DbgengKernelDebugger - False - True - - - - False - False - True - - 133563 - $(OutDir)TapDriver Package - - - - - - - - - {689210b1-467c-4850-bb7d-2e10d5b4a3da} - - - - - - \ No newline at end of file diff --git a/vsprojects/TapDriver Package/TapDriver Package.vcxproj.filters b/vsprojects/TapDriver Package/TapDriver Package.vcxproj.filters deleted file mode 100644 index e1b34f2a..00000000 --- a/vsprojects/TapDriver Package/TapDriver Package.vcxproj.filters +++ /dev/null @@ -1,9 +0,0 @@ - - - - - {8E41214B-6785-4CFE-B992-037D68949A14} - inf;inv;inx;mof;mc; - - - \ No newline at end of file diff --git a/vsprojects/TapDriver/TapDriver.vcxproj b/vsprojects/TapDriver/TapDriver.vcxproj deleted file mode 100644 index 03357d5f..00000000 --- a/vsprojects/TapDriver/TapDriver.vcxproj +++ /dev/null @@ -1,352 +0,0 @@ - - - - - Win8 Debug - Win32 - - - Win8 Release - Win32 - - - Win7 Debug - Win32 - - - Win7 Release - Win32 - - - Vista Debug - Win32 - - - Vista Release - Win32 - - - Win8 Debug - x64 - - - Win8 Release - x64 - - - Win7 Debug - x64 - - - Win7 Release - x64 - - - Vista Debug - x64 - - - Vista Release - x64 - - - - {689210B1-467C-4850-BB7D-2E10D5B4A3DA} - {1bc93793-694f-48fe-9372-81e2b05556fd} - v4.5 - 11.0 - Win8 Debug - Win32 - - - TapDriver - $(VCTargetsPath11) - - - WindowsKernelModeDriver8.0 - Driver - KMDF - - - - Windows8 - true - - - Windows8 - false - - - Windows7 - true - - - Windows7 - false - - - Vista - true - - - Vista - false - - - Windows8 - true - - - Windows8 - false - - - Windows7 - true - - - Windows7 - false - - - Vista - true - - - Vista - false - - - - - - - - - - ztTap100 - $(SolutionDir)\Build\$(Platform)\$(ConfigurationName)\ - $(Platform)\$(ConfigurationName)\ - - - DbgengKernelDebugger - - - ztTap100 - $(SolutionDir)\Build\$(Platform)\$(ConfigurationName)\ - $(Platform)\$(ConfigurationName)\ - - - ztTap100 - $(SolutionDir)\Build\$(Platform)\$(ConfigurationName)\ - $(Platform)\$(ConfigurationName)\ - - - ztTap100 - $(SolutionDir)\Build\$(Platform)\$(ConfigurationName)\ - $(Platform)\$(ConfigurationName)\ - - - ztTap100 - $(SolutionDir)\Build\$(Platform)\$(ConfigurationName)\ - $(Platform)\$(ConfigurationName)\ - - - ztTap100 - $(SolutionDir)\Build\$(Platform)\$(ConfigurationName)\ - $(Platform)\$(ConfigurationName)\ - - - ztTap100 - $(SolutionDir)\Build\$(Platform)\$(ConfigurationName)\ - - - ztTap100 - $(SolutionDir)\Build\$(Platform)\$(ConfigurationName)\ - - - ztTap100 - $(SolutionDir)\Build\$(Platform)\$(ConfigurationName)\ - - - ztTap100 - $(SolutionDir)\Build\$(Platform)\$(ConfigurationName)\ - - - ztTap100 - $(SolutionDir)\Build\$(Platform)\$(ConfigurationName)\ - - - ztTap100 - $(SolutionDir)\Build\$(Platform)\$(ConfigurationName)\ - - - - false - trace.h - true - Level2 - false - None - None - None - Level2 - false - Level2 - false - Level2 - false - Level2 - false - Level2 - false - Level2 - false - Level2 - false - Level2 - false - Level2 - false - Level2 - false - Level2 - false - None - None - None - - - C:\WinDDK\7600.16385.1\lib\wnet\i386\ndis.lib;C:\WinDDK\7600.16385.1\lib\wnet\i386\ntstrsafe.lib;%(AdditionalDependencies) - - - C:\WinDDK\7600.16385.1\lib\wnet\i386\ndis.lib;C:\WinDDK\7600.16385.1\lib\wnet\i386\ntstrsafe.lib;%(AdditionalDependencies) - - - C:\WinDDK\7600.16385.1\lib\wnet\i386\ndis.lib;C:\WinDDK\7600.16385.1\lib\wnet\i386\ntstrsafe.lib;%(AdditionalDependencies) - - - C:\WinDDK\7600.16385.1\lib\wnet\i386\ndis.lib;C:\WinDDK\7600.16385.1\lib\wnet\i386\ntstrsafe.lib;%(AdditionalDependencies) - - - C:\WinDDK\7600.16385.1\lib\wnet\i386\ndis.lib;C:\WinDDK\7600.16385.1\lib\wnet\i386\ntstrsafe.lib;%(AdditionalDependencies) - - - C:\WinDDK\7600.16385.1\lib\wnet\i386\ndis.lib;C:\WinDDK\7600.16385.1\lib\wnet\i386\ntstrsafe.lib;%(AdditionalDependencies) - - - C:\WinDDK\7600.16385.1\lib\wnet\amd64\ndis.lib;C:\WinDDK\7600.16385.1\lib\wnet\amd64\ntstrsafe.lib;%(AdditionalDependencies) - - - C:\WinDDK\7600.16385.1\lib\wnet\amd64\ndis.lib;C:\WinDDK\7600.16385.1\lib\wnet\amd64\ntstrsafe.lib;%(AdditionalDependencies) - - - C:\WinDDK\7600.16385.1\lib\wnet\amd64\ndis.lib;C:\WinDDK\7600.16385.1\lib\wnet\amd64\ntstrsafe.lib;%(AdditionalDependencies) - - - C:\WinDDK\7600.16385.1\lib\wnet\amd64\ndis.lib;C:\WinDDK\7600.16385.1\lib\wnet\amd64\ntstrsafe.lib;%(AdditionalDependencies) - - - C:\WinDDK\7600.16385.1\lib\wnet\amd64\ndis.lib;C:\WinDDK\7600.16385.1\lib\wnet\amd64\ntstrsafe.lib;%(AdditionalDependencies) - - - C:\WinDDK\7600.16385.1\lib\wnet\amd64\ndis.lib;C:\WinDDK\7600.16385.1\lib\wnet\amd64\ntstrsafe.lib;%(AdditionalDependencies) - - - - - - - - - - - - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - - - true - true - true - true - true - true - true - true - true - true - true - true - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vsprojects/TapDriver/TapDriver.vcxproj.filters b/vsprojects/TapDriver/TapDriver.vcxproj.filters deleted file mode 100644 index 4bac59db..00000000 --- a/vsprojects/TapDriver/TapDriver.vcxproj.filters +++ /dev/null @@ -1,81 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {8E41214B-6785-4CFE-B992-037D68949A14} - inf;inv;inx;mof;mc; - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Driver Files - - - \ No newline at end of file diff --git a/vsprojects/TapDriver/config.h b/vsprojects/TapDriver/config.h deleted file mode 100644 index 5a6ff247..00000000 --- a/vsprojects/TapDriver/config.h +++ /dev/null @@ -1,12 +0,0 @@ -#define PRODUCT_NAME "ZeroTier One Ethernet Tap" -#define PRODUCT_VERSION "1.0.0" -#define PRODUCT_VERSION_RESOURCE 1,0,0,1 -#define PRODUCT_TAP_WIN_COMPONENT_ID "ztTap100" -#define PRODUCT_TAP_WIN_MAJOR 1 -#define PRODUCT_TAP_WIN_MINOR 0 -#define PRODUCT_TAP_WIN_PROVIDER "ZeroTier Networks" -#define PRODUCT_TAP_WIN_DEVICE_DESCRIPTION PRODUCT_NAME -#define PRODUCT_TAP_WIN_RELDATE "08/01/2013" - -#define TAP_DRIVER_MAJOR_VERSION PRODUCT_TAP_WIN_MAJOR -#define TAP_DRIVER_MINOR_VERSION PRODUCT_TAP_WIN_MINOR diff --git a/vsprojects/TapDriver/constants.h b/vsprojects/TapDriver/constants.h deleted file mode 100644 index 698dc629..00000000 --- a/vsprojects/TapDriver/constants.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * TAP-Windows -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -//==================================================================== -// Product and Version public settings -//==================================================================== - -#define PRODUCT_STRING PRODUCT_TAP_DEVICE_DESCRIPTION - -#define TAP_NDIS_MAJOR_VERSION 5 -#define TAP_NDIS_MINOR_VERSION 0 - -//=========================================================== -// Driver constants -//=========================================================== - -#define ETHERNET_HEADER_SIZE (sizeof (ETH_HEADER)) -#define ETHERNET_MTU 2800 // ZeroTier One MTU -#define ETHERNET_PACKET_SIZE (ETHERNET_MTU + ETHERNET_HEADER_SIZE) -#define DEFAULT_PACKET_LOOKAHEAD (ETHERNET_PACKET_SIZE) - -#define NIC_MAX_MCAST_LIST 32 // Max length of multicast address list - -#define MINIMUM_MTU 576 // USE TCP Minimum MTU -#define MAXIMUM_MTU 65536 // IP maximum MTU - -#define PACKET_QUEUE_SIZE 64 // tap -> userspace queue size -#define IRP_QUEUE_SIZE 16 // max number of simultaneous i/o operations from userspace -#define INJECT_QUEUE_SIZE 16 // DHCP/ARP -> tap injection queue - -#define TAP_LITTLE_ENDIAN // affects ntohs, htonl, etc. functions diff --git a/vsprojects/TapDriver/dhcp.c b/vsprojects/TapDriver/dhcp.c deleted file mode 100644 index f3c61d6f..00000000 --- a/vsprojects/TapDriver/dhcp.c +++ /dev/null @@ -1,603 +0,0 @@ -/* - * TAP-Windows -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#if 0 - -//========================= -// Code to set DHCP options -//========================= - -VOID -SetDHCPOpt (DHCPMsg *m, void *data, unsigned int len) -{ - if (!m->overflow) - { - if (m->optlen + len <= DHCP_OPTIONS_BUFFER_SIZE) - { - if (len) - { - NdisMoveMemory (m->msg.options + m->optlen, data, len); - m->optlen += len; - } - } - else - { - m->overflow = TRUE; - } - } -} - -VOID -SetDHCPOpt0 (DHCPMsg *msg, int type) -{ - DHCPOPT0 opt; - opt.type = (UCHAR) type; - SetDHCPOpt (msg, &opt, sizeof (opt)); -} - -VOID -SetDHCPOpt8 (DHCPMsg *msg, int type, ULONG data) -{ - DHCPOPT8 opt; - opt.type = (UCHAR) type; - opt.len = sizeof (opt.data); - opt.data = (UCHAR) data; - SetDHCPOpt (msg, &opt, sizeof (opt)); -} - -VOID -SetDHCPOpt32 (DHCPMsg *msg, int type, ULONG data) -{ - DHCPOPT32 opt; - opt.type = (UCHAR) type; - opt.len = sizeof (opt.data); - opt.data = data; - SetDHCPOpt (msg, &opt, sizeof (opt)); -} - -//============== -// Checksum code -//============== - -USHORT -ip_checksum (const UCHAR *buf, const int len_ip_header) -{ - USHORT word16; - ULONG sum = 0; - int i; - - // make 16 bit words out of every two adjacent 8 bit words in the packet - // and add them up - for (i = 0; i < len_ip_header - 1; i += 2) { - word16 = ((buf[i] << 8) & 0xFF00) + (buf[i+1] & 0xFF); - sum += (ULONG) word16; - } - - // take only 16 bits out of the 32 bit sum and add up the carries - while (sum >> 16) - sum = (sum & 0xFFFF) + (sum >> 16); - - // one's complement the result - return ((USHORT) ~sum); -} - -USHORT -udp_checksum (const UCHAR *buf, - const int len_udp, - const UCHAR *src_addr, - const UCHAR *dest_addr) -{ - USHORT word16; - ULONG sum = 0; - int i; - - // make 16 bit words out of every two adjacent 8 bit words and - // calculate the sum of all 16 bit words - for (i = 0; i < len_udp; i += 2){ - word16 = ((buf[i] << 8) & 0xFF00) + ((i + 1 < len_udp) ? (buf[i+1] & 0xFF) : 0); - sum += word16; - } - - // add the UDP pseudo header which contains the IP source and destination addresses - for (i = 0; i < 4; i += 2){ - word16 =((src_addr[i] << 8) & 0xFF00) + (src_addr[i+1] & 0xFF); - sum += word16; - } - for (i = 0; i < 4; i += 2){ - word16 =((dest_addr[i] << 8) & 0xFF00) + (dest_addr[i+1] & 0xFF); - sum += word16; - } - - // the protocol number and the length of the UDP packet - sum += (USHORT) IPPROTO_UDP + (USHORT) len_udp; - - // keep only the last 16 bits of the 32 bit calculated sum and add the carries - while (sum >> 16) - sum = (sum & 0xFFFF) + (sum >> 16); - - // Take the one's complement of sum - return ((USHORT) ~sum); -} - -//================================ -// Set IP and UDP packet checksums -//================================ - -VOID -SetChecksumDHCPMsg (DHCPMsg *m) -{ - // Set IP checksum - m->msg.pre.ip.check = htons (ip_checksum ((UCHAR *) &m->msg.pre.ip, sizeof (IPHDR))); - - // Set UDP Checksum - m->msg.pre.udp.check = htons (udp_checksum ((UCHAR *) &m->msg.pre.udp, - sizeof (UDPHDR) + sizeof (DHCP) + m->optlen, - (UCHAR *)&m->msg.pre.ip.saddr, - (UCHAR *)&m->msg.pre.ip.daddr)); -} - -//=================== -// DHCP message tests -//=================== - -int -GetDHCPMessageType (const DHCP *dhcp, const int optlen) -{ - const UCHAR *p = (UCHAR *) (dhcp + 1); - int i; - - for (i = 0; i < optlen; ++i) - { - const UCHAR type = p[i]; - const int room = optlen - i - 1; - if (type == DHCP_END) // didn't find what we were looking for - return -1; - else if (type == DHCP_PAD) // no-operation - ; - else if (type == DHCP_MSG_TYPE) // what we are looking for - { - if (room >= 2) - { - if (p[i+1] == 1) // message length should be 1 - return p[i+2]; // return message type - } - return -1; - } - else // some other message - { - if (room >= 1) - { - const int len = p[i+1]; // get message length - i += (len + 1); // advance to next message - } - } - } - return -1; -} - -BOOLEAN -DHCPMessageOurs (const TapAdapterPointer p_Adapter, - const ETH_HEADER *eth, - const IPHDR *ip, - const UDPHDR *udp, - const DHCP *dhcp) -{ - // Must be UDPv4 protocol - if (!(eth->proto == htons (ETH_P_IP) && ip->protocol == IPPROTO_UDP)) - return FALSE; - - // Source MAC must be our adapter - if (!MAC_EQUAL (eth->src, p_Adapter->m_MAC)) - return FALSE; - - // Dest MAC must be either broadcast or our virtual DHCP server - if (!(MAC_EQUAL (eth->dest, p_Adapter->m_MAC_Broadcast) - || MAC_EQUAL (eth->dest, p_Adapter->m_dhcp_server_mac))) - return FALSE; - - // Port numbers must be correct - if (!(udp->dest == htons (BOOTPS_PORT) - && udp->source == htons (BOOTPC_PORT))) - return FALSE; - - // Hardware address must be MAC addr sized - if (!(dhcp->hlen == sizeof (MACADDR))) - return FALSE; - - // Hardware address must match our adapter - if (!MAC_EQUAL (eth->src, dhcp->chaddr)) - return FALSE; - - return TRUE; -} - - -//===================================================== -// Build all of DHCP packet except for DHCP options. -// Assume that *p has been zeroed before we are called. -//===================================================== - -VOID -BuildDHCPPre (const TapAdapterPointer a, - DHCPPre *p, - const ETH_HEADER *eth, - const IPHDR *ip, - const UDPHDR *udp, - const DHCP *dhcp, - const int optlen, - const int type) -{ - // Should we broadcast or direct to a specific MAC / IP address? - const BOOLEAN broadcast = (type == DHCPNAK - || MAC_EQUAL (eth->dest, a->m_MAC_Broadcast)); - // Build ethernet header - - COPY_MAC (p->eth.src, a->m_dhcp_server_mac); - - if (broadcast) - COPY_MAC (p->eth.dest, a->m_MAC_Broadcast); - else - COPY_MAC (p->eth.dest, eth->src); - - p->eth.proto = htons (ETH_P_IP); - - // Build IP header - - p->ip.version_len = (4 << 4) | (sizeof (IPHDR) >> 2); - p->ip.tos = 0; - p->ip.tot_len = htons (sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP) + optlen); - p->ip.id = 0; - p->ip.frag_off = 0; - p->ip.ttl = 16; - p->ip.protocol = IPPROTO_UDP; - p->ip.check = 0; - p->ip.saddr = a->m_dhcp_server_ip; - - if (broadcast) - p->ip.daddr = ~0; - else - p->ip.daddr = a->m_dhcp_addr; - - // Build UDP header - - p->udp.source = htons (BOOTPS_PORT); - p->udp.dest = htons (BOOTPC_PORT); - p->udp.len = htons (sizeof (UDPHDR) + sizeof (DHCP) + optlen); - p->udp.check = 0; - - // Build DHCP response - - p->dhcp.op = BOOTREPLY; - p->dhcp.htype = 1; - p->dhcp.hlen = sizeof (MACADDR); - p->dhcp.hops = 0; - p->dhcp.xid = dhcp->xid; - p->dhcp.secs = 0; - p->dhcp.flags = 0; - p->dhcp.ciaddr = 0; - - if (type == DHCPNAK) - p->dhcp.yiaddr = 0; - else - p->dhcp.yiaddr = a->m_dhcp_addr; - - p->dhcp.siaddr = a->m_dhcp_server_ip; - p->dhcp.giaddr = 0; - COPY_MAC (p->dhcp.chaddr, eth->src); - p->dhcp.magic = htonl (0x63825363); -} -//============================= -// Build specific DHCP messages -//============================= - -VOID -SendDHCPMsg (const TapAdapterPointer a, - const int type, - const ETH_HEADER *eth, - const IPHDR *ip, - const UDPHDR *udp, - const DHCP *dhcp) -{ - DHCPMsg *pkt; - - if (!(type == DHCPOFFER || type == DHCPACK || type == DHCPNAK)) - { - DEBUGP (("[TAP] SendDHCPMsg: Bad DHCP type: %d\n", type)); - return; - } - - pkt = (DHCPMsg *) MemAlloc (sizeof (DHCPMsg), TRUE); - - if (pkt) - { - //----------------------- - // Build DHCP options - //----------------------- - - // Message Type - SetDHCPOpt8 (pkt, DHCP_MSG_TYPE, type); - - // Server ID - SetDHCPOpt32 (pkt, DHCP_SERVER_ID, a->m_dhcp_server_ip); - - if (type == DHCPOFFER || type == DHCPACK) - { - // Lease Time - SetDHCPOpt32 (pkt, DHCP_LEASE_TIME, htonl (a->m_dhcp_lease_time)); - - // Netmask - SetDHCPOpt32 (pkt, DHCP_NETMASK, a->m_dhcp_netmask); - - // Other user-defined options - SetDHCPOpt (pkt, - a->m_dhcp_user_supplied_options_buffer, - a->m_dhcp_user_supplied_options_buffer_len); - } - - // End - SetDHCPOpt0 (pkt, DHCP_END); - - if (!DHCPMSG_OVERFLOW (pkt)) - { - // The initial part of the DHCP message (not including options) gets built here - BuildDHCPPre (a, - &pkt->msg.pre, - eth, - ip, - udp, - dhcp, - DHCPMSG_LEN_OPT (pkt), - type); - - SetChecksumDHCPMsg (pkt); - - DUMP_PACKET ("DHCPMsg", - DHCPMSG_BUF (pkt), - DHCPMSG_LEN_FULL (pkt)); - - // Return DHCP response to kernel - InjectPacketDeferred (a, - DHCPMSG_BUF (pkt), - DHCPMSG_LEN_FULL (pkt)); - } - else - { - DEBUGP (("[TAP] SendDHCPMsg: DHCP buffer overflow\n")); - } - - MemFree (pkt, sizeof (DHCPMsg)); - } -} - -//=================================================================== -// Handle a BOOTPS packet produced by the local system to -// resolve the address/netmask of this adapter. -// If we are in TAP_WIN_IOCTL_CONFIG_DHCP_MASQ mode, reply -// to the message. Return TRUE if we processed the passed -// message, so that downstream stages can ignore it. -//=================================================================== - -BOOLEAN -ProcessDHCP (TapAdapterPointer p_Adapter, - const ETH_HEADER *eth, - const IPHDR *ip, - const UDPHDR *udp, - const DHCP *dhcp, - int optlen) -{ - int msg_type; - - // Sanity check IP header - if (!(ntohs (ip->tot_len) == sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP) + optlen - && (ntohs (ip->frag_off) & IP_OFFMASK) == 0)) - return TRUE; - - // Does this message belong to us? - if (!DHCPMessageOurs (p_Adapter, eth, ip, udp, dhcp)) - return FALSE; - - msg_type = GetDHCPMessageType (dhcp, optlen); - - // Drop non-BOOTREQUEST messages - if (dhcp->op != BOOTREQUEST) - return TRUE; - - // Drop any messages except DHCPDISCOVER or DHCPREQUEST - if (!(msg_type == DHCPDISCOVER || msg_type == DHCPREQUEST)) - return TRUE; - - // Should we reply with DHCPOFFER, DHCPACK, or DHCPNAK? - if (msg_type == DHCPREQUEST - && ((dhcp->ciaddr && dhcp->ciaddr != p_Adapter->m_dhcp_addr) - || !p_Adapter->m_dhcp_received_discover - || p_Adapter->m_dhcp_bad_requests >= BAD_DHCPREQUEST_NAK_THRESHOLD)) - SendDHCPMsg (p_Adapter, - DHCPNAK, - eth, ip, udp, dhcp); - else - SendDHCPMsg (p_Adapter, - (msg_type == DHCPDISCOVER ? DHCPOFFER : DHCPACK), - eth, ip, udp, dhcp); - - // Remember if we received a DHCPDISCOVER - if (msg_type == DHCPDISCOVER) - p_Adapter->m_dhcp_received_discover = TRUE; - - // Is this a bad DHCPREQUEST? - if (msg_type == DHCPREQUEST && dhcp->ciaddr && dhcp->ciaddr != p_Adapter->m_dhcp_addr) - ++p_Adapter->m_dhcp_bad_requests; - - return TRUE; -} - -#if DBG - -const char * -message_op_text (int op) -{ - switch (op) - { - case BOOTREQUEST: - return "BOOTREQUEST"; - case BOOTREPLY: - return "BOOTREPLY"; - default: - return "???"; - } -} - -const char * -message_type_text (int type) -{ - switch (type) - { - case DHCPDISCOVER: - return "DHCPDISCOVER"; - case DHCPOFFER: - return "DHCPOFFER"; - case DHCPREQUEST: - return "DHCPREQUEST"; - case DHCPDECLINE: - return "DHCPDECLINE"; - case DHCPACK: - return "DHCPACK"; - case DHCPNAK: - return "DHCPNAK"; - case DHCPRELEASE: - return "DHCPRELEASE"; - case DHCPINFORM: - return "DHCPINFORM"; - default: - return "???"; - } -} - -const char * -port_name (int port) -{ - switch (port) - { - case BOOTPS_PORT: - return "BOOTPS"; - case BOOTPC_PORT: - return "BOOTPC"; - default: - return "unknown"; - } -} - -VOID -DumpDHCP (const ETH_HEADER *eth, - const IPHDR *ip, - const UDPHDR *udp, - const DHCP *dhcp, - const int optlen) -{ - DEBUGP ((" %s", message_op_text (dhcp->op))); - DEBUGP ((" %s ", message_type_text (GetDHCPMessageType (dhcp, optlen)))); - PrIP (ip->saddr); - DEBUGP ((":%s[", port_name (ntohs (udp->source)))); - PrMac (eth->src); - DEBUGP (("] -> ")); - PrIP (ip->daddr); - DEBUGP ((":%s[", port_name (ntohs (udp->dest)))); - PrMac (eth->dest); - DEBUGP (("]")); - if (dhcp->ciaddr) - { - DEBUGP ((" ci=")); - PrIP (dhcp->ciaddr); - } - if (dhcp->yiaddr) - { - DEBUGP ((" yi=")); - PrIP (dhcp->yiaddr); - } - if (dhcp->siaddr) - { - DEBUGP ((" si=")); - PrIP (dhcp->siaddr); - } - if (dhcp->hlen == sizeof (MACADDR)) - { - DEBUGP ((" ch=")); - PrMac (dhcp->chaddr); - } - - DEBUGP ((" xid=0x%08x", ntohl (dhcp->xid))); - - if (ntohl (dhcp->magic) != 0x63825363) - DEBUGP ((" ma=0x%08x", ntohl (dhcp->magic))); - if (dhcp->htype != 1) - DEBUGP ((" htype=%d", dhcp->htype)); - if (dhcp->hops) - DEBUGP ((" hops=%d", dhcp->hops)); - if (ntohs (dhcp->secs)) - DEBUGP ((" secs=%d", ntohs (dhcp->secs))); - if (ntohs (dhcp->flags)) - DEBUGP ((" flags=0x%04x", ntohs (dhcp->flags))); - - // extra stuff - - if (ip->version_len != 0x45) - DEBUGP ((" vl=0x%02x", ip->version_len)); - if (ntohs (ip->tot_len) != sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP) + optlen) - DEBUGP ((" tl=%d", ntohs (ip->tot_len))); - if (ntohs (udp->len) != sizeof (UDPHDR) + sizeof (DHCP) + optlen) - DEBUGP ((" ul=%d", ntohs (udp->len))); - - if (ip->tos) - DEBUGP ((" tos=0x%02x", ip->tos)); - if (ntohs (ip->id)) - DEBUGP ((" id=0x%04x", ntohs (ip->id))); - if (ntohs (ip->frag_off)) - DEBUGP ((" frag_off=0x%04x", ntohs (ip->frag_off))); - - DEBUGP ((" ttl=%d", ip->ttl)); - DEBUGP ((" ic=0x%04x [0x%04x]", ntohs (ip->check), - ip_checksum ((UCHAR*)ip, sizeof (IPHDR)))); - DEBUGP ((" uc=0x%04x [0x%04x/%d]", ntohs (udp->check), - udp_checksum ((UCHAR *) udp, - sizeof (UDPHDR) + sizeof (DHCP) + optlen, - (UCHAR *) &ip->saddr, - (UCHAR *) &ip->daddr), - optlen)); - - // Options - { - const UCHAR *opt = (UCHAR *) (dhcp + 1); - int i; - - DEBUGP ((" OPT")); - for (i = 0; i < optlen; ++i) - { - const UCHAR data = opt[i]; - DEBUGP ((".%d", data)); - } - } -} - -#endif /* DBG */ - -#endif diff --git a/vsprojects/TapDriver/dhcp.h b/vsprojects/TapDriver/dhcp.h deleted file mode 100644 index 92e5ca87..00000000 --- a/vsprojects/TapDriver/dhcp.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * TAP-Windows -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#if 0 - -#pragma pack(1) - -//=================================================== -// How many bad DHCPREQUESTs do we receive before we -// return a NAK? -// -// A bad DHCPREQUEST is defined to be one where the -// requestor doesn't know its IP address. -//=================================================== - -#define BAD_DHCPREQUEST_NAK_THRESHOLD 3 - -//============================================== -// Maximum number of DHCP options bytes supplied -//============================================== - -#define DHCP_USER_SUPPLIED_OPTIONS_BUFFER_SIZE 256 -#define DHCP_OPTIONS_BUFFER_SIZE 256 - -//=================================== -// UDP port numbers of DHCP messages. -//=================================== - -#define BOOTPS_PORT 67 -#define BOOTPC_PORT 68 - -//=========================== -// The DHCP message structure -//=========================== - -typedef struct { -# define BOOTREQUEST 1 -# define BOOTREPLY 2 - UCHAR op; /* message op */ - - UCHAR htype; /* hardware address type (e.g. '1' = 10Mb Ethernet) */ - UCHAR hlen; /* hardware address length (e.g. '6' for 10Mb Ethernet) */ - UCHAR hops; /* client sets to 0, may be used by relay agents */ - ULONG xid; /* transaction ID, chosen by client */ - USHORT secs; /* seconds since request process began, set by client */ - USHORT flags; - ULONG ciaddr; /* client IP address, client sets if known */ - ULONG yiaddr; /* 'your' IP address -- server's response to client */ - ULONG siaddr; /* server IP address */ - ULONG giaddr; /* relay agent IP address */ - UCHAR chaddr[16]; /* client hardware address */ - UCHAR sname[64]; /* optional server host name */ - UCHAR file[128]; /* boot file name */ - ULONG magic; /* must be 0x63825363 (network order) */ -} DHCP; - -typedef struct { - ETH_HEADER eth; - IPHDR ip; - UDPHDR udp; - DHCP dhcp; -} DHCPPre; - -typedef struct { - DHCPPre pre; - UCHAR options[DHCP_OPTIONS_BUFFER_SIZE]; -} DHCPFull; - -typedef struct { - unsigned int optlen; - BOOLEAN overflow; - DHCPFull msg; -} DHCPMsg; - -//=================== -// Macros for DHCPMSG -//=================== - -#define DHCPMSG_LEN_BASE(p) (sizeof (DHCPPre)) -#define DHCPMSG_LEN_OPT(p) ((p)->optlen) -#define DHCPMSG_LEN_FULL(p) (DHCPMSG_LEN_BASE(p) + DHCPMSG_LEN_OPT(p)) -#define DHCPMSG_BUF(p) ((UCHAR*) &(p)->msg) -#define DHCPMSG_OVERFLOW(p) ((p)->overflow) - -//======================================== -// structs to hold individual DHCP options -//======================================== - -typedef struct { - UCHAR type; -} DHCPOPT0; - -typedef struct { - UCHAR type; - UCHAR len; - UCHAR data; -} DHCPOPT8; - -typedef struct { - UCHAR type; - UCHAR len; - ULONG data; -} DHCPOPT32; - -#pragma pack() - -//================== -// DHCP Option types -//================== - -#define DHCP_MSG_TYPE 53 /* message type (u8) */ -#define DHCP_PARM_REQ 55 /* parameter request list: c1 (u8), ... */ -#define DHCP_CLIENT_ID 61 /* client ID: type (u8), i1 (u8), ... */ -#define DHCP_IP 50 /* requested IP addr (u32) */ -#define DHCP_NETMASK 1 /* subnet mask (u32) */ -#define DHCP_LEASE_TIME 51 /* lease time sec (u32) */ -#define DHCP_RENEW_TIME 58 /* renewal time sec (u32) */ -#define DHCP_REBIND_TIME 59 /* rebind time sec (u32) */ -#define DHCP_SERVER_ID 54 /* server ID: IP addr (u32) */ -#define DHCP_PAD 0 -#define DHCP_END 255 - -//==================== -// DHCP Messages types -//==================== - -#define DHCPDISCOVER 1 -#define DHCPOFFER 2 -#define DHCPREQUEST 3 -#define DHCPDECLINE 4 -#define DHCPACK 5 -#define DHCPNAK 6 -#define DHCPRELEASE 7 -#define DHCPINFORM 8 - -#if DBG - -VOID -DumpDHCP (const ETH_HEADER *eth, - const IPHDR *ip, - const UDPHDR *udp, - const DHCP *dhcp, - const int optlen); - -#endif - -#endif diff --git a/vsprojects/TapDriver/endian.h b/vsprojects/TapDriver/endian.h deleted file mode 100644 index 0f7025d5..00000000 --- a/vsprojects/TapDriver/endian.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * TAP-Windows -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifdef TAP_LITTLE_ENDIAN -#define ntohs(x) RtlUshortByteSwap(x) -#define htons(x) RtlUshortByteSwap(x) -#define ntohl(x) RtlUlongByteSwap(x) -#define htonl(x) RtlUlongByteSwap(x) -#else -#define ntohs(x) ((USHORT)(x)) -#define htons(x) ((USHORT)(x)) -#define ntohl(x) ((ULONG)(x)) -#define htonl(x) ((ULONG)(x)) -#endif diff --git a/vsprojects/TapDriver/error.c b/vsprojects/TapDriver/error.c deleted file mode 100644 index e03fd114..00000000 --- a/vsprojects/TapDriver/error.c +++ /dev/null @@ -1,387 +0,0 @@ -/* - * TAP-Windows -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -//----------------- -// DEBUGGING OUTPUT -//----------------- - -const char *g_LastErrorFilename; -int g_LastErrorLineNumber; - -#if DBG - -DebugOutput g_Debug; - -BOOLEAN -NewlineExists (const char *str, int len) -{ - while (len-- > 0) - { - const char c = *str++; - if (c == '\n') - return TRUE; - else if (c == '\0') - break; - } - return FALSE; -} - -VOID -MyDebugInit (unsigned int bufsiz) -{ - NdisZeroMemory (&g_Debug, sizeof (g_Debug)); - g_Debug.text = (char *) MemAlloc (bufsiz, FALSE); - if (g_Debug.text) - g_Debug.capacity = bufsiz; -} - -VOID -MyDebugFree () -{ - if (g_Debug.text) - MemFree (g_Debug.text, g_Debug.capacity); - NdisZeroMemory (&g_Debug, sizeof (g_Debug)); -} - -VOID -MyDebugPrint (const unsigned char* format, ...) -{ - if (g_Debug.text && g_Debug.capacity > 0 && CAN_WE_PRINT) - { - BOOLEAN owned; - ACQUIRE_MUTEX_ADAPTIVE (&g_Debug.lock, owned); - if (owned) - { - const int remaining = (int)g_Debug.capacity - (int)g_Debug.out; - - if (remaining > 0) - { - va_list args; - NTSTATUS status; - char *end; - -#ifdef DBG_PRINT - va_start (args, format); - vDbgPrintEx (DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, format, args); - va_end (args); -#endif - va_start (args, format); - status = RtlStringCchVPrintfExA (g_Debug.text + g_Debug.out, - remaining, - &end, - NULL, - STRSAFE_NO_TRUNCATION | STRSAFE_IGNORE_NULLS, - format, - args); - va_end (args); -va_start (args, format); -vDbgPrintEx(DPFLTR_IHVDRIVER_ID , 1, format, args); -va_end (args); - if (status == STATUS_SUCCESS) - g_Debug.out = (unsigned int) (end - g_Debug.text); - else - g_Debug.error = TRUE; - } - else - g_Debug.error = TRUE; - - RELEASE_MUTEX (&g_Debug.lock); - } - else - g_Debug.error = TRUE; - } -} - -BOOLEAN -GetDebugLine (char *buf, const int len) -{ - static const char *truncated = "[OUTPUT TRUNCATED]\n"; - BOOLEAN ret = FALSE; - - NdisZeroMemory (buf, len); - - if (g_Debug.text && g_Debug.capacity > 0) - { - BOOLEAN owned; - ACQUIRE_MUTEX_ADAPTIVE (&g_Debug.lock, owned); - if (owned) - { - int i = 0; - - if (g_Debug.error || NewlineExists (g_Debug.text + g_Debug.in, (int)g_Debug.out - (int)g_Debug.in)) - { - while (i < (len - 1) && g_Debug.in < g_Debug.out) - { - const char c = g_Debug.text[g_Debug.in++]; - if (c == '\n') - break; - buf[i++] = c; - } - if (i < len) - buf[i] = '\0'; - } - - if (!i) - { - if (g_Debug.in == g_Debug.out) - { - g_Debug.in = g_Debug.out = 0; - if (g_Debug.error) - { - const unsigned int tlen = strlen (truncated); - if (tlen < g_Debug.capacity) - { - NdisMoveMemory (g_Debug.text, truncated, tlen+1); - g_Debug.out = tlen; - } - g_Debug.error = FALSE; - } - } - } - else - ret = TRUE; - - RELEASE_MUTEX (&g_Debug.lock); - } - } - return ret; -} - -VOID -MyAssert (const unsigned char *file, int line) -{ - DEBUGP (("MYASSERT failed %s/%d\n", file, line)); - KeBugCheckEx (0x0F00BABA, - (ULONG_PTR) line, - (ULONG_PTR) 0, - (ULONG_PTR) 0, - (ULONG_PTR) 0); -} - -VOID -PrMac (const MACADDR mac) -{ - DEBUGP (("%x:%x:%x:%x:%x:%x", - mac[0], mac[1], mac[2], - mac[3], mac[4], mac[5])); -} - -VOID -PrIP (IPADDR ip_addr) -{ - const unsigned char *ip = (const unsigned char *) &ip_addr; - - DEBUGP (("%d.%d.%d.%d", - ip[0], ip[1], ip[2], ip[3])); -} - -const char * -PrIPProto (int proto) -{ - switch (proto) - { - case IPPROTO_UDP: - return "UDP"; - case IPPROTO_TCP: - return "TCP"; - case IPPROTO_ICMP: - return "ICMP"; - case IPPROTO_IGMP: - return "IGMP"; - default: - return "???"; - } -} - -VOID -DumpARP (const char *prefix, const ARP_PACKET *arp) -{ - DEBUGP (("%s ARP src=", prefix)); - PrMac (arp->m_MAC_Source); - DEBUGP ((" dest=")); - PrMac (arp->m_MAC_Destination); - DEBUGP ((" OP=0x%04x", - (int)ntohs(arp->m_ARP_Operation))); - DEBUGP ((" M=0x%04x(%d)", - (int)ntohs(arp->m_MAC_AddressType), - (int)arp->m_MAC_AddressSize)); - DEBUGP ((" P=0x%04x(%d)", - (int)ntohs(arp->m_PROTO_AddressType), - (int)arp->m_PROTO_AddressSize)); - - DEBUGP ((" MacSrc=")); - PrMac (arp->m_ARP_MAC_Source); - DEBUGP ((" MacDest=")); - PrMac (arp->m_ARP_MAC_Destination); - - DEBUGP ((" IPSrc=")); - PrIP (arp->m_ARP_IP_Source); - DEBUGP ((" IPDest=")); - PrIP (arp->m_ARP_IP_Destination); - - DEBUGP (("\n")); -} - -struct ethpayload { - ETH_HEADER eth; - UCHAR payload[DEFAULT_PACKET_LOOKAHEAD]; -}; - -VOID -DumpPacket2 (const char *prefix, - const ETH_HEADER *eth, - const unsigned char *data, - unsigned int len) -{ - struct ethpayload *ep = (struct ethpayload *) MemAlloc (sizeof (struct ethpayload), TRUE); - if (ep) - { - if (len > DEFAULT_PACKET_LOOKAHEAD) - len = DEFAULT_PACKET_LOOKAHEAD; - ep->eth = *eth; - NdisMoveMemory (ep->payload, data, len); - DumpPacket (prefix, (unsigned char *) ep, sizeof (ETH_HEADER) + len); - MemFree (ep, sizeof (struct ethpayload)); - } -} - -VOID -DumpPacket (const char *prefix, - const unsigned char *data, - unsigned int len) -{ - const ETH_HEADER *eth = (const ETH_HEADER *) data; - const IPHDR *ip = (const IPHDR *) (data + sizeof (ETH_HEADER)); - - if (len < sizeof (ETH_HEADER)) - { - DEBUGP (("%s TRUNCATED PACKET LEN=%d\n", prefix, len)); - return; - } - - // ARP Packet? - if (len >= sizeof (ARP_PACKET) && eth->proto == htons (ETH_P_ARP)) - { - DumpARP (prefix, (const ARP_PACKET *) data); - return; - } - - // IPv4 packet? - if (len >= (sizeof (IPHDR) + sizeof (ETH_HEADER)) - && eth->proto == htons (ETH_P_IP) - && IPH_GET_VER (ip->version_len) == 4) - { - const int hlen = IPH_GET_LEN (ip->version_len); - const int blen = len - sizeof (ETH_HEADER); - BOOLEAN did = FALSE; - - DEBUGP (("%s IPv4 %s[%d]", prefix, PrIPProto (ip->protocol), len)); - - if (!(ntohs (ip->tot_len) == blen && hlen <= blen)) - { - DEBUGP ((" XXX")); - return; - } - - // TCP packet? - if (ip->protocol == IPPROTO_TCP - && blen - hlen >= (sizeof (TCPHDR))) - { - const TCPHDR *tcp = (TCPHDR *) (data + sizeof (ETH_HEADER) + hlen); - DEBUGP ((" ")); - PrIP (ip->saddr); - DEBUGP ((":%d", ntohs (tcp->source))); - DEBUGP ((" -> ")); - PrIP (ip->daddr); - DEBUGP ((":%d", ntohs (tcp->dest))); - did = TRUE; - } - - // UDP packet? - else if ((ntohs (ip->frag_off) & IP_OFFMASK) == 0 - && ip->protocol == IPPROTO_UDP - && blen - hlen >= (sizeof (UDPHDR))) - { - const UDPHDR *udp = (UDPHDR *) (data + sizeof (ETH_HEADER) + hlen); - -#if 0 - // DHCP packet? - if ((udp->dest == htons (BOOTPC_PORT) || udp->dest == htons (BOOTPS_PORT)) - && blen - hlen >= (sizeof (UDPHDR) + sizeof (DHCP))) - { - const DHCP *dhcp = (DHCP *) (data - + hlen - + sizeof (ETH_HEADER) - + sizeof (UDPHDR)); - - int optlen = len - - sizeof (ETH_HEADER) - - hlen - - sizeof (UDPHDR) - - sizeof (DHCP); - - if (optlen < 0) - optlen = 0; - - DumpDHCP (eth, ip, udp, dhcp, optlen); - did = TRUE; - } -#endif - - if (!did) - { - DEBUGP ((" ")); - PrIP (ip->saddr); - DEBUGP ((":%d", ntohs (udp->source))); - DEBUGP ((" -> ")); - PrIP (ip->daddr); - DEBUGP ((":%d", ntohs (udp->dest))); - did = TRUE; - } - } - - if (!did) - { - DEBUGP ((" ipproto=%d ", ip->protocol)); - PrIP (ip->saddr); - DEBUGP ((" -> ")); - PrIP (ip->daddr); - } - - DEBUGP (("\n")); - return; - } - - { - DEBUGP (("%s ??? src=", prefix)); - PrMac (eth->src); - DEBUGP ((" dest=")); - PrMac (eth->dest); - DEBUGP ((" proto=0x%04x len=%d\n", - (int) ntohs(eth->proto), - len)); - } -} - -#endif diff --git a/vsprojects/TapDriver/error.h b/vsprojects/TapDriver/error.h deleted file mode 100644 index 47f436c5..00000000 --- a/vsprojects/TapDriver/error.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * TAP-Windows -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -//----------------- -// DEBUGGING OUTPUT -//----------------- - -#define NOTE_ERROR() \ -{ \ - g_LastErrorFilename = __FILE__; \ - g_LastErrorLineNumber = __LINE__; \ -} - -#if DBG - -typedef struct { - unsigned int in; - unsigned int out; - unsigned int capacity; - char *text; - BOOLEAN error; - MUTEX lock; -} DebugOutput; - -VOID MyDebugPrint (const unsigned char* format, ...); - -VOID MyAssert (const unsigned char *file, int line); - -VOID DumpPacket (const char *prefix, - const unsigned char *data, - unsigned int len); - -VOID DumpPacket2 (const char *prefix, - const ETH_HEADER *eth, - const unsigned char *data, - unsigned int len); - -#define CAN_WE_PRINT (DEBUGP_AT_DISPATCH || KeGetCurrentIrql () < DISPATCH_LEVEL) - -#if ALSO_DBGPRINT -#define DEBUGP(fmt) { MyDebugPrint fmt; if (CAN_WE_PRINT) DbgPrint fmt; } -#else -#define DEBUGP(fmt) { MyDebugPrint fmt; } -#endif - -#define MYASSERT(exp) \ -{ \ - if (!(exp)) \ - { \ - MyAssert(__FILE__, __LINE__); \ - } \ -} - -#define DUMP_PACKET(prefix, data, len) \ - DumpPacket (prefix, data, len) - -#define DUMP_PACKET2(prefix, eth, data, len) \ - DumpPacket2 (prefix, eth, data, len) - -#else - -#define DEBUGP(fmt) -#define MYASSERT(exp) -#define DUMP_PACKET(prefix, data, len) -#define DUMP_PACKET2(prefix, eth, data, len) - -#endif diff --git a/vsprojects/TapDriver/instance.c b/vsprojects/TapDriver/instance.c deleted file mode 100644 index 33ef878f..00000000 --- a/vsprojects/TapDriver/instance.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * TAP-Windows -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#define INSTANCE_KEY(a) ((PVOID)((a)->m_Extension.m_TapDevice)) - -#define N_INSTANCE_BUCKETS 256 - -typedef struct _INSTANCE { - struct _INSTANCE *next; - TapAdapterPointer m_Adapter; -} INSTANCE; - -typedef struct { - INSTANCE *list; - MUTEX lock; -} INSTANCE_BUCKET; - -typedef struct { - INSTANCE_BUCKET buckets[N_INSTANCE_BUCKETS]; -} INSTANCE_HASH; - -INSTANCE_HASH *g_InstanceHash = NULL; - -// must return a hash >= 0 and < N_INSTANCE_BUCKETS -int -InstanceHashValue (PVOID addr) -{ - UCHAR *p = (UCHAR *) &addr; - - if (sizeof (addr) == 4) - return p[0] ^ p[1] ^ p[2] ^ p[3]; - else if (sizeof (addr) == 8) - return p[0] ^ p[1] ^ p[2] ^ p[3] ^ p[4] ^ p[5] ^ p[6] ^ p[7]; - else - { - MYASSERT (0); - } -} - -BOOLEAN -InitInstanceList (VOID) -{ - MYASSERT (g_InstanceHash == NULL); - g_InstanceHash = MemAlloc (sizeof (INSTANCE_HASH), TRUE); - if (g_InstanceHash) - { - int i; - for (i = 0; i < N_INSTANCE_BUCKETS; ++i) - INIT_MUTEX (&g_InstanceHash->buckets[i].lock); - return TRUE; - } - else - return FALSE; -} - -int -NInstances (VOID) -{ - int i, n = 0; - - if (g_InstanceHash) - { - for (i = 0; i < N_INSTANCE_BUCKETS; ++i) - { - BOOLEAN got_lock; - INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[i]; - ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock); - - if (got_lock) - { - INSTANCE *current; - for (current = ib->list; current != NULL; current = current->next) - ++n; - RELEASE_MUTEX (&ib->lock); - } - else - return -1; - } - } - - return n; -} - -int -InstanceMaxBucketSize (VOID) -{ - int i, n = 0; - - if (g_InstanceHash) - { - for (i = 0; i < N_INSTANCE_BUCKETS; ++i) - { - BOOLEAN got_lock; - int bucket_size = 0; - INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[i]; - ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock); - - if (got_lock) - { - INSTANCE *current; - for (current = ib->list; current != NULL; current = current->next) - ++bucket_size; - if (bucket_size > n) - n = bucket_size; - RELEASE_MUTEX (&ib->lock); - } - else - return -1; - } - } - - return n; -} - -VOID -FreeInstanceList (VOID) -{ - if (g_InstanceHash) - { - MYASSERT (NInstances() == 0); - MemFree (g_InstanceHash, sizeof (INSTANCE_HASH)); - g_InstanceHash = NULL; - } -} - -BOOLEAN -AddAdapterToInstanceList (TapAdapterPointer p_Adapter) -{ - BOOLEAN got_lock; - BOOLEAN ret = FALSE; - const int hash = InstanceHashValue(INSTANCE_KEY(p_Adapter)); - INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[hash]; - - DEBUGP (("[TAP] AddAdapterToInstanceList hash=%d\n", hash)); - - ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock); - - if (got_lock) - { - INSTANCE *i = MemAlloc (sizeof (INSTANCE), FALSE); - if (i) - { - MYASSERT (p_Adapter); - i->m_Adapter = p_Adapter; - i->next = ib->list; - ib->list = i; - ret = TRUE; - } - RELEASE_MUTEX (&ib->lock); - } - - return ret; -} - -BOOLEAN -RemoveAdapterFromInstanceList (TapAdapterPointer p_Adapter) -{ - BOOLEAN got_lock; - BOOLEAN ret = FALSE; - INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[InstanceHashValue(INSTANCE_KEY(p_Adapter))]; - - ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock); - - if (got_lock) - { - INSTANCE *current, *prev=NULL; - for (current = ib->list; current != NULL; current = current->next) - { - if (current->m_Adapter == p_Adapter) // found match - { - if (prev) - prev->next = current->next; - else - ib->list = current->next; - MemFree (current->m_Adapter, sizeof (TapAdapter)); - MemFree (current, sizeof (INSTANCE)); - ret = TRUE; - break; - } - prev = current; - } - RELEASE_MUTEX (&ib->lock); - } - - return ret; -} - -TapAdapterPointer -LookupAdapterInInstanceList (PDEVICE_OBJECT p_DeviceObject) -{ - BOOLEAN got_lock; - TapAdapterPointer ret = NULL; - INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[InstanceHashValue((PVOID)p_DeviceObject)]; - - ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock); - - if (got_lock) - { - INSTANCE *current, *prev=NULL; - for (current = ib->list; current != NULL; current = current->next) - { - if (p_DeviceObject == INSTANCE_KEY (current->m_Adapter)) // found match - { - // move it to head of list - if (prev) - { - prev->next = current->next; - current->next = ib->list; - ib->list = current; - } - ret = ib->list->m_Adapter; - break; - } - prev = current; - } - RELEASE_MUTEX (&ib->lock); - } - - return ret; -} diff --git a/vsprojects/TapDriver/lock.h b/vsprojects/TapDriver/lock.h deleted file mode 100644 index e2a2029e..00000000 --- a/vsprojects/TapDriver/lock.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * TAP-Windows -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -typedef struct -{ - volatile long count; -} MUTEX; - -#define MUTEX_SLEEP_TIME 10000 // microseconds - -#define INIT_MUTEX(m) { (m)->count = 0; } - -#define ACQUIRE_MUTEX_BLOCKING(m) \ -{ \ - while (NdisInterlockedIncrement (&((m)->count)) != 1) \ - { \ - NdisInterlockedDecrement(&((m)->count)); \ - NdisMSleep(MUTEX_SLEEP_TIME); \ - } \ -} - -#define RELEASE_MUTEX(m) \ -{ \ - NdisInterlockedDecrement(&((m)->count)); \ -} - -#define ACQUIRE_MUTEX_NONBLOCKING(m, result) \ -{ \ - if (NdisInterlockedIncrement (&((m)->count)) != 1) \ - { \ - NdisInterlockedDecrement(&((m)->count)); \ - result = FALSE; \ - } \ - else \ - { \ - result = TRUE; \ - } \ -} - -#define ACQUIRE_MUTEX_ADAPTIVE(m, result) \ -{ \ - result = TRUE; \ - while (NdisInterlockedIncrement (&((m)->count)) != 1) \ - { \ - NdisInterlockedDecrement(&((m)->count)); \ - if (KeGetCurrentIrql () < DISPATCH_LEVEL) \ - NdisMSleep(MUTEX_SLEEP_TIME); \ - else \ - { \ - result = FALSE; \ - break; \ - } \ - } \ -} diff --git a/vsprojects/TapDriver/macinfo.c b/vsprojects/TapDriver/macinfo.c deleted file mode 100644 index fca53079..00000000 --- a/vsprojects/TapDriver/macinfo.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * TAP-Windows -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "macinfo.h" - -int -HexStringToDecimalInt (const int p_Character) -{ - int l_Value = 0; - - if (p_Character >= 'A' && p_Character <= 'F') - l_Value = (p_Character - 'A') + 10; - else if (p_Character >= 'a' && p_Character <= 'f') - l_Value = (p_Character - 'a') + 10; - else if (p_Character >= '0' && p_Character <= '9') - l_Value = p_Character - '0'; - - return l_Value; -} - -BOOLEAN -ParseMAC (MACADDR dest, const char *src) -{ - int c; - int mac_index = 0; - BOOLEAN high_digit = FALSE; - int delim_action = 1; - - MYASSERT (src); - MYASSERT (dest); - - CLEAR_MAC (dest); - - while (c = *src++) - { - if (IsMacDelimiter (c)) - { - mac_index += delim_action; - high_digit = FALSE; - delim_action = 1; - } - else if (IsHexDigit (c)) - { - const int digit = HexStringToDecimalInt (c); - if (mac_index < sizeof (MACADDR)) - { - if (!high_digit) - { - dest[mac_index] = (char)(digit); - high_digit = TRUE; - delim_action = 1; - } - else - { - dest[mac_index] = (char)(dest[mac_index] * 16 + digit); - ++mac_index; - high_digit = FALSE; - delim_action = 0; - } - } - else - return FALSE; - } - else - return FALSE; - } - - return (mac_index + delim_action) >= sizeof (MACADDR); -} - -/* - * Generate a MAC using the GUID in the adapter name. - * - * The mac is constructed as 00:FF:xx:xx:xx:xx where - * the Xs are taken from the first 32 bits of the GUID in the - * adapter name. This is similar to the Linux 2.4 tap MAC - * generator, except linux uses 32 random bits for the Xs. - * - * In general, this solution is reasonable for most - * applications except for very large bridged TAP networks, - * where the probability of address collisions becomes more - * than infintesimal. - * - * Using the well-known "birthday paradox", on a 1000 node - * network the probability of collision would be - * 0.000116292153. On a 10,000 node network, the probability - * of collision would be 0.01157288998621678766. - */ - -VOID GenerateRandomMac (MACADDR mac, const unsigned char *adapter_name) -{ - unsigned const char *cp = adapter_name; - unsigned char c; - unsigned int i = 2; - unsigned int byte = 0; - int brace = 0; - int state = 0; - - CLEAR_MAC (mac); - - mac[0] = 0x00; - mac[1] = 0xFF; - - while (c = *cp++) - { - if (i >= sizeof (MACADDR)) - break; - if (c == '{') - brace = 1; - if (IsHexDigit (c) && brace) - { - const unsigned int digit = HexStringToDecimalInt (c); - if (state) - { - byte <<= 4; - byte |= digit; - mac[i++] = (unsigned char) byte; - state = 0; - } - else - { - byte = digit; - state = 1; - } - } - } -} - -VOID GenerateRelatedMAC (MACADDR dest, const MACADDR src, const int delta) -{ - COPY_MAC (dest, src); - dest[2] += (UCHAR) delta; -} diff --git a/vsprojects/TapDriver/macinfo.h b/vsprojects/TapDriver/macinfo.h deleted file mode 100644 index ba843e8c..00000000 --- a/vsprojects/TapDriver/macinfo.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * TAP-Windows -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef MacInfoDefined -#define MacInfoDefined - -//=================================================================================== -// Macros -//=================================================================================== -#define IsMacDelimiter(a) (a == ':' || a == '-' || a == '.') -#define IsHexDigit(c) ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) - -#define COPY_MAC(dest, src) NdisMoveMemory ((dest), (src), sizeof (MACADDR)) -#define CLEAR_MAC(dest) NdisZeroMemory ((dest), sizeof (MACADDR)) -#define MAC_EQUAL(a,b) (memcmp ((a), (b), sizeof (MACADDR)) == 0) - -#endif diff --git a/vsprojects/TapDriver/mem.c b/vsprojects/TapDriver/mem.c deleted file mode 100644 index c56304cc..00000000 --- a/vsprojects/TapDriver/mem.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * TAP-Windows -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -//------------------ -// Memory Management -//------------------ - -PVOID -MemAlloc (ULONG p_Size, BOOLEAN zero) -{ - PVOID l_Return = NULL; - - if (p_Size) - { - __try - { - if (NdisAllocateMemoryWithTag (&l_Return, p_Size, 'APAT') - == NDIS_STATUS_SUCCESS) - { - if (zero) - NdisZeroMemory (l_Return, p_Size); - } - else - l_Return = NULL; - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - l_Return = NULL; - } - } - - return l_Return; -} - -VOID -MemFree (PVOID p_Addr, ULONG p_Size) -{ - if (p_Addr && p_Size) - { - __try - { -#if DBG - NdisZeroMemory (p_Addr, p_Size); -#endif - NdisFreeMemory (p_Addr, p_Size, 0); - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - } - } -} - -/* - * Circular queue management routines. - */ - -#define QUEUE_BYTE_ALLOCATION(size) \ - (sizeof (Queue) + (size * sizeof (PVOID))) - -#define QUEUE_ADD_INDEX(var, inc) \ -{ \ - var += inc; \ - if (var >= q->capacity) \ - var -= q->capacity; \ - MYASSERT (var < q->capacity); \ -} - -#define QUEUE_SANITY_CHECK() \ - MYASSERT (q != NULL && q->base < q->capacity && q->size <= q->capacity) - -#define QueueCount(q) (q->size) - -#define UPDATE_MAX_SIZE() \ -{ \ - if (q->size > q->max_size) \ - q->max_size = q->size; \ -} - -Queue * -QueueInit (ULONG capacity) -{ - Queue *q; - - MYASSERT (capacity > 0); - q = (Queue *) MemAlloc (QUEUE_BYTE_ALLOCATION (capacity), TRUE); - if (!q) - return NULL; - - q->base = q->size = 0; - q->capacity = capacity; - q->max_size = 0; - return q; -} - -VOID -QueueFree (Queue *q) -{ - if (q) - { - QUEUE_SANITY_CHECK (); - MemFree (q, QUEUE_BYTE_ALLOCATION (q->capacity)); - } -} - -PVOID -QueuePush (Queue *q, PVOID item) -{ - ULONG dest; - QUEUE_SANITY_CHECK (); - if (q->size == q->capacity) - return NULL; - dest = q->base; - QUEUE_ADD_INDEX (dest, q->size); - q->data[dest] = item; - ++q->size; - UPDATE_MAX_SIZE(); - return item; -} - -PVOID -QueuePop (Queue *q) -{ - ULONG oldbase; - QUEUE_SANITY_CHECK (); - if (!q->size) - return NULL; - oldbase = q->base; - QUEUE_ADD_INDEX (q->base, 1); - --q->size; - UPDATE_MAX_SIZE(); - return q->data[oldbase]; -} - -PVOID -QueueExtract (Queue *q, PVOID item) -{ - ULONG src, dest, count, n; - QUEUE_SANITY_CHECK (); - n = 0; - src = dest = q->base; - count = q->size; - while (count--) - { - if (item == q->data[src]) - { - ++n; - --q->size; - } - else - { - q->data[dest] = q->data[src]; - QUEUE_ADD_INDEX (dest, 1); - } - QUEUE_ADD_INDEX (src, 1); - } - if (n) - return item; - else - return NULL; -} - -#undef QUEUE_BYTE_ALLOCATION -#undef QUEUE_ADD_INDEX -#undef QUEUE_SANITY_CHECK -#undef UPDATE_MAX_SIZE diff --git a/vsprojects/TapDriver/proto.h b/vsprojects/TapDriver/proto.h deleted file mode 100644 index 71916a96..00000000 --- a/vsprojects/TapDriver/proto.h +++ /dev/null @@ -1,224 +0,0 @@ -/* - * TAP-Windows -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -//============================================================ -// MAC address, Ethernet header, and ARP -//============================================================ - -#pragma pack(1) - -#define IP_HEADER_SIZE 20 -#define IPV6_HEADER_SIZE 40 - -typedef unsigned char MACADDR [6]; -typedef unsigned long IPADDR; -typedef unsigned char IPV6ADDR [16]; - -//----------------- -// Ethernet address -//----------------- - -typedef struct { - MACADDR addr; -} ETH_ADDR; - -typedef struct { - ETH_ADDR list[NIC_MAX_MCAST_LIST]; -} MC_LIST; - -//---------------- -// Ethernet header -//---------------- - -typedef struct -{ - MACADDR dest; /* destination eth addr */ - MACADDR src; /* source ether addr */ - -# define ETH_P_IP 0x0800 /* IPv4 protocol */ -# define ETH_P_IPV6 0x86DD /* IPv6 protocol */ -# define ETH_P_ARP 0x0806 /* ARP protocol */ - USHORT proto; /* packet type ID field */ -} ETH_HEADER, *PETH_HEADER; - -//---------------- -// ARP packet -//---------------- - -typedef struct - { - MACADDR m_MAC_Destination; // Reverse these two - MACADDR m_MAC_Source; // to answer ARP requests - USHORT m_Proto; // 0x0806 - -# define MAC_ADDR_TYPE 0x0001 - USHORT m_MAC_AddressType; // 0x0001 - - USHORT m_PROTO_AddressType; // 0x0800 - UCHAR m_MAC_AddressSize; // 0x06 - UCHAR m_PROTO_AddressSize; // 0x04 - -# define ARP_REQUEST 0x0001 -# define ARP_REPLY 0x0002 - USHORT m_ARP_Operation; // 0x0001 for ARP request, 0x0002 for ARP reply - - MACADDR m_ARP_MAC_Source; - IPADDR m_ARP_IP_Source; - MACADDR m_ARP_MAC_Destination; - IPADDR m_ARP_IP_Destination; - } -ARP_PACKET, *PARP_PACKET; - -//---------- -// IP Header -//---------- - -typedef struct { -# define IPH_GET_VER(v) (((v) >> 4) & 0x0F) -# define IPH_GET_LEN(v) (((v) & 0x0F) << 2) - UCHAR version_len; - - UCHAR tos; - USHORT tot_len; - USHORT id; - -# define IP_OFFMASK 0x1fff - USHORT frag_off; - - UCHAR ttl; - -# define IPPROTO_UDP 17 /* UDP protocol */ -# define IPPROTO_TCP 6 /* TCP protocol */ -# define IPPROTO_ICMP 1 /* ICMP protocol */ -# define IPPROTO_IGMP 2 /* IGMP protocol */ - UCHAR protocol; - - USHORT check; - ULONG saddr; - ULONG daddr; - /* The options start here. */ -} IPHDR; - -//----------- -// UDP header -//----------- - -typedef struct { - USHORT source; - USHORT dest; - USHORT len; - USHORT check; -} UDPHDR; - -//-------------------------- -// TCP header, per RFC 793. -//-------------------------- - -typedef struct { - USHORT source; /* source port */ - USHORT dest; /* destination port */ - ULONG seq; /* sequence number */ - ULONG ack_seq; /* acknowledgement number */ - -# define TCPH_GET_DOFF(d) (((d) & 0xF0) >> 2) - UCHAR doff_res; - -# define TCPH_FIN_MASK (1<<0) -# define TCPH_SYN_MASK (1<<1) -# define TCPH_RST_MASK (1<<2) -# define TCPH_PSH_MASK (1<<3) -# define TCPH_ACK_MASK (1<<4) -# define TCPH_URG_MASK (1<<5) -# define TCPH_ECE_MASK (1<<6) -# define TCPH_CWR_MASK (1<<7) - UCHAR flags; - - USHORT window; - USHORT check; - USHORT urg_ptr; -} TCPHDR; - -#define TCPOPT_EOL 0 -#define TCPOPT_NOP 1 -#define TCPOPT_MAXSEG 2 -#define TCPOLEN_MAXSEG 4 - -//------------ -// IPv6 Header -//------------ - -typedef struct { - UCHAR version_prio; - UCHAR flow_lbl[3]; - USHORT payload_len; -# define IPPROTO_ICMPV6 0x3a /* ICMP protocol v6 */ - UCHAR nexthdr; - UCHAR hop_limit; - IPV6ADDR saddr; - IPV6ADDR daddr; -} IPV6HDR; - -//-------------------------------------------- -// IPCMPv6 NS/NA Packets (RFC4443 and RFC4861) -//-------------------------------------------- - -// Neighbor Solictiation - RFC 4861, 4.3 -// (this is just the ICMPv6 part of the packet) -typedef struct { - UCHAR type; -# define ICMPV6_TYPE_NS 135 // neighbour solicitation - UCHAR code; -# define ICMPV6_CODE_0 0 // no specific sub-code for NS/NA - USHORT checksum; - ULONG reserved; - IPV6ADDR target_addr; -} ICMPV6_NS; - -// Neighbor Advertisement - RFC 4861, 4.4 + 4.6/4.6.1 -// (this is just the ICMPv6 payload) -typedef struct { - UCHAR type; -# define ICMPV6_TYPE_NA 136 // neighbour advertisement - UCHAR code; -# define ICMPV6_CODE_0 0 // no specific sub-code for NS/NA - USHORT checksum; - UCHAR rso_bits; // Router(0), Solicited(2), Ovrrd(4) - UCHAR reserved[3]; - IPV6ADDR target_addr; -// always include "Target Link-layer Address" option (RFC 4861 4.6.1) - UCHAR opt_type; -#define ICMPV6_OPTION_TLLA 2 - UCHAR opt_length; -#define ICMPV6_LENGTH_TLLA 1 // multiplied by 8 -> 1 = 8 bytes - MACADDR target_macaddr; -} ICMPV6_NA; - -// this is the complete packet with Ethernet and IPv6 headers -typedef struct { - ETH_HEADER eth; - IPV6HDR ipv6; - ICMPV6_NA icmpv6; -} ICMPV6_NA_PKT; - -#pragma pack() diff --git a/vsprojects/TapDriver/prototypes.h b/vsprojects/TapDriver/prototypes.h deleted file mode 100644 index 50cc4610..00000000 --- a/vsprojects/TapDriver/prototypes.h +++ /dev/null @@ -1,260 +0,0 @@ -/* - * TAP-Windows -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef TAP_PROTOTYPES_DEFINED -#define TAP_PROTOTYPES_DEFINED - -NTSTATUS DriverEntry - ( - IN PDRIVER_OBJECT p_DriverObject, - IN PUNICODE_STRING p_RegistryPath - ); - -VOID TapDriverUnload - ( - IN PDRIVER_OBJECT p_DriverObject - ); - -NDIS_STATUS AdapterCreate - ( - OUT PNDIS_STATUS p_ErrorStatus, - OUT PUINT p_MediaIndex, - IN PNDIS_MEDIUM p_Media, - IN UINT p_MediaCount, - IN NDIS_HANDLE p_AdapterHandle, - IN NDIS_HANDLE p_ConfigurationHandle - ); - -VOID AdapterHalt - ( - IN NDIS_HANDLE p_AdapterContext - ); - -VOID AdapterFreeResources - ( - TapAdapterPointer p_Adapter - ); - -NDIS_STATUS AdapterReset - ( - OUT PBOOLEAN p_AddressingReset, - IN NDIS_HANDLE p_AdapterContext - ); - -NDIS_STATUS AdapterQuery - ( - IN NDIS_HANDLE p_AdapterContext, - IN NDIS_OID p_OID, - IN PVOID p_Buffer, - IN ULONG p_BufferLength, - OUT PULONG p_BytesWritten, - OUT PULONG p_BytesNeeded - ); - -NDIS_STATUS AdapterModify - ( - IN NDIS_HANDLE p_AdapterContext, - IN NDIS_OID p_OID, - IN PVOID p_Buffer, - IN ULONG p_BufferLength, - OUT PULONG p_BytesRead, - OUT PULONG p_BytesNeeded - ); - -NDIS_STATUS AdapterTransmit - ( - IN NDIS_HANDLE p_AdapterContext, - IN PNDIS_PACKET p_Packet, - IN UINT p_Flags - ); - -NDIS_STATUS AdapterReceive - ( - OUT PNDIS_PACKET p_Packet, - OUT PUINT p_Transferred, - IN NDIS_HANDLE p_AdapterContext, - IN NDIS_HANDLE p_ReceiveContext, - IN UINT p_Offset, - IN UINT p_ToTransfer - ); - -NTSTATUS TapDeviceHook - ( - IN PDEVICE_OBJECT p_DeviceObject, - IN PIRP p_IRP - ); - -NDIS_STATUS CreateTapDevice - ( - TapExtensionPointer p_Extension, - const char *p_Name - ); - -VOID DestroyTapDevice - ( - TapExtensionPointer p_Extension - ); - -VOID TapDeviceFreeResources - ( - TapExtensionPointer p_Extension - ); - -NTSTATUS CompleteIRP - ( - IN PIRP p_IRP, - IN TapPacketPointer p_PacketBuffer, - IN CCHAR PriorityBoost - ); - -VOID CancelIRPCallback - ( - IN PDEVICE_OBJECT p_DeviceObject, - IN PIRP p_IRP - ); - -VOID CancelIRP - ( - TapExtensionPointer p_Extension, - IN PIRP p_IRP, - BOOLEAN callback - ); - -VOID FlushQueues - ( - TapExtensionPointer p_Extension - ); - -VOID ResetTapAdapterState - ( - TapAdapterPointer p_Adapter - ); - -BOOLEAN ProcessARP - ( - TapAdapterPointer p_Adapter, - const PARP_PACKET src, - const IPADDR adapter_ip, - const IPADDR ip_network, - const IPADDR ip_netmask, - const MACADDR mac - ); - -VOID SetMediaStatus - ( - TapAdapterPointer p_Adapter, - BOOLEAN state - ); - -VOID InjectPacketDeferred - ( - TapAdapterPointer p_Adapter, - UCHAR *packet, - const unsigned int len - ); - -VOID InjectPacketNow - ( - TapAdapterPointer p_Adapter, - UCHAR *packet, - const unsigned int len - ); - -// for KDEFERRED_ROUTINE and Static Driver Verifier -//#include -//KDEFERRED_ROUTINE InjectPacketDpc; - -VOID InjectPacketDpc - ( - KDPC *Dpc, - PVOID DeferredContext, - PVOID SystemArgument1, - PVOID SystemArgument2 - ); - -VOID CheckIfDhcpAndTunMode - ( - TapAdapterPointer p_Adapter - ); - -VOID HookDispatchFunctions(); - -#if ENABLE_NONADMIN - -#if defined(DDKVER_MAJOR) && DDKVER_MAJOR < 5600 -/* - * Better solution for use on Vista DDK, but possibly not compatible with - * earlier DDKs: - * - * Eliminate the definition of SECURITY_DESCRIPTOR (and even ZwSetSecurityObject), - * and at the top of tapdrv.c change: - * - * #include - * #include - * #include - * - * To - * - * #include - * #include - * #include - */ -typedef struct _SECURITY_DESCRIPTOR { - unsigned char opaque[64]; -} SECURITY_DESCRIPTOR; - -NTSYSAPI -NTSTATUS -NTAPI -ZwSetSecurityObject ( - IN HANDLE Handle, - IN SECURITY_INFORMATION SecurityInformation, - IN PSECURITY_DESCRIPTOR SecurityDescriptor); - -#endif - -VOID AllowNonAdmin (TapExtensionPointer p_Extension); - -#endif - -struct WIN2K_NDIS_MINIPORT_BLOCK -{ - unsigned char opaque[16]; - UNICODE_STRING MiniportName; // how mini-port refers to us -}; - -#if PACKET_TRUNCATION_CHECK - -VOID IPv4PacketSizeVerify - ( - const UCHAR *data, - ULONG length, - BOOLEAN tun, - const char *prefix, - LONG *counter - ); - -#endif - -#endif diff --git a/vsprojects/TapDriver/tap-windows.h b/vsprojects/TapDriver/tap-windows.h deleted file mode 100644 index ff1baf17..00000000 --- a/vsprojects/TapDriver/tap-windows.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * TAP-Windows -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef __TAP_WIN_H -#define __TAP_WIN_H - -/* - * ============= - * TAP IOCTLs - * ============= - */ - -#define TAP_WIN_CONTROL_CODE(request,method) \ - CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS) - -/* Present in 8.1 */ - -#define TAP_WIN_IOCTL_GET_MAC TAP_WIN_CONTROL_CODE (1, METHOD_BUFFERED) -#define TAP_WIN_IOCTL_GET_VERSION TAP_WIN_CONTROL_CODE (2, METHOD_BUFFERED) -#define TAP_WIN_IOCTL_GET_MTU TAP_WIN_CONTROL_CODE (3, METHOD_BUFFERED) -#define TAP_WIN_IOCTL_GET_INFO TAP_WIN_CONTROL_CODE (4, METHOD_BUFFERED) -//#define TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT TAP_WIN_CONTROL_CODE (5, METHOD_BUFFERED) -#define TAP_WIN_IOCTL_SET_MEDIA_STATUS TAP_WIN_CONTROL_CODE (6, METHOD_BUFFERED) -//#define TAP_WIN_IOCTL_CONFIG_DHCP_MASQ TAP_WIN_CONTROL_CODE (7, METHOD_BUFFERED) -#define TAP_WIN_IOCTL_GET_LOG_LINE TAP_WIN_CONTROL_CODE (8, METHOD_BUFFERED) -//#define TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT TAP_WIN_CONTROL_CODE (9, METHOD_BUFFERED) - -/* Added in 8.2 */ - -/* obsoletes TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT */ -//#define TAP_WIN_IOCTL_CONFIG_TUN TAP_WIN_CONTROL_CODE (10, METHOD_BUFFERED) - -/* - * ================= - * Registry keys - * ================= - */ - -#define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}" -#define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}" - -/* - * ====================== - * Filesystem prefixes - * ====================== - */ - -#define USERMODEDEVICEDIR "\\\\.\\Global\\" -#define SYSDEVICEDIR "\\Device\\" -#define USERDEVICEDIR "\\DosDevices\\Global\\" -#define TAP_WIN_SUFFIX ".tap" - -#endif diff --git a/vsprojects/TapDriver/tapdrvr.c b/vsprojects/TapDriver/tapdrvr.c deleted file mode 100644 index 4781c872..00000000 --- a/vsprojects/TapDriver/tapdrvr.c +++ /dev/null @@ -1,3173 +0,0 @@ -/* - * TAP-Windows -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -//====================================================== -// This driver is designed to work on Win 2000 or higher -// versions of Windows. -// -// It is SMP-safe and handles NDIS 5 power management. -// -// By default we operate as a "tap" virtual ethernet -// 802.3 interface, but we can emulate a "tun" -// interface (point-to-point IPv4) through the -// TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT or -// TAP_WIN_IOCTL_CONFIG_TUN ioctl. -//====================================================== - -#include "tap-windows.h" -#include "config.h" - -#define NDIS_MINIPORT_DRIVER -#define BINARY_COMPATIBLE 0 -#define NDIS50_MINIPORT 1 -#define NDIS_WDM 0 -#define NDIS50 1 -#define NTSTRSAFE_LIB - -// Debug info output -#define ALSO_DBGPRINT 1 -#define DEBUGP_AT_DISPATCH 0 - -//======================================================== -// Check for truncated IPv4 packets, log errors if found. -//======================================================== -#define PACKET_TRUNCATION_CHECK 0 - -//======================================================== -// EXPERIMENTAL -- Configure TAP device object to be -// accessible from non-administrative accounts, based -// on an advanced properties setting. -// -// Duplicates the functionality of OpenVPN's -// --allow-nonadmin directive. -//======================================================== -//#define ENABLE_NONADMIN 1 - -#if defined(DDKVER_MAJOR) && DDKVER_MAJOR < 5600 -#include -#include -#include -#else -#include -#include -#include -#endif - -#include "lock.h" -#include "constants.h" -#include "proto.h" -#include "error.h" -#include "endian.h" -#include "dhcp.h" -#include "types.h" -#include "prototypes.h" - -#include "mem.c" -#include "macinfo.c" -#include "error.c" -#include "dhcp.c" -#include "instance.c" - -#define IS_UP(ta) \ - ((ta)->m_InterfaceIsRunning && (ta)->m_Extension.m_TapIsRunning) - -#define INCREMENT_STAT(s) ++(s) - -#define NAME_BUFFER_SIZE 80 - -//======================================================== -// Globals -//======================================================== - -NDIS_HANDLE g_NdisWrapperHandle; - -const UINT g_SupportedOIDList[] = { - OID_GEN_HARDWARE_STATUS, - OID_GEN_MEDIA_SUPPORTED, - OID_GEN_MEDIA_IN_USE, - OID_GEN_MAXIMUM_LOOKAHEAD, - OID_GEN_MAC_OPTIONS, - OID_GEN_LINK_SPEED, - OID_GEN_TRANSMIT_BLOCK_SIZE, - OID_GEN_RECEIVE_BLOCK_SIZE, - OID_GEN_VENDOR_DESCRIPTION, - OID_GEN_DRIVER_VERSION, - OID_GEN_XMIT_OK, - OID_GEN_RCV_OK, - OID_GEN_XMIT_ERROR, - OID_GEN_RCV_ERROR, - OID_802_3_PERMANENT_ADDRESS, - OID_802_3_CURRENT_ADDRESS, - OID_GEN_RCV_NO_BUFFER, - OID_802_3_RCV_ERROR_ALIGNMENT, - OID_802_3_XMIT_ONE_COLLISION, - OID_802_3_XMIT_MORE_COLLISIONS, - OID_802_3_MULTICAST_LIST, - OID_802_3_MAXIMUM_LIST_SIZE, - OID_GEN_VENDOR_ID, - OID_GEN_CURRENT_LOOKAHEAD, - OID_GEN_CURRENT_PACKET_FILTER, - OID_GEN_PROTOCOL_OPTIONS, - OID_GEN_MAXIMUM_TOTAL_SIZE, - OID_GEN_TRANSMIT_BUFFER_SPACE, - OID_GEN_RECEIVE_BUFFER_SPACE, - OID_GEN_MAXIMUM_FRAME_SIZE, - OID_GEN_VENDOR_DRIVER_VERSION, - OID_GEN_MAXIMUM_SEND_PACKETS, - OID_GEN_MEDIA_CONNECT_STATUS, - OID_GEN_SUPPORTED_LIST -}; - -//============================================================ -// Driver Entry -//============================================================ -#pragma NDIS_INIT_FUNCTION (DriverEntry) - -DRIVER_INITIALIZE DriverEntry; -NTSTATUS -DriverEntry (IN PDRIVER_OBJECT p_DriverObject, - IN PUNICODE_STRING p_RegistryPath) -{ - NDIS_STATUS l_Status = NDIS_STATUS_FAILURE; - NDIS_MINIPORT_CHARACTERISTICS *l_Properties = NULL; - - //======================================================== - // Notify NDIS that a new miniport driver is initializing. - //======================================================== - - NdisMInitializeWrapper (&g_NdisWrapperHandle, - p_DriverObject, - p_RegistryPath, NULL); - - //====================== - // Global initialization - //====================== - -#if DBG - MyDebugInit (10000); // Allocate debugging text space -#endif - - if (!InitInstanceList ()) - { - DEBUGP (("[TAP] Allocation failed for adapter instance list\n")); - goto cleanup; - } - - //======================================= - // Set and register miniport entry points - //======================================= - - l_Properties = MemAlloc (sizeof (NDIS_MINIPORT_CHARACTERISTICS), TRUE); - - if (l_Properties == NULL) - { - DEBUGP (("[TAP] Allocation failed for miniport entry points\n")); - goto cleanup; - } - - l_Properties->MajorNdisVersion = TAP_NDIS_MAJOR_VERSION; - l_Properties->MinorNdisVersion = TAP_NDIS_MINOR_VERSION; - l_Properties->InitializeHandler = AdapterCreate; - l_Properties->HaltHandler = AdapterHalt; - l_Properties->ResetHandler = AdapterReset; /* DISPATCH_LEVEL */ - l_Properties->TransferDataHandler = AdapterReceive; /* DISPATCH_LEVEL */ - l_Properties->SendHandler = AdapterTransmit; /* DISPATCH_LEVEL */ - l_Properties->QueryInformationHandler = AdapterQuery; /* DISPATCH_LEVEL */ - l_Properties->SetInformationHandler = AdapterModify; /* DISPATCH_LEVEL */ - - switch (l_Status = - NdisMRegisterMiniport (g_NdisWrapperHandle, l_Properties, - sizeof (NDIS_MINIPORT_CHARACTERISTICS))) - { - case NDIS_STATUS_SUCCESS: - { - DEBUGP (("[TAP] version [%d.%d] %s %s registered miniport successfully\n", - TAP_DRIVER_MAJOR_VERSION, - TAP_DRIVER_MINOR_VERSION, - __DATE__, - __TIME__)); - DEBUGP (("Registry Path: '%.*S'\n", p_RegistryPath->Length/2, p_RegistryPath->Buffer)); - break; - } - - case NDIS_STATUS_BAD_CHARACTERISTICS: - { - DEBUGP (("[TAP] Miniport characteristics were badly defined\n")); - NdisTerminateWrapper (g_NdisWrapperHandle, NULL); - break; - } - - case NDIS_STATUS_BAD_VERSION: - { - DEBUGP - (("[TAP] NDIS Version is wrong for the given characteristics\n")); - NdisTerminateWrapper (g_NdisWrapperHandle, NULL); - break; - } - - case NDIS_STATUS_RESOURCES: - { - DEBUGP (("[TAP] Insufficient resources\n")); - NdisTerminateWrapper (g_NdisWrapperHandle, NULL); - break; - } - - default: - case NDIS_STATUS_FAILURE: - { - DEBUGP (("[TAP] Unknown fatal registration error\n")); - NdisTerminateWrapper (g_NdisWrapperHandle, NULL); - break; - } - } - - cleanup: - if (l_Properties) - MemFree (l_Properties, sizeof (NDIS_MINIPORT_CHARACTERISTICS)); - - if (l_Status == NDIS_STATUS_SUCCESS) - NdisMRegisterUnloadHandler (g_NdisWrapperHandle, TapDriverUnload); - else - TapDriverUnload (p_DriverObject); - - return l_Status; -} - -//============================================================ -// Driver Unload -//============================================================ -DRIVER_UNLOAD TapDriverUnload; -VOID -TapDriverUnload (IN PDRIVER_OBJECT p_DriverObject) -{ - DEBUGP (("[TAP] version [%d.%d] %s %s unloaded, instances=%d, imbs=%d\n", - TAP_DRIVER_MAJOR_VERSION, - TAP_DRIVER_MINOR_VERSION, - __DATE__, - __TIME__, - NInstances(), - InstanceMaxBucketSize())); - - FreeInstanceList (); - - //============================== - // Free debugging text space - //============================== -#if DBG - MyDebugFree (); -#endif -} - -//========================================================== -// Adapter Initialization -//========================================================== -NDIS_STATUS AdapterCreate -(OUT PNDIS_STATUS p_ErrorStatus, - OUT PUINT p_MediaIndex, - IN PNDIS_MEDIUM p_Media, - IN UINT p_MediaCount, - IN NDIS_HANDLE p_AdapterHandle, - IN NDIS_HANDLE p_ConfigurationHandle) -{ - TapAdapterPointer l_Adapter = NULL; - - NDIS_MEDIUM l_PreferredMedium = NdisMedium802_3; // Ethernet - BOOLEAN l_MacFromRegistry = FALSE; - UINT l_Index; - NDIS_STATUS status; - -#if ENABLE_NONADMIN - BOOLEAN enable_non_admin = FALSE; -#endif - - DEBUGP (("[TAP] AdapterCreate called\n")); - - //==================================== - // Make sure adapter type is supported - //==================================== - - for (l_Index = 0; - l_Index < p_MediaCount && p_Media[l_Index] != l_PreferredMedium; - ++l_Index); - - if (l_Index == p_MediaCount) - { - DEBUGP (("[TAP] Unsupported adapter type [wanted: %d]\n", - l_PreferredMedium)); - return NDIS_STATUS_UNSUPPORTED_MEDIA; - } - - *p_MediaIndex = l_Index; - - //========================================= - // Allocate memory for TapAdapter structure - //========================================= - - l_Adapter = MemAlloc (sizeof (TapAdapter), TRUE); - - if (l_Adapter == NULL) - { - DEBUGP (("[TAP] Couldn't allocate adapter memory\n")); - return NDIS_STATUS_RESOURCES; - } - - //========================================== - // Inform the NDIS library about significant - // features of our virtual NIC. - //========================================== - - NdisMSetAttributesEx - (p_AdapterHandle, - (NDIS_HANDLE) l_Adapter, - 16, - NDIS_ATTRIBUTE_DESERIALIZE - | NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT - | NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT - | NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND, - NdisInterfaceInternal); - - //===================================== - // Initialize simple Adapter parameters - //===================================== - - l_Adapter->m_Lookahead = DEFAULT_PACKET_LOOKAHEAD; - l_Adapter->m_Medium = l_PreferredMedium; - l_Adapter->m_DeviceState = '?'; - l_Adapter->m_MiniportAdapterHandle = p_AdapterHandle; - - //================================== - // Allocate spinlock for controlling - // access to multicast address list. - //================================== - NdisAllocateSpinLock (&l_Adapter->m_MCLock); - l_Adapter->m_MCLockAllocated = TRUE; - - //==================================================== - // Register a shutdown handler which will be called - // on system restart/shutdown to halt our virtual NIC. - //==================================================== - - NdisMRegisterAdapterShutdownHandler (p_AdapterHandle, l_Adapter, - AdapterHalt); - l_Adapter->m_RegisteredAdapterShutdownHandler = TRUE; - - //============================================ - // Get parameters from registry which were set - // in the adapter advanced properties dialog. - //============================================ - { - NDIS_STATUS status; - NDIS_HANDLE configHandle; - NDIS_CONFIGURATION_PARAMETER *parm; - - // set defaults in case our registry query fails - l_Adapter->m_MTU = ETHERNET_MTU; - l_Adapter->m_MediaStateAlwaysConnected = FALSE; - l_Adapter->m_MediaState = FALSE; - - NdisOpenConfiguration (&status, &configHandle, p_ConfigurationHandle); - if (status != NDIS_STATUS_SUCCESS) - { - DEBUGP (("[TAP] Couldn't open adapter registry\n")); - AdapterFreeResources (l_Adapter); - return status; - } - - //==================================== - // Allocate and construct adapter name - //==================================== - { - - NDIS_STRING mkey = NDIS_STRING_CONST("MiniportName"); - NDIS_STRING vkey = NDIS_STRING_CONST("NdisVersion"); - NDIS_STATUS vstatus; - NDIS_CONFIGURATION_PARAMETER *vparm; - - NdisReadConfiguration (&vstatus, &vparm, configHandle, &vkey, NdisParameterInteger); - if (vstatus == NDIS_STATUS_SUCCESS) - DEBUGP (("[TAP] NdisReadConfiguration NdisVersion=%X\n", vparm->ParameterData.IntegerData)); - - NdisReadConfiguration (&status, &parm, configHandle, &mkey, NdisParameterString); - if (status == NDIS_STATUS_SUCCESS) - { - if (parm->ParameterType == NdisParameterString) - { - DEBUGP (("[TAP] NdisReadConfiguration (MiniportName=%.*S)\n", - parm->ParameterData.StringData.Length/2, - parm->ParameterData.StringData.Buffer)); - - if (RtlUnicodeStringToAnsiString ( - &l_Adapter->m_NameAnsi, - &parm->ParameterData.StringData, - TRUE) != STATUS_SUCCESS) - { - DEBUGP (("[TAP] MiniportName failed\n")); - status = NDIS_STATUS_RESOURCES; - } - } - } - else - { - /* "MiniportName" is available only XP and above. Not on Windows 2000. */ - if (vstatus == NDIS_STATUS_SUCCESS && vparm->ParameterData.IntegerData == 0x50000) - { - /* Fallback for Windows 2000 with NDIS version 5.00.00 - Don't use this on Vista, 'NDIS_MINIPORT_BLOCK' was changed! */ - if (RtlUnicodeStringToAnsiString (&l_Adapter->m_NameAnsi, - &((struct WIN2K_NDIS_MINIPORT_BLOCK *) p_AdapterHandle)->MiniportName, - TRUE) != STATUS_SUCCESS) - { - DEBUGP (("[TAP] MiniportName (W2K) failed\n")); - status = NDIS_STATUS_RESOURCES; - } - else - { - DEBUGP (("[TAP] MiniportName (W2K) succeeded: %s\n", l_Adapter->m_NameAnsi.Buffer)); - status = NDIS_STATUS_SUCCESS; - } - } - } - } - - /* Can't continue without name (see macro 'NAME') */ - if (status != NDIS_STATUS_SUCCESS || !l_Adapter->m_NameAnsi.Buffer) - { - NdisCloseConfiguration (configHandle); - AdapterFreeResources (l_Adapter); - DEBUGP (("[TAP] failed to get miniport name\n")); - return NDIS_STATUS_RESOURCES; - } - - /* Read MTU setting from registry */ - { - NDIS_STRING key = NDIS_STRING_CONST("MTU"); - NdisReadConfiguration (&status, &parm, configHandle, - &key, NdisParameterInteger); - if (status == NDIS_STATUS_SUCCESS) - { - if (parm->ParameterType == NdisParameterInteger) - { - int mtu = parm->ParameterData.IntegerData; - if (mtu < MINIMUM_MTU) - mtu = MINIMUM_MTU; - if (mtu > MAXIMUM_MTU) - mtu = MAXIMUM_MTU; - l_Adapter->m_MTU = mtu; - } - } - } - - /* Read Media Status setting from registry */ - { - NDIS_STRING key = NDIS_STRING_CONST("MediaStatus"); - NdisReadConfiguration (&status, &parm, configHandle, - &key, NdisParameterInteger); - if (status == NDIS_STATUS_SUCCESS) - { - if (parm->ParameterType == NdisParameterInteger) - { - if (parm->ParameterData.IntegerData) - { - l_Adapter->m_MediaStateAlwaysConnected = TRUE; - l_Adapter->m_MediaState = TRUE; - } - } - } - } - -#if ENABLE_NONADMIN - /* Read AllowNonAdmin setting from registry */ - { - NDIS_STRING key = NDIS_STRING_CONST("AllowNonAdmin"); - NdisReadConfiguration (&status, &parm, configHandle, - &key, NdisParameterInteger); - if (status == NDIS_STATUS_SUCCESS) - { - if (parm->ParameterType == NdisParameterInteger) - { - if (parm->ParameterData.IntegerData) - { - enable_non_admin = TRUE; - } - } - } - } -#endif - - /* Read optional MAC setting from registry */ - { - NDIS_STRING key = NDIS_STRING_CONST("MAC"); - ANSI_STRING mac_string; - NdisReadConfiguration (&status, &parm, configHandle, - &key, NdisParameterString); - if (status == NDIS_STATUS_SUCCESS) - { - if (parm->ParameterType == NdisParameterString) - { - if (RtlUnicodeStringToAnsiString (&mac_string, &parm->ParameterData.StringData, TRUE) == STATUS_SUCCESS) - { - l_MacFromRegistry = ParseMAC (l_Adapter->m_MAC, mac_string.Buffer); - RtlFreeAnsiString (&mac_string); - } - } - } - } - - NdisCloseConfiguration (configHandle); - - DEBUGP (("[%s] MTU=%d\n", NAME (l_Adapter), l_Adapter->m_MTU)); - } - - //================================== - // Store and update MAC address info - //================================== - - if (!l_MacFromRegistry) - GenerateRandomMac (l_Adapter->m_MAC, NAME (l_Adapter)); - - DEBUGP (("[%s] Using MAC %x:%x:%x:%x:%x:%x\n", - NAME (l_Adapter), - l_Adapter->m_MAC[0], l_Adapter->m_MAC[1], l_Adapter->m_MAC[2], - l_Adapter->m_MAC[3], l_Adapter->m_MAC[4], l_Adapter->m_MAC[5])); - -#if 0 - //================== - // Set broadcast MAC - //================== - { - int i; - for (i = 0; i < sizeof (MACADDR); ++i) - l_Adapter->m_MAC_Broadcast[i] = 0xFF; - } -#endif - - //==================================== - // Initialize TAP device - //==================================== - { - NDIS_STATUS tap_status; - tap_status = CreateTapDevice (&l_Adapter->m_Extension, NAME (l_Adapter)); - if (tap_status != NDIS_STATUS_SUCCESS) - { - AdapterFreeResources (l_Adapter); - DEBUGP (("[TAP] CreateTapDevice failed\n")); - return tap_status; - } - } - - if (!AddAdapterToInstanceList (l_Adapter)) - { - NOTE_ERROR (); - TapDeviceFreeResources (&l_Adapter->m_Extension); - AdapterFreeResources (l_Adapter); - DEBUGP (("[TAP] AddAdapterToInstanceList failed\n")); - return NDIS_STATUS_RESOURCES; - } - - l_Adapter->m_InterfaceIsRunning = TRUE; - -#if ENABLE_NONADMIN - if (enable_non_admin) - AllowNonAdmin (&l_Adapter->m_Extension); -#endif - - return NDIS_STATUS_SUCCESS; -} - -VOID -AdapterHalt (IN NDIS_HANDLE p_AdapterContext) -{ - BOOLEAN status; - - TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext; - - NOTE_ERROR (); - - l_Adapter->m_InterfaceIsRunning = FALSE; - - DEBUGP (("[%s] is being halted\n", NAME (l_Adapter))); - - DestroyTapDevice (&l_Adapter->m_Extension); - - // Free resources - DEBUGP (("[%s] Freeing Resources\n", NAME (l_Adapter))); - AdapterFreeResources (l_Adapter); - - status = RemoveAdapterFromInstanceList (l_Adapter); - DEBUGP (("[TAP] RemoveAdapterFromInstanceList returned %d\n", (int) status)); - - DEBUGP (("[TAP] version [%d.%d] %s %s AdapterHalt returning\n", - TAP_DRIVER_MAJOR_VERSION, - TAP_DRIVER_MINOR_VERSION, - __DATE__, - __TIME__)); -} - -VOID -AdapterFreeResources (TapAdapterPointer p_Adapter) -{ - MYASSERT (!p_Adapter->m_CalledAdapterFreeResources); - p_Adapter->m_CalledAdapterFreeResources = TRUE; - - if (p_Adapter->m_NameAnsi.Buffer) - RtlFreeAnsiString (&p_Adapter->m_NameAnsi); - - if (p_Adapter->m_RegisteredAdapterShutdownHandler) - NdisMDeregisterAdapterShutdownHandler (p_Adapter->m_MiniportAdapterHandle); - - if (p_Adapter->m_MCLockAllocated) - NdisFreeSpinLock (&p_Adapter->m_MCLock); -} - -VOID -DestroyTapDevice (TapExtensionPointer p_Extension) -{ - DEBUGP (("[%s] Destroying tap device\n", p_Extension->m_TapName)); - - //====================================== - // Let clients know we are shutting down - //====================================== - p_Extension->m_TapIsRunning = FALSE; - p_Extension->m_TapOpens = 0; - p_Extension->m_Halt = TRUE; - - //===================================== - // If we are concurrently executing in - // TapDeviceHook or AdapterTransmit, - // give those calls time to finish. - // Note that we must be running at IRQL - // < DISPATCH_LEVEL in order to call - // NdisMSleep. - //===================================== - NdisMSleep (500000); - - //=========================================================== - // Exhaust IRP and packet queues. Any pending IRPs will - // be cancelled, causing user-space to get this error - // on overlapped reads: - // The I/O operation has been aborted because of either a - // thread exit or an application request. (code=995) - // It's important that user-space close the device handle - // when this code is returned, so that when we finally - // do a NdisMDeregisterDevice, the device reference count - // is 0. Otherwise the driver will not unload even if the - // the last adapter has been halted. - //=========================================================== - FlushQueues (p_Extension); - NdisMSleep (500000); // give user space time to respond to IRP cancel - - TapDeviceFreeResources (p_Extension); -} - -VOID -TapDeviceFreeResources (TapExtensionPointer p_Extension) -{ - MYASSERT (p_Extension); - MYASSERT (!p_Extension->m_CalledTapDeviceFreeResources); - p_Extension->m_CalledTapDeviceFreeResources = TRUE; - - if (p_Extension->m_PacketQueue) - QueueFree (p_Extension->m_PacketQueue); - if (p_Extension->m_IrpQueue) - QueueFree (p_Extension->m_IrpQueue); - if (p_Extension->m_InjectQueue) - QueueFree (p_Extension->m_InjectQueue); - - if (p_Extension->m_CreatedUnicodeLinkName) - RtlFreeUnicodeString (&p_Extension->m_UnicodeLinkName); - - //========================================================== - // According to DDK docs, the device is not actually deleted - // until its reference count falls to zero. That means we - // still need to gracefully fail TapDeviceHook requests - // after this point, otherwise ugly things would happen if - // the device was disabled (e.g. in the network connections - // control panel) while a userspace app still held an open - // file handle to it. - //========================================================== - - if (p_Extension->m_TapDevice) - { - BOOLEAN status; - status = (NdisMDeregisterDevice (p_Extension->m_TapDeviceHandle) - == NDIS_STATUS_SUCCESS); - DEBUGP (("[TAP] Deregistering TAP device, status=%d\n", (int)status)); - } - - if (p_Extension->m_TapName) - MemFree (p_Extension->m_TapName, NAME_BUFFER_SIZE); - - if (p_Extension->m_InjectDpcInitialized) - KeRemoveQueueDpc (&p_Extension->m_InjectDpc); - - if (p_Extension->m_AllocatedSpinlocks) - { - NdisFreeSpinLock (&p_Extension->m_QueueLock); - NdisFreeSpinLock (&p_Extension->m_InjectLock); - } -} - -//======================================================================== -// Tap Device Initialization -//======================================================================== - -NDIS_STATUS -CreateTapDevice (TapExtensionPointer p_Extension, const char *p_Name) -{ -# define SIZEOF_DISPATCH (sizeof(PDRIVER_DISPATCH) * (IRP_MJ_MAXIMUM_FUNCTION + 1)) - PDRIVER_DISPATCH *l_Dispatch = NULL; - ANSI_STRING l_TapString, l_LinkString; - UNICODE_STRING l_TapUnicode; - BOOLEAN l_FreeTapUnicode = FALSE; - NTSTATUS l_Status, l_Return = NDIS_STATUS_SUCCESS; - const char *l_UsableName; - - DEBUGP (("[TAP] version [%d.%d] creating tap device: %s\n", - TAP_DRIVER_MAJOR_VERSION, - TAP_DRIVER_MINOR_VERSION, - p_Name)); - - NdisZeroMemory (p_Extension, sizeof (TapExtension)); - - INIT_MUTEX (&p_Extension->m_OpenCloseMutex); - - l_LinkString.Buffer = NULL; - l_TapString.Buffer = NULL; - - l_TapString.MaximumLength = l_LinkString.MaximumLength = NAME_BUFFER_SIZE; - - //======================================= - // Set TAP device entry points - //======================================= - - if ((l_Dispatch = MemAlloc (SIZEOF_DISPATCH, TRUE)) == NULL) - { - DEBUGP (("[%s] couldn't alloc TAP dispatch table\n", p_Name)); - l_Return = NDIS_STATUS_RESOURCES; - goto cleanup; - } - - l_Dispatch[IRP_MJ_DEVICE_CONTROL] = TapDeviceHook; - l_Dispatch[IRP_MJ_READ] = TapDeviceHook; - l_Dispatch[IRP_MJ_WRITE] = TapDeviceHook; - l_Dispatch[IRP_MJ_CREATE] = TapDeviceHook; - l_Dispatch[IRP_MJ_CLOSE] = TapDeviceHook; - - //================================== - // Find the beginning of the GUID - //================================== - l_UsableName = p_Name; - while (*l_UsableName != '{') - { - if (*l_UsableName == '\0') - { - DEBUGP (("[%s] couldn't find leading '{' in name\n", p_Name)); - l_Return = NDIS_STATUS_RESOURCES; - goto cleanup; - } - ++l_UsableName; - } - - //================================== - // Allocate pool for TAP device name - //================================== - - if ((p_Extension->m_TapName = l_TapString.Buffer = - MemAlloc (NAME_BUFFER_SIZE, TRUE)) == NULL) - { - DEBUGP (("[%s] couldn't alloc TAP name buffer\n", p_Name)); - l_Return = NDIS_STATUS_RESOURCES; - goto cleanup; - } - - //================================================ - // Allocate pool for TAP symbolic link name buffer - //================================================ - - if ((l_LinkString.Buffer = - MemAlloc (NAME_BUFFER_SIZE, TRUE)) == NULL) - { - DEBUGP (("[%s] couldn't alloc TAP symbolic link name buffer\n", - p_Name)); - l_Return = NDIS_STATUS_RESOURCES; - goto cleanup; - } - - //======================================================= - // Set TAP device name - //======================================================= - - l_Status = RtlStringCchPrintfExA - (l_TapString.Buffer, - l_TapString.MaximumLength, - NULL, - NULL, - STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS, - "%s%s%s", - SYSDEVICEDIR, - l_UsableName, - TAP_WIN_SUFFIX); - - if (l_Status != STATUS_SUCCESS) - { - DEBUGP (("[%s] couldn't format TAP device name\n", - p_Name)); - l_Return = NDIS_STATUS_RESOURCES; - goto cleanup; - } - l_TapString.Length = (USHORT) strlen (l_TapString.Buffer); - - DEBUGP (("TAP DEV NAME: '%s'\n", l_TapString.Buffer)); - - //======================================================= - // Set TAP link name - //======================================================= - - l_Status = RtlStringCchPrintfExA - (l_LinkString.Buffer, - l_LinkString.MaximumLength, - NULL, - NULL, - STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS, - "%s%s%s", - USERDEVICEDIR, - l_UsableName, - TAP_WIN_SUFFIX); - - if (l_Status != STATUS_SUCCESS) - { - DEBUGP (("[%s] couldn't format TAP device symbolic link\n", - p_Name)); - l_Return = NDIS_STATUS_RESOURCES; - goto cleanup; - } - l_LinkString.Length = (USHORT) strlen (l_LinkString.Buffer); - - DEBUGP (("TAP LINK NAME: '%s'\n", l_LinkString.Buffer)); - - //================================================== - // Convert strings to unicode - //================================================== - if (RtlAnsiStringToUnicodeString (&l_TapUnicode, &l_TapString, TRUE) != - STATUS_SUCCESS) - { - DEBUGP (("[%s] couldn't alloc TAP unicode name buffer\n", - p_Name)); - l_Return = NDIS_STATUS_RESOURCES; - goto cleanup; - } - l_FreeTapUnicode = TRUE; - - if (RtlAnsiStringToUnicodeString - (&p_Extension->m_UnicodeLinkName, &l_LinkString, TRUE) - != STATUS_SUCCESS) - { - DEBUGP - (("[%s] Couldn't allocate unicode string for symbolic link name\n", - p_Name)); - l_Return = NDIS_STATUS_RESOURCES; - goto cleanup; - } - p_Extension->m_CreatedUnicodeLinkName = TRUE; - - //================================================== - // Create new TAP device with symbolic - // link and associate with adapter. - //================================================== - - l_Status = NdisMRegisterDevice - (g_NdisWrapperHandle, - &l_TapUnicode, - &p_Extension->m_UnicodeLinkName, - l_Dispatch, - &p_Extension->m_TapDevice, - &p_Extension->m_TapDeviceHandle - ); - - if (l_Status != STATUS_SUCCESS) - { - DEBUGP (("[%s] couldn't be created\n", p_Name)); - l_Return = NDIS_STATUS_RESOURCES; - goto cleanup; - } - - /* Set TAP device flags */ - p_Extension->m_TapDevice->Flags |= DO_DIRECT_IO; - - //======================================================== - // Initialize Packet and IRP queues. - // - // The packet queue is used to buffer data which has been - // "transmitted" by the virtual NIC, before user space - // has had a chance to read it. - // - // The IRP queue is used to buffer pending I/O requests - // from userspace, i.e. read requests on the TAP device - // waiting for the system to "transmit" something through - // the virtual NIC. - // - // Basically, packets in the packet queue are used - // to satisfy IRP requests in the IRP queue. - // - // QueueLock is used to lock the packet queue used - // for the TAP-Windows NIC -> User Space packet flow direction. - // - // All accesses to packet or IRP queues should be - // bracketed by the QueueLock spinlock, - // in order to be SMP-safe. - //======================================================== - - NdisAllocateSpinLock (&p_Extension->m_QueueLock); - NdisAllocateSpinLock (&p_Extension->m_InjectLock); - p_Extension->m_AllocatedSpinlocks = TRUE; - - p_Extension->m_PacketQueue = QueueInit (PACKET_QUEUE_SIZE); - p_Extension->m_IrpQueue = QueueInit (IRP_QUEUE_SIZE); - p_Extension->m_InjectQueue = QueueInit (INJECT_QUEUE_SIZE); - if (!p_Extension->m_PacketQueue - || !p_Extension->m_IrpQueue - || !p_Extension->m_InjectQueue) - { - DEBUGP (("[%s] couldn't alloc TAP queues\n", p_Name)); - l_Return = NDIS_STATUS_RESOURCES; - goto cleanup; - } - - //================================================================= - // Initialize deferred procedure call for DHCP/ARP packet injection - //================================================================= - - KeInitializeDpc (&p_Extension->m_InjectDpc, InjectPacketDpc, NULL); - p_Extension->m_InjectDpcInitialized = TRUE; - - //======================== - // Finalize initialization - //======================== - - p_Extension->m_TapIsRunning = TRUE; - - DEBUGP (("[%s] successfully created TAP device [%s]\n", p_Name, - p_Extension->m_TapName)); - - cleanup: - if (l_FreeTapUnicode) - RtlFreeUnicodeString (&l_TapUnicode); - if (l_LinkString.Buffer) - MemFree (l_LinkString.Buffer, NAME_BUFFER_SIZE); - if (l_Dispatch) - MemFree (l_Dispatch, SIZEOF_DISPATCH); - - if (l_Return != NDIS_STATUS_SUCCESS) - TapDeviceFreeResources (p_Extension); - - return l_Return; -} -#undef SIZEOF_DISPATCH - -//======================================================== -// Adapter Control -//======================================================== -NDIS_STATUS -AdapterReset (OUT PBOOLEAN p_AddressingReset, IN NDIS_HANDLE p_AdapterContext) -{ - TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext; - DEBUGP (("[%s] is resetting\n", NAME (l_Adapter))); - return NDIS_STATUS_SUCCESS; -} - -NDIS_STATUS AdapterReceive - (OUT PNDIS_PACKET p_Packet, - OUT PUINT p_Transferred, - IN NDIS_HANDLE p_AdapterContext, - IN NDIS_HANDLE p_ReceiveContext, - IN UINT p_Offset, - IN UINT p_ToTransfer) -{ - return NDIS_STATUS_SUCCESS; -} - -//============================================================== -// Adapter Option Query/Modification -//============================================================== -NDIS_STATUS AdapterQuery -(IN NDIS_HANDLE p_AdapterContext, - IN NDIS_OID p_OID, - IN PVOID p_Buffer, - IN ULONG p_BufferLength, - OUT PULONG p_BytesWritten, OUT PULONG p_BytesNeeded) -{ - TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext; - TapAdapterQuery l_Query, *l_QueryPtr = &l_Query; - NDIS_STATUS l_Status = NDIS_STATUS_SUCCESS; - UINT l_QueryLength = 4; - BOOLEAN lock_succeeded; - - NdisZeroMemory (&l_Query, sizeof (l_Query)); - - switch (p_OID) - { - //=================================================================== - // Vendor & Driver version Info - //=================================================================== - case OID_GEN_VENDOR_DESCRIPTION: - l_QueryPtr = (TapAdapterQueryPointer) PRODUCT_TAP_WIN_DEVICE_DESCRIPTION; - l_QueryLength = strlen (PRODUCT_TAP_WIN_DEVICE_DESCRIPTION) + 1; - break; - - case OID_GEN_VENDOR_ID: - l_Query.m_Long = 0xffffff; - break; - - case OID_GEN_DRIVER_VERSION: - l_Query.m_Short = - (((USHORT) TAP_NDIS_MAJOR_VERSION) << 8 | (USHORT) - TAP_NDIS_MINOR_VERSION); - l_QueryLength = sizeof (unsigned short); - break; - - case OID_GEN_VENDOR_DRIVER_VERSION: - l_Query.m_Long = - (((USHORT) PRODUCT_TAP_WIN_MAJOR) << 8 | (USHORT) - PRODUCT_TAP_WIN_MINOR); - break; - - //================================================================= - // Statistics - //================================================================= - case OID_GEN_RCV_NO_BUFFER: - l_Query.m_Long = 0; - break; - - case OID_802_3_RCV_ERROR_ALIGNMENT: - l_Query.m_Long = 0; - break; - - case OID_802_3_XMIT_ONE_COLLISION: - l_Query.m_Long = 0; - break; - - case OID_802_3_XMIT_MORE_COLLISIONS: - l_Query.m_Long = 0; - break; - - case OID_GEN_XMIT_OK: - l_Query.m_Long = l_Adapter->m_Tx; - break; - - case OID_GEN_RCV_OK: - l_Query.m_Long = l_Adapter->m_Rx; - break; - - case OID_GEN_XMIT_ERROR: - l_Query.m_Long = l_Adapter->m_TxErr; - break; - - case OID_GEN_RCV_ERROR: - l_Query.m_Long = l_Adapter->m_RxErr; - break; - - //=================================================================== - // Device & Protocol Options - //=================================================================== - case OID_GEN_SUPPORTED_LIST: - l_QueryPtr = (TapAdapterQueryPointer) g_SupportedOIDList; - l_QueryLength = sizeof (g_SupportedOIDList); - break; - - case OID_GEN_MAC_OPTIONS: - // This MUST be here !!! - l_Query.m_Long = (NDIS_MAC_OPTION_RECEIVE_SERIALIZED - | NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA - | NDIS_MAC_OPTION_NO_LOOPBACK - | NDIS_MAC_OPTION_TRANSFERS_NOT_PEND); - - break; - - case OID_GEN_CURRENT_PACKET_FILTER: - l_Query.m_Long = - (NDIS_PACKET_TYPE_ALL_LOCAL | - NDIS_PACKET_TYPE_BROADCAST | - NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_ALL_FUNCTIONAL); - - break; - - case OID_GEN_PROTOCOL_OPTIONS: - l_Query.m_Long = 0; - break; - - //================================================================== - // Device Info - //================================================================== - case OID_GEN_MEDIA_CONNECT_STATUS: - l_Query.m_Long = l_Adapter->m_MediaState - ? NdisMediaStateConnected : NdisMediaStateDisconnected; - break; - - case OID_GEN_HARDWARE_STATUS: - l_Query.m_HardwareStatus = NdisHardwareStatusReady; - l_QueryLength = sizeof (NDIS_HARDWARE_STATUS); - break; - - case OID_GEN_MEDIA_SUPPORTED: - case OID_GEN_MEDIA_IN_USE: - l_Query.m_Medium = l_Adapter->m_Medium; - l_QueryLength = sizeof (NDIS_MEDIUM); - break; - - case OID_GEN_PHYSICAL_MEDIUM: - l_Query.m_PhysicalMedium = NdisPhysicalMediumUnspecified; - l_QueryLength = sizeof (NDIS_PHYSICAL_MEDIUM); - break; - - case OID_GEN_LINK_SPEED: - l_Query.m_Long = 100000; // rate / 100 bps - break; - - case OID_802_3_PERMANENT_ADDRESS: - case OID_802_3_CURRENT_ADDRESS: - COPY_MAC (l_Query.m_MacAddress, l_Adapter->m_MAC); - l_QueryLength = sizeof (MACADDR); - break; - - //================================================================== - // Limits - //================================================================== - - case OID_GEN_MAXIMUM_SEND_PACKETS: - l_Query.m_Long = 1; - break; - - case OID_802_3_MAXIMUM_LIST_SIZE: - l_Query.m_Long = NIC_MAX_MCAST_LIST; - break; - - case OID_GEN_CURRENT_LOOKAHEAD: - l_Query.m_Long = l_Adapter->m_Lookahead; - break; - - case OID_GEN_MAXIMUM_LOOKAHEAD: - case OID_GEN_MAXIMUM_TOTAL_SIZE: - case OID_GEN_RECEIVE_BUFFER_SPACE: - case OID_GEN_RECEIVE_BLOCK_SIZE: - l_Query.m_Long = DEFAULT_PACKET_LOOKAHEAD; - break; - - case OID_GEN_MAXIMUM_FRAME_SIZE: - case OID_GEN_TRANSMIT_BLOCK_SIZE: - case OID_GEN_TRANSMIT_BUFFER_SPACE: - l_Query.m_Long = l_Adapter->m_MTU; - break; - - case OID_PNP_CAPABILITIES: - do - { - PNDIS_PNP_CAPABILITIES pPNPCapabilities; - PNDIS_PM_WAKE_UP_CAPABILITIES pPMstruct; - - if (p_BufferLength >= sizeof (NDIS_PNP_CAPABILITIES)) - { - pPNPCapabilities = (PNDIS_PNP_CAPABILITIES) (p_Buffer); - - // - // Setting up the buffer to be returned - // to the Protocol above the Passthru miniport - // - pPMstruct = &pPNPCapabilities->WakeUpCapabilities; - pPMstruct->MinMagicPacketWakeUp = NdisDeviceStateUnspecified; - pPMstruct->MinPatternWakeUp = NdisDeviceStateUnspecified; - pPMstruct->MinLinkChangeWakeUp = NdisDeviceStateUnspecified; - } - l_QueryLength = sizeof (NDIS_PNP_CAPABILITIES); - } - while (FALSE); - break; - case OID_PNP_QUERY_POWER: - break; - - // Required OIDs that we don't support - - case OID_GEN_SUPPORTED_GUIDS: - case OID_GEN_MEDIA_CAPABILITIES: - case OID_TCP_TASK_OFFLOAD: - case OID_FFP_SUPPORT: - l_Status = NDIS_STATUS_INVALID_OID; - break; - - // Optional stats OIDs - - case OID_GEN_DIRECTED_BYTES_XMIT: - case OID_GEN_DIRECTED_FRAMES_XMIT: - case OID_GEN_MULTICAST_BYTES_XMIT: - case OID_GEN_MULTICAST_FRAMES_XMIT: - case OID_GEN_BROADCAST_BYTES_XMIT: - case OID_GEN_BROADCAST_FRAMES_XMIT: - case OID_GEN_DIRECTED_BYTES_RCV: - case OID_GEN_DIRECTED_FRAMES_RCV: - case OID_GEN_MULTICAST_BYTES_RCV: - case OID_GEN_MULTICAST_FRAMES_RCV: - case OID_GEN_BROADCAST_BYTES_RCV: - case OID_GEN_BROADCAST_FRAMES_RCV: - l_Status = NDIS_STATUS_INVALID_OID; - break; - - //=================================================================== - // Not Handled - //=================================================================== - default: - DEBUGP (("[%s] Unhandled OID %lx\n", NAME (l_Adapter), p_OID)); - l_Status = NDIS_STATUS_INVALID_OID; - break; - } - - if (l_Status != NDIS_STATUS_SUCCESS) - ; - else if (l_QueryLength > p_BufferLength) - { - l_Status = NDIS_STATUS_INVALID_LENGTH; - *p_BytesNeeded = l_QueryLength; - } - else - NdisMoveMemory (p_Buffer, (PVOID) l_QueryPtr, - (*p_BytesWritten = l_QueryLength)); - - return l_Status; -} - -NDIS_STATUS AdapterModify -(IN NDIS_HANDLE p_AdapterContext, - IN NDIS_OID p_OID, - IN PVOID p_Buffer, - IN ULONG p_BufferLength, - OUT PULONG p_BytesRead, - OUT PULONG p_BytesNeeded) -{ - TapAdapterQueryPointer l_Query = (TapAdapterQueryPointer) p_Buffer; - TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext; - NDIS_STATUS l_Status = NDIS_STATUS_INVALID_OID; - ULONG l_Long; - - switch (p_OID) - { - //================================================================== - // Device Info - //================================================================== - case OID_802_3_MULTICAST_LIST: - DEBUGP (("[%s] Setting [OID_802_3_MULTICAST_LIST]\n", - NAME (l_Adapter))); - - *p_BytesNeeded = sizeof (ETH_ADDR); - *p_BytesRead = p_BufferLength; - - if (p_BufferLength % sizeof (ETH_ADDR)) - l_Status = NDIS_STATUS_INVALID_LENGTH; - else if (p_BufferLength > sizeof (MC_LIST)) - { - l_Status = NDIS_STATUS_MULTICAST_FULL; - *p_BytesNeeded = sizeof (MC_LIST); - } - else - { - NdisAcquireSpinLock (&l_Adapter->m_MCLock); - - NdisZeroMemory(&l_Adapter->m_MCList, sizeof (MC_LIST)); - - NdisMoveMemory(&l_Adapter->m_MCList, - p_Buffer, - p_BufferLength); - - l_Adapter->m_MCListSize = p_BufferLength / sizeof (ETH_ADDR); - - NdisReleaseSpinLock (&l_Adapter->m_MCLock); - - l_Status = NDIS_STATUS_SUCCESS; - } - break; - - case OID_GEN_CURRENT_PACKET_FILTER: - l_Status = NDIS_STATUS_INVALID_LENGTH; - *p_BytesNeeded = 4; - - if (p_BufferLength >= sizeof (ULONG)) - { - DEBUGP - (("[%s] Setting [OID_GEN_CURRENT_PACKET_FILTER] to [0x%02lx]\n", - NAME (l_Adapter), l_Query->m_Long)); - l_Status = NDIS_STATUS_SUCCESS; - *p_BytesRead = sizeof (ULONG); - } - break; - - case OID_GEN_CURRENT_LOOKAHEAD: - if (p_BufferLength < sizeof (ULONG)) - { - l_Status = NDIS_STATUS_INVALID_LENGTH; - *p_BytesNeeded = 4; - } - else if (l_Query->m_Long > DEFAULT_PACKET_LOOKAHEAD - || l_Query->m_Long <= 0) - { - l_Status = NDIS_STATUS_INVALID_DATA; - } - else - { - DEBUGP (("[%s] Setting [OID_GEN_CURRENT_LOOKAHEAD] to [%d]\n", - NAME (l_Adapter), l_Query->m_Long)); - l_Adapter->m_Lookahead = l_Query->m_Long; - l_Status = NDIS_STATUS_SUCCESS; - *p_BytesRead = sizeof (ULONG); - } - break; - - case OID_GEN_NETWORK_LAYER_ADDRESSES: - l_Status = NDIS_STATUS_SUCCESS; - *p_BytesRead = *p_BytesNeeded = 0; - break; - - case OID_GEN_TRANSPORT_HEADER_OFFSET: - l_Status = NDIS_STATUS_SUCCESS; - *p_BytesRead = *p_BytesNeeded = 0; - break; - - case OID_PNP_SET_POWER: - do - { - NDIS_DEVICE_POWER_STATE NewDeviceState; - - NewDeviceState = (*(PNDIS_DEVICE_POWER_STATE) p_Buffer); - - switch (NewDeviceState) - { - case NdisDeviceStateD0: - l_Adapter->m_DeviceState = '0'; - break; - case NdisDeviceStateD1: - l_Adapter->m_DeviceState = '1'; - break; - case NdisDeviceStateD2: - l_Adapter->m_DeviceState = '2'; - break; - case NdisDeviceStateD3: - l_Adapter->m_DeviceState = '3'; - break; - default: - l_Adapter->m_DeviceState = '?'; - break; - } - - l_Status = NDIS_STATUS_FAILURE; - - // - // Check for invalid length - // - if (p_BufferLength < sizeof (NDIS_DEVICE_POWER_STATE)) - { - l_Status = NDIS_STATUS_INVALID_LENGTH; - break; - } - - if (NewDeviceState > NdisDeviceStateD0) - { - l_Adapter->m_InterfaceIsRunning = FALSE; - DEBUGP (("[%s] Power management device state OFF\n", - NAME (l_Adapter))); - } - else - { - l_Adapter->m_InterfaceIsRunning = TRUE; - DEBUGP (("[%s] Power management device state ON\n", - NAME (l_Adapter))); - } - - l_Status = NDIS_STATUS_SUCCESS; - } - while (FALSE); - - if (l_Status == NDIS_STATUS_SUCCESS) - { - *p_BytesRead = sizeof (NDIS_DEVICE_POWER_STATE); - *p_BytesNeeded = 0; - } - else - { - *p_BytesRead = 0; - *p_BytesNeeded = sizeof (NDIS_DEVICE_POWER_STATE); - } - break; - - case OID_PNP_REMOVE_WAKE_UP_PATTERN: - case OID_PNP_ADD_WAKE_UP_PATTERN: - l_Status = NDIS_STATUS_SUCCESS; - *p_BytesRead = *p_BytesNeeded = 0; - break; - - default: - DEBUGP (("[%s] Can't set value for OID %lx\n", NAME (l_Adapter), - p_OID)); - l_Status = NDIS_STATUS_INVALID_OID; - *p_BytesRead = *p_BytesNeeded = 0; - break; - } - - return l_Status; -} - -// checksum code for ICMPv6 packet, taken from dhcp.c / udp_checksum -// see RFC 4443, 2.3, and RFC 2460, 8.1 -USHORT -icmpv6_checksum (const UCHAR *buf, - const int len_icmpv6, - const UCHAR *saddr6, - const UCHAR *daddr6) -{ - USHORT word16; - ULONG sum = 0; - int i; - - // make 16 bit words out of every two adjacent 8 bit words and - // calculate the sum of all 16 bit words - for (i = 0; i < len_icmpv6; i += 2){ - word16 = ((buf[i] << 8) & 0xFF00) + ((i + 1 < len_icmpv6) ? (buf[i+1] & 0xFF) : 0); - sum += word16; - } - - // add the IPv6 pseudo header which contains the IP source and destination addresses - for (i = 0; i < 16; i += 2){ - word16 =((saddr6[i] << 8) & 0xFF00) + (saddr6[i+1] & 0xFF); - sum += word16; - } - for (i = 0; i < 16; i += 2){ - word16 =((daddr6[i] << 8) & 0xFF00) + (daddr6[i+1] & 0xFF); - sum += word16; - } - - // the next-header number and the length of the ICMPv6 packet - sum += (USHORT) IPPROTO_ICMPV6 + (USHORT) len_icmpv6; - - // keep only the last 16 bits of the 32 bit calculated sum and add the carries - while (sum >> 16) - sum = (sum & 0xFFFF) + (sum >> 16); - - // Take the one's complement of sum - return ((USHORT) ~sum); -} - -// check IPv6 packet for "is this an IPv6 Neighbor Solicitation that -// the tap driver needs to answer?" -// see RFC 4861 4.3 for the different cases -static IPV6ADDR IPV6_NS_TARGET_MCAST = - { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x08 }; -static IPV6ADDR IPV6_NS_TARGET_UNICAST = - { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08 }; - -#if 0 -BOOLEAN -HandleIPv6NeighborDiscovery( TapAdapterPointer p_Adapter, UCHAR * m_Data ) -{ - const ETH_HEADER * e = (ETH_HEADER *) m_Data; - const IPV6HDR *ipv6 = (IPV6HDR *) (m_Data + sizeof (ETH_HEADER)); - const ICMPV6_NS * icmpv6_ns = (ICMPV6_NS *) (m_Data + sizeof (ETH_HEADER) + sizeof (IPV6HDR)); - ICMPV6_NA_PKT *na; - USHORT icmpv6_len, icmpv6_csum; - - // we don't really care about the destination MAC address here - // - it's either a multicast MAC, or the userland destination MAC - // but since the TAP driver is point-to-point, all packets are "for us" - - // IPv6 target address must be ff02::1::ff00:8 (multicast for - // initial NS) or fe80::1 (unicast for recurrent NUD) - if ( memcmp( ipv6->daddr, IPV6_NS_TARGET_MCAST, - sizeof(IPV6ADDR) ) != 0 && - memcmp( ipv6->daddr, IPV6_NS_TARGET_UNICAST, - sizeof(IPV6ADDR) ) != 0 ) - { - return FALSE; // wrong target address - } - - // IPv6 Next-Header must be ICMPv6 - if ( ipv6->nexthdr != IPPROTO_ICMPV6 ) - { - return FALSE; // wrong next-header - } - - // ICMPv6 type+code must be 135/0 for NS - if ( icmpv6_ns->type != ICMPV6_TYPE_NS || - icmpv6_ns->code != ICMPV6_CODE_0 ) - { - return FALSE; // wrong ICMPv6 type - } - - // ICMPv6 target address must be fe80::8 (magic) - if ( memcmp( icmpv6_ns->target_addr, IPV6_NS_TARGET_UNICAST, - sizeof(IPV6ADDR) ) != 0 ) - { - return FALSE; // not for us - } - - // packet identified, build magic response packet - - na = (ICMPV6_NA_PKT *) MemAlloc (sizeof (ICMPV6_NA_PKT), TRUE); - if ( !na ) return FALSE; - - //------------------------------------------------ - // Initialize Neighbour Advertisement reply packet - //------------------------------------------------ - - // ethernet header - na->eth.proto = htons(ETH_P_IPV6); - COPY_MAC(na->eth.dest, p_Adapter->m_MAC); - COPY_MAC(na->eth.src, p_Adapter->m_TapToUser.dest); - - // IPv6 header - na->ipv6.version_prio = ipv6->version_prio; - NdisMoveMemory( na->ipv6.flow_lbl, ipv6->flow_lbl, - sizeof(na->ipv6.flow_lbl) ); - icmpv6_len = sizeof(ICMPV6_NA_PKT) - sizeof(ETH_HEADER) - sizeof(IPV6HDR); - na->ipv6.payload_len = htons(icmpv6_len); - na->ipv6.nexthdr = IPPROTO_ICMPV6; - na->ipv6.hop_limit = 255; - NdisMoveMemory( na->ipv6.saddr, IPV6_NS_TARGET_UNICAST, - sizeof(IPV6ADDR) ); - NdisMoveMemory( na->ipv6.daddr, ipv6->saddr, - sizeof(IPV6ADDR) ); - - // ICMPv6 - na->icmpv6.type = ICMPV6_TYPE_NA; - na->icmpv6.code = ICMPV6_CODE_0; - na->icmpv6.checksum = 0; - na->icmpv6.rso_bits = 0x60; // Solicited + Override - NdisZeroMemory( na->icmpv6.reserved, sizeof(na->icmpv6.reserved) ); - NdisMoveMemory( na->icmpv6.target_addr, IPV6_NS_TARGET_UNICAST, - sizeof(IPV6ADDR) ); - - // ICMPv6 option "Target Link Layer Address" - na->icmpv6.opt_type = ICMPV6_OPTION_TLLA; - na->icmpv6.opt_length = ICMPV6_LENGTH_TLLA; - COPY_MAC( na->icmpv6.target_macaddr, p_Adapter->m_TapToUser.dest ); - - // calculate and set checksum - icmpv6_csum = icmpv6_checksum ( (UCHAR*) &(na->icmpv6), - icmpv6_len, - na->ipv6.saddr, - na->ipv6.daddr ); - na->icmpv6.checksum = htons( icmpv6_csum ); - - DUMP_PACKET ("HandleIPv6NeighborDiscovery", - (unsigned char *) na, - sizeof (ICMPV6_NA_PKT)); - - InjectPacketDeferred (p_Adapter, (UCHAR *) na, sizeof (ICMPV6_NA_PKT)); - - MemFree (na, sizeof (ICMPV6_NA_PKT)); - - return TRUE; // all fine -} -#endif - -//==================================================================== -// Adapter Transmission -//==================================================================== -NDIS_STATUS -AdapterTransmit (IN NDIS_HANDLE p_AdapterContext, - IN PNDIS_PACKET p_Packet, - IN UINT p_Flags) -{ - TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext; - ULONG l_Index = 0, l_PacketLength = 0; - UINT l_BufferLength = 0; - PIRP l_IRP; - TapPacketPointer l_PacketBuffer; - PNDIS_BUFFER l_NDIS_Buffer; - PUCHAR l_Buffer; - PVOID result; - - NdisQueryPacket (p_Packet, NULL, NULL, &l_NDIS_Buffer, &l_PacketLength); - - //==================================================== - // Here we abandon the transmission attempt if any of - // the parameters is wrong or memory allocation fails - // but we do not indicate failure. The packet is - // silently dropped. - //==================================================== - - if (l_PacketLength < ETHERNET_HEADER_SIZE || l_PacketLength > 65535) - goto exit_fail; - else if (!l_Adapter->m_Extension.m_TapOpens || !l_Adapter->m_MediaState) - goto exit_success; // Nothing is bound to the TAP device - - if (NdisAllocateMemoryWithTag (&l_PacketBuffer, - TAP_PACKET_SIZE (l_PacketLength), - '5PAT') != NDIS_STATUS_SUCCESS) - goto exit_no_resources; - - if (l_PacketBuffer == NULL) - goto exit_no_resources; - - l_PacketBuffer->m_SizeFlags = (l_PacketLength & TP_SIZE_MASK); - - //=========================== - // Reassemble packet contents - //=========================== - - __try - { - l_Index = 0; - while (l_NDIS_Buffer && l_Index < l_PacketLength) - { - ULONG newlen; - NdisQueryBuffer (l_NDIS_Buffer, (PVOID *) & l_Buffer, - &l_BufferLength); - newlen = l_Index + l_BufferLength; - if (newlen > l_PacketLength) - { - NOTE_ERROR (); - goto no_queue; /* overflow */ - } - NdisMoveMemory (l_PacketBuffer->m_Data + l_Index, l_Buffer, - l_BufferLength); - l_Index = newlen; - NdisGetNextBuffer (l_NDIS_Buffer, &l_NDIS_Buffer); - } - if (l_Index != l_PacketLength) - { - NOTE_ERROR (); - goto no_queue; /* underflow */ - } - - DUMP_PACKET ("AdapterTransmit", l_PacketBuffer->m_Data, l_PacketLength); - - //===================================================== - // If IPv4 packet, check whether or not packet - // was truncated. - //===================================================== -#if PACKET_TRUNCATION_CHECK - IPv4PacketSizeVerify (l_PacketBuffer->m_Data, l_PacketLength, FALSE, "TX", &l_Adapter->m_TxTrunc); -#endif - -#if 0 - //===================================================== - // Are we running in DHCP server masquerade mode? - // - // If so, catch both DHCP requests and ARP queries - // to resolve the address of our virtual DHCP server. - //===================================================== - if (l_Adapter->m_dhcp_enabled) - { - const ETH_HEADER *eth = (ETH_HEADER *) l_PacketBuffer->m_Data; - const IPHDR *ip = (IPHDR *) (l_PacketBuffer->m_Data + sizeof (ETH_HEADER)); - const UDPHDR *udp = (UDPHDR *) (l_PacketBuffer->m_Data + sizeof (ETH_HEADER) + sizeof (IPHDR)); - - // ARP packet? - if (l_PacketLength == sizeof (ARP_PACKET) - && eth->proto == htons (ETH_P_ARP) - && l_Adapter->m_dhcp_server_arp) - { - if (ProcessARP (l_Adapter, - (PARP_PACKET) l_PacketBuffer->m_Data, - l_Adapter->m_dhcp_addr, - l_Adapter->m_dhcp_server_ip, - ~0, - l_Adapter->m_dhcp_server_mac)) - goto no_queue; - } -#endif - -#if 0 - // DHCP packet? - else if (l_PacketLength >= sizeof (ETH_HEADER) + sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP) - && eth->proto == htons (ETH_P_IP) - && ip->version_len == 0x45 // IPv4, 20 byte header - && ip->protocol == IPPROTO_UDP - && udp->dest == htons (BOOTPS_PORT)) - { - const DHCP *dhcp = (DHCP *) (l_PacketBuffer->m_Data - + sizeof (ETH_HEADER) - + sizeof (IPHDR) - + sizeof (UDPHDR)); - - const int optlen = l_PacketLength - - sizeof (ETH_HEADER) - - sizeof (IPHDR) - - sizeof (UDPHDR) - - sizeof (DHCP); - - if (optlen > 0) // we must have at least one DHCP option - { - if (ProcessDHCP (l_Adapter, eth, ip, udp, dhcp, optlen)) - goto no_queue; - } - else - goto no_queue; - } - } -#endif - - //=============================================== - // In Point-To-Point mode, check to see whether - // packet is ARP (handled) or IPv4 (sent to app). - // IPv6 packets are inspected for neighbour discovery - // (to be handled locally), and the rest is forwarded - // all other protocols are dropped - //=============================================== -#if 0 - if (l_Adapter->m_tun) - { - ETH_HEADER *e; - - if (l_PacketLength < ETHERNET_HEADER_SIZE) - goto no_queue; - - e = (ETH_HEADER *) l_PacketBuffer->m_Data; - - switch (ntohs (e->proto)) - { - case ETH_P_ARP: - - // Make sure that packet is the - // right size for ARP. - if (l_PacketLength != sizeof (ARP_PACKET)) - goto no_queue; - - ProcessARP (l_Adapter, - (PARP_PACKET) l_PacketBuffer->m_Data, - l_Adapter->m_localIP, - l_Adapter->m_remoteNetwork, - l_Adapter->m_remoteNetmask, - l_Adapter->m_TapToUser.dest); - - default: - goto no_queue; - - case ETH_P_IP: - - // Make sure that packet is large - // enough to be IPv4. - if (l_PacketLength - < ETHERNET_HEADER_SIZE + IP_HEADER_SIZE) - goto no_queue; - - // Only accept directed packets, - // not broadcasts. - if (memcmp (e, &l_Adapter->m_TapToUser, ETHERNET_HEADER_SIZE)) - goto no_queue; - - // Packet looks like IPv4, queue it. - l_PacketBuffer->m_SizeFlags |= TP_TUN; - break; - - case ETH_P_IPV6: - // make sure that packet is large - // enough to be IPv6 - if (l_PacketLength - < ETHERNET_HEADER_SIZE + IPV6_HEADER_SIZE) - goto no_queue; - - // broadcasts and multicasts are handled specially - // (to be implemented) - - // neighbor discovery packets to fe80::8 are special - // OpenVPN sets this next-hop to signal "handled by tapdrv" - if ( HandleIPv6NeighborDiscovery( l_Adapter, - l_PacketBuffer->m_Data )) - { - goto no_queue; - } - - // Packet looks like IPv6, queue it :-) - l_PacketBuffer->m_SizeFlags |= TP_TUN; - } - } -#endif - - //=============================================== - // Push packet onto queue to wait for read from - // userspace. - //=============================================== - - NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock); - - result = NULL; - if (IS_UP (l_Adapter)) - result = QueuePush (l_Adapter->m_Extension.m_PacketQueue, l_PacketBuffer); - - NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock); - - if ((TapPacketPointer) result != l_PacketBuffer) - { - // adapter receive overrun - INCREMENT_STAT (l_Adapter->m_TxErr); - goto no_queue; - } - else - { - INCREMENT_STAT (l_Adapter->m_Tx); - } - - //============================================================ - // Cycle through IRPs and packets, try to satisfy each pending - // IRP with a queued packet. - //============================================================ - while (TRUE) - { - l_IRP = NULL; - l_PacketBuffer = NULL; - - NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock); - - if (IS_UP (l_Adapter) - && QueueCount (l_Adapter->m_Extension.m_PacketQueue) - && QueueCount (l_Adapter->m_Extension.m_IrpQueue)) - { - l_IRP = (PIRP) QueuePop (l_Adapter->m_Extension.m_IrpQueue); - l_PacketBuffer = (TapPacketPointer) - QueuePop (l_Adapter->m_Extension.m_PacketQueue); - } - - NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock); - - MYASSERT ((l_IRP != NULL) + (l_PacketBuffer != NULL) != 1); - - if (l_IRP && l_PacketBuffer) - { - CompleteIRP (l_IRP, - l_PacketBuffer, - IO_NETWORK_INCREMENT); - } - else - break; - } - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - } - - return NDIS_STATUS_SUCCESS; - - no_queue: - NdisFreeMemory (l_PacketBuffer, - TAP_PACKET_SIZE (l_PacketLength), - 0); - - exit_success: - return NDIS_STATUS_SUCCESS; - - exit_fail: - return NDIS_STATUS_FAILURE; - - exit_no_resources: - return NDIS_STATUS_RESOURCES; -} - -//====================================================================== -// Hooks for catching TAP device IRP's. -//====================================================================== - -DRIVER_DISPATCH TapDeviceHook; -NTSTATUS -TapDeviceHook (IN PDEVICE_OBJECT p_DeviceObject, IN PIRP p_IRP) -{ - TapAdapterPointer l_Adapter = LookupAdapterInInstanceList (p_DeviceObject); - PIO_STACK_LOCATION l_IrpSp; - NTSTATUS l_Status = STATUS_SUCCESS; - BOOLEAN accessible; - - l_IrpSp = IoGetCurrentIrpStackLocation (p_IRP); - - p_IRP->IoStatus.Status = STATUS_SUCCESS; - p_IRP->IoStatus.Information = 0; - - if (!l_Adapter || l_Adapter->m_Extension.m_Halt) - { - DEBUGP (("TapDeviceHook called when TAP device is halted, MajorFunction=%d\n", - (int)l_IrpSp->MajorFunction)); - - if (l_IrpSp->MajorFunction == IRP_MJ_CLOSE) - { - IoCompleteRequest (p_IRP, IO_NO_INCREMENT); - return STATUS_SUCCESS; - } - else - { - p_IRP->IoStatus.Status = STATUS_NO_SUCH_DEVICE; - IoCompleteRequest (p_IRP, IO_NO_INCREMENT); - return STATUS_NO_SUCH_DEVICE; - } - } - - switch (l_IrpSp->MajorFunction) - { - //=========================================================== - // Ioctl call handlers - //=========================================================== - case IRP_MJ_DEVICE_CONTROL: - { - switch (l_IrpSp->Parameters.DeviceIoControl.IoControlCode) - { - case TAP_WIN_IOCTL_GET_MAC: - { - if (l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength - >= sizeof (MACADDR)) - { - COPY_MAC (p_IRP->AssociatedIrp.SystemBuffer, - l_Adapter->m_MAC); - p_IRP->IoStatus.Information = sizeof (MACADDR); - } - else - { - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL; - } - break; - } - case TAP_WIN_IOCTL_GET_VERSION: - { - const ULONG size = sizeof (ULONG) * 3; - if (l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength - >= size) - { - ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[0] - = TAP_DRIVER_MAJOR_VERSION; - ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[1] - = TAP_DRIVER_MINOR_VERSION; - ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[2] -#if DBG - = 1; -#else - = 0; -#endif - p_IRP->IoStatus.Information = size; - } - else - { - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL; - } - - break; - } - case TAP_WIN_IOCTL_GET_MTU: - { - const ULONG size = sizeof (ULONG) * 1; - if (l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength - >= size) - { - ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[0] - = l_Adapter->m_MTU; - p_IRP->IoStatus.Information = size; - } - else - { - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL; - } - - break; - } - case TAP_WIN_IOCTL_GET_INFO: - { - char state[16]; - if (l_Adapter->m_InterfaceIsRunning) - state[0] = 'A'; - else - state[0] = 'a'; - if (l_Adapter->m_Extension.m_TapIsRunning) - state[1] = 'T'; - else - state[1] = 't'; - state[2] = l_Adapter->m_DeviceState; - if (l_Adapter->m_MediaStateAlwaysConnected) - state[3] = 'C'; - else - state[3] = 'c'; - state[4] = '\0'; - - p_IRP->IoStatus.Status = l_Status = RtlStringCchPrintfExA ( - ((LPTSTR) (p_IRP->AssociatedIrp.SystemBuffer)), - l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength, - NULL, - NULL, - STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS, -#if PACKET_TRUNCATION_CHECK - "State=%s Err=[%s/%d] #O=%d Tx=[%d,%d,%d] Rx=[%d,%d,%d] IrpQ=[%d,%d,%d] PktQ=[%d,%d,%d] InjQ=[%d,%d,%d]", -#else - "State=%s Err=[%s/%d] #O=%d Tx=[%d,%d] Rx=[%d,%d] IrpQ=[%d,%d,%d] PktQ=[%d,%d,%d] InjQ=[%d,%d,%d]", -#endif - state, - g_LastErrorFilename, - g_LastErrorLineNumber, - (int)l_Adapter->m_Extension.m_NumTapOpens, - (int)l_Adapter->m_Tx, - (int)l_Adapter->m_TxErr, -#if PACKET_TRUNCATION_CHECK - (int)l_Adapter->m_TxTrunc, -#endif - (int)l_Adapter->m_Rx, - (int)l_Adapter->m_RxErr, -#if PACKET_TRUNCATION_CHECK - (int)l_Adapter->m_RxTrunc, -#endif - (int)l_Adapter->m_Extension.m_IrpQueue->size, - (int)l_Adapter->m_Extension.m_IrpQueue->max_size, - (int)IRP_QUEUE_SIZE, - (int)l_Adapter->m_Extension.m_PacketQueue->size, - (int)l_Adapter->m_Extension.m_PacketQueue->max_size, - (int)PACKET_QUEUE_SIZE, - (int)l_Adapter->m_Extension.m_InjectQueue->size, - (int)l_Adapter->m_Extension.m_InjectQueue->max_size, - (int)INJECT_QUEUE_SIZE - ); - - p_IRP->IoStatus.Information - = l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength; - - break; - } - -#if DBG - case TAP_WIN_IOCTL_GET_LOG_LINE: - { - if (GetDebugLine ((LPTSTR)p_IRP->AssociatedIrp.SystemBuffer, - l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength)) - p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS; - else - p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; - - p_IRP->IoStatus.Information - = l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength; - - break; - } -#endif - -#if 0 - case TAP_WIN_IOCTL_CONFIG_TUN: - { - if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >= - (sizeof (IPADDR) * 3)) - { - MACADDR dest; - - l_Adapter->m_tun = FALSE; - - GenerateRelatedMAC (dest, l_Adapter->m_MAC, 1); - - l_Adapter->m_localIP = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[0]; - l_Adapter->m_remoteNetwork = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[1]; - l_Adapter->m_remoteNetmask = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[2]; - - // sanity check on network/netmask - if ((l_Adapter->m_remoteNetwork & l_Adapter->m_remoteNetmask) != l_Adapter->m_remoteNetwork) - { - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; - break; - } - - COPY_MAC (l_Adapter->m_TapToUser.src, l_Adapter->m_MAC); - COPY_MAC (l_Adapter->m_TapToUser.dest, dest); - COPY_MAC (l_Adapter->m_UserToTap.src, dest); - COPY_MAC (l_Adapter->m_UserToTap.dest, l_Adapter->m_MAC); - - l_Adapter->m_TapToUser.proto = l_Adapter->m_UserToTap.proto = htons (ETH_P_IP); - l_Adapter->m_UserToTap_IPv6 = l_Adapter->m_UserToTap; - l_Adapter->m_UserToTap_IPv6.proto = htons(ETH_P_IPV6); - - l_Adapter->m_tun = TRUE; - - CheckIfDhcpAndTunMode (l_Adapter); - - p_IRP->IoStatus.Information = 1; // Simple boolean value - } - else - { - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; - } - - break; - } -#endif - -#if 0 - case TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT: // Obsoleted by TAP_WIN_IOCTL_CONFIG_TUN - { - if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >= - (sizeof (IPADDR) * 2)) - { - MACADDR dest; - - l_Adapter->m_tun = FALSE; - - GenerateRelatedMAC (dest, l_Adapter->m_MAC, 1); - - l_Adapter->m_localIP = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[0]; - l_Adapter->m_remoteNetwork = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[1]; - l_Adapter->m_remoteNetmask = ~0; - - COPY_MAC (l_Adapter->m_TapToUser.src, l_Adapter->m_MAC); - COPY_MAC (l_Adapter->m_TapToUser.dest, dest); - COPY_MAC (l_Adapter->m_UserToTap.src, dest); - COPY_MAC (l_Adapter->m_UserToTap.dest, l_Adapter->m_MAC); - - l_Adapter->m_TapToUser.proto = l_Adapter->m_UserToTap.proto = htons (ETH_P_IP); - l_Adapter->m_UserToTap_IPv6 = l_Adapter->m_UserToTap; - l_Adapter->m_UserToTap_IPv6.proto = htons(ETH_P_IPV6); - - l_Adapter->m_tun = TRUE; - - CheckIfDhcpAndTunMode (l_Adapter); - - p_IRP->IoStatus.Information = 1; // Simple boolean value - } - else - { - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; - } - - break; - } -#endif - - case TAP_WIN_IOCTL_SET_MEDIA_STATUS: - { - if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >= - (sizeof (ULONG) * 1)) - { - ULONG parm = ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[0]; - SetMediaStatus (l_Adapter, (BOOLEAN) parm); - p_IRP->IoStatus.Information = 1; - } - else - { - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; - } - break; - } - -#if 0 - case TAP_WIN_IOCTL_CONFIG_DHCP_MASQ: - { - if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >= - (sizeof (IPADDR) * 4)) - { - l_Adapter->m_dhcp_enabled = FALSE; - l_Adapter->m_dhcp_server_arp = FALSE; - l_Adapter->m_dhcp_user_supplied_options_buffer_len = 0; - - // Adapter IP addr / netmask - l_Adapter->m_dhcp_addr = - ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[0]; - l_Adapter->m_dhcp_netmask = - ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[1]; - - // IP addr of DHCP masq server - l_Adapter->m_dhcp_server_ip = - ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[2]; - - // Lease time in seconds - l_Adapter->m_dhcp_lease_time = - ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[3]; - - GenerateRelatedMAC (l_Adapter->m_dhcp_server_mac, l_Adapter->m_MAC, 2); - - l_Adapter->m_dhcp_enabled = TRUE; - l_Adapter->m_dhcp_server_arp = TRUE; - - CheckIfDhcpAndTunMode (l_Adapter); - - p_IRP->IoStatus.Information = 1; // Simple boolean value - } - else - { - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; - } - - break; - } - - case TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT: - { - if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength <= - DHCP_USER_SUPPLIED_OPTIONS_BUFFER_SIZE - && l_Adapter->m_dhcp_enabled) - { - l_Adapter->m_dhcp_user_supplied_options_buffer_len = 0; - - NdisMoveMemory (l_Adapter->m_dhcp_user_supplied_options_buffer, - p_IRP->AssociatedIrp.SystemBuffer, - l_IrpSp->Parameters.DeviceIoControl.InputBufferLength); - - l_Adapter->m_dhcp_user_supplied_options_buffer_len = - l_IrpSp->Parameters.DeviceIoControl.InputBufferLength; - - p_IRP->IoStatus.Information = 1; // Simple boolean value - } - else - { - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; - } - - break; - } -#endif - - default: - { - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; - break; - } - } - - IoCompleteRequest (p_IRP, IO_NO_INCREMENT); - break; - } - - //=========================================================== - // User mode thread issued a read request on the tap device - // If there are packets waiting to be read, then the request - // will be satisfied here. If not, then the request will be - // queued and satisfied by any packet that is not used to - // satisfy requests ahead of it. - //=========================================================== - case IRP_MJ_READ: - { - TapPacketPointer l_PacketBuffer; - BOOLEAN pending = FALSE; - - // Save IRP-accessible copy of buffer length - p_IRP->IoStatus.Information = l_IrpSp->Parameters.Read.Length; - - if (p_IRP->MdlAddress == NULL) - { - DEBUGP (("[%s] MdlAddress is NULL for IRP_MJ_READ\n", - NAME (l_Adapter))); - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; - p_IRP->IoStatus.Information = 0; - IoCompleteRequest (p_IRP, IO_NO_INCREMENT); - break; - } - else if ((p_IRP->AssociatedIrp.SystemBuffer = - MmGetSystemAddressForMdlSafe - (p_IRP->MdlAddress, NormalPagePriority)) == NULL) - { - DEBUGP (("[%s] Could not map address in IRP_MJ_READ\n", - NAME (l_Adapter))); - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_INSUFFICIENT_RESOURCES; - p_IRP->IoStatus.Information = 0; - IoCompleteRequest (p_IRP, IO_NO_INCREMENT); - break; - } - else if (!l_Adapter->m_InterfaceIsRunning) - { - DEBUGP (("[%s] Interface is down in IRP_MJ_READ\n", - NAME (l_Adapter))); - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; - p_IRP->IoStatus.Information = 0; - IoCompleteRequest (p_IRP, IO_NO_INCREMENT); - break; - } - - //================================== - // Can we provide immediate service? - //================================== - - l_PacketBuffer = NULL; - - NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock); - - if (IS_UP (l_Adapter) - && QueueCount (l_Adapter->m_Extension.m_PacketQueue) - && QueueCount (l_Adapter->m_Extension.m_IrpQueue) == 0) - { - l_PacketBuffer = (TapPacketPointer) - QueuePop (l_Adapter->m_Extension.m_PacketQueue); - } - - NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock); - - if (l_PacketBuffer) - { - l_Status = CompleteIRP (p_IRP, - l_PacketBuffer, - IO_NO_INCREMENT); - break; - } - - //============================= - // Attempt to pend read request - //============================= - - NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock); - - if (IS_UP (l_Adapter) - && QueuePush (l_Adapter->m_Extension.m_IrpQueue, p_IRP) == (PIRP) p_IRP) - { - IoSetCancelRoutine (p_IRP, CancelIRPCallback); - l_Status = STATUS_PENDING; - IoMarkIrpPending (p_IRP); - pending = TRUE; - } - - NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock); - - if (pending) - break; - - // Can't queue anymore IRP's - DEBUGP (("[%s] TAP [%s] read IRP overrun\n", - NAME (l_Adapter), l_Adapter->m_Extension.m_TapName)); - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; - p_IRP->IoStatus.Information = 0; - IoCompleteRequest (p_IRP, IO_NO_INCREMENT); - break; - } - - //============================================================== - // User mode issued a WriteFile request on the TAP file handle. - // The request will always get satisfied here. The call may - // fail if there are too many pending packets (queue full). - //============================================================== - case IRP_MJ_WRITE: - { - if (p_IRP->MdlAddress == NULL) - { - DEBUGP (("[%s] MdlAddress is NULL for IRP_MJ_WRITE\n", - NAME (l_Adapter))); - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; - p_IRP->IoStatus.Information = 0; - } - else if ((p_IRP->AssociatedIrp.SystemBuffer = - MmGetSystemAddressForMdlSafe - (p_IRP->MdlAddress, NormalPagePriority)) == NULL) - { - DEBUGP (("[%s] Could not map address in IRP_MJ_WRITE\n", - NAME (l_Adapter))); - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_INSUFFICIENT_RESOURCES; - p_IRP->IoStatus.Information = 0; - } - else if (!l_Adapter->m_InterfaceIsRunning) - { - DEBUGP (("[%s] Interface is down in IRP_MJ_WRITE\n", - NAME (l_Adapter))); - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; - p_IRP->IoStatus.Information = 0; - } -#if 0 - else if (!l_Adapter->m_tun && ((l_IrpSp->Parameters.Write.Length) >= ETHERNET_HEADER_SIZE)) - { - __try - { - p_IRP->IoStatus.Information = l_IrpSp->Parameters.Write.Length; - - DUMP_PACKET ("IRP_MJ_WRITE ETH", - (unsigned char *) p_IRP->AssociatedIrp.SystemBuffer, - l_IrpSp->Parameters.Write.Length); - - //===================================================== - // If IPv4 packet, check whether or not packet - // was truncated. - //===================================================== -#if PACKET_TRUNCATION_CHECK - IPv4PacketSizeVerify ((unsigned char *) p_IRP->AssociatedIrp.SystemBuffer, - l_IrpSp->Parameters.Write.Length, - FALSE, - "RX", - &l_Adapter->m_RxTrunc); -#endif - - NdisMEthIndicateReceive - (l_Adapter->m_MiniportAdapterHandle, - (NDIS_HANDLE) l_Adapter, - (unsigned char *) p_IRP->AssociatedIrp.SystemBuffer, - ETHERNET_HEADER_SIZE, - (unsigned char *) p_IRP->AssociatedIrp.SystemBuffer + ETHERNET_HEADER_SIZE, - l_IrpSp->Parameters.Write.Length - ETHERNET_HEADER_SIZE, - l_IrpSp->Parameters.Write.Length - ETHERNET_HEADER_SIZE); - - NdisMEthIndicateReceiveComplete (l_Adapter->m_MiniportAdapterHandle); - - p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS; - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - DEBUGP (("[%s] NdisMEthIndicateReceive failed in IRP_MJ_WRITE\n", - NAME (l_Adapter))); - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; - p_IRP->IoStatus.Information = 0; - } - } -#endif -#if 0 - else if (l_Adapter->m_tun && ((l_IrpSp->Parameters.Write.Length) >= IP_HEADER_SIZE)) - { - __try - { - ETH_HEADER * p_UserToTap = &l_Adapter->m_UserToTap; - - // for IPv6, need to use ethernet header with IPv6 proto - if ( IPH_GET_VER( ((IPHDR*) p_IRP->AssociatedIrp.SystemBuffer)->version_len) == 6 ) - { - p_UserToTap = &l_Adapter->m_UserToTap_IPv6; - } - - p_IRP->IoStatus.Information = l_IrpSp->Parameters.Write.Length; - - DUMP_PACKET2 ("IRP_MJ_WRITE P2P", - p_UserToTap, - (unsigned char *) p_IRP->AssociatedIrp.SystemBuffer, - l_IrpSp->Parameters.Write.Length); - - //===================================================== - // If IPv4 packet, check whether or not packet - // was truncated. - //===================================================== -#if PACKET_TRUNCATION_CHECK - IPv4PacketSizeVerify ((unsigned char *) p_IRP->AssociatedIrp.SystemBuffer, - l_IrpSp->Parameters.Write.Length, - TRUE, - "RX", - &l_Adapter->m_RxTrunc); -#endif - - NdisMEthIndicateReceive - (l_Adapter->m_MiniportAdapterHandle, - (NDIS_HANDLE) l_Adapter, - (unsigned char *) p_UserToTap, - sizeof (ETH_HEADER), - (unsigned char *) p_IRP->AssociatedIrp.SystemBuffer, - l_IrpSp->Parameters.Write.Length, - l_IrpSp->Parameters.Write.Length); - - NdisMEthIndicateReceiveComplete (l_Adapter->m_MiniportAdapterHandle); - - p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS; - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - DEBUGP (("[%s] NdisMEthIndicateReceive failed in IRP_MJ_WRITE (P2P)\n", - NAME (l_Adapter))); - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; - p_IRP->IoStatus.Information = 0; - } - } -#endif - else - { - DEBUGP (("[%s] Bad buffer size in IRP_MJ_WRITE, len=%d\n", - NAME (l_Adapter), - l_IrpSp->Parameters.Write.Length)); - NOTE_ERROR (); - p_IRP->IoStatus.Information = 0; // ETHERNET_HEADER_SIZE; - p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL; - } - - if (l_Status == STATUS_SUCCESS) - INCREMENT_STAT (l_Adapter->m_Rx); - else - INCREMENT_STAT (l_Adapter->m_RxErr); - - IoCompleteRequest (p_IRP, IO_NO_INCREMENT); - break; - } - - //-------------------------------------------------------------- - // User mode thread has called CreateFile() on the tap device - //-------------------------------------------------------------- - case IRP_MJ_CREATE: - { - BOOLEAN succeeded = FALSE; - BOOLEAN mutex_succeeded; - - DEBUGP - (("[%s] [TAP] release [%d.%d] open request (m_TapOpens=%d)\n", - NAME (l_Adapter), TAP_DRIVER_MAJOR_VERSION, - TAP_DRIVER_MINOR_VERSION, l_Adapter->m_Extension.m_TapOpens)); - - ACQUIRE_MUTEX_ADAPTIVE (&l_Adapter->m_Extension.m_OpenCloseMutex, mutex_succeeded); - if (mutex_succeeded) - { - if (l_Adapter->m_Extension.m_TapIsRunning && !l_Adapter->m_Extension.m_TapOpens) - { - ResetTapAdapterState (l_Adapter); - l_Adapter->m_Extension.m_TapOpens = 1; - succeeded = TRUE; - } - - if (succeeded) - { - INCREMENT_STAT (l_Adapter->m_Extension.m_NumTapOpens); - p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS; - p_IRP->IoStatus.Information = 0; - } - else - { - DEBUGP (("[%s] TAP is presently unavailable (m_TapOpens=%d)\n", - NAME (l_Adapter), l_Adapter->m_Extension.m_TapOpens)); - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; - p_IRP->IoStatus.Information = 0; - } - - RELEASE_MUTEX (&l_Adapter->m_Extension.m_OpenCloseMutex); - } - else - { - DEBUGP (("[%s] TAP is presently locked (m_TapOpens=%d)\n", - NAME (l_Adapter), l_Adapter->m_Extension.m_TapOpens)); - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; - p_IRP->IoStatus.Information = 0; - } - - IoCompleteRequest (p_IRP, IO_NO_INCREMENT); - break; - } - - //----------------------------------------------------------- - // User mode thread called CloseHandle() on the tap device - //----------------------------------------------------------- - case IRP_MJ_CLOSE: - { - BOOLEAN mutex_succeeded; - - DEBUGP (("[%s] [TAP] release [%d.%d] close/cleanup request\n", - NAME (l_Adapter), TAP_DRIVER_MAJOR_VERSION, - TAP_DRIVER_MINOR_VERSION)); - - ACQUIRE_MUTEX_ADAPTIVE (&l_Adapter->m_Extension.m_OpenCloseMutex, mutex_succeeded); - if (mutex_succeeded) - { - l_Adapter->m_Extension.m_TapOpens = 0; - ResetTapAdapterState (l_Adapter); - FlushQueues (&l_Adapter->m_Extension); - SetMediaStatus (l_Adapter, FALSE); - RELEASE_MUTEX (&l_Adapter->m_Extension.m_OpenCloseMutex); - } - else - { - DEBUGP (("[%s] TAP is presently locked (m_TapOpens=%d)\n", - NAME (l_Adapter), l_Adapter->m_Extension.m_TapOpens)); - NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; - p_IRP->IoStatus.Information = 0; - } - - IoCompleteRequest (p_IRP, IO_NO_INCREMENT); - break; - } - - //------------------ - // Strange Request - //------------------ - default: - { - //NOTE_ERROR (); - p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; - IoCompleteRequest (p_IRP, IO_NO_INCREMENT); - break; - } - } - - return l_Status; -} - -//============================================================= -// CompleteIRP is normally called with an adapter -> userspace -// network packet and an IRP (Pending I/O request) from userspace. -// -// The IRP will normally represent a queued overlapped read -// operation from userspace that is in a wait state. -// -// Use the ethernet packet to satisfy the IRP. -//============================================================= - -NTSTATUS -CompleteIRP (IN PIRP p_IRP, - IN TapPacketPointer p_PacketBuffer, - IN CCHAR PriorityBoost) -{ - NTSTATUS l_Status = STATUS_UNSUCCESSFUL; - - int offset; - int len; - - MYASSERT (p_IRP); - MYASSERT (p_PacketBuffer); - - IoSetCancelRoutine (p_IRP, NULL); // Disable cancel routine - - //------------------------------------------- - // While p_PacketBuffer always contains a - // full ethernet packet, including the - // ethernet header, in point-to-point mode, - // we only want to return the IPv4 - // component. - //------------------------------------------- - - if (p_PacketBuffer->m_SizeFlags & TP_TUN) - { - offset = ETHERNET_HEADER_SIZE; - len = (int) (p_PacketBuffer->m_SizeFlags & TP_SIZE_MASK) - ETHERNET_HEADER_SIZE; - } - else - { - offset = 0; - len = (p_PacketBuffer->m_SizeFlags & TP_SIZE_MASK); - } - - if (len < 0 || (int) p_IRP->IoStatus.Information < len) - { - p_IRP->IoStatus.Information = 0; - p_IRP->IoStatus.Status = STATUS_BUFFER_OVERFLOW; - NOTE_ERROR (); - } - else - { - p_IRP->IoStatus.Information = len; - p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS; - - __try - { - NdisMoveMemory (p_IRP->AssociatedIrp.SystemBuffer, - p_PacketBuffer->m_Data + offset, - len); - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - NOTE_ERROR (); - p_IRP->IoStatus.Status = STATUS_UNSUCCESSFUL; - p_IRP->IoStatus.Information = 0; - } - } - - __try - { - NdisFreeMemory (p_PacketBuffer, - TAP_PACKET_SIZE (p_PacketBuffer->m_SizeFlags & TP_SIZE_MASK), - 0); - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - } - - if (l_Status == STATUS_SUCCESS) - { - IoCompleteRequest (p_IRP, PriorityBoost); - } - else - IoCompleteRequest (p_IRP, IO_NO_INCREMENT); - - return l_Status; -} - -//============================================== -// IRPs get cancelled for a number of reasons. -// -// The TAP device could be closed by userspace -// when there are still pending read operations. -// -// The user could disable the TAP adapter in the -// network connections control panel, while the -// device is still open by a process. -//============================================== -VOID -CancelIRPCallback (IN PDEVICE_OBJECT p_DeviceObject, - IN PIRP p_IRP) -{ - TapAdapterPointer l_Adapter = LookupAdapterInInstanceList (p_DeviceObject); - CancelIRP (l_Adapter ? &l_Adapter->m_Extension : NULL, p_IRP, TRUE); -} - -VOID -CancelIRP (TapExtensionPointer p_Extension, - IN PIRP p_IRP, - BOOLEAN callback) -{ - BOOLEAN exists = FALSE; - - MYASSERT (p_IRP); - - if (p_Extension) - { - NdisAcquireSpinLock (&p_Extension->m_QueueLock); - exists = (QueueExtract (p_Extension->m_IrpQueue, p_IRP) == p_IRP); - NdisReleaseSpinLock (&p_Extension->m_QueueLock); - } - else - exists = TRUE; - - if (exists) - { - IoSetCancelRoutine (p_IRP, NULL); - p_IRP->IoStatus.Status = STATUS_CANCELLED; - p_IRP->IoStatus.Information = 0; - } - - if (callback) - IoReleaseCancelSpinLock (p_IRP->CancelIrql); - - if (exists) - IoCompleteRequest (p_IRP, IO_NO_INCREMENT); -} - -//=========================================== -// Exhaust packet, IRP, and injection queues. -//=========================================== -VOID -FlushQueues (TapExtensionPointer p_Extension) -{ - PIRP l_IRP; - TapPacketPointer l_PacketBuffer; - InjectPacketPointer l_InjectBuffer; - int n_IRP=0, n_Packet=0, n_Inject=0; - - MYASSERT (p_Extension); - MYASSERT (p_Extension->m_TapDevice); - - while (TRUE) - { - NdisAcquireSpinLock (&p_Extension->m_QueueLock); - l_IRP = QueuePop (p_Extension->m_IrpQueue); - NdisReleaseSpinLock (&p_Extension->m_QueueLock); - if (l_IRP) - { - ++n_IRP; - CancelIRP (NULL, l_IRP, FALSE); - } - else - break; - } - - while (TRUE) - { - NdisAcquireSpinLock (&p_Extension->m_QueueLock); - l_PacketBuffer = QueuePop (p_Extension->m_PacketQueue); - NdisReleaseSpinLock (&p_Extension->m_QueueLock); - if (l_PacketBuffer) - { - ++n_Packet; - MemFree (l_PacketBuffer, TAP_PACKET_SIZE (l_PacketBuffer->m_SizeFlags & TP_SIZE_MASK)); - } - else - break; - } - - while (TRUE) - { - NdisAcquireSpinLock (&p_Extension->m_InjectLock); - l_InjectBuffer = QueuePop (p_Extension->m_InjectQueue); - NdisReleaseSpinLock (&p_Extension->m_InjectLock); - if (l_InjectBuffer) - { - ++n_Inject; - INJECT_PACKET_FREE(l_InjectBuffer); - } - else - break; - } - - DEBUGP (( - "[%s] [TAP] FlushQueues n_IRP=[%d,%d,%d] n_Packet=[%d,%d,%d] n_Inject=[%d,%d,%d]\n", - p_Extension->m_TapName, - n_IRP, - p_Extension->m_IrpQueue->max_size, - IRP_QUEUE_SIZE, - n_Packet, - p_Extension->m_PacketQueue->max_size, - PACKET_QUEUE_SIZE, - n_Inject, - p_Extension->m_InjectQueue->max_size, - INJECT_QUEUE_SIZE - )); -} - -//=================================================== -// Tell Windows whether the TAP device should be -// considered "connected" or "disconnected". -//=================================================== -VOID -SetMediaStatus (TapAdapterPointer p_Adapter, BOOLEAN state) -{ - if (p_Adapter->m_MediaState != state && !p_Adapter->m_MediaStateAlwaysConnected) - { - if (state) - NdisMIndicateStatus (p_Adapter->m_MiniportAdapterHandle, - NDIS_STATUS_MEDIA_CONNECT, NULL, 0); - else - NdisMIndicateStatus (p_Adapter->m_MiniportAdapterHandle, - NDIS_STATUS_MEDIA_DISCONNECT, NULL, 0); - - NdisMIndicateStatusComplete (p_Adapter->m_MiniportAdapterHandle); - p_Adapter->m_MediaState = state; - } -} - - -//====================================================== -// If DHCP mode is used together with tun -// mode, consider the fact that the P2P remote subnet -// might enclose the DHCP masq server address. -//====================================================== -VOID -CheckIfDhcpAndTunMode (TapAdapterPointer p_Adapter) -{ -#if 0 - if (p_Adapter->m_tun && p_Adapter->m_dhcp_enabled) - { - if ((p_Adapter->m_dhcp_server_ip & p_Adapter->m_remoteNetmask) == p_Adapter->m_remoteNetwork) - { - COPY_MAC (p_Adapter->m_dhcp_server_mac, p_Adapter->m_TapToUser.dest); - p_Adapter->m_dhcp_server_arp = FALSE; - } - } -#endif -} - -#if 0 -//=================================================== -// Generate an ARP reply message for specific kinds -// ARP queries. -//=================================================== -BOOLEAN -ProcessARP (TapAdapterPointer p_Adapter, - const PARP_PACKET src, - const IPADDR adapter_ip, - const IPADDR ip_network, - const IPADDR ip_netmask, - const MACADDR mac) -{ - //----------------------------------------------- - // Is this the kind of packet we are looking for? - //----------------------------------------------- - if (src->m_Proto == htons (ETH_P_ARP) - && MAC_EQUAL (src->m_MAC_Source, p_Adapter->m_MAC) - && MAC_EQUAL (src->m_ARP_MAC_Source, p_Adapter->m_MAC) - && MAC_EQUAL (src->m_MAC_Destination, p_Adapter->m_MAC_Broadcast) - && src->m_ARP_Operation == htons (ARP_REQUEST) - && src->m_MAC_AddressType == htons (MAC_ADDR_TYPE) - && src->m_MAC_AddressSize == sizeof (MACADDR) - && src->m_PROTO_AddressType == htons (ETH_P_IP) - && src->m_PROTO_AddressSize == sizeof (IPADDR) - && src->m_ARP_IP_Source == adapter_ip - && (src->m_ARP_IP_Destination & ip_netmask) == ip_network - && src->m_ARP_IP_Destination != adapter_ip) - { - ARP_PACKET *arp = (ARP_PACKET *) MemAlloc (sizeof (ARP_PACKET), TRUE); - if (arp) - { - //---------------------------------------------- - // Initialize ARP reply fields - //---------------------------------------------- - arp->m_Proto = htons (ETH_P_ARP); - arp->m_MAC_AddressType = htons (MAC_ADDR_TYPE); - arp->m_PROTO_AddressType = htons (ETH_P_IP); - arp->m_MAC_AddressSize = sizeof (MACADDR); - arp->m_PROTO_AddressSize = sizeof (IPADDR); - arp->m_ARP_Operation = htons (ARP_REPLY); - - //---------------------------------------------- - // ARP addresses - //---------------------------------------------- - COPY_MAC (arp->m_MAC_Source, mac); - COPY_MAC (arp->m_MAC_Destination, p_Adapter->m_MAC); - COPY_MAC (arp->m_ARP_MAC_Source, mac); - COPY_MAC (arp->m_ARP_MAC_Destination, p_Adapter->m_MAC); - arp->m_ARP_IP_Source = src->m_ARP_IP_Destination; - arp->m_ARP_IP_Destination = adapter_ip; - - DUMP_PACKET ("ProcessARP", - (unsigned char *) arp, - sizeof (ARP_PACKET)); - - InjectPacketDeferred (p_Adapter, (UCHAR *) arp, sizeof (ARP_PACKET)); - - MemFree (arp, sizeof (ARP_PACKET)); - } - - return TRUE; - } - else - return FALSE; -} -#endif - -//=============================================================== -// Used in cases where internally generated packets such as -// ARP or DHCP replies must be returned to the kernel, to be -// seen as an incoming packet "arriving" on the interface. -//=============================================================== - -// Defer packet injection till IRQL < DISPATCH_LEVEL -VOID -InjectPacketDeferred (TapAdapterPointer p_Adapter, - UCHAR *packet, - const unsigned int len) -{ - InjectPacketPointer l_InjectBuffer; - PVOID result; - - if (NdisAllocateMemoryWithTag (&l_InjectBuffer, - INJECT_PACKET_SIZE (len), - 'IPAT') == NDIS_STATUS_SUCCESS) - { - l_InjectBuffer->m_Size = len; - NdisMoveMemory (l_InjectBuffer->m_Data, packet, len); - NdisAcquireSpinLock (&p_Adapter->m_Extension.m_InjectLock); - result = QueuePush (p_Adapter->m_Extension.m_InjectQueue, l_InjectBuffer); - NdisReleaseSpinLock (&p_Adapter->m_Extension.m_InjectLock); - if (result) - KeInsertQueueDpc (&p_Adapter->m_Extension.m_InjectDpc, p_Adapter, NULL); - else - INJECT_PACKET_FREE(l_InjectBuffer); - } -} - -// Handle the injection of previously deferred packets -VOID -InjectPacketDpc(KDPC *Dpc, - PVOID DeferredContext, - PVOID SystemArgument1, - PVOID SystemArgument2) -{ - InjectPacketPointer l_InjectBuffer; - TapAdapterPointer l_Adapter = (TapAdapterPointer)SystemArgument1; - while (TRUE) - { - NdisAcquireSpinLock (&l_Adapter->m_Extension.m_InjectLock); - l_InjectBuffer = QueuePop (l_Adapter->m_Extension.m_InjectQueue); - NdisReleaseSpinLock (&l_Adapter->m_Extension.m_InjectLock); - if (l_InjectBuffer) - { - InjectPacketNow(l_Adapter, l_InjectBuffer->m_Data, l_InjectBuffer->m_Size); - INJECT_PACKET_FREE(l_InjectBuffer); - } - else - break; - } -} - -// Do packet injection now -VOID -InjectPacketNow (TapAdapterPointer p_Adapter, - UCHAR *packet, - const unsigned int len) -{ - MYASSERT (len >= ETHERNET_HEADER_SIZE); - - __try - { - //------------------------------------------------------------ - // NdisMEthIndicateReceive and NdisMEthIndicateReceiveComplete - // could potentially be called reentrantly both here and in - // TapDeviceHook/IRP_MJ_WRITE. - // - // The DDK docs imply that this is okay. - // - // Note that reentrant behavior could only occur if the - // non-deferred version of InjectPacket is used. - //------------------------------------------------------------ - NdisMEthIndicateReceive - (p_Adapter->m_MiniportAdapterHandle, - (NDIS_HANDLE) p_Adapter, - packet, - ETHERNET_HEADER_SIZE, - packet + ETHERNET_HEADER_SIZE, - len - ETHERNET_HEADER_SIZE, - len - ETHERNET_HEADER_SIZE); - - NdisMEthIndicateReceiveComplete (p_Adapter->m_MiniportAdapterHandle); - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - DEBUGP (("[%s] NdisMEthIndicateReceive failed in InjectPacketNow\n", - NAME (p_Adapter))); - NOTE_ERROR (); - } -} - -//=================================================================== -// Go back to default TAP mode from Point-To-Point mode. -// Also reset (i.e. disable) DHCP Masq mode. -//=================================================================== -VOID ResetTapAdapterState (TapAdapterPointer p_Adapter) -{ -#if 0 - // Point-To-Point - p_Adapter->m_tun = FALSE; - p_Adapter->m_localIP = 0; - p_Adapter->m_remoteNetwork = 0; - p_Adapter->m_remoteNetmask = 0; - NdisZeroMemory (&p_Adapter->m_TapToUser, sizeof (p_Adapter->m_TapToUser)); - NdisZeroMemory (&p_Adapter->m_UserToTap, sizeof (p_Adapter->m_UserToTap)); - NdisZeroMemory (&p_Adapter->m_UserToTap_IPv6, sizeof (p_Adapter->m_UserToTap_IPv6)); - - // DHCP Masq - p_Adapter->m_dhcp_enabled = FALSE; - p_Adapter->m_dhcp_server_arp = FALSE; - p_Adapter->m_dhcp_user_supplied_options_buffer_len = 0; - p_Adapter->m_dhcp_addr = 0; - p_Adapter->m_dhcp_netmask = 0; - p_Adapter->m_dhcp_server_ip = 0; - p_Adapter->m_dhcp_lease_time = 0; - p_Adapter->m_dhcp_received_discover = FALSE; - p_Adapter->m_dhcp_bad_requests = 0; - NdisZeroMemory (p_Adapter->m_dhcp_server_mac, sizeof (MACADDR)); -#endif -} - -#if ENABLE_NONADMIN - -//=================================================================== -// Set TAP device handle to be accessible without admin privileges. -//=================================================================== -VOID AllowNonAdmin (TapExtensionPointer p_Extension) -{ - NTSTATUS stat; - SECURITY_DESCRIPTOR sd; - OBJECT_ATTRIBUTES oa; - IO_STATUS_BLOCK isb; - HANDLE hand = NULL; - - NdisZeroMemory (&sd, sizeof (sd)); - NdisZeroMemory (&oa, sizeof (oa)); - NdisZeroMemory (&isb, sizeof (isb)); - - if (!p_Extension->m_CreatedUnicodeLinkName) - { - DEBUGP (("[TAP] AllowNonAdmin: UnicodeLinkName is uninitialized\n")); - NOTE_ERROR (); - return; - } - - stat = RtlCreateSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION); - if (stat != STATUS_SUCCESS) - { - DEBUGP (("[TAP] AllowNonAdmin: RtlCreateSecurityDescriptor failed\n")); - NOTE_ERROR (); - return; - } - - InitializeObjectAttributes ( - &oa, - &p_Extension->m_UnicodeLinkName, - OBJ_KERNEL_HANDLE, - NULL, - NULL - ); - - stat = ZwOpenFile ( - &hand, - WRITE_DAC, - &oa, - &isb, - 0, - 0 - ); - if (stat != STATUS_SUCCESS) - { - DEBUGP (("[TAP] AllowNonAdmin: ZwOpenFile failed, status=0x%08x\n", (unsigned int)stat)); - NOTE_ERROR (); - return; - } - - stat = ZwSetSecurityObject (hand, DACL_SECURITY_INFORMATION, &sd); - if (stat != STATUS_SUCCESS) - { - DEBUGP (("[TAP] AllowNonAdmin: ZwSetSecurityObject failed\n")); - NOTE_ERROR (); - return; - } - - stat = ZwClose (hand); - if (stat != STATUS_SUCCESS) - { - DEBUGP (("[TAP] AllowNonAdmin: ZwClose failed\n")); - NOTE_ERROR (); - return; - } - - DEBUGP (("[TAP] AllowNonAdmin: SUCCEEDED\n")); -} - -#endif - -#if PACKET_TRUNCATION_CHECK - -VOID -IPv4PacketSizeVerify (const UCHAR *data, ULONG length, BOOLEAN tun, const char *prefix, LONG *counter) -{ - const IPHDR *ip; - int len = length; - - if (tun) - { - ip = (IPHDR *) data; - } - else - { - if (length >= sizeof (ETH_HEADER)) - { - const ETH_HEADER *eth = (ETH_HEADER *) data; - - if (eth->proto != htons (ETH_P_IP)) - return; - - ip = (IPHDR *) (data + sizeof (ETH_HEADER)); - len -= sizeof (ETH_HEADER); - } - else - return; - } - - if (len >= sizeof (IPHDR)) - { - const int totlen = ntohs (ip->tot_len); - - DEBUGP (("[TAP] IPv4PacketSizeVerify %s len=%d totlen=%d\n", prefix, len, totlen)); - - if (len != totlen) - ++(*counter); - } -} - -#endif - -//====================================================================== -// End of Source -//====================================================================== diff --git a/vsprojects/TapDriver/testcert.pfx b/vsprojects/TapDriver/testcert.pfx deleted file mode 100644 index 74f6b471..00000000 Binary files a/vsprojects/TapDriver/testcert.pfx and /dev/null differ diff --git a/vsprojects/TapDriver/types.h b/vsprojects/TapDriver/types.h deleted file mode 100644 index 4867a3e4..00000000 --- a/vsprojects/TapDriver/types.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - * TAP-Windows -- A kernel driver to provide virtual tap - * device functionality on Windows. - * - * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. - * - * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., - * and is released under the GPL version 2 (see below). - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef TAP_TYPES_DEFINED -#define TAP_TYPES_DEFINED - -typedef struct _Queue -{ - ULONG base; - ULONG size; - ULONG capacity; - ULONG max_size; - PVOID data[]; -} Queue; - -typedef struct _TapAdapter; -typedef struct _TapPacket; - -typedef union _TapAdapterQuery -{ - NDIS_HARDWARE_STATUS m_HardwareStatus; - NDIS_MEDIUM m_Medium; - NDIS_PHYSICAL_MEDIUM m_PhysicalMedium; - UCHAR m_MacAddress [6]; - UCHAR m_Buffer [256]; - ULONG m_Long; - USHORT m_Short; - UCHAR m_Byte; -} -TapAdapterQuery, *TapAdapterQueryPointer; - -typedef struct _TapExtension -{ - // TAP device object and packet queues - Queue *m_PacketQueue, *m_IrpQueue; - PDEVICE_OBJECT m_TapDevice; - NDIS_HANDLE m_TapDeviceHandle; - ULONG m_TapOpens; - - // Used to lock packet queues - NDIS_SPIN_LOCK m_QueueLock; - BOOLEAN m_AllocatedSpinlocks; - - // Used to bracket open/close - // state changes. - MUTEX m_OpenCloseMutex; - - // True if device has been permanently halted - BOOLEAN m_Halt; - - // TAP device name - unsigned char *m_TapName; - UNICODE_STRING m_UnicodeLinkName; - BOOLEAN m_CreatedUnicodeLinkName; - - // Used for device status ioctl only - const char *m_LastErrorFilename; - int m_LastErrorLineNumber; - LONG m_NumTapOpens; - - // Flags - BOOLEAN m_TapIsRunning; - BOOLEAN m_CalledTapDeviceFreeResources; - - // DPC queue for deferred packet injection - BOOLEAN m_InjectDpcInitialized; - KDPC m_InjectDpc; - NDIS_SPIN_LOCK m_InjectLock; - Queue *m_InjectQueue; -} -TapExtension, *TapExtensionPointer; - -typedef struct _TapPacket - { -# define TAP_PACKET_SIZE(data_size) (sizeof (TapPacket) + (data_size)) -# define TP_TUN 0x80000000 -# define TP_SIZE_MASK (~TP_TUN) - ULONG m_SizeFlags; - UCHAR m_Data []; // m_Data must be the last struct member - } -TapPacket, *TapPacketPointer; - -typedef struct _InjectPacket - { -# define INJECT_PACKET_SIZE(data_size) (sizeof (InjectPacket) + (data_size)) -# define INJECT_PACKET_FREE(ib) NdisFreeMemory ((ib), INJECT_PACKET_SIZE ((ib)->m_Size), 0) - ULONG m_Size; - UCHAR m_Data []; // m_Data must be the last struct member - } -InjectPacket, *InjectPacketPointer; - -typedef struct _TapAdapter -{ -# define NAME(a) ((a)->m_NameAnsi.Buffer) - ANSI_STRING m_NameAnsi; - MACADDR m_MAC; - BOOLEAN m_InterfaceIsRunning; - NDIS_HANDLE m_MiniportAdapterHandle; - LONG m_Rx, m_Tx, m_RxErr, m_TxErr; -#if PACKET_TRUNCATION_CHECK - LONG m_RxTrunc, m_TxTrunc; -#endif - NDIS_MEDIUM m_Medium; - ULONG m_Lookahead; - ULONG m_MTU; - - // TRUE if adapter should always be - // "connected" even when device node - // is not open by a userspace process. - BOOLEAN m_MediaStateAlwaysConnected; - - // TRUE if device is "connected" - BOOLEAN m_MediaState; - - // Adapter power state - char m_DeviceState; - -#if 0 - // Info for point-to-point mode - BOOLEAN m_tun; - IPADDR m_localIP; - IPADDR m_remoteNetwork; - IPADDR m_remoteNetmask; - ETH_HEADER m_TapToUser; - ETH_HEADER m_UserToTap; - ETH_HEADER m_UserToTap_IPv6; // same as UserToTap but proto=ipv6 - MACADDR m_MAC_Broadcast; -#endif - -#if 0 - // Used for DHCP server masquerade - BOOLEAN m_dhcp_enabled; - IPADDR m_dhcp_addr; - ULONG m_dhcp_netmask; - IPADDR m_dhcp_server_ip; - BOOLEAN m_dhcp_server_arp; - MACADDR m_dhcp_server_mac; - ULONG m_dhcp_lease_time; - UCHAR m_dhcp_user_supplied_options_buffer[DHCP_USER_SUPPLIED_OPTIONS_BUFFER_SIZE]; - ULONG m_dhcp_user_supplied_options_buffer_len; - BOOLEAN m_dhcp_received_discover; - ULONG m_dhcp_bad_requests; -#endif - - // Help to tear down the adapter by keeping - // some state information on allocated - // resources. - BOOLEAN m_CalledAdapterFreeResources; - BOOLEAN m_RegisteredAdapterShutdownHandler; - - // Multicast list info - NDIS_SPIN_LOCK m_MCLock; - BOOLEAN m_MCLockAllocated; - ULONG m_MCListSize; - MC_LIST m_MCList; - - // Information on the TAP device - TapExtension m_Extension; -} TapAdapter, *TapAdapterPointer; - -#endif diff --git a/vsprojects/TapDriver/ztTap100.inf b/vsprojects/TapDriver/ztTap100.inf deleted file mode 100644 index cf31e9ff..00000000 --- a/vsprojects/TapDriver/ztTap100.inf +++ /dev/null @@ -1,84 +0,0 @@ -[Version] -Signature="$WINDOWS NT$" -Class=Net -ClassGuid={4d36e972-e325-11ce-bfc1-08002be10318} -Provider=%Provider% -CatalogFile=ztTap100.cat - - -[Strings] -DeviceDescription = "ZeroTier One Ethernet Tap" -Provider = "ZeroTier Networks" - -[Manufacturer] -%Provider%=ztTap100,NTamd64 - -[ztTap100] -%DeviceDescription%=ztTap100.ndi,ztTap100 - -[ztTap100.NTamd64] -%DeviceDescription%=ztTap100.ndi,ztTap100 - -[ztTap100.ndi] -CopyFiles = ztTap100.driver,ztTap100.files -AddReg = ztTap100.reg -AddReg = ztTap100.params.reg -Characteristics = 0x81 - -[ztTap100.ndi.Services] -AddService = ztTap100, 2, ztTap100.service - -[ztTap100.reg] -HKR, Ndi, Service, 0, "ztTap100" -HKR, Ndi\Interfaces, UpperRange, 0, "ndis5" -HKR, Ndi\Interfaces, LowerRange, 0, "ethernet" -HKR, , Manufacturer, 0, "%Provider%" -HKR, , ProductName, 0, "%DeviceDescription%" - -[ztTap100.params.reg] -HKR, Ndi\params\MTU, ParamDesc, 0, "MTU" -HKR, Ndi\params\MTU, Type, 0, "int" -HKR, Ndi\params\MTU, Default, 0, "2800" -HKR, Ndi\params\MTU, Optional, 0, "0" -HKR, Ndi\params\MTU, Min, 0, "100" -HKR, Ndi\params\MTU, Max, 0, "2800" -HKR, Ndi\params\MTU, Step, 0, "1" -HKR, Ndi\params\MediaStatus, ParamDesc, 0, "Media Status" -HKR, Ndi\params\MediaStatus, Type, 0, "enum" -HKR, Ndi\params\MediaStatus, Default, 0, "0" -HKR, Ndi\params\MediaStatus, Optional, 0, "0" -HKR, Ndi\params\MediaStatus\enum, "0", 0, "Application Controlled" -HKR, Ndi\params\MediaStatus\enum, "1", 0, "Always Connected" -HKR, Ndi\params\MAC, ParamDesc, 0, "MAC Address" -HKR, Ndi\params\MAC, Type, 0, "edit" -HKR, Ndi\params\MAC, Optional, 0, "1" -HKR, Ndi\params\AllowNonAdmin, ParamDesc, 0, "Non-Admin Access" -HKR, Ndi\params\AllowNonAdmin, Type, 0, "enum" -HKR, Ndi\params\AllowNonAdmin, Default, 0, "0" -HKR, Ndi\params\AllowNonAdmin, Optional, 0, "0" -HKR, Ndi\params\AllowNonAdmin\enum, "0", 0, "Not Allowed" -HKR, Ndi\params\AllowNonAdmin\enum, "1", 0, "Allowed" - -[ztTap100.service] -DisplayName = %DeviceDescription% -ServiceType = 1 -StartType = 3 -ErrorControl = 1 -LoadOrderGroup = NDIS -ServiceBinary = %12%\ztTap100.sys - -[SourceDisksNames] -1 = %DeviceDescription%, ztTap100.sys - -[SourceDisksFiles] -ztTap100.sys = 1 - -[DestinationDirs] -ztTap100.files = 11 -ztTap100.driver = 12 - -[ztTap100.files] -; - -[ztTap100.driver] -ztTap100.sys,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK diff --git a/vsprojects/ZeroTierOne/ZeroTierOne.vcxproj b/vsprojects/ZeroTierOne/ZeroTierOne.vcxproj deleted file mode 100644 index 2d01154d..00000000 --- a/vsprojects/ZeroTierOne/ZeroTierOne.vcxproj +++ /dev/null @@ -1,228 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {B00A4957-5977-4AC1-9EF4-571DC27EADA2} - ZeroTierOne - - - - Application - true - v110 - MultiByte - - - Application - true - v110 - MultiByte - - - Application - false - v110 - true - MultiByte - - - Application - false - v110 - true - MultiByte - - - - - - - - - - - - - - - - - - - .exe - $(SolutionDir)\Build\$(Platform)\$(Configuration)\ - zerotier-one-x86 - - - .exe - $(SolutionDir)\Build\$(Platform)\$(Configuration)\ - zerotier-one-x86 - - - .exe - $(SolutionDir)\Build\$(Platform)\$(Configuration)\ - zerotier-one-x64 - - - .exe - $(SolutionDir)\Build\$(Platform)\$(Configuration)\ - zerotier-one-x64 - - - - Level3 - Disabled - true - $(SolutionDir)\ext\bin\libcrypto\include - ZT_LOG_STDOUT;ZT_TRACE;%(PreprocessorDefinitions) - - - true - wsock32.lib;ws2_32.lib;iphlpapi.lib;rpcrt4.lib;$(SolutionDir)\ext\bin\libcrypto\win32-vs2012\libeay32.lib;%(AdditionalDependencies) - false - - - - - Level3 - Disabled - true - $(SolutionDir)\ext\bin\libcrypto\include - ZT_LOG_STDOUT;ZT_TRACE;%(PreprocessorDefinitions) - - - true - wsock32.lib;ws2_32.lib;iphlpapi.lib;rpcrt4.lib;$(SolutionDir)\ext\bin\libcrypto\win64-vs2012\libeay32.lib;%(AdditionalDependencies) - false - - - - - Level3 - MaxSpeed - true - true - true - $(SolutionDir)\ext\bin\libcrypto\include - ZT_LOG_STDOUT;ZT_TRACE;%(PreprocessorDefinitions) - - - true - true - true - wsock32.lib;ws2_32.lib;iphlpapi.lib;rpcrt4.lib;$(SolutionDir)\ext\bin\libcrypto\win32-vs2012\libeay32.lib;%(AdditionalDependencies) - false - - - - - Level3 - MaxSpeed - true - true - true - $(SolutionDir)\ext\bin\libcrypto\include - ZT_LOG_STDOUT;ZT_TRACE;%(PreprocessorDefinitions) - - - true - true - true - wsock32.lib;ws2_32.lib;iphlpapi.lib;rpcrt4.lib;$(SolutionDir)\ext\bin\libcrypto\win64-vs2012\libeay32.lib;%(AdditionalDependencies) - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/vsprojects/ZeroTierOne/ZeroTierOne.vcxproj.filters b/vsprojects/ZeroTierOne/ZeroTierOne.vcxproj.filters deleted file mode 100644 index 67e668e1..00000000 --- a/vsprojects/ZeroTierOne/ZeroTierOne.vcxproj.filters +++ /dev/null @@ -1,228 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/windows/SelfTest/SelfTest.vcxproj b/windows/SelfTest/SelfTest.vcxproj new file mode 100644 index 00000000..db4e163f --- /dev/null +++ b/windows/SelfTest/SelfTest.vcxproj @@ -0,0 +1,231 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD} + Win32Proj + SelfTest + + + + Application + true + v110 + Unicode + + + Application + true + v110 + Unicode + + + Application + false + v110 + true + Unicode + + + Application + false + v110 + true + Unicode + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\Build\$(Configuration)\ + + + true + + + false + $(SolutionDir)\Build\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\Build\$(Platform)\$(Configuration)\ + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + $(SolutionDir)\ext\bin\libcrypto\include;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\ext\bin\libcrypto\win32-vs2012\libeay32.lib;wsock32.lib;ws2_32.lib;%(AdditionalDependencies) + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + $(SolutionDir)\ext\bin\libcrypto\include;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\ext\bin\libcrypto\win32-vs2012\libeay32.lib;wsock32.lib;ws2_32.lib;%(AdditionalDependencies) + + + + + Level3 + NotUsing + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + $(SolutionDir)\ext\bin\libcrypto\include;%(AdditionalIncludeDirectories) + + + Console + true + true + true + wsock32.lib;ws2_32.lib;iphlpapi.lib;$(SolutionDir)\ext\bin\libcrypto\win32-vs2012\libeay32.lib;%(AdditionalDependencies) + false + + + + + Level3 + NotUsing + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + $(SolutionDir)\ext\bin\libcrypto\include;%(AdditionalIncludeDirectories) + + + Console + true + true + true + wsock32.lib;ws2_32.lib;iphlpapi.lib;$(SolutionDir)\ext\bin\libcrypto\win64-vs2012\libeay32.lib;%(AdditionalDependencies) + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/windows/SelfTest/SelfTest.vcxproj.filters b/windows/SelfTest/SelfTest.vcxproj.filters new file mode 100644 index 00000000..fa8c8331 --- /dev/null +++ b/windows/SelfTest/SelfTest.vcxproj.filters @@ -0,0 +1,227 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/windows/SelfTest/targetver.h b/windows/SelfTest/targetver.h new file mode 100644 index 00000000..87c0086d --- /dev/null +++ b/windows/SelfTest/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/windows/TapDriver Package/TapDriver Package.vcxproj b/windows/TapDriver Package/TapDriver Package.vcxproj new file mode 100644 index 00000000..6ac36e9e --- /dev/null +++ b/windows/TapDriver Package/TapDriver Package.vcxproj @@ -0,0 +1,155 @@ + + + + + Win8 Debug + Win32 + + + Win8 Release + Win32 + + + Win7 Debug + Win32 + + + Win7 Release + Win32 + + + Vista Debug + Win32 + + + Vista Release + Win32 + + + Win8 Debug + x64 + + + Win8 Release + x64 + + + Win7 Debug + x64 + + + Win7 Release + x64 + + + Vista Debug + x64 + + + Vista Release + x64 + + + + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946} + {4605da2c-74a5-4865-98e1-152ef136825f} + v4.5 + 11.0 + Win8 Debug + Win32 + + + TapDriver_Package + $(VCTargetsPath11) + + + WindowsKernelModeDriver8.0 + Utility + Package + true + + + + Windows8 + true + + + Windows8 + false + + + Windows7 + true + + + Windows7 + false + + + Vista + true + + + Vista + false + + + Windows8 + true + + + Windows8 + false + + + Windows7 + true + + + Windows7 + false + + + Vista + true + + + Vista + false + + + + + + + + + + + DbgengKernelDebugger + False + True + + + + False + False + True + + 133563 + $(OutDir)TapDriver Package + + + + + + + + + {689210b1-467c-4850-bb7d-2e10d5b4a3da} + + + + + + \ No newline at end of file diff --git a/windows/TapDriver Package/TapDriver Package.vcxproj.filters b/windows/TapDriver Package/TapDriver Package.vcxproj.filters new file mode 100644 index 00000000..e1b34f2a --- /dev/null +++ b/windows/TapDriver Package/TapDriver Package.vcxproj.filters @@ -0,0 +1,9 @@ + + + + + {8E41214B-6785-4CFE-B992-037D68949A14} + inf;inv;inx;mof;mc; + + + \ No newline at end of file diff --git a/windows/TapDriver/TapDriver.vcxproj b/windows/TapDriver/TapDriver.vcxproj new file mode 100644 index 00000000..03357d5f --- /dev/null +++ b/windows/TapDriver/TapDriver.vcxproj @@ -0,0 +1,352 @@ + + + + + Win8 Debug + Win32 + + + Win8 Release + Win32 + + + Win7 Debug + Win32 + + + Win7 Release + Win32 + + + Vista Debug + Win32 + + + Vista Release + Win32 + + + Win8 Debug + x64 + + + Win8 Release + x64 + + + Win7 Debug + x64 + + + Win7 Release + x64 + + + Vista Debug + x64 + + + Vista Release + x64 + + + + {689210B1-467C-4850-BB7D-2E10D5B4A3DA} + {1bc93793-694f-48fe-9372-81e2b05556fd} + v4.5 + 11.0 + Win8 Debug + Win32 + + + TapDriver + $(VCTargetsPath11) + + + WindowsKernelModeDriver8.0 + Driver + KMDF + + + + Windows8 + true + + + Windows8 + false + + + Windows7 + true + + + Windows7 + false + + + Vista + true + + + Vista + false + + + Windows8 + true + + + Windows8 + false + + + Windows7 + true + + + Windows7 + false + + + Vista + true + + + Vista + false + + + + + + + + + + ztTap100 + $(SolutionDir)\Build\$(Platform)\$(ConfigurationName)\ + $(Platform)\$(ConfigurationName)\ + + + DbgengKernelDebugger + + + ztTap100 + $(SolutionDir)\Build\$(Platform)\$(ConfigurationName)\ + $(Platform)\$(ConfigurationName)\ + + + ztTap100 + $(SolutionDir)\Build\$(Platform)\$(ConfigurationName)\ + $(Platform)\$(ConfigurationName)\ + + + ztTap100 + $(SolutionDir)\Build\$(Platform)\$(ConfigurationName)\ + $(Platform)\$(ConfigurationName)\ + + + ztTap100 + $(SolutionDir)\Build\$(Platform)\$(ConfigurationName)\ + $(Platform)\$(ConfigurationName)\ + + + ztTap100 + $(SolutionDir)\Build\$(Platform)\$(ConfigurationName)\ + $(Platform)\$(ConfigurationName)\ + + + ztTap100 + $(SolutionDir)\Build\$(Platform)\$(ConfigurationName)\ + + + ztTap100 + $(SolutionDir)\Build\$(Platform)\$(ConfigurationName)\ + + + ztTap100 + $(SolutionDir)\Build\$(Platform)\$(ConfigurationName)\ + + + ztTap100 + $(SolutionDir)\Build\$(Platform)\$(ConfigurationName)\ + + + ztTap100 + $(SolutionDir)\Build\$(Platform)\$(ConfigurationName)\ + + + ztTap100 + $(SolutionDir)\Build\$(Platform)\$(ConfigurationName)\ + + + + false + trace.h + true + Level2 + false + None + None + None + Level2 + false + Level2 + false + Level2 + false + Level2 + false + Level2 + false + Level2 + false + Level2 + false + Level2 + false + Level2 + false + Level2 + false + Level2 + false + None + None + None + + + C:\WinDDK\7600.16385.1\lib\wnet\i386\ndis.lib;C:\WinDDK\7600.16385.1\lib\wnet\i386\ntstrsafe.lib;%(AdditionalDependencies) + + + C:\WinDDK\7600.16385.1\lib\wnet\i386\ndis.lib;C:\WinDDK\7600.16385.1\lib\wnet\i386\ntstrsafe.lib;%(AdditionalDependencies) + + + C:\WinDDK\7600.16385.1\lib\wnet\i386\ndis.lib;C:\WinDDK\7600.16385.1\lib\wnet\i386\ntstrsafe.lib;%(AdditionalDependencies) + + + C:\WinDDK\7600.16385.1\lib\wnet\i386\ndis.lib;C:\WinDDK\7600.16385.1\lib\wnet\i386\ntstrsafe.lib;%(AdditionalDependencies) + + + C:\WinDDK\7600.16385.1\lib\wnet\i386\ndis.lib;C:\WinDDK\7600.16385.1\lib\wnet\i386\ntstrsafe.lib;%(AdditionalDependencies) + + + C:\WinDDK\7600.16385.1\lib\wnet\i386\ndis.lib;C:\WinDDK\7600.16385.1\lib\wnet\i386\ntstrsafe.lib;%(AdditionalDependencies) + + + C:\WinDDK\7600.16385.1\lib\wnet\amd64\ndis.lib;C:\WinDDK\7600.16385.1\lib\wnet\amd64\ntstrsafe.lib;%(AdditionalDependencies) + + + C:\WinDDK\7600.16385.1\lib\wnet\amd64\ndis.lib;C:\WinDDK\7600.16385.1\lib\wnet\amd64\ntstrsafe.lib;%(AdditionalDependencies) + + + C:\WinDDK\7600.16385.1\lib\wnet\amd64\ndis.lib;C:\WinDDK\7600.16385.1\lib\wnet\amd64\ntstrsafe.lib;%(AdditionalDependencies) + + + C:\WinDDK\7600.16385.1\lib\wnet\amd64\ndis.lib;C:\WinDDK\7600.16385.1\lib\wnet\amd64\ntstrsafe.lib;%(AdditionalDependencies) + + + C:\WinDDK\7600.16385.1\lib\wnet\amd64\ndis.lib;C:\WinDDK\7600.16385.1\lib\wnet\amd64\ntstrsafe.lib;%(AdditionalDependencies) + + + C:\WinDDK\7600.16385.1\lib\wnet\amd64\ndis.lib;C:\WinDDK\7600.16385.1\lib\wnet\amd64\ntstrsafe.lib;%(AdditionalDependencies) + + + + + + + + + + + + true + true + true + true + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + true + true + true + true + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/windows/TapDriver/TapDriver.vcxproj.filters b/windows/TapDriver/TapDriver.vcxproj.filters new file mode 100644 index 00000000..4bac59db --- /dev/null +++ b/windows/TapDriver/TapDriver.vcxproj.filters @@ -0,0 +1,81 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {8E41214B-6785-4CFE-B992-037D68949A14} + inf;inv;inx;mof;mc; + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Driver Files + + + \ No newline at end of file diff --git a/windows/TapDriver/config.h b/windows/TapDriver/config.h new file mode 100644 index 00000000..5a6ff247 --- /dev/null +++ b/windows/TapDriver/config.h @@ -0,0 +1,12 @@ +#define PRODUCT_NAME "ZeroTier One Ethernet Tap" +#define PRODUCT_VERSION "1.0.0" +#define PRODUCT_VERSION_RESOURCE 1,0,0,1 +#define PRODUCT_TAP_WIN_COMPONENT_ID "ztTap100" +#define PRODUCT_TAP_WIN_MAJOR 1 +#define PRODUCT_TAP_WIN_MINOR 0 +#define PRODUCT_TAP_WIN_PROVIDER "ZeroTier Networks" +#define PRODUCT_TAP_WIN_DEVICE_DESCRIPTION PRODUCT_NAME +#define PRODUCT_TAP_WIN_RELDATE "08/01/2013" + +#define TAP_DRIVER_MAJOR_VERSION PRODUCT_TAP_WIN_MAJOR +#define TAP_DRIVER_MINOR_VERSION PRODUCT_TAP_WIN_MINOR diff --git a/windows/TapDriver/constants.h b/windows/TapDriver/constants.h new file mode 100644 index 00000000..698dc629 --- /dev/null +++ b/windows/TapDriver/constants.h @@ -0,0 +1,52 @@ +/* + * TAP-Windows -- A kernel driver to provide virtual tap + * device functionality on Windows. + * + * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. + * + * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., + * and is released under the GPL version 2 (see below). + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +//==================================================================== +// Product and Version public settings +//==================================================================== + +#define PRODUCT_STRING PRODUCT_TAP_DEVICE_DESCRIPTION + +#define TAP_NDIS_MAJOR_VERSION 5 +#define TAP_NDIS_MINOR_VERSION 0 + +//=========================================================== +// Driver constants +//=========================================================== + +#define ETHERNET_HEADER_SIZE (sizeof (ETH_HEADER)) +#define ETHERNET_MTU 2800 // ZeroTier One MTU +#define ETHERNET_PACKET_SIZE (ETHERNET_MTU + ETHERNET_HEADER_SIZE) +#define DEFAULT_PACKET_LOOKAHEAD (ETHERNET_PACKET_SIZE) + +#define NIC_MAX_MCAST_LIST 32 // Max length of multicast address list + +#define MINIMUM_MTU 576 // USE TCP Minimum MTU +#define MAXIMUM_MTU 65536 // IP maximum MTU + +#define PACKET_QUEUE_SIZE 64 // tap -> userspace queue size +#define IRP_QUEUE_SIZE 16 // max number of simultaneous i/o operations from userspace +#define INJECT_QUEUE_SIZE 16 // DHCP/ARP -> tap injection queue + +#define TAP_LITTLE_ENDIAN // affects ntohs, htonl, etc. functions diff --git a/windows/TapDriver/dhcp.c b/windows/TapDriver/dhcp.c new file mode 100644 index 00000000..f3c61d6f --- /dev/null +++ b/windows/TapDriver/dhcp.c @@ -0,0 +1,603 @@ +/* + * TAP-Windows -- A kernel driver to provide virtual tap + * device functionality on Windows. + * + * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. + * + * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., + * and is released under the GPL version 2 (see below). + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#if 0 + +//========================= +// Code to set DHCP options +//========================= + +VOID +SetDHCPOpt (DHCPMsg *m, void *data, unsigned int len) +{ + if (!m->overflow) + { + if (m->optlen + len <= DHCP_OPTIONS_BUFFER_SIZE) + { + if (len) + { + NdisMoveMemory (m->msg.options + m->optlen, data, len); + m->optlen += len; + } + } + else + { + m->overflow = TRUE; + } + } +} + +VOID +SetDHCPOpt0 (DHCPMsg *msg, int type) +{ + DHCPOPT0 opt; + opt.type = (UCHAR) type; + SetDHCPOpt (msg, &opt, sizeof (opt)); +} + +VOID +SetDHCPOpt8 (DHCPMsg *msg, int type, ULONG data) +{ + DHCPOPT8 opt; + opt.type = (UCHAR) type; + opt.len = sizeof (opt.data); + opt.data = (UCHAR) data; + SetDHCPOpt (msg, &opt, sizeof (opt)); +} + +VOID +SetDHCPOpt32 (DHCPMsg *msg, int type, ULONG data) +{ + DHCPOPT32 opt; + opt.type = (UCHAR) type; + opt.len = sizeof (opt.data); + opt.data = data; + SetDHCPOpt (msg, &opt, sizeof (opt)); +} + +//============== +// Checksum code +//============== + +USHORT +ip_checksum (const UCHAR *buf, const int len_ip_header) +{ + USHORT word16; + ULONG sum = 0; + int i; + + // make 16 bit words out of every two adjacent 8 bit words in the packet + // and add them up + for (i = 0; i < len_ip_header - 1; i += 2) { + word16 = ((buf[i] << 8) & 0xFF00) + (buf[i+1] & 0xFF); + sum += (ULONG) word16; + } + + // take only 16 bits out of the 32 bit sum and add up the carries + while (sum >> 16) + sum = (sum & 0xFFFF) + (sum >> 16); + + // one's complement the result + return ((USHORT) ~sum); +} + +USHORT +udp_checksum (const UCHAR *buf, + const int len_udp, + const UCHAR *src_addr, + const UCHAR *dest_addr) +{ + USHORT word16; + ULONG sum = 0; + int i; + + // make 16 bit words out of every two adjacent 8 bit words and + // calculate the sum of all 16 bit words + for (i = 0; i < len_udp; i += 2){ + word16 = ((buf[i] << 8) & 0xFF00) + ((i + 1 < len_udp) ? (buf[i+1] & 0xFF) : 0); + sum += word16; + } + + // add the UDP pseudo header which contains the IP source and destination addresses + for (i = 0; i < 4; i += 2){ + word16 =((src_addr[i] << 8) & 0xFF00) + (src_addr[i+1] & 0xFF); + sum += word16; + } + for (i = 0; i < 4; i += 2){ + word16 =((dest_addr[i] << 8) & 0xFF00) + (dest_addr[i+1] & 0xFF); + sum += word16; + } + + // the protocol number and the length of the UDP packet + sum += (USHORT) IPPROTO_UDP + (USHORT) len_udp; + + // keep only the last 16 bits of the 32 bit calculated sum and add the carries + while (sum >> 16) + sum = (sum & 0xFFFF) + (sum >> 16); + + // Take the one's complement of sum + return ((USHORT) ~sum); +} + +//================================ +// Set IP and UDP packet checksums +//================================ + +VOID +SetChecksumDHCPMsg (DHCPMsg *m) +{ + // Set IP checksum + m->msg.pre.ip.check = htons (ip_checksum ((UCHAR *) &m->msg.pre.ip, sizeof (IPHDR))); + + // Set UDP Checksum + m->msg.pre.udp.check = htons (udp_checksum ((UCHAR *) &m->msg.pre.udp, + sizeof (UDPHDR) + sizeof (DHCP) + m->optlen, + (UCHAR *)&m->msg.pre.ip.saddr, + (UCHAR *)&m->msg.pre.ip.daddr)); +} + +//=================== +// DHCP message tests +//=================== + +int +GetDHCPMessageType (const DHCP *dhcp, const int optlen) +{ + const UCHAR *p = (UCHAR *) (dhcp + 1); + int i; + + for (i = 0; i < optlen; ++i) + { + const UCHAR type = p[i]; + const int room = optlen - i - 1; + if (type == DHCP_END) // didn't find what we were looking for + return -1; + else if (type == DHCP_PAD) // no-operation + ; + else if (type == DHCP_MSG_TYPE) // what we are looking for + { + if (room >= 2) + { + if (p[i+1] == 1) // message length should be 1 + return p[i+2]; // return message type + } + return -1; + } + else // some other message + { + if (room >= 1) + { + const int len = p[i+1]; // get message length + i += (len + 1); // advance to next message + } + } + } + return -1; +} + +BOOLEAN +DHCPMessageOurs (const TapAdapterPointer p_Adapter, + const ETH_HEADER *eth, + const IPHDR *ip, + const UDPHDR *udp, + const DHCP *dhcp) +{ + // Must be UDPv4 protocol + if (!(eth->proto == htons (ETH_P_IP) && ip->protocol == IPPROTO_UDP)) + return FALSE; + + // Source MAC must be our adapter + if (!MAC_EQUAL (eth->src, p_Adapter->m_MAC)) + return FALSE; + + // Dest MAC must be either broadcast or our virtual DHCP server + if (!(MAC_EQUAL (eth->dest, p_Adapter->m_MAC_Broadcast) + || MAC_EQUAL (eth->dest, p_Adapter->m_dhcp_server_mac))) + return FALSE; + + // Port numbers must be correct + if (!(udp->dest == htons (BOOTPS_PORT) + && udp->source == htons (BOOTPC_PORT))) + return FALSE; + + // Hardware address must be MAC addr sized + if (!(dhcp->hlen == sizeof (MACADDR))) + return FALSE; + + // Hardware address must match our adapter + if (!MAC_EQUAL (eth->src, dhcp->chaddr)) + return FALSE; + + return TRUE; +} + + +//===================================================== +// Build all of DHCP packet except for DHCP options. +// Assume that *p has been zeroed before we are called. +//===================================================== + +VOID +BuildDHCPPre (const TapAdapterPointer a, + DHCPPre *p, + const ETH_HEADER *eth, + const IPHDR *ip, + const UDPHDR *udp, + const DHCP *dhcp, + const int optlen, + const int type) +{ + // Should we broadcast or direct to a specific MAC / IP address? + const BOOLEAN broadcast = (type == DHCPNAK + || MAC_EQUAL (eth->dest, a->m_MAC_Broadcast)); + // Build ethernet header + + COPY_MAC (p->eth.src, a->m_dhcp_server_mac); + + if (broadcast) + COPY_MAC (p->eth.dest, a->m_MAC_Broadcast); + else + COPY_MAC (p->eth.dest, eth->src); + + p->eth.proto = htons (ETH_P_IP); + + // Build IP header + + p->ip.version_len = (4 << 4) | (sizeof (IPHDR) >> 2); + p->ip.tos = 0; + p->ip.tot_len = htons (sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP) + optlen); + p->ip.id = 0; + p->ip.frag_off = 0; + p->ip.ttl = 16; + p->ip.protocol = IPPROTO_UDP; + p->ip.check = 0; + p->ip.saddr = a->m_dhcp_server_ip; + + if (broadcast) + p->ip.daddr = ~0; + else + p->ip.daddr = a->m_dhcp_addr; + + // Build UDP header + + p->udp.source = htons (BOOTPS_PORT); + p->udp.dest = htons (BOOTPC_PORT); + p->udp.len = htons (sizeof (UDPHDR) + sizeof (DHCP) + optlen); + p->udp.check = 0; + + // Build DHCP response + + p->dhcp.op = BOOTREPLY; + p->dhcp.htype = 1; + p->dhcp.hlen = sizeof (MACADDR); + p->dhcp.hops = 0; + p->dhcp.xid = dhcp->xid; + p->dhcp.secs = 0; + p->dhcp.flags = 0; + p->dhcp.ciaddr = 0; + + if (type == DHCPNAK) + p->dhcp.yiaddr = 0; + else + p->dhcp.yiaddr = a->m_dhcp_addr; + + p->dhcp.siaddr = a->m_dhcp_server_ip; + p->dhcp.giaddr = 0; + COPY_MAC (p->dhcp.chaddr, eth->src); + p->dhcp.magic = htonl (0x63825363); +} +//============================= +// Build specific DHCP messages +//============================= + +VOID +SendDHCPMsg (const TapAdapterPointer a, + const int type, + const ETH_HEADER *eth, + const IPHDR *ip, + const UDPHDR *udp, + const DHCP *dhcp) +{ + DHCPMsg *pkt; + + if (!(type == DHCPOFFER || type == DHCPACK || type == DHCPNAK)) + { + DEBUGP (("[TAP] SendDHCPMsg: Bad DHCP type: %d\n", type)); + return; + } + + pkt = (DHCPMsg *) MemAlloc (sizeof (DHCPMsg), TRUE); + + if (pkt) + { + //----------------------- + // Build DHCP options + //----------------------- + + // Message Type + SetDHCPOpt8 (pkt, DHCP_MSG_TYPE, type); + + // Server ID + SetDHCPOpt32 (pkt, DHCP_SERVER_ID, a->m_dhcp_server_ip); + + if (type == DHCPOFFER || type == DHCPACK) + { + // Lease Time + SetDHCPOpt32 (pkt, DHCP_LEASE_TIME, htonl (a->m_dhcp_lease_time)); + + // Netmask + SetDHCPOpt32 (pkt, DHCP_NETMASK, a->m_dhcp_netmask); + + // Other user-defined options + SetDHCPOpt (pkt, + a->m_dhcp_user_supplied_options_buffer, + a->m_dhcp_user_supplied_options_buffer_len); + } + + // End + SetDHCPOpt0 (pkt, DHCP_END); + + if (!DHCPMSG_OVERFLOW (pkt)) + { + // The initial part of the DHCP message (not including options) gets built here + BuildDHCPPre (a, + &pkt->msg.pre, + eth, + ip, + udp, + dhcp, + DHCPMSG_LEN_OPT (pkt), + type); + + SetChecksumDHCPMsg (pkt); + + DUMP_PACKET ("DHCPMsg", + DHCPMSG_BUF (pkt), + DHCPMSG_LEN_FULL (pkt)); + + // Return DHCP response to kernel + InjectPacketDeferred (a, + DHCPMSG_BUF (pkt), + DHCPMSG_LEN_FULL (pkt)); + } + else + { + DEBUGP (("[TAP] SendDHCPMsg: DHCP buffer overflow\n")); + } + + MemFree (pkt, sizeof (DHCPMsg)); + } +} + +//=================================================================== +// Handle a BOOTPS packet produced by the local system to +// resolve the address/netmask of this adapter. +// If we are in TAP_WIN_IOCTL_CONFIG_DHCP_MASQ mode, reply +// to the message. Return TRUE if we processed the passed +// message, so that downstream stages can ignore it. +//=================================================================== + +BOOLEAN +ProcessDHCP (TapAdapterPointer p_Adapter, + const ETH_HEADER *eth, + const IPHDR *ip, + const UDPHDR *udp, + const DHCP *dhcp, + int optlen) +{ + int msg_type; + + // Sanity check IP header + if (!(ntohs (ip->tot_len) == sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP) + optlen + && (ntohs (ip->frag_off) & IP_OFFMASK) == 0)) + return TRUE; + + // Does this message belong to us? + if (!DHCPMessageOurs (p_Adapter, eth, ip, udp, dhcp)) + return FALSE; + + msg_type = GetDHCPMessageType (dhcp, optlen); + + // Drop non-BOOTREQUEST messages + if (dhcp->op != BOOTREQUEST) + return TRUE; + + // Drop any messages except DHCPDISCOVER or DHCPREQUEST + if (!(msg_type == DHCPDISCOVER || msg_type == DHCPREQUEST)) + return TRUE; + + // Should we reply with DHCPOFFER, DHCPACK, or DHCPNAK? + if (msg_type == DHCPREQUEST + && ((dhcp->ciaddr && dhcp->ciaddr != p_Adapter->m_dhcp_addr) + || !p_Adapter->m_dhcp_received_discover + || p_Adapter->m_dhcp_bad_requests >= BAD_DHCPREQUEST_NAK_THRESHOLD)) + SendDHCPMsg (p_Adapter, + DHCPNAK, + eth, ip, udp, dhcp); + else + SendDHCPMsg (p_Adapter, + (msg_type == DHCPDISCOVER ? DHCPOFFER : DHCPACK), + eth, ip, udp, dhcp); + + // Remember if we received a DHCPDISCOVER + if (msg_type == DHCPDISCOVER) + p_Adapter->m_dhcp_received_discover = TRUE; + + // Is this a bad DHCPREQUEST? + if (msg_type == DHCPREQUEST && dhcp->ciaddr && dhcp->ciaddr != p_Adapter->m_dhcp_addr) + ++p_Adapter->m_dhcp_bad_requests; + + return TRUE; +} + +#if DBG + +const char * +message_op_text (int op) +{ + switch (op) + { + case BOOTREQUEST: + return "BOOTREQUEST"; + case BOOTREPLY: + return "BOOTREPLY"; + default: + return "???"; + } +} + +const char * +message_type_text (int type) +{ + switch (type) + { + case DHCPDISCOVER: + return "DHCPDISCOVER"; + case DHCPOFFER: + return "DHCPOFFER"; + case DHCPREQUEST: + return "DHCPREQUEST"; + case DHCPDECLINE: + return "DHCPDECLINE"; + case DHCPACK: + return "DHCPACK"; + case DHCPNAK: + return "DHCPNAK"; + case DHCPRELEASE: + return "DHCPRELEASE"; + case DHCPINFORM: + return "DHCPINFORM"; + default: + return "???"; + } +} + +const char * +port_name (int port) +{ + switch (port) + { + case BOOTPS_PORT: + return "BOOTPS"; + case BOOTPC_PORT: + return "BOOTPC"; + default: + return "unknown"; + } +} + +VOID +DumpDHCP (const ETH_HEADER *eth, + const IPHDR *ip, + const UDPHDR *udp, + const DHCP *dhcp, + const int optlen) +{ + DEBUGP ((" %s", message_op_text (dhcp->op))); + DEBUGP ((" %s ", message_type_text (GetDHCPMessageType (dhcp, optlen)))); + PrIP (ip->saddr); + DEBUGP ((":%s[", port_name (ntohs (udp->source)))); + PrMac (eth->src); + DEBUGP (("] -> ")); + PrIP (ip->daddr); + DEBUGP ((":%s[", port_name (ntohs (udp->dest)))); + PrMac (eth->dest); + DEBUGP (("]")); + if (dhcp->ciaddr) + { + DEBUGP ((" ci=")); + PrIP (dhcp->ciaddr); + } + if (dhcp->yiaddr) + { + DEBUGP ((" yi=")); + PrIP (dhcp->yiaddr); + } + if (dhcp->siaddr) + { + DEBUGP ((" si=")); + PrIP (dhcp->siaddr); + } + if (dhcp->hlen == sizeof (MACADDR)) + { + DEBUGP ((" ch=")); + PrMac (dhcp->chaddr); + } + + DEBUGP ((" xid=0x%08x", ntohl (dhcp->xid))); + + if (ntohl (dhcp->magic) != 0x63825363) + DEBUGP ((" ma=0x%08x", ntohl (dhcp->magic))); + if (dhcp->htype != 1) + DEBUGP ((" htype=%d", dhcp->htype)); + if (dhcp->hops) + DEBUGP ((" hops=%d", dhcp->hops)); + if (ntohs (dhcp->secs)) + DEBUGP ((" secs=%d", ntohs (dhcp->secs))); + if (ntohs (dhcp->flags)) + DEBUGP ((" flags=0x%04x", ntohs (dhcp->flags))); + + // extra stuff + + if (ip->version_len != 0x45) + DEBUGP ((" vl=0x%02x", ip->version_len)); + if (ntohs (ip->tot_len) != sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP) + optlen) + DEBUGP ((" tl=%d", ntohs (ip->tot_len))); + if (ntohs (udp->len) != sizeof (UDPHDR) + sizeof (DHCP) + optlen) + DEBUGP ((" ul=%d", ntohs (udp->len))); + + if (ip->tos) + DEBUGP ((" tos=0x%02x", ip->tos)); + if (ntohs (ip->id)) + DEBUGP ((" id=0x%04x", ntohs (ip->id))); + if (ntohs (ip->frag_off)) + DEBUGP ((" frag_off=0x%04x", ntohs (ip->frag_off))); + + DEBUGP ((" ttl=%d", ip->ttl)); + DEBUGP ((" ic=0x%04x [0x%04x]", ntohs (ip->check), + ip_checksum ((UCHAR*)ip, sizeof (IPHDR)))); + DEBUGP ((" uc=0x%04x [0x%04x/%d]", ntohs (udp->check), + udp_checksum ((UCHAR *) udp, + sizeof (UDPHDR) + sizeof (DHCP) + optlen, + (UCHAR *) &ip->saddr, + (UCHAR *) &ip->daddr), + optlen)); + + // Options + { + const UCHAR *opt = (UCHAR *) (dhcp + 1); + int i; + + DEBUGP ((" OPT")); + for (i = 0; i < optlen; ++i) + { + const UCHAR data = opt[i]; + DEBUGP ((".%d", data)); + } + } +} + +#endif /* DBG */ + +#endif diff --git a/windows/TapDriver/dhcp.h b/windows/TapDriver/dhcp.h new file mode 100644 index 00000000..92e5ca87 --- /dev/null +++ b/windows/TapDriver/dhcp.h @@ -0,0 +1,168 @@ +/* + * TAP-Windows -- A kernel driver to provide virtual tap + * device functionality on Windows. + * + * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. + * + * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., + * and is released under the GPL version 2 (see below). + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#if 0 + +#pragma pack(1) + +//=================================================== +// How many bad DHCPREQUESTs do we receive before we +// return a NAK? +// +// A bad DHCPREQUEST is defined to be one where the +// requestor doesn't know its IP address. +//=================================================== + +#define BAD_DHCPREQUEST_NAK_THRESHOLD 3 + +//============================================== +// Maximum number of DHCP options bytes supplied +//============================================== + +#define DHCP_USER_SUPPLIED_OPTIONS_BUFFER_SIZE 256 +#define DHCP_OPTIONS_BUFFER_SIZE 256 + +//=================================== +// UDP port numbers of DHCP messages. +//=================================== + +#define BOOTPS_PORT 67 +#define BOOTPC_PORT 68 + +//=========================== +// The DHCP message structure +//=========================== + +typedef struct { +# define BOOTREQUEST 1 +# define BOOTREPLY 2 + UCHAR op; /* message op */ + + UCHAR htype; /* hardware address type (e.g. '1' = 10Mb Ethernet) */ + UCHAR hlen; /* hardware address length (e.g. '6' for 10Mb Ethernet) */ + UCHAR hops; /* client sets to 0, may be used by relay agents */ + ULONG xid; /* transaction ID, chosen by client */ + USHORT secs; /* seconds since request process began, set by client */ + USHORT flags; + ULONG ciaddr; /* client IP address, client sets if known */ + ULONG yiaddr; /* 'your' IP address -- server's response to client */ + ULONG siaddr; /* server IP address */ + ULONG giaddr; /* relay agent IP address */ + UCHAR chaddr[16]; /* client hardware address */ + UCHAR sname[64]; /* optional server host name */ + UCHAR file[128]; /* boot file name */ + ULONG magic; /* must be 0x63825363 (network order) */ +} DHCP; + +typedef struct { + ETH_HEADER eth; + IPHDR ip; + UDPHDR udp; + DHCP dhcp; +} DHCPPre; + +typedef struct { + DHCPPre pre; + UCHAR options[DHCP_OPTIONS_BUFFER_SIZE]; +} DHCPFull; + +typedef struct { + unsigned int optlen; + BOOLEAN overflow; + DHCPFull msg; +} DHCPMsg; + +//=================== +// Macros for DHCPMSG +//=================== + +#define DHCPMSG_LEN_BASE(p) (sizeof (DHCPPre)) +#define DHCPMSG_LEN_OPT(p) ((p)->optlen) +#define DHCPMSG_LEN_FULL(p) (DHCPMSG_LEN_BASE(p) + DHCPMSG_LEN_OPT(p)) +#define DHCPMSG_BUF(p) ((UCHAR*) &(p)->msg) +#define DHCPMSG_OVERFLOW(p) ((p)->overflow) + +//======================================== +// structs to hold individual DHCP options +//======================================== + +typedef struct { + UCHAR type; +} DHCPOPT0; + +typedef struct { + UCHAR type; + UCHAR len; + UCHAR data; +} DHCPOPT8; + +typedef struct { + UCHAR type; + UCHAR len; + ULONG data; +} DHCPOPT32; + +#pragma pack() + +//================== +// DHCP Option types +//================== + +#define DHCP_MSG_TYPE 53 /* message type (u8) */ +#define DHCP_PARM_REQ 55 /* parameter request list: c1 (u8), ... */ +#define DHCP_CLIENT_ID 61 /* client ID: type (u8), i1 (u8), ... */ +#define DHCP_IP 50 /* requested IP addr (u32) */ +#define DHCP_NETMASK 1 /* subnet mask (u32) */ +#define DHCP_LEASE_TIME 51 /* lease time sec (u32) */ +#define DHCP_RENEW_TIME 58 /* renewal time sec (u32) */ +#define DHCP_REBIND_TIME 59 /* rebind time sec (u32) */ +#define DHCP_SERVER_ID 54 /* server ID: IP addr (u32) */ +#define DHCP_PAD 0 +#define DHCP_END 255 + +//==================== +// DHCP Messages types +//==================== + +#define DHCPDISCOVER 1 +#define DHCPOFFER 2 +#define DHCPREQUEST 3 +#define DHCPDECLINE 4 +#define DHCPACK 5 +#define DHCPNAK 6 +#define DHCPRELEASE 7 +#define DHCPINFORM 8 + +#if DBG + +VOID +DumpDHCP (const ETH_HEADER *eth, + const IPHDR *ip, + const UDPHDR *udp, + const DHCP *dhcp, + const int optlen); + +#endif + +#endif diff --git a/windows/TapDriver/endian.h b/windows/TapDriver/endian.h new file mode 100644 index 00000000..0f7025d5 --- /dev/null +++ b/windows/TapDriver/endian.h @@ -0,0 +1,35 @@ +/* + * TAP-Windows -- A kernel driver to provide virtual tap + * device functionality on Windows. + * + * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. + * + * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., + * and is released under the GPL version 2 (see below). + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef TAP_LITTLE_ENDIAN +#define ntohs(x) RtlUshortByteSwap(x) +#define htons(x) RtlUshortByteSwap(x) +#define ntohl(x) RtlUlongByteSwap(x) +#define htonl(x) RtlUlongByteSwap(x) +#else +#define ntohs(x) ((USHORT)(x)) +#define htons(x) ((USHORT)(x)) +#define ntohl(x) ((ULONG)(x)) +#define htonl(x) ((ULONG)(x)) +#endif diff --git a/windows/TapDriver/error.c b/windows/TapDriver/error.c new file mode 100644 index 00000000..e03fd114 --- /dev/null +++ b/windows/TapDriver/error.c @@ -0,0 +1,387 @@ +/* + * TAP-Windows -- A kernel driver to provide virtual tap + * device functionality on Windows. + * + * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. + * + * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., + * and is released under the GPL version 2 (see below). + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +//----------------- +// DEBUGGING OUTPUT +//----------------- + +const char *g_LastErrorFilename; +int g_LastErrorLineNumber; + +#if DBG + +DebugOutput g_Debug; + +BOOLEAN +NewlineExists (const char *str, int len) +{ + while (len-- > 0) + { + const char c = *str++; + if (c == '\n') + return TRUE; + else if (c == '\0') + break; + } + return FALSE; +} + +VOID +MyDebugInit (unsigned int bufsiz) +{ + NdisZeroMemory (&g_Debug, sizeof (g_Debug)); + g_Debug.text = (char *) MemAlloc (bufsiz, FALSE); + if (g_Debug.text) + g_Debug.capacity = bufsiz; +} + +VOID +MyDebugFree () +{ + if (g_Debug.text) + MemFree (g_Debug.text, g_Debug.capacity); + NdisZeroMemory (&g_Debug, sizeof (g_Debug)); +} + +VOID +MyDebugPrint (const unsigned char* format, ...) +{ + if (g_Debug.text && g_Debug.capacity > 0 && CAN_WE_PRINT) + { + BOOLEAN owned; + ACQUIRE_MUTEX_ADAPTIVE (&g_Debug.lock, owned); + if (owned) + { + const int remaining = (int)g_Debug.capacity - (int)g_Debug.out; + + if (remaining > 0) + { + va_list args; + NTSTATUS status; + char *end; + +#ifdef DBG_PRINT + va_start (args, format); + vDbgPrintEx (DPFLTR_IHVNETWORK_ID, DPFLTR_INFO_LEVEL, format, args); + va_end (args); +#endif + va_start (args, format); + status = RtlStringCchVPrintfExA (g_Debug.text + g_Debug.out, + remaining, + &end, + NULL, + STRSAFE_NO_TRUNCATION | STRSAFE_IGNORE_NULLS, + format, + args); + va_end (args); +va_start (args, format); +vDbgPrintEx(DPFLTR_IHVDRIVER_ID , 1, format, args); +va_end (args); + if (status == STATUS_SUCCESS) + g_Debug.out = (unsigned int) (end - g_Debug.text); + else + g_Debug.error = TRUE; + } + else + g_Debug.error = TRUE; + + RELEASE_MUTEX (&g_Debug.lock); + } + else + g_Debug.error = TRUE; + } +} + +BOOLEAN +GetDebugLine (char *buf, const int len) +{ + static const char *truncated = "[OUTPUT TRUNCATED]\n"; + BOOLEAN ret = FALSE; + + NdisZeroMemory (buf, len); + + if (g_Debug.text && g_Debug.capacity > 0) + { + BOOLEAN owned; + ACQUIRE_MUTEX_ADAPTIVE (&g_Debug.lock, owned); + if (owned) + { + int i = 0; + + if (g_Debug.error || NewlineExists (g_Debug.text + g_Debug.in, (int)g_Debug.out - (int)g_Debug.in)) + { + while (i < (len - 1) && g_Debug.in < g_Debug.out) + { + const char c = g_Debug.text[g_Debug.in++]; + if (c == '\n') + break; + buf[i++] = c; + } + if (i < len) + buf[i] = '\0'; + } + + if (!i) + { + if (g_Debug.in == g_Debug.out) + { + g_Debug.in = g_Debug.out = 0; + if (g_Debug.error) + { + const unsigned int tlen = strlen (truncated); + if (tlen < g_Debug.capacity) + { + NdisMoveMemory (g_Debug.text, truncated, tlen+1); + g_Debug.out = tlen; + } + g_Debug.error = FALSE; + } + } + } + else + ret = TRUE; + + RELEASE_MUTEX (&g_Debug.lock); + } + } + return ret; +} + +VOID +MyAssert (const unsigned char *file, int line) +{ + DEBUGP (("MYASSERT failed %s/%d\n", file, line)); + KeBugCheckEx (0x0F00BABA, + (ULONG_PTR) line, + (ULONG_PTR) 0, + (ULONG_PTR) 0, + (ULONG_PTR) 0); +} + +VOID +PrMac (const MACADDR mac) +{ + DEBUGP (("%x:%x:%x:%x:%x:%x", + mac[0], mac[1], mac[2], + mac[3], mac[4], mac[5])); +} + +VOID +PrIP (IPADDR ip_addr) +{ + const unsigned char *ip = (const unsigned char *) &ip_addr; + + DEBUGP (("%d.%d.%d.%d", + ip[0], ip[1], ip[2], ip[3])); +} + +const char * +PrIPProto (int proto) +{ + switch (proto) + { + case IPPROTO_UDP: + return "UDP"; + case IPPROTO_TCP: + return "TCP"; + case IPPROTO_ICMP: + return "ICMP"; + case IPPROTO_IGMP: + return "IGMP"; + default: + return "???"; + } +} + +VOID +DumpARP (const char *prefix, const ARP_PACKET *arp) +{ + DEBUGP (("%s ARP src=", prefix)); + PrMac (arp->m_MAC_Source); + DEBUGP ((" dest=")); + PrMac (arp->m_MAC_Destination); + DEBUGP ((" OP=0x%04x", + (int)ntohs(arp->m_ARP_Operation))); + DEBUGP ((" M=0x%04x(%d)", + (int)ntohs(arp->m_MAC_AddressType), + (int)arp->m_MAC_AddressSize)); + DEBUGP ((" P=0x%04x(%d)", + (int)ntohs(arp->m_PROTO_AddressType), + (int)arp->m_PROTO_AddressSize)); + + DEBUGP ((" MacSrc=")); + PrMac (arp->m_ARP_MAC_Source); + DEBUGP ((" MacDest=")); + PrMac (arp->m_ARP_MAC_Destination); + + DEBUGP ((" IPSrc=")); + PrIP (arp->m_ARP_IP_Source); + DEBUGP ((" IPDest=")); + PrIP (arp->m_ARP_IP_Destination); + + DEBUGP (("\n")); +} + +struct ethpayload { + ETH_HEADER eth; + UCHAR payload[DEFAULT_PACKET_LOOKAHEAD]; +}; + +VOID +DumpPacket2 (const char *prefix, + const ETH_HEADER *eth, + const unsigned char *data, + unsigned int len) +{ + struct ethpayload *ep = (struct ethpayload *) MemAlloc (sizeof (struct ethpayload), TRUE); + if (ep) + { + if (len > DEFAULT_PACKET_LOOKAHEAD) + len = DEFAULT_PACKET_LOOKAHEAD; + ep->eth = *eth; + NdisMoveMemory (ep->payload, data, len); + DumpPacket (prefix, (unsigned char *) ep, sizeof (ETH_HEADER) + len); + MemFree (ep, sizeof (struct ethpayload)); + } +} + +VOID +DumpPacket (const char *prefix, + const unsigned char *data, + unsigned int len) +{ + const ETH_HEADER *eth = (const ETH_HEADER *) data; + const IPHDR *ip = (const IPHDR *) (data + sizeof (ETH_HEADER)); + + if (len < sizeof (ETH_HEADER)) + { + DEBUGP (("%s TRUNCATED PACKET LEN=%d\n", prefix, len)); + return; + } + + // ARP Packet? + if (len >= sizeof (ARP_PACKET) && eth->proto == htons (ETH_P_ARP)) + { + DumpARP (prefix, (const ARP_PACKET *) data); + return; + } + + // IPv4 packet? + if (len >= (sizeof (IPHDR) + sizeof (ETH_HEADER)) + && eth->proto == htons (ETH_P_IP) + && IPH_GET_VER (ip->version_len) == 4) + { + const int hlen = IPH_GET_LEN (ip->version_len); + const int blen = len - sizeof (ETH_HEADER); + BOOLEAN did = FALSE; + + DEBUGP (("%s IPv4 %s[%d]", prefix, PrIPProto (ip->protocol), len)); + + if (!(ntohs (ip->tot_len) == blen && hlen <= blen)) + { + DEBUGP ((" XXX")); + return; + } + + // TCP packet? + if (ip->protocol == IPPROTO_TCP + && blen - hlen >= (sizeof (TCPHDR))) + { + const TCPHDR *tcp = (TCPHDR *) (data + sizeof (ETH_HEADER) + hlen); + DEBUGP ((" ")); + PrIP (ip->saddr); + DEBUGP ((":%d", ntohs (tcp->source))); + DEBUGP ((" -> ")); + PrIP (ip->daddr); + DEBUGP ((":%d", ntohs (tcp->dest))); + did = TRUE; + } + + // UDP packet? + else if ((ntohs (ip->frag_off) & IP_OFFMASK) == 0 + && ip->protocol == IPPROTO_UDP + && blen - hlen >= (sizeof (UDPHDR))) + { + const UDPHDR *udp = (UDPHDR *) (data + sizeof (ETH_HEADER) + hlen); + +#if 0 + // DHCP packet? + if ((udp->dest == htons (BOOTPC_PORT) || udp->dest == htons (BOOTPS_PORT)) + && blen - hlen >= (sizeof (UDPHDR) + sizeof (DHCP))) + { + const DHCP *dhcp = (DHCP *) (data + + hlen + + sizeof (ETH_HEADER) + + sizeof (UDPHDR)); + + int optlen = len + - sizeof (ETH_HEADER) + - hlen + - sizeof (UDPHDR) + - sizeof (DHCP); + + if (optlen < 0) + optlen = 0; + + DumpDHCP (eth, ip, udp, dhcp, optlen); + did = TRUE; + } +#endif + + if (!did) + { + DEBUGP ((" ")); + PrIP (ip->saddr); + DEBUGP ((":%d", ntohs (udp->source))); + DEBUGP ((" -> ")); + PrIP (ip->daddr); + DEBUGP ((":%d", ntohs (udp->dest))); + did = TRUE; + } + } + + if (!did) + { + DEBUGP ((" ipproto=%d ", ip->protocol)); + PrIP (ip->saddr); + DEBUGP ((" -> ")); + PrIP (ip->daddr); + } + + DEBUGP (("\n")); + return; + } + + { + DEBUGP (("%s ??? src=", prefix)); + PrMac (eth->src); + DEBUGP ((" dest=")); + PrMac (eth->dest); + DEBUGP ((" proto=0x%04x len=%d\n", + (int) ntohs(eth->proto), + len)); + } +} + +#endif diff --git a/windows/TapDriver/error.h b/windows/TapDriver/error.h new file mode 100644 index 00000000..47f436c5 --- /dev/null +++ b/windows/TapDriver/error.h @@ -0,0 +1,88 @@ +/* + * TAP-Windows -- A kernel driver to provide virtual tap + * device functionality on Windows. + * + * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. + * + * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., + * and is released under the GPL version 2 (see below). + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +//----------------- +// DEBUGGING OUTPUT +//----------------- + +#define NOTE_ERROR() \ +{ \ + g_LastErrorFilename = __FILE__; \ + g_LastErrorLineNumber = __LINE__; \ +} + +#if DBG + +typedef struct { + unsigned int in; + unsigned int out; + unsigned int capacity; + char *text; + BOOLEAN error; + MUTEX lock; +} DebugOutput; + +VOID MyDebugPrint (const unsigned char* format, ...); + +VOID MyAssert (const unsigned char *file, int line); + +VOID DumpPacket (const char *prefix, + const unsigned char *data, + unsigned int len); + +VOID DumpPacket2 (const char *prefix, + const ETH_HEADER *eth, + const unsigned char *data, + unsigned int len); + +#define CAN_WE_PRINT (DEBUGP_AT_DISPATCH || KeGetCurrentIrql () < DISPATCH_LEVEL) + +#if ALSO_DBGPRINT +#define DEBUGP(fmt) { MyDebugPrint fmt; if (CAN_WE_PRINT) DbgPrint fmt; } +#else +#define DEBUGP(fmt) { MyDebugPrint fmt; } +#endif + +#define MYASSERT(exp) \ +{ \ + if (!(exp)) \ + { \ + MyAssert(__FILE__, __LINE__); \ + } \ +} + +#define DUMP_PACKET(prefix, data, len) \ + DumpPacket (prefix, data, len) + +#define DUMP_PACKET2(prefix, eth, data, len) \ + DumpPacket2 (prefix, eth, data, len) + +#else + +#define DEBUGP(fmt) +#define MYASSERT(exp) +#define DUMP_PACKET(prefix, data, len) +#define DUMP_PACKET2(prefix, eth, data, len) + +#endif diff --git a/windows/TapDriver/instance.c b/windows/TapDriver/instance.c new file mode 100644 index 00000000..33ef878f --- /dev/null +++ b/windows/TapDriver/instance.c @@ -0,0 +1,241 @@ +/* + * TAP-Windows -- A kernel driver to provide virtual tap + * device functionality on Windows. + * + * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. + * + * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., + * and is released under the GPL version 2 (see below). + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define INSTANCE_KEY(a) ((PVOID)((a)->m_Extension.m_TapDevice)) + +#define N_INSTANCE_BUCKETS 256 + +typedef struct _INSTANCE { + struct _INSTANCE *next; + TapAdapterPointer m_Adapter; +} INSTANCE; + +typedef struct { + INSTANCE *list; + MUTEX lock; +} INSTANCE_BUCKET; + +typedef struct { + INSTANCE_BUCKET buckets[N_INSTANCE_BUCKETS]; +} INSTANCE_HASH; + +INSTANCE_HASH *g_InstanceHash = NULL; + +// must return a hash >= 0 and < N_INSTANCE_BUCKETS +int +InstanceHashValue (PVOID addr) +{ + UCHAR *p = (UCHAR *) &addr; + + if (sizeof (addr) == 4) + return p[0] ^ p[1] ^ p[2] ^ p[3]; + else if (sizeof (addr) == 8) + return p[0] ^ p[1] ^ p[2] ^ p[3] ^ p[4] ^ p[5] ^ p[6] ^ p[7]; + else + { + MYASSERT (0); + } +} + +BOOLEAN +InitInstanceList (VOID) +{ + MYASSERT (g_InstanceHash == NULL); + g_InstanceHash = MemAlloc (sizeof (INSTANCE_HASH), TRUE); + if (g_InstanceHash) + { + int i; + for (i = 0; i < N_INSTANCE_BUCKETS; ++i) + INIT_MUTEX (&g_InstanceHash->buckets[i].lock); + return TRUE; + } + else + return FALSE; +} + +int +NInstances (VOID) +{ + int i, n = 0; + + if (g_InstanceHash) + { + for (i = 0; i < N_INSTANCE_BUCKETS; ++i) + { + BOOLEAN got_lock; + INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[i]; + ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock); + + if (got_lock) + { + INSTANCE *current; + for (current = ib->list; current != NULL; current = current->next) + ++n; + RELEASE_MUTEX (&ib->lock); + } + else + return -1; + } + } + + return n; +} + +int +InstanceMaxBucketSize (VOID) +{ + int i, n = 0; + + if (g_InstanceHash) + { + for (i = 0; i < N_INSTANCE_BUCKETS; ++i) + { + BOOLEAN got_lock; + int bucket_size = 0; + INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[i]; + ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock); + + if (got_lock) + { + INSTANCE *current; + for (current = ib->list; current != NULL; current = current->next) + ++bucket_size; + if (bucket_size > n) + n = bucket_size; + RELEASE_MUTEX (&ib->lock); + } + else + return -1; + } + } + + return n; +} + +VOID +FreeInstanceList (VOID) +{ + if (g_InstanceHash) + { + MYASSERT (NInstances() == 0); + MemFree (g_InstanceHash, sizeof (INSTANCE_HASH)); + g_InstanceHash = NULL; + } +} + +BOOLEAN +AddAdapterToInstanceList (TapAdapterPointer p_Adapter) +{ + BOOLEAN got_lock; + BOOLEAN ret = FALSE; + const int hash = InstanceHashValue(INSTANCE_KEY(p_Adapter)); + INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[hash]; + + DEBUGP (("[TAP] AddAdapterToInstanceList hash=%d\n", hash)); + + ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock); + + if (got_lock) + { + INSTANCE *i = MemAlloc (sizeof (INSTANCE), FALSE); + if (i) + { + MYASSERT (p_Adapter); + i->m_Adapter = p_Adapter; + i->next = ib->list; + ib->list = i; + ret = TRUE; + } + RELEASE_MUTEX (&ib->lock); + } + + return ret; +} + +BOOLEAN +RemoveAdapterFromInstanceList (TapAdapterPointer p_Adapter) +{ + BOOLEAN got_lock; + BOOLEAN ret = FALSE; + INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[InstanceHashValue(INSTANCE_KEY(p_Adapter))]; + + ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock); + + if (got_lock) + { + INSTANCE *current, *prev=NULL; + for (current = ib->list; current != NULL; current = current->next) + { + if (current->m_Adapter == p_Adapter) // found match + { + if (prev) + prev->next = current->next; + else + ib->list = current->next; + MemFree (current->m_Adapter, sizeof (TapAdapter)); + MemFree (current, sizeof (INSTANCE)); + ret = TRUE; + break; + } + prev = current; + } + RELEASE_MUTEX (&ib->lock); + } + + return ret; +} + +TapAdapterPointer +LookupAdapterInInstanceList (PDEVICE_OBJECT p_DeviceObject) +{ + BOOLEAN got_lock; + TapAdapterPointer ret = NULL; + INSTANCE_BUCKET *ib = &g_InstanceHash->buckets[InstanceHashValue((PVOID)p_DeviceObject)]; + + ACQUIRE_MUTEX_ADAPTIVE (&ib->lock, got_lock); + + if (got_lock) + { + INSTANCE *current, *prev=NULL; + for (current = ib->list; current != NULL; current = current->next) + { + if (p_DeviceObject == INSTANCE_KEY (current->m_Adapter)) // found match + { + // move it to head of list + if (prev) + { + prev->next = current->next; + current->next = ib->list; + ib->list = current; + } + ret = ib->list->m_Adapter; + break; + } + prev = current; + } + RELEASE_MUTEX (&ib->lock); + } + + return ret; +} diff --git a/windows/TapDriver/lock.h b/windows/TapDriver/lock.h new file mode 100644 index 00000000..e2a2029e --- /dev/null +++ b/windows/TapDriver/lock.h @@ -0,0 +1,75 @@ +/* + * TAP-Windows -- A kernel driver to provide virtual tap + * device functionality on Windows. + * + * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. + * + * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., + * and is released under the GPL version 2 (see below). + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +typedef struct +{ + volatile long count; +} MUTEX; + +#define MUTEX_SLEEP_TIME 10000 // microseconds + +#define INIT_MUTEX(m) { (m)->count = 0; } + +#define ACQUIRE_MUTEX_BLOCKING(m) \ +{ \ + while (NdisInterlockedIncrement (&((m)->count)) != 1) \ + { \ + NdisInterlockedDecrement(&((m)->count)); \ + NdisMSleep(MUTEX_SLEEP_TIME); \ + } \ +} + +#define RELEASE_MUTEX(m) \ +{ \ + NdisInterlockedDecrement(&((m)->count)); \ +} + +#define ACQUIRE_MUTEX_NONBLOCKING(m, result) \ +{ \ + if (NdisInterlockedIncrement (&((m)->count)) != 1) \ + { \ + NdisInterlockedDecrement(&((m)->count)); \ + result = FALSE; \ + } \ + else \ + { \ + result = TRUE; \ + } \ +} + +#define ACQUIRE_MUTEX_ADAPTIVE(m, result) \ +{ \ + result = TRUE; \ + while (NdisInterlockedIncrement (&((m)->count)) != 1) \ + { \ + NdisInterlockedDecrement(&((m)->count)); \ + if (KeGetCurrentIrql () < DISPATCH_LEVEL) \ + NdisMSleep(MUTEX_SLEEP_TIME); \ + else \ + { \ + result = FALSE; \ + break; \ + } \ + } \ +} diff --git a/windows/TapDriver/macinfo.c b/windows/TapDriver/macinfo.c new file mode 100644 index 00000000..fca53079 --- /dev/null +++ b/windows/TapDriver/macinfo.c @@ -0,0 +1,154 @@ +/* + * TAP-Windows -- A kernel driver to provide virtual tap + * device functionality on Windows. + * + * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. + * + * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., + * and is released under the GPL version 2 (see below). + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "macinfo.h" + +int +HexStringToDecimalInt (const int p_Character) +{ + int l_Value = 0; + + if (p_Character >= 'A' && p_Character <= 'F') + l_Value = (p_Character - 'A') + 10; + else if (p_Character >= 'a' && p_Character <= 'f') + l_Value = (p_Character - 'a') + 10; + else if (p_Character >= '0' && p_Character <= '9') + l_Value = p_Character - '0'; + + return l_Value; +} + +BOOLEAN +ParseMAC (MACADDR dest, const char *src) +{ + int c; + int mac_index = 0; + BOOLEAN high_digit = FALSE; + int delim_action = 1; + + MYASSERT (src); + MYASSERT (dest); + + CLEAR_MAC (dest); + + while (c = *src++) + { + if (IsMacDelimiter (c)) + { + mac_index += delim_action; + high_digit = FALSE; + delim_action = 1; + } + else if (IsHexDigit (c)) + { + const int digit = HexStringToDecimalInt (c); + if (mac_index < sizeof (MACADDR)) + { + if (!high_digit) + { + dest[mac_index] = (char)(digit); + high_digit = TRUE; + delim_action = 1; + } + else + { + dest[mac_index] = (char)(dest[mac_index] * 16 + digit); + ++mac_index; + high_digit = FALSE; + delim_action = 0; + } + } + else + return FALSE; + } + else + return FALSE; + } + + return (mac_index + delim_action) >= sizeof (MACADDR); +} + +/* + * Generate a MAC using the GUID in the adapter name. + * + * The mac is constructed as 00:FF:xx:xx:xx:xx where + * the Xs are taken from the first 32 bits of the GUID in the + * adapter name. This is similar to the Linux 2.4 tap MAC + * generator, except linux uses 32 random bits for the Xs. + * + * In general, this solution is reasonable for most + * applications except for very large bridged TAP networks, + * where the probability of address collisions becomes more + * than infintesimal. + * + * Using the well-known "birthday paradox", on a 1000 node + * network the probability of collision would be + * 0.000116292153. On a 10,000 node network, the probability + * of collision would be 0.01157288998621678766. + */ + +VOID GenerateRandomMac (MACADDR mac, const unsigned char *adapter_name) +{ + unsigned const char *cp = adapter_name; + unsigned char c; + unsigned int i = 2; + unsigned int byte = 0; + int brace = 0; + int state = 0; + + CLEAR_MAC (mac); + + mac[0] = 0x00; + mac[1] = 0xFF; + + while (c = *cp++) + { + if (i >= sizeof (MACADDR)) + break; + if (c == '{') + brace = 1; + if (IsHexDigit (c) && brace) + { + const unsigned int digit = HexStringToDecimalInt (c); + if (state) + { + byte <<= 4; + byte |= digit; + mac[i++] = (unsigned char) byte; + state = 0; + } + else + { + byte = digit; + state = 1; + } + } + } +} + +VOID GenerateRelatedMAC (MACADDR dest, const MACADDR src, const int delta) +{ + COPY_MAC (dest, src); + dest[2] += (UCHAR) delta; +} diff --git a/windows/TapDriver/macinfo.h b/windows/TapDriver/macinfo.h new file mode 100644 index 00000000..ba843e8c --- /dev/null +++ b/windows/TapDriver/macinfo.h @@ -0,0 +1,38 @@ +/* + * TAP-Windows -- A kernel driver to provide virtual tap + * device functionality on Windows. + * + * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. + * + * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., + * and is released under the GPL version 2 (see below). + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MacInfoDefined +#define MacInfoDefined + +//=================================================================================== +// Macros +//=================================================================================== +#define IsMacDelimiter(a) (a == ':' || a == '-' || a == '.') +#define IsHexDigit(c) ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) + +#define COPY_MAC(dest, src) NdisMoveMemory ((dest), (src), sizeof (MACADDR)) +#define CLEAR_MAC(dest) NdisZeroMemory ((dest), sizeof (MACADDR)) +#define MAC_EQUAL(a,b) (memcmp ((a), (b), sizeof (MACADDR)) == 0) + +#endif diff --git a/windows/TapDriver/mem.c b/windows/TapDriver/mem.c new file mode 100644 index 00000000..c56304cc --- /dev/null +++ b/windows/TapDriver/mem.c @@ -0,0 +1,186 @@ +/* + * TAP-Windows -- A kernel driver to provide virtual tap + * device functionality on Windows. + * + * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. + * + * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., + * and is released under the GPL version 2 (see below). + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +//------------------ +// Memory Management +//------------------ + +PVOID +MemAlloc (ULONG p_Size, BOOLEAN zero) +{ + PVOID l_Return = NULL; + + if (p_Size) + { + __try + { + if (NdisAllocateMemoryWithTag (&l_Return, p_Size, 'APAT') + == NDIS_STATUS_SUCCESS) + { + if (zero) + NdisZeroMemory (l_Return, p_Size); + } + else + l_Return = NULL; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + l_Return = NULL; + } + } + + return l_Return; +} + +VOID +MemFree (PVOID p_Addr, ULONG p_Size) +{ + if (p_Addr && p_Size) + { + __try + { +#if DBG + NdisZeroMemory (p_Addr, p_Size); +#endif + NdisFreeMemory (p_Addr, p_Size, 0); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + } + } +} + +/* + * Circular queue management routines. + */ + +#define QUEUE_BYTE_ALLOCATION(size) \ + (sizeof (Queue) + (size * sizeof (PVOID))) + +#define QUEUE_ADD_INDEX(var, inc) \ +{ \ + var += inc; \ + if (var >= q->capacity) \ + var -= q->capacity; \ + MYASSERT (var < q->capacity); \ +} + +#define QUEUE_SANITY_CHECK() \ + MYASSERT (q != NULL && q->base < q->capacity && q->size <= q->capacity) + +#define QueueCount(q) (q->size) + +#define UPDATE_MAX_SIZE() \ +{ \ + if (q->size > q->max_size) \ + q->max_size = q->size; \ +} + +Queue * +QueueInit (ULONG capacity) +{ + Queue *q; + + MYASSERT (capacity > 0); + q = (Queue *) MemAlloc (QUEUE_BYTE_ALLOCATION (capacity), TRUE); + if (!q) + return NULL; + + q->base = q->size = 0; + q->capacity = capacity; + q->max_size = 0; + return q; +} + +VOID +QueueFree (Queue *q) +{ + if (q) + { + QUEUE_SANITY_CHECK (); + MemFree (q, QUEUE_BYTE_ALLOCATION (q->capacity)); + } +} + +PVOID +QueuePush (Queue *q, PVOID item) +{ + ULONG dest; + QUEUE_SANITY_CHECK (); + if (q->size == q->capacity) + return NULL; + dest = q->base; + QUEUE_ADD_INDEX (dest, q->size); + q->data[dest] = item; + ++q->size; + UPDATE_MAX_SIZE(); + return item; +} + +PVOID +QueuePop (Queue *q) +{ + ULONG oldbase; + QUEUE_SANITY_CHECK (); + if (!q->size) + return NULL; + oldbase = q->base; + QUEUE_ADD_INDEX (q->base, 1); + --q->size; + UPDATE_MAX_SIZE(); + return q->data[oldbase]; +} + +PVOID +QueueExtract (Queue *q, PVOID item) +{ + ULONG src, dest, count, n; + QUEUE_SANITY_CHECK (); + n = 0; + src = dest = q->base; + count = q->size; + while (count--) + { + if (item == q->data[src]) + { + ++n; + --q->size; + } + else + { + q->data[dest] = q->data[src]; + QUEUE_ADD_INDEX (dest, 1); + } + QUEUE_ADD_INDEX (src, 1); + } + if (n) + return item; + else + return NULL; +} + +#undef QUEUE_BYTE_ALLOCATION +#undef QUEUE_ADD_INDEX +#undef QUEUE_SANITY_CHECK +#undef UPDATE_MAX_SIZE diff --git a/windows/TapDriver/proto.h b/windows/TapDriver/proto.h new file mode 100644 index 00000000..71916a96 --- /dev/null +++ b/windows/TapDriver/proto.h @@ -0,0 +1,224 @@ +/* + * TAP-Windows -- A kernel driver to provide virtual tap + * device functionality on Windows. + * + * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. + * + * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., + * and is released under the GPL version 2 (see below). + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +//============================================================ +// MAC address, Ethernet header, and ARP +//============================================================ + +#pragma pack(1) + +#define IP_HEADER_SIZE 20 +#define IPV6_HEADER_SIZE 40 + +typedef unsigned char MACADDR [6]; +typedef unsigned long IPADDR; +typedef unsigned char IPV6ADDR [16]; + +//----------------- +// Ethernet address +//----------------- + +typedef struct { + MACADDR addr; +} ETH_ADDR; + +typedef struct { + ETH_ADDR list[NIC_MAX_MCAST_LIST]; +} MC_LIST; + +//---------------- +// Ethernet header +//---------------- + +typedef struct +{ + MACADDR dest; /* destination eth addr */ + MACADDR src; /* source ether addr */ + +# define ETH_P_IP 0x0800 /* IPv4 protocol */ +# define ETH_P_IPV6 0x86DD /* IPv6 protocol */ +# define ETH_P_ARP 0x0806 /* ARP protocol */ + USHORT proto; /* packet type ID field */ +} ETH_HEADER, *PETH_HEADER; + +//---------------- +// ARP packet +//---------------- + +typedef struct + { + MACADDR m_MAC_Destination; // Reverse these two + MACADDR m_MAC_Source; // to answer ARP requests + USHORT m_Proto; // 0x0806 + +# define MAC_ADDR_TYPE 0x0001 + USHORT m_MAC_AddressType; // 0x0001 + + USHORT m_PROTO_AddressType; // 0x0800 + UCHAR m_MAC_AddressSize; // 0x06 + UCHAR m_PROTO_AddressSize; // 0x04 + +# define ARP_REQUEST 0x0001 +# define ARP_REPLY 0x0002 + USHORT m_ARP_Operation; // 0x0001 for ARP request, 0x0002 for ARP reply + + MACADDR m_ARP_MAC_Source; + IPADDR m_ARP_IP_Source; + MACADDR m_ARP_MAC_Destination; + IPADDR m_ARP_IP_Destination; + } +ARP_PACKET, *PARP_PACKET; + +//---------- +// IP Header +//---------- + +typedef struct { +# define IPH_GET_VER(v) (((v) >> 4) & 0x0F) +# define IPH_GET_LEN(v) (((v) & 0x0F) << 2) + UCHAR version_len; + + UCHAR tos; + USHORT tot_len; + USHORT id; + +# define IP_OFFMASK 0x1fff + USHORT frag_off; + + UCHAR ttl; + +# define IPPROTO_UDP 17 /* UDP protocol */ +# define IPPROTO_TCP 6 /* TCP protocol */ +# define IPPROTO_ICMP 1 /* ICMP protocol */ +# define IPPROTO_IGMP 2 /* IGMP protocol */ + UCHAR protocol; + + USHORT check; + ULONG saddr; + ULONG daddr; + /* The options start here. */ +} IPHDR; + +//----------- +// UDP header +//----------- + +typedef struct { + USHORT source; + USHORT dest; + USHORT len; + USHORT check; +} UDPHDR; + +//-------------------------- +// TCP header, per RFC 793. +//-------------------------- + +typedef struct { + USHORT source; /* source port */ + USHORT dest; /* destination port */ + ULONG seq; /* sequence number */ + ULONG ack_seq; /* acknowledgement number */ + +# define TCPH_GET_DOFF(d) (((d) & 0xF0) >> 2) + UCHAR doff_res; + +# define TCPH_FIN_MASK (1<<0) +# define TCPH_SYN_MASK (1<<1) +# define TCPH_RST_MASK (1<<2) +# define TCPH_PSH_MASK (1<<3) +# define TCPH_ACK_MASK (1<<4) +# define TCPH_URG_MASK (1<<5) +# define TCPH_ECE_MASK (1<<6) +# define TCPH_CWR_MASK (1<<7) + UCHAR flags; + + USHORT window; + USHORT check; + USHORT urg_ptr; +} TCPHDR; + +#define TCPOPT_EOL 0 +#define TCPOPT_NOP 1 +#define TCPOPT_MAXSEG 2 +#define TCPOLEN_MAXSEG 4 + +//------------ +// IPv6 Header +//------------ + +typedef struct { + UCHAR version_prio; + UCHAR flow_lbl[3]; + USHORT payload_len; +# define IPPROTO_ICMPV6 0x3a /* ICMP protocol v6 */ + UCHAR nexthdr; + UCHAR hop_limit; + IPV6ADDR saddr; + IPV6ADDR daddr; +} IPV6HDR; + +//-------------------------------------------- +// IPCMPv6 NS/NA Packets (RFC4443 and RFC4861) +//-------------------------------------------- + +// Neighbor Solictiation - RFC 4861, 4.3 +// (this is just the ICMPv6 part of the packet) +typedef struct { + UCHAR type; +# define ICMPV6_TYPE_NS 135 // neighbour solicitation + UCHAR code; +# define ICMPV6_CODE_0 0 // no specific sub-code for NS/NA + USHORT checksum; + ULONG reserved; + IPV6ADDR target_addr; +} ICMPV6_NS; + +// Neighbor Advertisement - RFC 4861, 4.4 + 4.6/4.6.1 +// (this is just the ICMPv6 payload) +typedef struct { + UCHAR type; +# define ICMPV6_TYPE_NA 136 // neighbour advertisement + UCHAR code; +# define ICMPV6_CODE_0 0 // no specific sub-code for NS/NA + USHORT checksum; + UCHAR rso_bits; // Router(0), Solicited(2), Ovrrd(4) + UCHAR reserved[3]; + IPV6ADDR target_addr; +// always include "Target Link-layer Address" option (RFC 4861 4.6.1) + UCHAR opt_type; +#define ICMPV6_OPTION_TLLA 2 + UCHAR opt_length; +#define ICMPV6_LENGTH_TLLA 1 // multiplied by 8 -> 1 = 8 bytes + MACADDR target_macaddr; +} ICMPV6_NA; + +// this is the complete packet with Ethernet and IPv6 headers +typedef struct { + ETH_HEADER eth; + IPV6HDR ipv6; + ICMPV6_NA icmpv6; +} ICMPV6_NA_PKT; + +#pragma pack() diff --git a/windows/TapDriver/prototypes.h b/windows/TapDriver/prototypes.h new file mode 100644 index 00000000..50cc4610 --- /dev/null +++ b/windows/TapDriver/prototypes.h @@ -0,0 +1,260 @@ +/* + * TAP-Windows -- A kernel driver to provide virtual tap + * device functionality on Windows. + * + * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. + * + * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., + * and is released under the GPL version 2 (see below). + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef TAP_PROTOTYPES_DEFINED +#define TAP_PROTOTYPES_DEFINED + +NTSTATUS DriverEntry + ( + IN PDRIVER_OBJECT p_DriverObject, + IN PUNICODE_STRING p_RegistryPath + ); + +VOID TapDriverUnload + ( + IN PDRIVER_OBJECT p_DriverObject + ); + +NDIS_STATUS AdapterCreate + ( + OUT PNDIS_STATUS p_ErrorStatus, + OUT PUINT p_MediaIndex, + IN PNDIS_MEDIUM p_Media, + IN UINT p_MediaCount, + IN NDIS_HANDLE p_AdapterHandle, + IN NDIS_HANDLE p_ConfigurationHandle + ); + +VOID AdapterHalt + ( + IN NDIS_HANDLE p_AdapterContext + ); + +VOID AdapterFreeResources + ( + TapAdapterPointer p_Adapter + ); + +NDIS_STATUS AdapterReset + ( + OUT PBOOLEAN p_AddressingReset, + IN NDIS_HANDLE p_AdapterContext + ); + +NDIS_STATUS AdapterQuery + ( + IN NDIS_HANDLE p_AdapterContext, + IN NDIS_OID p_OID, + IN PVOID p_Buffer, + IN ULONG p_BufferLength, + OUT PULONG p_BytesWritten, + OUT PULONG p_BytesNeeded + ); + +NDIS_STATUS AdapterModify + ( + IN NDIS_HANDLE p_AdapterContext, + IN NDIS_OID p_OID, + IN PVOID p_Buffer, + IN ULONG p_BufferLength, + OUT PULONG p_BytesRead, + OUT PULONG p_BytesNeeded + ); + +NDIS_STATUS AdapterTransmit + ( + IN NDIS_HANDLE p_AdapterContext, + IN PNDIS_PACKET p_Packet, + IN UINT p_Flags + ); + +NDIS_STATUS AdapterReceive + ( + OUT PNDIS_PACKET p_Packet, + OUT PUINT p_Transferred, + IN NDIS_HANDLE p_AdapterContext, + IN NDIS_HANDLE p_ReceiveContext, + IN UINT p_Offset, + IN UINT p_ToTransfer + ); + +NTSTATUS TapDeviceHook + ( + IN PDEVICE_OBJECT p_DeviceObject, + IN PIRP p_IRP + ); + +NDIS_STATUS CreateTapDevice + ( + TapExtensionPointer p_Extension, + const char *p_Name + ); + +VOID DestroyTapDevice + ( + TapExtensionPointer p_Extension + ); + +VOID TapDeviceFreeResources + ( + TapExtensionPointer p_Extension + ); + +NTSTATUS CompleteIRP + ( + IN PIRP p_IRP, + IN TapPacketPointer p_PacketBuffer, + IN CCHAR PriorityBoost + ); + +VOID CancelIRPCallback + ( + IN PDEVICE_OBJECT p_DeviceObject, + IN PIRP p_IRP + ); + +VOID CancelIRP + ( + TapExtensionPointer p_Extension, + IN PIRP p_IRP, + BOOLEAN callback + ); + +VOID FlushQueues + ( + TapExtensionPointer p_Extension + ); + +VOID ResetTapAdapterState + ( + TapAdapterPointer p_Adapter + ); + +BOOLEAN ProcessARP + ( + TapAdapterPointer p_Adapter, + const PARP_PACKET src, + const IPADDR adapter_ip, + const IPADDR ip_network, + const IPADDR ip_netmask, + const MACADDR mac + ); + +VOID SetMediaStatus + ( + TapAdapterPointer p_Adapter, + BOOLEAN state + ); + +VOID InjectPacketDeferred + ( + TapAdapterPointer p_Adapter, + UCHAR *packet, + const unsigned int len + ); + +VOID InjectPacketNow + ( + TapAdapterPointer p_Adapter, + UCHAR *packet, + const unsigned int len + ); + +// for KDEFERRED_ROUTINE and Static Driver Verifier +//#include +//KDEFERRED_ROUTINE InjectPacketDpc; + +VOID InjectPacketDpc + ( + KDPC *Dpc, + PVOID DeferredContext, + PVOID SystemArgument1, + PVOID SystemArgument2 + ); + +VOID CheckIfDhcpAndTunMode + ( + TapAdapterPointer p_Adapter + ); + +VOID HookDispatchFunctions(); + +#if ENABLE_NONADMIN + +#if defined(DDKVER_MAJOR) && DDKVER_MAJOR < 5600 +/* + * Better solution for use on Vista DDK, but possibly not compatible with + * earlier DDKs: + * + * Eliminate the definition of SECURITY_DESCRIPTOR (and even ZwSetSecurityObject), + * and at the top of tapdrv.c change: + * + * #include + * #include + * #include + * + * To + * + * #include + * #include + * #include + */ +typedef struct _SECURITY_DESCRIPTOR { + unsigned char opaque[64]; +} SECURITY_DESCRIPTOR; + +NTSYSAPI +NTSTATUS +NTAPI +ZwSetSecurityObject ( + IN HANDLE Handle, + IN SECURITY_INFORMATION SecurityInformation, + IN PSECURITY_DESCRIPTOR SecurityDescriptor); + +#endif + +VOID AllowNonAdmin (TapExtensionPointer p_Extension); + +#endif + +struct WIN2K_NDIS_MINIPORT_BLOCK +{ + unsigned char opaque[16]; + UNICODE_STRING MiniportName; // how mini-port refers to us +}; + +#if PACKET_TRUNCATION_CHECK + +VOID IPv4PacketSizeVerify + ( + const UCHAR *data, + ULONG length, + BOOLEAN tun, + const char *prefix, + LONG *counter + ); + +#endif + +#endif diff --git a/windows/TapDriver/tap-windows.h b/windows/TapDriver/tap-windows.h new file mode 100644 index 00000000..ff1baf17 --- /dev/null +++ b/windows/TapDriver/tap-windows.h @@ -0,0 +1,73 @@ +/* + * TAP-Windows -- A kernel driver to provide virtual tap + * device functionality on Windows. + * + * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. + * + * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., + * and is released under the GPL version 2 (see below). + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef __TAP_WIN_H +#define __TAP_WIN_H + +/* + * ============= + * TAP IOCTLs + * ============= + */ + +#define TAP_WIN_CONTROL_CODE(request,method) \ + CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS) + +/* Present in 8.1 */ + +#define TAP_WIN_IOCTL_GET_MAC TAP_WIN_CONTROL_CODE (1, METHOD_BUFFERED) +#define TAP_WIN_IOCTL_GET_VERSION TAP_WIN_CONTROL_CODE (2, METHOD_BUFFERED) +#define TAP_WIN_IOCTL_GET_MTU TAP_WIN_CONTROL_CODE (3, METHOD_BUFFERED) +#define TAP_WIN_IOCTL_GET_INFO TAP_WIN_CONTROL_CODE (4, METHOD_BUFFERED) +//#define TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT TAP_WIN_CONTROL_CODE (5, METHOD_BUFFERED) +#define TAP_WIN_IOCTL_SET_MEDIA_STATUS TAP_WIN_CONTROL_CODE (6, METHOD_BUFFERED) +//#define TAP_WIN_IOCTL_CONFIG_DHCP_MASQ TAP_WIN_CONTROL_CODE (7, METHOD_BUFFERED) +#define TAP_WIN_IOCTL_GET_LOG_LINE TAP_WIN_CONTROL_CODE (8, METHOD_BUFFERED) +//#define TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT TAP_WIN_CONTROL_CODE (9, METHOD_BUFFERED) + +/* Added in 8.2 */ + +/* obsoletes TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT */ +//#define TAP_WIN_IOCTL_CONFIG_TUN TAP_WIN_CONTROL_CODE (10, METHOD_BUFFERED) + +/* + * ================= + * Registry keys + * ================= + */ + +#define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}" +#define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}" + +/* + * ====================== + * Filesystem prefixes + * ====================== + */ + +#define USERMODEDEVICEDIR "\\\\.\\Global\\" +#define SYSDEVICEDIR "\\Device\\" +#define USERDEVICEDIR "\\DosDevices\\Global\\" +#define TAP_WIN_SUFFIX ".tap" + +#endif diff --git a/windows/TapDriver/tapdrvr.c b/windows/TapDriver/tapdrvr.c new file mode 100644 index 00000000..4781c872 --- /dev/null +++ b/windows/TapDriver/tapdrvr.c @@ -0,0 +1,3173 @@ +/* + * TAP-Windows -- A kernel driver to provide virtual tap + * device functionality on Windows. + * + * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. + * + * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., + * and is released under the GPL version 2 (see below). + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +//====================================================== +// This driver is designed to work on Win 2000 or higher +// versions of Windows. +// +// It is SMP-safe and handles NDIS 5 power management. +// +// By default we operate as a "tap" virtual ethernet +// 802.3 interface, but we can emulate a "tun" +// interface (point-to-point IPv4) through the +// TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT or +// TAP_WIN_IOCTL_CONFIG_TUN ioctl. +//====================================================== + +#include "tap-windows.h" +#include "config.h" + +#define NDIS_MINIPORT_DRIVER +#define BINARY_COMPATIBLE 0 +#define NDIS50_MINIPORT 1 +#define NDIS_WDM 0 +#define NDIS50 1 +#define NTSTRSAFE_LIB + +// Debug info output +#define ALSO_DBGPRINT 1 +#define DEBUGP_AT_DISPATCH 0 + +//======================================================== +// Check for truncated IPv4 packets, log errors if found. +//======================================================== +#define PACKET_TRUNCATION_CHECK 0 + +//======================================================== +// EXPERIMENTAL -- Configure TAP device object to be +// accessible from non-administrative accounts, based +// on an advanced properties setting. +// +// Duplicates the functionality of OpenVPN's +// --allow-nonadmin directive. +//======================================================== +//#define ENABLE_NONADMIN 1 + +#if defined(DDKVER_MAJOR) && DDKVER_MAJOR < 5600 +#include +#include +#include +#else +#include +#include +#include +#endif + +#include "lock.h" +#include "constants.h" +#include "proto.h" +#include "error.h" +#include "endian.h" +#include "dhcp.h" +#include "types.h" +#include "prototypes.h" + +#include "mem.c" +#include "macinfo.c" +#include "error.c" +#include "dhcp.c" +#include "instance.c" + +#define IS_UP(ta) \ + ((ta)->m_InterfaceIsRunning && (ta)->m_Extension.m_TapIsRunning) + +#define INCREMENT_STAT(s) ++(s) + +#define NAME_BUFFER_SIZE 80 + +//======================================================== +// Globals +//======================================================== + +NDIS_HANDLE g_NdisWrapperHandle; + +const UINT g_SupportedOIDList[] = { + OID_GEN_HARDWARE_STATUS, + OID_GEN_MEDIA_SUPPORTED, + OID_GEN_MEDIA_IN_USE, + OID_GEN_MAXIMUM_LOOKAHEAD, + OID_GEN_MAC_OPTIONS, + OID_GEN_LINK_SPEED, + OID_GEN_TRANSMIT_BLOCK_SIZE, + OID_GEN_RECEIVE_BLOCK_SIZE, + OID_GEN_VENDOR_DESCRIPTION, + OID_GEN_DRIVER_VERSION, + OID_GEN_XMIT_OK, + OID_GEN_RCV_OK, + OID_GEN_XMIT_ERROR, + OID_GEN_RCV_ERROR, + OID_802_3_PERMANENT_ADDRESS, + OID_802_3_CURRENT_ADDRESS, + OID_GEN_RCV_NO_BUFFER, + OID_802_3_RCV_ERROR_ALIGNMENT, + OID_802_3_XMIT_ONE_COLLISION, + OID_802_3_XMIT_MORE_COLLISIONS, + OID_802_3_MULTICAST_LIST, + OID_802_3_MAXIMUM_LIST_SIZE, + OID_GEN_VENDOR_ID, + OID_GEN_CURRENT_LOOKAHEAD, + OID_GEN_CURRENT_PACKET_FILTER, + OID_GEN_PROTOCOL_OPTIONS, + OID_GEN_MAXIMUM_TOTAL_SIZE, + OID_GEN_TRANSMIT_BUFFER_SPACE, + OID_GEN_RECEIVE_BUFFER_SPACE, + OID_GEN_MAXIMUM_FRAME_SIZE, + OID_GEN_VENDOR_DRIVER_VERSION, + OID_GEN_MAXIMUM_SEND_PACKETS, + OID_GEN_MEDIA_CONNECT_STATUS, + OID_GEN_SUPPORTED_LIST +}; + +//============================================================ +// Driver Entry +//============================================================ +#pragma NDIS_INIT_FUNCTION (DriverEntry) + +DRIVER_INITIALIZE DriverEntry; +NTSTATUS +DriverEntry (IN PDRIVER_OBJECT p_DriverObject, + IN PUNICODE_STRING p_RegistryPath) +{ + NDIS_STATUS l_Status = NDIS_STATUS_FAILURE; + NDIS_MINIPORT_CHARACTERISTICS *l_Properties = NULL; + + //======================================================== + // Notify NDIS that a new miniport driver is initializing. + //======================================================== + + NdisMInitializeWrapper (&g_NdisWrapperHandle, + p_DriverObject, + p_RegistryPath, NULL); + + //====================== + // Global initialization + //====================== + +#if DBG + MyDebugInit (10000); // Allocate debugging text space +#endif + + if (!InitInstanceList ()) + { + DEBUGP (("[TAP] Allocation failed for adapter instance list\n")); + goto cleanup; + } + + //======================================= + // Set and register miniport entry points + //======================================= + + l_Properties = MemAlloc (sizeof (NDIS_MINIPORT_CHARACTERISTICS), TRUE); + + if (l_Properties == NULL) + { + DEBUGP (("[TAP] Allocation failed for miniport entry points\n")); + goto cleanup; + } + + l_Properties->MajorNdisVersion = TAP_NDIS_MAJOR_VERSION; + l_Properties->MinorNdisVersion = TAP_NDIS_MINOR_VERSION; + l_Properties->InitializeHandler = AdapterCreate; + l_Properties->HaltHandler = AdapterHalt; + l_Properties->ResetHandler = AdapterReset; /* DISPATCH_LEVEL */ + l_Properties->TransferDataHandler = AdapterReceive; /* DISPATCH_LEVEL */ + l_Properties->SendHandler = AdapterTransmit; /* DISPATCH_LEVEL */ + l_Properties->QueryInformationHandler = AdapterQuery; /* DISPATCH_LEVEL */ + l_Properties->SetInformationHandler = AdapterModify; /* DISPATCH_LEVEL */ + + switch (l_Status = + NdisMRegisterMiniport (g_NdisWrapperHandle, l_Properties, + sizeof (NDIS_MINIPORT_CHARACTERISTICS))) + { + case NDIS_STATUS_SUCCESS: + { + DEBUGP (("[TAP] version [%d.%d] %s %s registered miniport successfully\n", + TAP_DRIVER_MAJOR_VERSION, + TAP_DRIVER_MINOR_VERSION, + __DATE__, + __TIME__)); + DEBUGP (("Registry Path: '%.*S'\n", p_RegistryPath->Length/2, p_RegistryPath->Buffer)); + break; + } + + case NDIS_STATUS_BAD_CHARACTERISTICS: + { + DEBUGP (("[TAP] Miniport characteristics were badly defined\n")); + NdisTerminateWrapper (g_NdisWrapperHandle, NULL); + break; + } + + case NDIS_STATUS_BAD_VERSION: + { + DEBUGP + (("[TAP] NDIS Version is wrong for the given characteristics\n")); + NdisTerminateWrapper (g_NdisWrapperHandle, NULL); + break; + } + + case NDIS_STATUS_RESOURCES: + { + DEBUGP (("[TAP] Insufficient resources\n")); + NdisTerminateWrapper (g_NdisWrapperHandle, NULL); + break; + } + + default: + case NDIS_STATUS_FAILURE: + { + DEBUGP (("[TAP] Unknown fatal registration error\n")); + NdisTerminateWrapper (g_NdisWrapperHandle, NULL); + break; + } + } + + cleanup: + if (l_Properties) + MemFree (l_Properties, sizeof (NDIS_MINIPORT_CHARACTERISTICS)); + + if (l_Status == NDIS_STATUS_SUCCESS) + NdisMRegisterUnloadHandler (g_NdisWrapperHandle, TapDriverUnload); + else + TapDriverUnload (p_DriverObject); + + return l_Status; +} + +//============================================================ +// Driver Unload +//============================================================ +DRIVER_UNLOAD TapDriverUnload; +VOID +TapDriverUnload (IN PDRIVER_OBJECT p_DriverObject) +{ + DEBUGP (("[TAP] version [%d.%d] %s %s unloaded, instances=%d, imbs=%d\n", + TAP_DRIVER_MAJOR_VERSION, + TAP_DRIVER_MINOR_VERSION, + __DATE__, + __TIME__, + NInstances(), + InstanceMaxBucketSize())); + + FreeInstanceList (); + + //============================== + // Free debugging text space + //============================== +#if DBG + MyDebugFree (); +#endif +} + +//========================================================== +// Adapter Initialization +//========================================================== +NDIS_STATUS AdapterCreate +(OUT PNDIS_STATUS p_ErrorStatus, + OUT PUINT p_MediaIndex, + IN PNDIS_MEDIUM p_Media, + IN UINT p_MediaCount, + IN NDIS_HANDLE p_AdapterHandle, + IN NDIS_HANDLE p_ConfigurationHandle) +{ + TapAdapterPointer l_Adapter = NULL; + + NDIS_MEDIUM l_PreferredMedium = NdisMedium802_3; // Ethernet + BOOLEAN l_MacFromRegistry = FALSE; + UINT l_Index; + NDIS_STATUS status; + +#if ENABLE_NONADMIN + BOOLEAN enable_non_admin = FALSE; +#endif + + DEBUGP (("[TAP] AdapterCreate called\n")); + + //==================================== + // Make sure adapter type is supported + //==================================== + + for (l_Index = 0; + l_Index < p_MediaCount && p_Media[l_Index] != l_PreferredMedium; + ++l_Index); + + if (l_Index == p_MediaCount) + { + DEBUGP (("[TAP] Unsupported adapter type [wanted: %d]\n", + l_PreferredMedium)); + return NDIS_STATUS_UNSUPPORTED_MEDIA; + } + + *p_MediaIndex = l_Index; + + //========================================= + // Allocate memory for TapAdapter structure + //========================================= + + l_Adapter = MemAlloc (sizeof (TapAdapter), TRUE); + + if (l_Adapter == NULL) + { + DEBUGP (("[TAP] Couldn't allocate adapter memory\n")); + return NDIS_STATUS_RESOURCES; + } + + //========================================== + // Inform the NDIS library about significant + // features of our virtual NIC. + //========================================== + + NdisMSetAttributesEx + (p_AdapterHandle, + (NDIS_HANDLE) l_Adapter, + 16, + NDIS_ATTRIBUTE_DESERIALIZE + | NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT + | NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT + | NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND, + NdisInterfaceInternal); + + //===================================== + // Initialize simple Adapter parameters + //===================================== + + l_Adapter->m_Lookahead = DEFAULT_PACKET_LOOKAHEAD; + l_Adapter->m_Medium = l_PreferredMedium; + l_Adapter->m_DeviceState = '?'; + l_Adapter->m_MiniportAdapterHandle = p_AdapterHandle; + + //================================== + // Allocate spinlock for controlling + // access to multicast address list. + //================================== + NdisAllocateSpinLock (&l_Adapter->m_MCLock); + l_Adapter->m_MCLockAllocated = TRUE; + + //==================================================== + // Register a shutdown handler which will be called + // on system restart/shutdown to halt our virtual NIC. + //==================================================== + + NdisMRegisterAdapterShutdownHandler (p_AdapterHandle, l_Adapter, + AdapterHalt); + l_Adapter->m_RegisteredAdapterShutdownHandler = TRUE; + + //============================================ + // Get parameters from registry which were set + // in the adapter advanced properties dialog. + //============================================ + { + NDIS_STATUS status; + NDIS_HANDLE configHandle; + NDIS_CONFIGURATION_PARAMETER *parm; + + // set defaults in case our registry query fails + l_Adapter->m_MTU = ETHERNET_MTU; + l_Adapter->m_MediaStateAlwaysConnected = FALSE; + l_Adapter->m_MediaState = FALSE; + + NdisOpenConfiguration (&status, &configHandle, p_ConfigurationHandle); + if (status != NDIS_STATUS_SUCCESS) + { + DEBUGP (("[TAP] Couldn't open adapter registry\n")); + AdapterFreeResources (l_Adapter); + return status; + } + + //==================================== + // Allocate and construct adapter name + //==================================== + { + + NDIS_STRING mkey = NDIS_STRING_CONST("MiniportName"); + NDIS_STRING vkey = NDIS_STRING_CONST("NdisVersion"); + NDIS_STATUS vstatus; + NDIS_CONFIGURATION_PARAMETER *vparm; + + NdisReadConfiguration (&vstatus, &vparm, configHandle, &vkey, NdisParameterInteger); + if (vstatus == NDIS_STATUS_SUCCESS) + DEBUGP (("[TAP] NdisReadConfiguration NdisVersion=%X\n", vparm->ParameterData.IntegerData)); + + NdisReadConfiguration (&status, &parm, configHandle, &mkey, NdisParameterString); + if (status == NDIS_STATUS_SUCCESS) + { + if (parm->ParameterType == NdisParameterString) + { + DEBUGP (("[TAP] NdisReadConfiguration (MiniportName=%.*S)\n", + parm->ParameterData.StringData.Length/2, + parm->ParameterData.StringData.Buffer)); + + if (RtlUnicodeStringToAnsiString ( + &l_Adapter->m_NameAnsi, + &parm->ParameterData.StringData, + TRUE) != STATUS_SUCCESS) + { + DEBUGP (("[TAP] MiniportName failed\n")); + status = NDIS_STATUS_RESOURCES; + } + } + } + else + { + /* "MiniportName" is available only XP and above. Not on Windows 2000. */ + if (vstatus == NDIS_STATUS_SUCCESS && vparm->ParameterData.IntegerData == 0x50000) + { + /* Fallback for Windows 2000 with NDIS version 5.00.00 + Don't use this on Vista, 'NDIS_MINIPORT_BLOCK' was changed! */ + if (RtlUnicodeStringToAnsiString (&l_Adapter->m_NameAnsi, + &((struct WIN2K_NDIS_MINIPORT_BLOCK *) p_AdapterHandle)->MiniportName, + TRUE) != STATUS_SUCCESS) + { + DEBUGP (("[TAP] MiniportName (W2K) failed\n")); + status = NDIS_STATUS_RESOURCES; + } + else + { + DEBUGP (("[TAP] MiniportName (W2K) succeeded: %s\n", l_Adapter->m_NameAnsi.Buffer)); + status = NDIS_STATUS_SUCCESS; + } + } + } + } + + /* Can't continue without name (see macro 'NAME') */ + if (status != NDIS_STATUS_SUCCESS || !l_Adapter->m_NameAnsi.Buffer) + { + NdisCloseConfiguration (configHandle); + AdapterFreeResources (l_Adapter); + DEBUGP (("[TAP] failed to get miniport name\n")); + return NDIS_STATUS_RESOURCES; + } + + /* Read MTU setting from registry */ + { + NDIS_STRING key = NDIS_STRING_CONST("MTU"); + NdisReadConfiguration (&status, &parm, configHandle, + &key, NdisParameterInteger); + if (status == NDIS_STATUS_SUCCESS) + { + if (parm->ParameterType == NdisParameterInteger) + { + int mtu = parm->ParameterData.IntegerData; + if (mtu < MINIMUM_MTU) + mtu = MINIMUM_MTU; + if (mtu > MAXIMUM_MTU) + mtu = MAXIMUM_MTU; + l_Adapter->m_MTU = mtu; + } + } + } + + /* Read Media Status setting from registry */ + { + NDIS_STRING key = NDIS_STRING_CONST("MediaStatus"); + NdisReadConfiguration (&status, &parm, configHandle, + &key, NdisParameterInteger); + if (status == NDIS_STATUS_SUCCESS) + { + if (parm->ParameterType == NdisParameterInteger) + { + if (parm->ParameterData.IntegerData) + { + l_Adapter->m_MediaStateAlwaysConnected = TRUE; + l_Adapter->m_MediaState = TRUE; + } + } + } + } + +#if ENABLE_NONADMIN + /* Read AllowNonAdmin setting from registry */ + { + NDIS_STRING key = NDIS_STRING_CONST("AllowNonAdmin"); + NdisReadConfiguration (&status, &parm, configHandle, + &key, NdisParameterInteger); + if (status == NDIS_STATUS_SUCCESS) + { + if (parm->ParameterType == NdisParameterInteger) + { + if (parm->ParameterData.IntegerData) + { + enable_non_admin = TRUE; + } + } + } + } +#endif + + /* Read optional MAC setting from registry */ + { + NDIS_STRING key = NDIS_STRING_CONST("MAC"); + ANSI_STRING mac_string; + NdisReadConfiguration (&status, &parm, configHandle, + &key, NdisParameterString); + if (status == NDIS_STATUS_SUCCESS) + { + if (parm->ParameterType == NdisParameterString) + { + if (RtlUnicodeStringToAnsiString (&mac_string, &parm->ParameterData.StringData, TRUE) == STATUS_SUCCESS) + { + l_MacFromRegistry = ParseMAC (l_Adapter->m_MAC, mac_string.Buffer); + RtlFreeAnsiString (&mac_string); + } + } + } + } + + NdisCloseConfiguration (configHandle); + + DEBUGP (("[%s] MTU=%d\n", NAME (l_Adapter), l_Adapter->m_MTU)); + } + + //================================== + // Store and update MAC address info + //================================== + + if (!l_MacFromRegistry) + GenerateRandomMac (l_Adapter->m_MAC, NAME (l_Adapter)); + + DEBUGP (("[%s] Using MAC %x:%x:%x:%x:%x:%x\n", + NAME (l_Adapter), + l_Adapter->m_MAC[0], l_Adapter->m_MAC[1], l_Adapter->m_MAC[2], + l_Adapter->m_MAC[3], l_Adapter->m_MAC[4], l_Adapter->m_MAC[5])); + +#if 0 + //================== + // Set broadcast MAC + //================== + { + int i; + for (i = 0; i < sizeof (MACADDR); ++i) + l_Adapter->m_MAC_Broadcast[i] = 0xFF; + } +#endif + + //==================================== + // Initialize TAP device + //==================================== + { + NDIS_STATUS tap_status; + tap_status = CreateTapDevice (&l_Adapter->m_Extension, NAME (l_Adapter)); + if (tap_status != NDIS_STATUS_SUCCESS) + { + AdapterFreeResources (l_Adapter); + DEBUGP (("[TAP] CreateTapDevice failed\n")); + return tap_status; + } + } + + if (!AddAdapterToInstanceList (l_Adapter)) + { + NOTE_ERROR (); + TapDeviceFreeResources (&l_Adapter->m_Extension); + AdapterFreeResources (l_Adapter); + DEBUGP (("[TAP] AddAdapterToInstanceList failed\n")); + return NDIS_STATUS_RESOURCES; + } + + l_Adapter->m_InterfaceIsRunning = TRUE; + +#if ENABLE_NONADMIN + if (enable_non_admin) + AllowNonAdmin (&l_Adapter->m_Extension); +#endif + + return NDIS_STATUS_SUCCESS; +} + +VOID +AdapterHalt (IN NDIS_HANDLE p_AdapterContext) +{ + BOOLEAN status; + + TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext; + + NOTE_ERROR (); + + l_Adapter->m_InterfaceIsRunning = FALSE; + + DEBUGP (("[%s] is being halted\n", NAME (l_Adapter))); + + DestroyTapDevice (&l_Adapter->m_Extension); + + // Free resources + DEBUGP (("[%s] Freeing Resources\n", NAME (l_Adapter))); + AdapterFreeResources (l_Adapter); + + status = RemoveAdapterFromInstanceList (l_Adapter); + DEBUGP (("[TAP] RemoveAdapterFromInstanceList returned %d\n", (int) status)); + + DEBUGP (("[TAP] version [%d.%d] %s %s AdapterHalt returning\n", + TAP_DRIVER_MAJOR_VERSION, + TAP_DRIVER_MINOR_VERSION, + __DATE__, + __TIME__)); +} + +VOID +AdapterFreeResources (TapAdapterPointer p_Adapter) +{ + MYASSERT (!p_Adapter->m_CalledAdapterFreeResources); + p_Adapter->m_CalledAdapterFreeResources = TRUE; + + if (p_Adapter->m_NameAnsi.Buffer) + RtlFreeAnsiString (&p_Adapter->m_NameAnsi); + + if (p_Adapter->m_RegisteredAdapterShutdownHandler) + NdisMDeregisterAdapterShutdownHandler (p_Adapter->m_MiniportAdapterHandle); + + if (p_Adapter->m_MCLockAllocated) + NdisFreeSpinLock (&p_Adapter->m_MCLock); +} + +VOID +DestroyTapDevice (TapExtensionPointer p_Extension) +{ + DEBUGP (("[%s] Destroying tap device\n", p_Extension->m_TapName)); + + //====================================== + // Let clients know we are shutting down + //====================================== + p_Extension->m_TapIsRunning = FALSE; + p_Extension->m_TapOpens = 0; + p_Extension->m_Halt = TRUE; + + //===================================== + // If we are concurrently executing in + // TapDeviceHook or AdapterTransmit, + // give those calls time to finish. + // Note that we must be running at IRQL + // < DISPATCH_LEVEL in order to call + // NdisMSleep. + //===================================== + NdisMSleep (500000); + + //=========================================================== + // Exhaust IRP and packet queues. Any pending IRPs will + // be cancelled, causing user-space to get this error + // on overlapped reads: + // The I/O operation has been aborted because of either a + // thread exit or an application request. (code=995) + // It's important that user-space close the device handle + // when this code is returned, so that when we finally + // do a NdisMDeregisterDevice, the device reference count + // is 0. Otherwise the driver will not unload even if the + // the last adapter has been halted. + //=========================================================== + FlushQueues (p_Extension); + NdisMSleep (500000); // give user space time to respond to IRP cancel + + TapDeviceFreeResources (p_Extension); +} + +VOID +TapDeviceFreeResources (TapExtensionPointer p_Extension) +{ + MYASSERT (p_Extension); + MYASSERT (!p_Extension->m_CalledTapDeviceFreeResources); + p_Extension->m_CalledTapDeviceFreeResources = TRUE; + + if (p_Extension->m_PacketQueue) + QueueFree (p_Extension->m_PacketQueue); + if (p_Extension->m_IrpQueue) + QueueFree (p_Extension->m_IrpQueue); + if (p_Extension->m_InjectQueue) + QueueFree (p_Extension->m_InjectQueue); + + if (p_Extension->m_CreatedUnicodeLinkName) + RtlFreeUnicodeString (&p_Extension->m_UnicodeLinkName); + + //========================================================== + // According to DDK docs, the device is not actually deleted + // until its reference count falls to zero. That means we + // still need to gracefully fail TapDeviceHook requests + // after this point, otherwise ugly things would happen if + // the device was disabled (e.g. in the network connections + // control panel) while a userspace app still held an open + // file handle to it. + //========================================================== + + if (p_Extension->m_TapDevice) + { + BOOLEAN status; + status = (NdisMDeregisterDevice (p_Extension->m_TapDeviceHandle) + == NDIS_STATUS_SUCCESS); + DEBUGP (("[TAP] Deregistering TAP device, status=%d\n", (int)status)); + } + + if (p_Extension->m_TapName) + MemFree (p_Extension->m_TapName, NAME_BUFFER_SIZE); + + if (p_Extension->m_InjectDpcInitialized) + KeRemoveQueueDpc (&p_Extension->m_InjectDpc); + + if (p_Extension->m_AllocatedSpinlocks) + { + NdisFreeSpinLock (&p_Extension->m_QueueLock); + NdisFreeSpinLock (&p_Extension->m_InjectLock); + } +} + +//======================================================================== +// Tap Device Initialization +//======================================================================== + +NDIS_STATUS +CreateTapDevice (TapExtensionPointer p_Extension, const char *p_Name) +{ +# define SIZEOF_DISPATCH (sizeof(PDRIVER_DISPATCH) * (IRP_MJ_MAXIMUM_FUNCTION + 1)) + PDRIVER_DISPATCH *l_Dispatch = NULL; + ANSI_STRING l_TapString, l_LinkString; + UNICODE_STRING l_TapUnicode; + BOOLEAN l_FreeTapUnicode = FALSE; + NTSTATUS l_Status, l_Return = NDIS_STATUS_SUCCESS; + const char *l_UsableName; + + DEBUGP (("[TAP] version [%d.%d] creating tap device: %s\n", + TAP_DRIVER_MAJOR_VERSION, + TAP_DRIVER_MINOR_VERSION, + p_Name)); + + NdisZeroMemory (p_Extension, sizeof (TapExtension)); + + INIT_MUTEX (&p_Extension->m_OpenCloseMutex); + + l_LinkString.Buffer = NULL; + l_TapString.Buffer = NULL; + + l_TapString.MaximumLength = l_LinkString.MaximumLength = NAME_BUFFER_SIZE; + + //======================================= + // Set TAP device entry points + //======================================= + + if ((l_Dispatch = MemAlloc (SIZEOF_DISPATCH, TRUE)) == NULL) + { + DEBUGP (("[%s] couldn't alloc TAP dispatch table\n", p_Name)); + l_Return = NDIS_STATUS_RESOURCES; + goto cleanup; + } + + l_Dispatch[IRP_MJ_DEVICE_CONTROL] = TapDeviceHook; + l_Dispatch[IRP_MJ_READ] = TapDeviceHook; + l_Dispatch[IRP_MJ_WRITE] = TapDeviceHook; + l_Dispatch[IRP_MJ_CREATE] = TapDeviceHook; + l_Dispatch[IRP_MJ_CLOSE] = TapDeviceHook; + + //================================== + // Find the beginning of the GUID + //================================== + l_UsableName = p_Name; + while (*l_UsableName != '{') + { + if (*l_UsableName == '\0') + { + DEBUGP (("[%s] couldn't find leading '{' in name\n", p_Name)); + l_Return = NDIS_STATUS_RESOURCES; + goto cleanup; + } + ++l_UsableName; + } + + //================================== + // Allocate pool for TAP device name + //================================== + + if ((p_Extension->m_TapName = l_TapString.Buffer = + MemAlloc (NAME_BUFFER_SIZE, TRUE)) == NULL) + { + DEBUGP (("[%s] couldn't alloc TAP name buffer\n", p_Name)); + l_Return = NDIS_STATUS_RESOURCES; + goto cleanup; + } + + //================================================ + // Allocate pool for TAP symbolic link name buffer + //================================================ + + if ((l_LinkString.Buffer = + MemAlloc (NAME_BUFFER_SIZE, TRUE)) == NULL) + { + DEBUGP (("[%s] couldn't alloc TAP symbolic link name buffer\n", + p_Name)); + l_Return = NDIS_STATUS_RESOURCES; + goto cleanup; + } + + //======================================================= + // Set TAP device name + //======================================================= + + l_Status = RtlStringCchPrintfExA + (l_TapString.Buffer, + l_TapString.MaximumLength, + NULL, + NULL, + STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS, + "%s%s%s", + SYSDEVICEDIR, + l_UsableName, + TAP_WIN_SUFFIX); + + if (l_Status != STATUS_SUCCESS) + { + DEBUGP (("[%s] couldn't format TAP device name\n", + p_Name)); + l_Return = NDIS_STATUS_RESOURCES; + goto cleanup; + } + l_TapString.Length = (USHORT) strlen (l_TapString.Buffer); + + DEBUGP (("TAP DEV NAME: '%s'\n", l_TapString.Buffer)); + + //======================================================= + // Set TAP link name + //======================================================= + + l_Status = RtlStringCchPrintfExA + (l_LinkString.Buffer, + l_LinkString.MaximumLength, + NULL, + NULL, + STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS, + "%s%s%s", + USERDEVICEDIR, + l_UsableName, + TAP_WIN_SUFFIX); + + if (l_Status != STATUS_SUCCESS) + { + DEBUGP (("[%s] couldn't format TAP device symbolic link\n", + p_Name)); + l_Return = NDIS_STATUS_RESOURCES; + goto cleanup; + } + l_LinkString.Length = (USHORT) strlen (l_LinkString.Buffer); + + DEBUGP (("TAP LINK NAME: '%s'\n", l_LinkString.Buffer)); + + //================================================== + // Convert strings to unicode + //================================================== + if (RtlAnsiStringToUnicodeString (&l_TapUnicode, &l_TapString, TRUE) != + STATUS_SUCCESS) + { + DEBUGP (("[%s] couldn't alloc TAP unicode name buffer\n", + p_Name)); + l_Return = NDIS_STATUS_RESOURCES; + goto cleanup; + } + l_FreeTapUnicode = TRUE; + + if (RtlAnsiStringToUnicodeString + (&p_Extension->m_UnicodeLinkName, &l_LinkString, TRUE) + != STATUS_SUCCESS) + { + DEBUGP + (("[%s] Couldn't allocate unicode string for symbolic link name\n", + p_Name)); + l_Return = NDIS_STATUS_RESOURCES; + goto cleanup; + } + p_Extension->m_CreatedUnicodeLinkName = TRUE; + + //================================================== + // Create new TAP device with symbolic + // link and associate with adapter. + //================================================== + + l_Status = NdisMRegisterDevice + (g_NdisWrapperHandle, + &l_TapUnicode, + &p_Extension->m_UnicodeLinkName, + l_Dispatch, + &p_Extension->m_TapDevice, + &p_Extension->m_TapDeviceHandle + ); + + if (l_Status != STATUS_SUCCESS) + { + DEBUGP (("[%s] couldn't be created\n", p_Name)); + l_Return = NDIS_STATUS_RESOURCES; + goto cleanup; + } + + /* Set TAP device flags */ + p_Extension->m_TapDevice->Flags |= DO_DIRECT_IO; + + //======================================================== + // Initialize Packet and IRP queues. + // + // The packet queue is used to buffer data which has been + // "transmitted" by the virtual NIC, before user space + // has had a chance to read it. + // + // The IRP queue is used to buffer pending I/O requests + // from userspace, i.e. read requests on the TAP device + // waiting for the system to "transmit" something through + // the virtual NIC. + // + // Basically, packets in the packet queue are used + // to satisfy IRP requests in the IRP queue. + // + // QueueLock is used to lock the packet queue used + // for the TAP-Windows NIC -> User Space packet flow direction. + // + // All accesses to packet or IRP queues should be + // bracketed by the QueueLock spinlock, + // in order to be SMP-safe. + //======================================================== + + NdisAllocateSpinLock (&p_Extension->m_QueueLock); + NdisAllocateSpinLock (&p_Extension->m_InjectLock); + p_Extension->m_AllocatedSpinlocks = TRUE; + + p_Extension->m_PacketQueue = QueueInit (PACKET_QUEUE_SIZE); + p_Extension->m_IrpQueue = QueueInit (IRP_QUEUE_SIZE); + p_Extension->m_InjectQueue = QueueInit (INJECT_QUEUE_SIZE); + if (!p_Extension->m_PacketQueue + || !p_Extension->m_IrpQueue + || !p_Extension->m_InjectQueue) + { + DEBUGP (("[%s] couldn't alloc TAP queues\n", p_Name)); + l_Return = NDIS_STATUS_RESOURCES; + goto cleanup; + } + + //================================================================= + // Initialize deferred procedure call for DHCP/ARP packet injection + //================================================================= + + KeInitializeDpc (&p_Extension->m_InjectDpc, InjectPacketDpc, NULL); + p_Extension->m_InjectDpcInitialized = TRUE; + + //======================== + // Finalize initialization + //======================== + + p_Extension->m_TapIsRunning = TRUE; + + DEBUGP (("[%s] successfully created TAP device [%s]\n", p_Name, + p_Extension->m_TapName)); + + cleanup: + if (l_FreeTapUnicode) + RtlFreeUnicodeString (&l_TapUnicode); + if (l_LinkString.Buffer) + MemFree (l_LinkString.Buffer, NAME_BUFFER_SIZE); + if (l_Dispatch) + MemFree (l_Dispatch, SIZEOF_DISPATCH); + + if (l_Return != NDIS_STATUS_SUCCESS) + TapDeviceFreeResources (p_Extension); + + return l_Return; +} +#undef SIZEOF_DISPATCH + +//======================================================== +// Adapter Control +//======================================================== +NDIS_STATUS +AdapterReset (OUT PBOOLEAN p_AddressingReset, IN NDIS_HANDLE p_AdapterContext) +{ + TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext; + DEBUGP (("[%s] is resetting\n", NAME (l_Adapter))); + return NDIS_STATUS_SUCCESS; +} + +NDIS_STATUS AdapterReceive + (OUT PNDIS_PACKET p_Packet, + OUT PUINT p_Transferred, + IN NDIS_HANDLE p_AdapterContext, + IN NDIS_HANDLE p_ReceiveContext, + IN UINT p_Offset, + IN UINT p_ToTransfer) +{ + return NDIS_STATUS_SUCCESS; +} + +//============================================================== +// Adapter Option Query/Modification +//============================================================== +NDIS_STATUS AdapterQuery +(IN NDIS_HANDLE p_AdapterContext, + IN NDIS_OID p_OID, + IN PVOID p_Buffer, + IN ULONG p_BufferLength, + OUT PULONG p_BytesWritten, OUT PULONG p_BytesNeeded) +{ + TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext; + TapAdapterQuery l_Query, *l_QueryPtr = &l_Query; + NDIS_STATUS l_Status = NDIS_STATUS_SUCCESS; + UINT l_QueryLength = 4; + BOOLEAN lock_succeeded; + + NdisZeroMemory (&l_Query, sizeof (l_Query)); + + switch (p_OID) + { + //=================================================================== + // Vendor & Driver version Info + //=================================================================== + case OID_GEN_VENDOR_DESCRIPTION: + l_QueryPtr = (TapAdapterQueryPointer) PRODUCT_TAP_WIN_DEVICE_DESCRIPTION; + l_QueryLength = strlen (PRODUCT_TAP_WIN_DEVICE_DESCRIPTION) + 1; + break; + + case OID_GEN_VENDOR_ID: + l_Query.m_Long = 0xffffff; + break; + + case OID_GEN_DRIVER_VERSION: + l_Query.m_Short = + (((USHORT) TAP_NDIS_MAJOR_VERSION) << 8 | (USHORT) + TAP_NDIS_MINOR_VERSION); + l_QueryLength = sizeof (unsigned short); + break; + + case OID_GEN_VENDOR_DRIVER_VERSION: + l_Query.m_Long = + (((USHORT) PRODUCT_TAP_WIN_MAJOR) << 8 | (USHORT) + PRODUCT_TAP_WIN_MINOR); + break; + + //================================================================= + // Statistics + //================================================================= + case OID_GEN_RCV_NO_BUFFER: + l_Query.m_Long = 0; + break; + + case OID_802_3_RCV_ERROR_ALIGNMENT: + l_Query.m_Long = 0; + break; + + case OID_802_3_XMIT_ONE_COLLISION: + l_Query.m_Long = 0; + break; + + case OID_802_3_XMIT_MORE_COLLISIONS: + l_Query.m_Long = 0; + break; + + case OID_GEN_XMIT_OK: + l_Query.m_Long = l_Adapter->m_Tx; + break; + + case OID_GEN_RCV_OK: + l_Query.m_Long = l_Adapter->m_Rx; + break; + + case OID_GEN_XMIT_ERROR: + l_Query.m_Long = l_Adapter->m_TxErr; + break; + + case OID_GEN_RCV_ERROR: + l_Query.m_Long = l_Adapter->m_RxErr; + break; + + //=================================================================== + // Device & Protocol Options + //=================================================================== + case OID_GEN_SUPPORTED_LIST: + l_QueryPtr = (TapAdapterQueryPointer) g_SupportedOIDList; + l_QueryLength = sizeof (g_SupportedOIDList); + break; + + case OID_GEN_MAC_OPTIONS: + // This MUST be here !!! + l_Query.m_Long = (NDIS_MAC_OPTION_RECEIVE_SERIALIZED + | NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA + | NDIS_MAC_OPTION_NO_LOOPBACK + | NDIS_MAC_OPTION_TRANSFERS_NOT_PEND); + + break; + + case OID_GEN_CURRENT_PACKET_FILTER: + l_Query.m_Long = + (NDIS_PACKET_TYPE_ALL_LOCAL | + NDIS_PACKET_TYPE_BROADCAST | + NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_ALL_FUNCTIONAL); + + break; + + case OID_GEN_PROTOCOL_OPTIONS: + l_Query.m_Long = 0; + break; + + //================================================================== + // Device Info + //================================================================== + case OID_GEN_MEDIA_CONNECT_STATUS: + l_Query.m_Long = l_Adapter->m_MediaState + ? NdisMediaStateConnected : NdisMediaStateDisconnected; + break; + + case OID_GEN_HARDWARE_STATUS: + l_Query.m_HardwareStatus = NdisHardwareStatusReady; + l_QueryLength = sizeof (NDIS_HARDWARE_STATUS); + break; + + case OID_GEN_MEDIA_SUPPORTED: + case OID_GEN_MEDIA_IN_USE: + l_Query.m_Medium = l_Adapter->m_Medium; + l_QueryLength = sizeof (NDIS_MEDIUM); + break; + + case OID_GEN_PHYSICAL_MEDIUM: + l_Query.m_PhysicalMedium = NdisPhysicalMediumUnspecified; + l_QueryLength = sizeof (NDIS_PHYSICAL_MEDIUM); + break; + + case OID_GEN_LINK_SPEED: + l_Query.m_Long = 100000; // rate / 100 bps + break; + + case OID_802_3_PERMANENT_ADDRESS: + case OID_802_3_CURRENT_ADDRESS: + COPY_MAC (l_Query.m_MacAddress, l_Adapter->m_MAC); + l_QueryLength = sizeof (MACADDR); + break; + + //================================================================== + // Limits + //================================================================== + + case OID_GEN_MAXIMUM_SEND_PACKETS: + l_Query.m_Long = 1; + break; + + case OID_802_3_MAXIMUM_LIST_SIZE: + l_Query.m_Long = NIC_MAX_MCAST_LIST; + break; + + case OID_GEN_CURRENT_LOOKAHEAD: + l_Query.m_Long = l_Adapter->m_Lookahead; + break; + + case OID_GEN_MAXIMUM_LOOKAHEAD: + case OID_GEN_MAXIMUM_TOTAL_SIZE: + case OID_GEN_RECEIVE_BUFFER_SPACE: + case OID_GEN_RECEIVE_BLOCK_SIZE: + l_Query.m_Long = DEFAULT_PACKET_LOOKAHEAD; + break; + + case OID_GEN_MAXIMUM_FRAME_SIZE: + case OID_GEN_TRANSMIT_BLOCK_SIZE: + case OID_GEN_TRANSMIT_BUFFER_SPACE: + l_Query.m_Long = l_Adapter->m_MTU; + break; + + case OID_PNP_CAPABILITIES: + do + { + PNDIS_PNP_CAPABILITIES pPNPCapabilities; + PNDIS_PM_WAKE_UP_CAPABILITIES pPMstruct; + + if (p_BufferLength >= sizeof (NDIS_PNP_CAPABILITIES)) + { + pPNPCapabilities = (PNDIS_PNP_CAPABILITIES) (p_Buffer); + + // + // Setting up the buffer to be returned + // to the Protocol above the Passthru miniport + // + pPMstruct = &pPNPCapabilities->WakeUpCapabilities; + pPMstruct->MinMagicPacketWakeUp = NdisDeviceStateUnspecified; + pPMstruct->MinPatternWakeUp = NdisDeviceStateUnspecified; + pPMstruct->MinLinkChangeWakeUp = NdisDeviceStateUnspecified; + } + l_QueryLength = sizeof (NDIS_PNP_CAPABILITIES); + } + while (FALSE); + break; + case OID_PNP_QUERY_POWER: + break; + + // Required OIDs that we don't support + + case OID_GEN_SUPPORTED_GUIDS: + case OID_GEN_MEDIA_CAPABILITIES: + case OID_TCP_TASK_OFFLOAD: + case OID_FFP_SUPPORT: + l_Status = NDIS_STATUS_INVALID_OID; + break; + + // Optional stats OIDs + + case OID_GEN_DIRECTED_BYTES_XMIT: + case OID_GEN_DIRECTED_FRAMES_XMIT: + case OID_GEN_MULTICAST_BYTES_XMIT: + case OID_GEN_MULTICAST_FRAMES_XMIT: + case OID_GEN_BROADCAST_BYTES_XMIT: + case OID_GEN_BROADCAST_FRAMES_XMIT: + case OID_GEN_DIRECTED_BYTES_RCV: + case OID_GEN_DIRECTED_FRAMES_RCV: + case OID_GEN_MULTICAST_BYTES_RCV: + case OID_GEN_MULTICAST_FRAMES_RCV: + case OID_GEN_BROADCAST_BYTES_RCV: + case OID_GEN_BROADCAST_FRAMES_RCV: + l_Status = NDIS_STATUS_INVALID_OID; + break; + + //=================================================================== + // Not Handled + //=================================================================== + default: + DEBUGP (("[%s] Unhandled OID %lx\n", NAME (l_Adapter), p_OID)); + l_Status = NDIS_STATUS_INVALID_OID; + break; + } + + if (l_Status != NDIS_STATUS_SUCCESS) + ; + else if (l_QueryLength > p_BufferLength) + { + l_Status = NDIS_STATUS_INVALID_LENGTH; + *p_BytesNeeded = l_QueryLength; + } + else + NdisMoveMemory (p_Buffer, (PVOID) l_QueryPtr, + (*p_BytesWritten = l_QueryLength)); + + return l_Status; +} + +NDIS_STATUS AdapterModify +(IN NDIS_HANDLE p_AdapterContext, + IN NDIS_OID p_OID, + IN PVOID p_Buffer, + IN ULONG p_BufferLength, + OUT PULONG p_BytesRead, + OUT PULONG p_BytesNeeded) +{ + TapAdapterQueryPointer l_Query = (TapAdapterQueryPointer) p_Buffer; + TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext; + NDIS_STATUS l_Status = NDIS_STATUS_INVALID_OID; + ULONG l_Long; + + switch (p_OID) + { + //================================================================== + // Device Info + //================================================================== + case OID_802_3_MULTICAST_LIST: + DEBUGP (("[%s] Setting [OID_802_3_MULTICAST_LIST]\n", + NAME (l_Adapter))); + + *p_BytesNeeded = sizeof (ETH_ADDR); + *p_BytesRead = p_BufferLength; + + if (p_BufferLength % sizeof (ETH_ADDR)) + l_Status = NDIS_STATUS_INVALID_LENGTH; + else if (p_BufferLength > sizeof (MC_LIST)) + { + l_Status = NDIS_STATUS_MULTICAST_FULL; + *p_BytesNeeded = sizeof (MC_LIST); + } + else + { + NdisAcquireSpinLock (&l_Adapter->m_MCLock); + + NdisZeroMemory(&l_Adapter->m_MCList, sizeof (MC_LIST)); + + NdisMoveMemory(&l_Adapter->m_MCList, + p_Buffer, + p_BufferLength); + + l_Adapter->m_MCListSize = p_BufferLength / sizeof (ETH_ADDR); + + NdisReleaseSpinLock (&l_Adapter->m_MCLock); + + l_Status = NDIS_STATUS_SUCCESS; + } + break; + + case OID_GEN_CURRENT_PACKET_FILTER: + l_Status = NDIS_STATUS_INVALID_LENGTH; + *p_BytesNeeded = 4; + + if (p_BufferLength >= sizeof (ULONG)) + { + DEBUGP + (("[%s] Setting [OID_GEN_CURRENT_PACKET_FILTER] to [0x%02lx]\n", + NAME (l_Adapter), l_Query->m_Long)); + l_Status = NDIS_STATUS_SUCCESS; + *p_BytesRead = sizeof (ULONG); + } + break; + + case OID_GEN_CURRENT_LOOKAHEAD: + if (p_BufferLength < sizeof (ULONG)) + { + l_Status = NDIS_STATUS_INVALID_LENGTH; + *p_BytesNeeded = 4; + } + else if (l_Query->m_Long > DEFAULT_PACKET_LOOKAHEAD + || l_Query->m_Long <= 0) + { + l_Status = NDIS_STATUS_INVALID_DATA; + } + else + { + DEBUGP (("[%s] Setting [OID_GEN_CURRENT_LOOKAHEAD] to [%d]\n", + NAME (l_Adapter), l_Query->m_Long)); + l_Adapter->m_Lookahead = l_Query->m_Long; + l_Status = NDIS_STATUS_SUCCESS; + *p_BytesRead = sizeof (ULONG); + } + break; + + case OID_GEN_NETWORK_LAYER_ADDRESSES: + l_Status = NDIS_STATUS_SUCCESS; + *p_BytesRead = *p_BytesNeeded = 0; + break; + + case OID_GEN_TRANSPORT_HEADER_OFFSET: + l_Status = NDIS_STATUS_SUCCESS; + *p_BytesRead = *p_BytesNeeded = 0; + break; + + case OID_PNP_SET_POWER: + do + { + NDIS_DEVICE_POWER_STATE NewDeviceState; + + NewDeviceState = (*(PNDIS_DEVICE_POWER_STATE) p_Buffer); + + switch (NewDeviceState) + { + case NdisDeviceStateD0: + l_Adapter->m_DeviceState = '0'; + break; + case NdisDeviceStateD1: + l_Adapter->m_DeviceState = '1'; + break; + case NdisDeviceStateD2: + l_Adapter->m_DeviceState = '2'; + break; + case NdisDeviceStateD3: + l_Adapter->m_DeviceState = '3'; + break; + default: + l_Adapter->m_DeviceState = '?'; + break; + } + + l_Status = NDIS_STATUS_FAILURE; + + // + // Check for invalid length + // + if (p_BufferLength < sizeof (NDIS_DEVICE_POWER_STATE)) + { + l_Status = NDIS_STATUS_INVALID_LENGTH; + break; + } + + if (NewDeviceState > NdisDeviceStateD0) + { + l_Adapter->m_InterfaceIsRunning = FALSE; + DEBUGP (("[%s] Power management device state OFF\n", + NAME (l_Adapter))); + } + else + { + l_Adapter->m_InterfaceIsRunning = TRUE; + DEBUGP (("[%s] Power management device state ON\n", + NAME (l_Adapter))); + } + + l_Status = NDIS_STATUS_SUCCESS; + } + while (FALSE); + + if (l_Status == NDIS_STATUS_SUCCESS) + { + *p_BytesRead = sizeof (NDIS_DEVICE_POWER_STATE); + *p_BytesNeeded = 0; + } + else + { + *p_BytesRead = 0; + *p_BytesNeeded = sizeof (NDIS_DEVICE_POWER_STATE); + } + break; + + case OID_PNP_REMOVE_WAKE_UP_PATTERN: + case OID_PNP_ADD_WAKE_UP_PATTERN: + l_Status = NDIS_STATUS_SUCCESS; + *p_BytesRead = *p_BytesNeeded = 0; + break; + + default: + DEBUGP (("[%s] Can't set value for OID %lx\n", NAME (l_Adapter), + p_OID)); + l_Status = NDIS_STATUS_INVALID_OID; + *p_BytesRead = *p_BytesNeeded = 0; + break; + } + + return l_Status; +} + +// checksum code for ICMPv6 packet, taken from dhcp.c / udp_checksum +// see RFC 4443, 2.3, and RFC 2460, 8.1 +USHORT +icmpv6_checksum (const UCHAR *buf, + const int len_icmpv6, + const UCHAR *saddr6, + const UCHAR *daddr6) +{ + USHORT word16; + ULONG sum = 0; + int i; + + // make 16 bit words out of every two adjacent 8 bit words and + // calculate the sum of all 16 bit words + for (i = 0; i < len_icmpv6; i += 2){ + word16 = ((buf[i] << 8) & 0xFF00) + ((i + 1 < len_icmpv6) ? (buf[i+1] & 0xFF) : 0); + sum += word16; + } + + // add the IPv6 pseudo header which contains the IP source and destination addresses + for (i = 0; i < 16; i += 2){ + word16 =((saddr6[i] << 8) & 0xFF00) + (saddr6[i+1] & 0xFF); + sum += word16; + } + for (i = 0; i < 16; i += 2){ + word16 =((daddr6[i] << 8) & 0xFF00) + (daddr6[i+1] & 0xFF); + sum += word16; + } + + // the next-header number and the length of the ICMPv6 packet + sum += (USHORT) IPPROTO_ICMPV6 + (USHORT) len_icmpv6; + + // keep only the last 16 bits of the 32 bit calculated sum and add the carries + while (sum >> 16) + sum = (sum & 0xFFFF) + (sum >> 16); + + // Take the one's complement of sum + return ((USHORT) ~sum); +} + +// check IPv6 packet for "is this an IPv6 Neighbor Solicitation that +// the tap driver needs to answer?" +// see RFC 4861 4.3 for the different cases +static IPV6ADDR IPV6_NS_TARGET_MCAST = + { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x08 }; +static IPV6ADDR IPV6_NS_TARGET_UNICAST = + { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08 }; + +#if 0 +BOOLEAN +HandleIPv6NeighborDiscovery( TapAdapterPointer p_Adapter, UCHAR * m_Data ) +{ + const ETH_HEADER * e = (ETH_HEADER *) m_Data; + const IPV6HDR *ipv6 = (IPV6HDR *) (m_Data + sizeof (ETH_HEADER)); + const ICMPV6_NS * icmpv6_ns = (ICMPV6_NS *) (m_Data + sizeof (ETH_HEADER) + sizeof (IPV6HDR)); + ICMPV6_NA_PKT *na; + USHORT icmpv6_len, icmpv6_csum; + + // we don't really care about the destination MAC address here + // - it's either a multicast MAC, or the userland destination MAC + // but since the TAP driver is point-to-point, all packets are "for us" + + // IPv6 target address must be ff02::1::ff00:8 (multicast for + // initial NS) or fe80::1 (unicast for recurrent NUD) + if ( memcmp( ipv6->daddr, IPV6_NS_TARGET_MCAST, + sizeof(IPV6ADDR) ) != 0 && + memcmp( ipv6->daddr, IPV6_NS_TARGET_UNICAST, + sizeof(IPV6ADDR) ) != 0 ) + { + return FALSE; // wrong target address + } + + // IPv6 Next-Header must be ICMPv6 + if ( ipv6->nexthdr != IPPROTO_ICMPV6 ) + { + return FALSE; // wrong next-header + } + + // ICMPv6 type+code must be 135/0 for NS + if ( icmpv6_ns->type != ICMPV6_TYPE_NS || + icmpv6_ns->code != ICMPV6_CODE_0 ) + { + return FALSE; // wrong ICMPv6 type + } + + // ICMPv6 target address must be fe80::8 (magic) + if ( memcmp( icmpv6_ns->target_addr, IPV6_NS_TARGET_UNICAST, + sizeof(IPV6ADDR) ) != 0 ) + { + return FALSE; // not for us + } + + // packet identified, build magic response packet + + na = (ICMPV6_NA_PKT *) MemAlloc (sizeof (ICMPV6_NA_PKT), TRUE); + if ( !na ) return FALSE; + + //------------------------------------------------ + // Initialize Neighbour Advertisement reply packet + //------------------------------------------------ + + // ethernet header + na->eth.proto = htons(ETH_P_IPV6); + COPY_MAC(na->eth.dest, p_Adapter->m_MAC); + COPY_MAC(na->eth.src, p_Adapter->m_TapToUser.dest); + + // IPv6 header + na->ipv6.version_prio = ipv6->version_prio; + NdisMoveMemory( na->ipv6.flow_lbl, ipv6->flow_lbl, + sizeof(na->ipv6.flow_lbl) ); + icmpv6_len = sizeof(ICMPV6_NA_PKT) - sizeof(ETH_HEADER) - sizeof(IPV6HDR); + na->ipv6.payload_len = htons(icmpv6_len); + na->ipv6.nexthdr = IPPROTO_ICMPV6; + na->ipv6.hop_limit = 255; + NdisMoveMemory( na->ipv6.saddr, IPV6_NS_TARGET_UNICAST, + sizeof(IPV6ADDR) ); + NdisMoveMemory( na->ipv6.daddr, ipv6->saddr, + sizeof(IPV6ADDR) ); + + // ICMPv6 + na->icmpv6.type = ICMPV6_TYPE_NA; + na->icmpv6.code = ICMPV6_CODE_0; + na->icmpv6.checksum = 0; + na->icmpv6.rso_bits = 0x60; // Solicited + Override + NdisZeroMemory( na->icmpv6.reserved, sizeof(na->icmpv6.reserved) ); + NdisMoveMemory( na->icmpv6.target_addr, IPV6_NS_TARGET_UNICAST, + sizeof(IPV6ADDR) ); + + // ICMPv6 option "Target Link Layer Address" + na->icmpv6.opt_type = ICMPV6_OPTION_TLLA; + na->icmpv6.opt_length = ICMPV6_LENGTH_TLLA; + COPY_MAC( na->icmpv6.target_macaddr, p_Adapter->m_TapToUser.dest ); + + // calculate and set checksum + icmpv6_csum = icmpv6_checksum ( (UCHAR*) &(na->icmpv6), + icmpv6_len, + na->ipv6.saddr, + na->ipv6.daddr ); + na->icmpv6.checksum = htons( icmpv6_csum ); + + DUMP_PACKET ("HandleIPv6NeighborDiscovery", + (unsigned char *) na, + sizeof (ICMPV6_NA_PKT)); + + InjectPacketDeferred (p_Adapter, (UCHAR *) na, sizeof (ICMPV6_NA_PKT)); + + MemFree (na, sizeof (ICMPV6_NA_PKT)); + + return TRUE; // all fine +} +#endif + +//==================================================================== +// Adapter Transmission +//==================================================================== +NDIS_STATUS +AdapterTransmit (IN NDIS_HANDLE p_AdapterContext, + IN PNDIS_PACKET p_Packet, + IN UINT p_Flags) +{ + TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext; + ULONG l_Index = 0, l_PacketLength = 0; + UINT l_BufferLength = 0; + PIRP l_IRP; + TapPacketPointer l_PacketBuffer; + PNDIS_BUFFER l_NDIS_Buffer; + PUCHAR l_Buffer; + PVOID result; + + NdisQueryPacket (p_Packet, NULL, NULL, &l_NDIS_Buffer, &l_PacketLength); + + //==================================================== + // Here we abandon the transmission attempt if any of + // the parameters is wrong or memory allocation fails + // but we do not indicate failure. The packet is + // silently dropped. + //==================================================== + + if (l_PacketLength < ETHERNET_HEADER_SIZE || l_PacketLength > 65535) + goto exit_fail; + else if (!l_Adapter->m_Extension.m_TapOpens || !l_Adapter->m_MediaState) + goto exit_success; // Nothing is bound to the TAP device + + if (NdisAllocateMemoryWithTag (&l_PacketBuffer, + TAP_PACKET_SIZE (l_PacketLength), + '5PAT') != NDIS_STATUS_SUCCESS) + goto exit_no_resources; + + if (l_PacketBuffer == NULL) + goto exit_no_resources; + + l_PacketBuffer->m_SizeFlags = (l_PacketLength & TP_SIZE_MASK); + + //=========================== + // Reassemble packet contents + //=========================== + + __try + { + l_Index = 0; + while (l_NDIS_Buffer && l_Index < l_PacketLength) + { + ULONG newlen; + NdisQueryBuffer (l_NDIS_Buffer, (PVOID *) & l_Buffer, + &l_BufferLength); + newlen = l_Index + l_BufferLength; + if (newlen > l_PacketLength) + { + NOTE_ERROR (); + goto no_queue; /* overflow */ + } + NdisMoveMemory (l_PacketBuffer->m_Data + l_Index, l_Buffer, + l_BufferLength); + l_Index = newlen; + NdisGetNextBuffer (l_NDIS_Buffer, &l_NDIS_Buffer); + } + if (l_Index != l_PacketLength) + { + NOTE_ERROR (); + goto no_queue; /* underflow */ + } + + DUMP_PACKET ("AdapterTransmit", l_PacketBuffer->m_Data, l_PacketLength); + + //===================================================== + // If IPv4 packet, check whether or not packet + // was truncated. + //===================================================== +#if PACKET_TRUNCATION_CHECK + IPv4PacketSizeVerify (l_PacketBuffer->m_Data, l_PacketLength, FALSE, "TX", &l_Adapter->m_TxTrunc); +#endif + +#if 0 + //===================================================== + // Are we running in DHCP server masquerade mode? + // + // If so, catch both DHCP requests and ARP queries + // to resolve the address of our virtual DHCP server. + //===================================================== + if (l_Adapter->m_dhcp_enabled) + { + const ETH_HEADER *eth = (ETH_HEADER *) l_PacketBuffer->m_Data; + const IPHDR *ip = (IPHDR *) (l_PacketBuffer->m_Data + sizeof (ETH_HEADER)); + const UDPHDR *udp = (UDPHDR *) (l_PacketBuffer->m_Data + sizeof (ETH_HEADER) + sizeof (IPHDR)); + + // ARP packet? + if (l_PacketLength == sizeof (ARP_PACKET) + && eth->proto == htons (ETH_P_ARP) + && l_Adapter->m_dhcp_server_arp) + { + if (ProcessARP (l_Adapter, + (PARP_PACKET) l_PacketBuffer->m_Data, + l_Adapter->m_dhcp_addr, + l_Adapter->m_dhcp_server_ip, + ~0, + l_Adapter->m_dhcp_server_mac)) + goto no_queue; + } +#endif + +#if 0 + // DHCP packet? + else if (l_PacketLength >= sizeof (ETH_HEADER) + sizeof (IPHDR) + sizeof (UDPHDR) + sizeof (DHCP) + && eth->proto == htons (ETH_P_IP) + && ip->version_len == 0x45 // IPv4, 20 byte header + && ip->protocol == IPPROTO_UDP + && udp->dest == htons (BOOTPS_PORT)) + { + const DHCP *dhcp = (DHCP *) (l_PacketBuffer->m_Data + + sizeof (ETH_HEADER) + + sizeof (IPHDR) + + sizeof (UDPHDR)); + + const int optlen = l_PacketLength + - sizeof (ETH_HEADER) + - sizeof (IPHDR) + - sizeof (UDPHDR) + - sizeof (DHCP); + + if (optlen > 0) // we must have at least one DHCP option + { + if (ProcessDHCP (l_Adapter, eth, ip, udp, dhcp, optlen)) + goto no_queue; + } + else + goto no_queue; + } + } +#endif + + //=============================================== + // In Point-To-Point mode, check to see whether + // packet is ARP (handled) or IPv4 (sent to app). + // IPv6 packets are inspected for neighbour discovery + // (to be handled locally), and the rest is forwarded + // all other protocols are dropped + //=============================================== +#if 0 + if (l_Adapter->m_tun) + { + ETH_HEADER *e; + + if (l_PacketLength < ETHERNET_HEADER_SIZE) + goto no_queue; + + e = (ETH_HEADER *) l_PacketBuffer->m_Data; + + switch (ntohs (e->proto)) + { + case ETH_P_ARP: + + // Make sure that packet is the + // right size for ARP. + if (l_PacketLength != sizeof (ARP_PACKET)) + goto no_queue; + + ProcessARP (l_Adapter, + (PARP_PACKET) l_PacketBuffer->m_Data, + l_Adapter->m_localIP, + l_Adapter->m_remoteNetwork, + l_Adapter->m_remoteNetmask, + l_Adapter->m_TapToUser.dest); + + default: + goto no_queue; + + case ETH_P_IP: + + // Make sure that packet is large + // enough to be IPv4. + if (l_PacketLength + < ETHERNET_HEADER_SIZE + IP_HEADER_SIZE) + goto no_queue; + + // Only accept directed packets, + // not broadcasts. + if (memcmp (e, &l_Adapter->m_TapToUser, ETHERNET_HEADER_SIZE)) + goto no_queue; + + // Packet looks like IPv4, queue it. + l_PacketBuffer->m_SizeFlags |= TP_TUN; + break; + + case ETH_P_IPV6: + // make sure that packet is large + // enough to be IPv6 + if (l_PacketLength + < ETHERNET_HEADER_SIZE + IPV6_HEADER_SIZE) + goto no_queue; + + // broadcasts and multicasts are handled specially + // (to be implemented) + + // neighbor discovery packets to fe80::8 are special + // OpenVPN sets this next-hop to signal "handled by tapdrv" + if ( HandleIPv6NeighborDiscovery( l_Adapter, + l_PacketBuffer->m_Data )) + { + goto no_queue; + } + + // Packet looks like IPv6, queue it :-) + l_PacketBuffer->m_SizeFlags |= TP_TUN; + } + } +#endif + + //=============================================== + // Push packet onto queue to wait for read from + // userspace. + //=============================================== + + NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock); + + result = NULL; + if (IS_UP (l_Adapter)) + result = QueuePush (l_Adapter->m_Extension.m_PacketQueue, l_PacketBuffer); + + NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock); + + if ((TapPacketPointer) result != l_PacketBuffer) + { + // adapter receive overrun + INCREMENT_STAT (l_Adapter->m_TxErr); + goto no_queue; + } + else + { + INCREMENT_STAT (l_Adapter->m_Tx); + } + + //============================================================ + // Cycle through IRPs and packets, try to satisfy each pending + // IRP with a queued packet. + //============================================================ + while (TRUE) + { + l_IRP = NULL; + l_PacketBuffer = NULL; + + NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock); + + if (IS_UP (l_Adapter) + && QueueCount (l_Adapter->m_Extension.m_PacketQueue) + && QueueCount (l_Adapter->m_Extension.m_IrpQueue)) + { + l_IRP = (PIRP) QueuePop (l_Adapter->m_Extension.m_IrpQueue); + l_PacketBuffer = (TapPacketPointer) + QueuePop (l_Adapter->m_Extension.m_PacketQueue); + } + + NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock); + + MYASSERT ((l_IRP != NULL) + (l_PacketBuffer != NULL) != 1); + + if (l_IRP && l_PacketBuffer) + { + CompleteIRP (l_IRP, + l_PacketBuffer, + IO_NETWORK_INCREMENT); + } + else + break; + } + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + } + + return NDIS_STATUS_SUCCESS; + + no_queue: + NdisFreeMemory (l_PacketBuffer, + TAP_PACKET_SIZE (l_PacketLength), + 0); + + exit_success: + return NDIS_STATUS_SUCCESS; + + exit_fail: + return NDIS_STATUS_FAILURE; + + exit_no_resources: + return NDIS_STATUS_RESOURCES; +} + +//====================================================================== +// Hooks for catching TAP device IRP's. +//====================================================================== + +DRIVER_DISPATCH TapDeviceHook; +NTSTATUS +TapDeviceHook (IN PDEVICE_OBJECT p_DeviceObject, IN PIRP p_IRP) +{ + TapAdapterPointer l_Adapter = LookupAdapterInInstanceList (p_DeviceObject); + PIO_STACK_LOCATION l_IrpSp; + NTSTATUS l_Status = STATUS_SUCCESS; + BOOLEAN accessible; + + l_IrpSp = IoGetCurrentIrpStackLocation (p_IRP); + + p_IRP->IoStatus.Status = STATUS_SUCCESS; + p_IRP->IoStatus.Information = 0; + + if (!l_Adapter || l_Adapter->m_Extension.m_Halt) + { + DEBUGP (("TapDeviceHook called when TAP device is halted, MajorFunction=%d\n", + (int)l_IrpSp->MajorFunction)); + + if (l_IrpSp->MajorFunction == IRP_MJ_CLOSE) + { + IoCompleteRequest (p_IRP, IO_NO_INCREMENT); + return STATUS_SUCCESS; + } + else + { + p_IRP->IoStatus.Status = STATUS_NO_SUCH_DEVICE; + IoCompleteRequest (p_IRP, IO_NO_INCREMENT); + return STATUS_NO_SUCH_DEVICE; + } + } + + switch (l_IrpSp->MajorFunction) + { + //=========================================================== + // Ioctl call handlers + //=========================================================== + case IRP_MJ_DEVICE_CONTROL: + { + switch (l_IrpSp->Parameters.DeviceIoControl.IoControlCode) + { + case TAP_WIN_IOCTL_GET_MAC: + { + if (l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength + >= sizeof (MACADDR)) + { + COPY_MAC (p_IRP->AssociatedIrp.SystemBuffer, + l_Adapter->m_MAC); + p_IRP->IoStatus.Information = sizeof (MACADDR); + } + else + { + NOTE_ERROR (); + p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL; + } + break; + } + case TAP_WIN_IOCTL_GET_VERSION: + { + const ULONG size = sizeof (ULONG) * 3; + if (l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength + >= size) + { + ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[0] + = TAP_DRIVER_MAJOR_VERSION; + ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[1] + = TAP_DRIVER_MINOR_VERSION; + ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[2] +#if DBG + = 1; +#else + = 0; +#endif + p_IRP->IoStatus.Information = size; + } + else + { + NOTE_ERROR (); + p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL; + } + + break; + } + case TAP_WIN_IOCTL_GET_MTU: + { + const ULONG size = sizeof (ULONG) * 1; + if (l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength + >= size) + { + ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[0] + = l_Adapter->m_MTU; + p_IRP->IoStatus.Information = size; + } + else + { + NOTE_ERROR (); + p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL; + } + + break; + } + case TAP_WIN_IOCTL_GET_INFO: + { + char state[16]; + if (l_Adapter->m_InterfaceIsRunning) + state[0] = 'A'; + else + state[0] = 'a'; + if (l_Adapter->m_Extension.m_TapIsRunning) + state[1] = 'T'; + else + state[1] = 't'; + state[2] = l_Adapter->m_DeviceState; + if (l_Adapter->m_MediaStateAlwaysConnected) + state[3] = 'C'; + else + state[3] = 'c'; + state[4] = '\0'; + + p_IRP->IoStatus.Status = l_Status = RtlStringCchPrintfExA ( + ((LPTSTR) (p_IRP->AssociatedIrp.SystemBuffer)), + l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength, + NULL, + NULL, + STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS, +#if PACKET_TRUNCATION_CHECK + "State=%s Err=[%s/%d] #O=%d Tx=[%d,%d,%d] Rx=[%d,%d,%d] IrpQ=[%d,%d,%d] PktQ=[%d,%d,%d] InjQ=[%d,%d,%d]", +#else + "State=%s Err=[%s/%d] #O=%d Tx=[%d,%d] Rx=[%d,%d] IrpQ=[%d,%d,%d] PktQ=[%d,%d,%d] InjQ=[%d,%d,%d]", +#endif + state, + g_LastErrorFilename, + g_LastErrorLineNumber, + (int)l_Adapter->m_Extension.m_NumTapOpens, + (int)l_Adapter->m_Tx, + (int)l_Adapter->m_TxErr, +#if PACKET_TRUNCATION_CHECK + (int)l_Adapter->m_TxTrunc, +#endif + (int)l_Adapter->m_Rx, + (int)l_Adapter->m_RxErr, +#if PACKET_TRUNCATION_CHECK + (int)l_Adapter->m_RxTrunc, +#endif + (int)l_Adapter->m_Extension.m_IrpQueue->size, + (int)l_Adapter->m_Extension.m_IrpQueue->max_size, + (int)IRP_QUEUE_SIZE, + (int)l_Adapter->m_Extension.m_PacketQueue->size, + (int)l_Adapter->m_Extension.m_PacketQueue->max_size, + (int)PACKET_QUEUE_SIZE, + (int)l_Adapter->m_Extension.m_InjectQueue->size, + (int)l_Adapter->m_Extension.m_InjectQueue->max_size, + (int)INJECT_QUEUE_SIZE + ); + + p_IRP->IoStatus.Information + = l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength; + + break; + } + +#if DBG + case TAP_WIN_IOCTL_GET_LOG_LINE: + { + if (GetDebugLine ((LPTSTR)p_IRP->AssociatedIrp.SystemBuffer, + l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength)) + p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS; + else + p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; + + p_IRP->IoStatus.Information + = l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength; + + break; + } +#endif + +#if 0 + case TAP_WIN_IOCTL_CONFIG_TUN: + { + if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >= + (sizeof (IPADDR) * 3)) + { + MACADDR dest; + + l_Adapter->m_tun = FALSE; + + GenerateRelatedMAC (dest, l_Adapter->m_MAC, 1); + + l_Adapter->m_localIP = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[0]; + l_Adapter->m_remoteNetwork = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[1]; + l_Adapter->m_remoteNetmask = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[2]; + + // sanity check on network/netmask + if ((l_Adapter->m_remoteNetwork & l_Adapter->m_remoteNetmask) != l_Adapter->m_remoteNetwork) + { + NOTE_ERROR (); + p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; + break; + } + + COPY_MAC (l_Adapter->m_TapToUser.src, l_Adapter->m_MAC); + COPY_MAC (l_Adapter->m_TapToUser.dest, dest); + COPY_MAC (l_Adapter->m_UserToTap.src, dest); + COPY_MAC (l_Adapter->m_UserToTap.dest, l_Adapter->m_MAC); + + l_Adapter->m_TapToUser.proto = l_Adapter->m_UserToTap.proto = htons (ETH_P_IP); + l_Adapter->m_UserToTap_IPv6 = l_Adapter->m_UserToTap; + l_Adapter->m_UserToTap_IPv6.proto = htons(ETH_P_IPV6); + + l_Adapter->m_tun = TRUE; + + CheckIfDhcpAndTunMode (l_Adapter); + + p_IRP->IoStatus.Information = 1; // Simple boolean value + } + else + { + NOTE_ERROR (); + p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; + } + + break; + } +#endif + +#if 0 + case TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT: // Obsoleted by TAP_WIN_IOCTL_CONFIG_TUN + { + if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >= + (sizeof (IPADDR) * 2)) + { + MACADDR dest; + + l_Adapter->m_tun = FALSE; + + GenerateRelatedMAC (dest, l_Adapter->m_MAC, 1); + + l_Adapter->m_localIP = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[0]; + l_Adapter->m_remoteNetwork = ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[1]; + l_Adapter->m_remoteNetmask = ~0; + + COPY_MAC (l_Adapter->m_TapToUser.src, l_Adapter->m_MAC); + COPY_MAC (l_Adapter->m_TapToUser.dest, dest); + COPY_MAC (l_Adapter->m_UserToTap.src, dest); + COPY_MAC (l_Adapter->m_UserToTap.dest, l_Adapter->m_MAC); + + l_Adapter->m_TapToUser.proto = l_Adapter->m_UserToTap.proto = htons (ETH_P_IP); + l_Adapter->m_UserToTap_IPv6 = l_Adapter->m_UserToTap; + l_Adapter->m_UserToTap_IPv6.proto = htons(ETH_P_IPV6); + + l_Adapter->m_tun = TRUE; + + CheckIfDhcpAndTunMode (l_Adapter); + + p_IRP->IoStatus.Information = 1; // Simple boolean value + } + else + { + NOTE_ERROR (); + p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; + } + + break; + } +#endif + + case TAP_WIN_IOCTL_SET_MEDIA_STATUS: + { + if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >= + (sizeof (ULONG) * 1)) + { + ULONG parm = ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[0]; + SetMediaStatus (l_Adapter, (BOOLEAN) parm); + p_IRP->IoStatus.Information = 1; + } + else + { + NOTE_ERROR (); + p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; + } + break; + } + +#if 0 + case TAP_WIN_IOCTL_CONFIG_DHCP_MASQ: + { + if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >= + (sizeof (IPADDR) * 4)) + { + l_Adapter->m_dhcp_enabled = FALSE; + l_Adapter->m_dhcp_server_arp = FALSE; + l_Adapter->m_dhcp_user_supplied_options_buffer_len = 0; + + // Adapter IP addr / netmask + l_Adapter->m_dhcp_addr = + ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[0]; + l_Adapter->m_dhcp_netmask = + ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[1]; + + // IP addr of DHCP masq server + l_Adapter->m_dhcp_server_ip = + ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[2]; + + // Lease time in seconds + l_Adapter->m_dhcp_lease_time = + ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[3]; + + GenerateRelatedMAC (l_Adapter->m_dhcp_server_mac, l_Adapter->m_MAC, 2); + + l_Adapter->m_dhcp_enabled = TRUE; + l_Adapter->m_dhcp_server_arp = TRUE; + + CheckIfDhcpAndTunMode (l_Adapter); + + p_IRP->IoStatus.Information = 1; // Simple boolean value + } + else + { + NOTE_ERROR (); + p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; + } + + break; + } + + case TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT: + { + if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength <= + DHCP_USER_SUPPLIED_OPTIONS_BUFFER_SIZE + && l_Adapter->m_dhcp_enabled) + { + l_Adapter->m_dhcp_user_supplied_options_buffer_len = 0; + + NdisMoveMemory (l_Adapter->m_dhcp_user_supplied_options_buffer, + p_IRP->AssociatedIrp.SystemBuffer, + l_IrpSp->Parameters.DeviceIoControl.InputBufferLength); + + l_Adapter->m_dhcp_user_supplied_options_buffer_len = + l_IrpSp->Parameters.DeviceIoControl.InputBufferLength; + + p_IRP->IoStatus.Information = 1; // Simple boolean value + } + else + { + NOTE_ERROR (); + p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; + } + + break; + } +#endif + + default: + { + NOTE_ERROR (); + p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; + break; + } + } + + IoCompleteRequest (p_IRP, IO_NO_INCREMENT); + break; + } + + //=========================================================== + // User mode thread issued a read request on the tap device + // If there are packets waiting to be read, then the request + // will be satisfied here. If not, then the request will be + // queued and satisfied by any packet that is not used to + // satisfy requests ahead of it. + //=========================================================== + case IRP_MJ_READ: + { + TapPacketPointer l_PacketBuffer; + BOOLEAN pending = FALSE; + + // Save IRP-accessible copy of buffer length + p_IRP->IoStatus.Information = l_IrpSp->Parameters.Read.Length; + + if (p_IRP->MdlAddress == NULL) + { + DEBUGP (("[%s] MdlAddress is NULL for IRP_MJ_READ\n", + NAME (l_Adapter))); + NOTE_ERROR (); + p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; + p_IRP->IoStatus.Information = 0; + IoCompleteRequest (p_IRP, IO_NO_INCREMENT); + break; + } + else if ((p_IRP->AssociatedIrp.SystemBuffer = + MmGetSystemAddressForMdlSafe + (p_IRP->MdlAddress, NormalPagePriority)) == NULL) + { + DEBUGP (("[%s] Could not map address in IRP_MJ_READ\n", + NAME (l_Adapter))); + NOTE_ERROR (); + p_IRP->IoStatus.Status = l_Status = STATUS_INSUFFICIENT_RESOURCES; + p_IRP->IoStatus.Information = 0; + IoCompleteRequest (p_IRP, IO_NO_INCREMENT); + break; + } + else if (!l_Adapter->m_InterfaceIsRunning) + { + DEBUGP (("[%s] Interface is down in IRP_MJ_READ\n", + NAME (l_Adapter))); + NOTE_ERROR (); + p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; + p_IRP->IoStatus.Information = 0; + IoCompleteRequest (p_IRP, IO_NO_INCREMENT); + break; + } + + //================================== + // Can we provide immediate service? + //================================== + + l_PacketBuffer = NULL; + + NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock); + + if (IS_UP (l_Adapter) + && QueueCount (l_Adapter->m_Extension.m_PacketQueue) + && QueueCount (l_Adapter->m_Extension.m_IrpQueue) == 0) + { + l_PacketBuffer = (TapPacketPointer) + QueuePop (l_Adapter->m_Extension.m_PacketQueue); + } + + NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock); + + if (l_PacketBuffer) + { + l_Status = CompleteIRP (p_IRP, + l_PacketBuffer, + IO_NO_INCREMENT); + break; + } + + //============================= + // Attempt to pend read request + //============================= + + NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock); + + if (IS_UP (l_Adapter) + && QueuePush (l_Adapter->m_Extension.m_IrpQueue, p_IRP) == (PIRP) p_IRP) + { + IoSetCancelRoutine (p_IRP, CancelIRPCallback); + l_Status = STATUS_PENDING; + IoMarkIrpPending (p_IRP); + pending = TRUE; + } + + NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock); + + if (pending) + break; + + // Can't queue anymore IRP's + DEBUGP (("[%s] TAP [%s] read IRP overrun\n", + NAME (l_Adapter), l_Adapter->m_Extension.m_TapName)); + NOTE_ERROR (); + p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; + p_IRP->IoStatus.Information = 0; + IoCompleteRequest (p_IRP, IO_NO_INCREMENT); + break; + } + + //============================================================== + // User mode issued a WriteFile request on the TAP file handle. + // The request will always get satisfied here. The call may + // fail if there are too many pending packets (queue full). + //============================================================== + case IRP_MJ_WRITE: + { + if (p_IRP->MdlAddress == NULL) + { + DEBUGP (("[%s] MdlAddress is NULL for IRP_MJ_WRITE\n", + NAME (l_Adapter))); + NOTE_ERROR (); + p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER; + p_IRP->IoStatus.Information = 0; + } + else if ((p_IRP->AssociatedIrp.SystemBuffer = + MmGetSystemAddressForMdlSafe + (p_IRP->MdlAddress, NormalPagePriority)) == NULL) + { + DEBUGP (("[%s] Could not map address in IRP_MJ_WRITE\n", + NAME (l_Adapter))); + NOTE_ERROR (); + p_IRP->IoStatus.Status = l_Status = STATUS_INSUFFICIENT_RESOURCES; + p_IRP->IoStatus.Information = 0; + } + else if (!l_Adapter->m_InterfaceIsRunning) + { + DEBUGP (("[%s] Interface is down in IRP_MJ_WRITE\n", + NAME (l_Adapter))); + NOTE_ERROR (); + p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; + p_IRP->IoStatus.Information = 0; + } +#if 0 + else if (!l_Adapter->m_tun && ((l_IrpSp->Parameters.Write.Length) >= ETHERNET_HEADER_SIZE)) + { + __try + { + p_IRP->IoStatus.Information = l_IrpSp->Parameters.Write.Length; + + DUMP_PACKET ("IRP_MJ_WRITE ETH", + (unsigned char *) p_IRP->AssociatedIrp.SystemBuffer, + l_IrpSp->Parameters.Write.Length); + + //===================================================== + // If IPv4 packet, check whether or not packet + // was truncated. + //===================================================== +#if PACKET_TRUNCATION_CHECK + IPv4PacketSizeVerify ((unsigned char *) p_IRP->AssociatedIrp.SystemBuffer, + l_IrpSp->Parameters.Write.Length, + FALSE, + "RX", + &l_Adapter->m_RxTrunc); +#endif + + NdisMEthIndicateReceive + (l_Adapter->m_MiniportAdapterHandle, + (NDIS_HANDLE) l_Adapter, + (unsigned char *) p_IRP->AssociatedIrp.SystemBuffer, + ETHERNET_HEADER_SIZE, + (unsigned char *) p_IRP->AssociatedIrp.SystemBuffer + ETHERNET_HEADER_SIZE, + l_IrpSp->Parameters.Write.Length - ETHERNET_HEADER_SIZE, + l_IrpSp->Parameters.Write.Length - ETHERNET_HEADER_SIZE); + + NdisMEthIndicateReceiveComplete (l_Adapter->m_MiniportAdapterHandle); + + p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + DEBUGP (("[%s] NdisMEthIndicateReceive failed in IRP_MJ_WRITE\n", + NAME (l_Adapter))); + NOTE_ERROR (); + p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; + p_IRP->IoStatus.Information = 0; + } + } +#endif +#if 0 + else if (l_Adapter->m_tun && ((l_IrpSp->Parameters.Write.Length) >= IP_HEADER_SIZE)) + { + __try + { + ETH_HEADER * p_UserToTap = &l_Adapter->m_UserToTap; + + // for IPv6, need to use ethernet header with IPv6 proto + if ( IPH_GET_VER( ((IPHDR*) p_IRP->AssociatedIrp.SystemBuffer)->version_len) == 6 ) + { + p_UserToTap = &l_Adapter->m_UserToTap_IPv6; + } + + p_IRP->IoStatus.Information = l_IrpSp->Parameters.Write.Length; + + DUMP_PACKET2 ("IRP_MJ_WRITE P2P", + p_UserToTap, + (unsigned char *) p_IRP->AssociatedIrp.SystemBuffer, + l_IrpSp->Parameters.Write.Length); + + //===================================================== + // If IPv4 packet, check whether or not packet + // was truncated. + //===================================================== +#if PACKET_TRUNCATION_CHECK + IPv4PacketSizeVerify ((unsigned char *) p_IRP->AssociatedIrp.SystemBuffer, + l_IrpSp->Parameters.Write.Length, + TRUE, + "RX", + &l_Adapter->m_RxTrunc); +#endif + + NdisMEthIndicateReceive + (l_Adapter->m_MiniportAdapterHandle, + (NDIS_HANDLE) l_Adapter, + (unsigned char *) p_UserToTap, + sizeof (ETH_HEADER), + (unsigned char *) p_IRP->AssociatedIrp.SystemBuffer, + l_IrpSp->Parameters.Write.Length, + l_IrpSp->Parameters.Write.Length); + + NdisMEthIndicateReceiveComplete (l_Adapter->m_MiniportAdapterHandle); + + p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + DEBUGP (("[%s] NdisMEthIndicateReceive failed in IRP_MJ_WRITE (P2P)\n", + NAME (l_Adapter))); + NOTE_ERROR (); + p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; + p_IRP->IoStatus.Information = 0; + } + } +#endif + else + { + DEBUGP (("[%s] Bad buffer size in IRP_MJ_WRITE, len=%d\n", + NAME (l_Adapter), + l_IrpSp->Parameters.Write.Length)); + NOTE_ERROR (); + p_IRP->IoStatus.Information = 0; // ETHERNET_HEADER_SIZE; + p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL; + } + + if (l_Status == STATUS_SUCCESS) + INCREMENT_STAT (l_Adapter->m_Rx); + else + INCREMENT_STAT (l_Adapter->m_RxErr); + + IoCompleteRequest (p_IRP, IO_NO_INCREMENT); + break; + } + + //-------------------------------------------------------------- + // User mode thread has called CreateFile() on the tap device + //-------------------------------------------------------------- + case IRP_MJ_CREATE: + { + BOOLEAN succeeded = FALSE; + BOOLEAN mutex_succeeded; + + DEBUGP + (("[%s] [TAP] release [%d.%d] open request (m_TapOpens=%d)\n", + NAME (l_Adapter), TAP_DRIVER_MAJOR_VERSION, + TAP_DRIVER_MINOR_VERSION, l_Adapter->m_Extension.m_TapOpens)); + + ACQUIRE_MUTEX_ADAPTIVE (&l_Adapter->m_Extension.m_OpenCloseMutex, mutex_succeeded); + if (mutex_succeeded) + { + if (l_Adapter->m_Extension.m_TapIsRunning && !l_Adapter->m_Extension.m_TapOpens) + { + ResetTapAdapterState (l_Adapter); + l_Adapter->m_Extension.m_TapOpens = 1; + succeeded = TRUE; + } + + if (succeeded) + { + INCREMENT_STAT (l_Adapter->m_Extension.m_NumTapOpens); + p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS; + p_IRP->IoStatus.Information = 0; + } + else + { + DEBUGP (("[%s] TAP is presently unavailable (m_TapOpens=%d)\n", + NAME (l_Adapter), l_Adapter->m_Extension.m_TapOpens)); + NOTE_ERROR (); + p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; + p_IRP->IoStatus.Information = 0; + } + + RELEASE_MUTEX (&l_Adapter->m_Extension.m_OpenCloseMutex); + } + else + { + DEBUGP (("[%s] TAP is presently locked (m_TapOpens=%d)\n", + NAME (l_Adapter), l_Adapter->m_Extension.m_TapOpens)); + NOTE_ERROR (); + p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; + p_IRP->IoStatus.Information = 0; + } + + IoCompleteRequest (p_IRP, IO_NO_INCREMENT); + break; + } + + //----------------------------------------------------------- + // User mode thread called CloseHandle() on the tap device + //----------------------------------------------------------- + case IRP_MJ_CLOSE: + { + BOOLEAN mutex_succeeded; + + DEBUGP (("[%s] [TAP] release [%d.%d] close/cleanup request\n", + NAME (l_Adapter), TAP_DRIVER_MAJOR_VERSION, + TAP_DRIVER_MINOR_VERSION)); + + ACQUIRE_MUTEX_ADAPTIVE (&l_Adapter->m_Extension.m_OpenCloseMutex, mutex_succeeded); + if (mutex_succeeded) + { + l_Adapter->m_Extension.m_TapOpens = 0; + ResetTapAdapterState (l_Adapter); + FlushQueues (&l_Adapter->m_Extension); + SetMediaStatus (l_Adapter, FALSE); + RELEASE_MUTEX (&l_Adapter->m_Extension.m_OpenCloseMutex); + } + else + { + DEBUGP (("[%s] TAP is presently locked (m_TapOpens=%d)\n", + NAME (l_Adapter), l_Adapter->m_Extension.m_TapOpens)); + NOTE_ERROR (); + p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; + p_IRP->IoStatus.Information = 0; + } + + IoCompleteRequest (p_IRP, IO_NO_INCREMENT); + break; + } + + //------------------ + // Strange Request + //------------------ + default: + { + //NOTE_ERROR (); + p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL; + IoCompleteRequest (p_IRP, IO_NO_INCREMENT); + break; + } + } + + return l_Status; +} + +//============================================================= +// CompleteIRP is normally called with an adapter -> userspace +// network packet and an IRP (Pending I/O request) from userspace. +// +// The IRP will normally represent a queued overlapped read +// operation from userspace that is in a wait state. +// +// Use the ethernet packet to satisfy the IRP. +//============================================================= + +NTSTATUS +CompleteIRP (IN PIRP p_IRP, + IN TapPacketPointer p_PacketBuffer, + IN CCHAR PriorityBoost) +{ + NTSTATUS l_Status = STATUS_UNSUCCESSFUL; + + int offset; + int len; + + MYASSERT (p_IRP); + MYASSERT (p_PacketBuffer); + + IoSetCancelRoutine (p_IRP, NULL); // Disable cancel routine + + //------------------------------------------- + // While p_PacketBuffer always contains a + // full ethernet packet, including the + // ethernet header, in point-to-point mode, + // we only want to return the IPv4 + // component. + //------------------------------------------- + + if (p_PacketBuffer->m_SizeFlags & TP_TUN) + { + offset = ETHERNET_HEADER_SIZE; + len = (int) (p_PacketBuffer->m_SizeFlags & TP_SIZE_MASK) - ETHERNET_HEADER_SIZE; + } + else + { + offset = 0; + len = (p_PacketBuffer->m_SizeFlags & TP_SIZE_MASK); + } + + if (len < 0 || (int) p_IRP->IoStatus.Information < len) + { + p_IRP->IoStatus.Information = 0; + p_IRP->IoStatus.Status = STATUS_BUFFER_OVERFLOW; + NOTE_ERROR (); + } + else + { + p_IRP->IoStatus.Information = len; + p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS; + + __try + { + NdisMoveMemory (p_IRP->AssociatedIrp.SystemBuffer, + p_PacketBuffer->m_Data + offset, + len); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + NOTE_ERROR (); + p_IRP->IoStatus.Status = STATUS_UNSUCCESSFUL; + p_IRP->IoStatus.Information = 0; + } + } + + __try + { + NdisFreeMemory (p_PacketBuffer, + TAP_PACKET_SIZE (p_PacketBuffer->m_SizeFlags & TP_SIZE_MASK), + 0); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + } + + if (l_Status == STATUS_SUCCESS) + { + IoCompleteRequest (p_IRP, PriorityBoost); + } + else + IoCompleteRequest (p_IRP, IO_NO_INCREMENT); + + return l_Status; +} + +//============================================== +// IRPs get cancelled for a number of reasons. +// +// The TAP device could be closed by userspace +// when there are still pending read operations. +// +// The user could disable the TAP adapter in the +// network connections control panel, while the +// device is still open by a process. +//============================================== +VOID +CancelIRPCallback (IN PDEVICE_OBJECT p_DeviceObject, + IN PIRP p_IRP) +{ + TapAdapterPointer l_Adapter = LookupAdapterInInstanceList (p_DeviceObject); + CancelIRP (l_Adapter ? &l_Adapter->m_Extension : NULL, p_IRP, TRUE); +} + +VOID +CancelIRP (TapExtensionPointer p_Extension, + IN PIRP p_IRP, + BOOLEAN callback) +{ + BOOLEAN exists = FALSE; + + MYASSERT (p_IRP); + + if (p_Extension) + { + NdisAcquireSpinLock (&p_Extension->m_QueueLock); + exists = (QueueExtract (p_Extension->m_IrpQueue, p_IRP) == p_IRP); + NdisReleaseSpinLock (&p_Extension->m_QueueLock); + } + else + exists = TRUE; + + if (exists) + { + IoSetCancelRoutine (p_IRP, NULL); + p_IRP->IoStatus.Status = STATUS_CANCELLED; + p_IRP->IoStatus.Information = 0; + } + + if (callback) + IoReleaseCancelSpinLock (p_IRP->CancelIrql); + + if (exists) + IoCompleteRequest (p_IRP, IO_NO_INCREMENT); +} + +//=========================================== +// Exhaust packet, IRP, and injection queues. +//=========================================== +VOID +FlushQueues (TapExtensionPointer p_Extension) +{ + PIRP l_IRP; + TapPacketPointer l_PacketBuffer; + InjectPacketPointer l_InjectBuffer; + int n_IRP=0, n_Packet=0, n_Inject=0; + + MYASSERT (p_Extension); + MYASSERT (p_Extension->m_TapDevice); + + while (TRUE) + { + NdisAcquireSpinLock (&p_Extension->m_QueueLock); + l_IRP = QueuePop (p_Extension->m_IrpQueue); + NdisReleaseSpinLock (&p_Extension->m_QueueLock); + if (l_IRP) + { + ++n_IRP; + CancelIRP (NULL, l_IRP, FALSE); + } + else + break; + } + + while (TRUE) + { + NdisAcquireSpinLock (&p_Extension->m_QueueLock); + l_PacketBuffer = QueuePop (p_Extension->m_PacketQueue); + NdisReleaseSpinLock (&p_Extension->m_QueueLock); + if (l_PacketBuffer) + { + ++n_Packet; + MemFree (l_PacketBuffer, TAP_PACKET_SIZE (l_PacketBuffer->m_SizeFlags & TP_SIZE_MASK)); + } + else + break; + } + + while (TRUE) + { + NdisAcquireSpinLock (&p_Extension->m_InjectLock); + l_InjectBuffer = QueuePop (p_Extension->m_InjectQueue); + NdisReleaseSpinLock (&p_Extension->m_InjectLock); + if (l_InjectBuffer) + { + ++n_Inject; + INJECT_PACKET_FREE(l_InjectBuffer); + } + else + break; + } + + DEBUGP (( + "[%s] [TAP] FlushQueues n_IRP=[%d,%d,%d] n_Packet=[%d,%d,%d] n_Inject=[%d,%d,%d]\n", + p_Extension->m_TapName, + n_IRP, + p_Extension->m_IrpQueue->max_size, + IRP_QUEUE_SIZE, + n_Packet, + p_Extension->m_PacketQueue->max_size, + PACKET_QUEUE_SIZE, + n_Inject, + p_Extension->m_InjectQueue->max_size, + INJECT_QUEUE_SIZE + )); +} + +//=================================================== +// Tell Windows whether the TAP device should be +// considered "connected" or "disconnected". +//=================================================== +VOID +SetMediaStatus (TapAdapterPointer p_Adapter, BOOLEAN state) +{ + if (p_Adapter->m_MediaState != state && !p_Adapter->m_MediaStateAlwaysConnected) + { + if (state) + NdisMIndicateStatus (p_Adapter->m_MiniportAdapterHandle, + NDIS_STATUS_MEDIA_CONNECT, NULL, 0); + else + NdisMIndicateStatus (p_Adapter->m_MiniportAdapterHandle, + NDIS_STATUS_MEDIA_DISCONNECT, NULL, 0); + + NdisMIndicateStatusComplete (p_Adapter->m_MiniportAdapterHandle); + p_Adapter->m_MediaState = state; + } +} + + +//====================================================== +// If DHCP mode is used together with tun +// mode, consider the fact that the P2P remote subnet +// might enclose the DHCP masq server address. +//====================================================== +VOID +CheckIfDhcpAndTunMode (TapAdapterPointer p_Adapter) +{ +#if 0 + if (p_Adapter->m_tun && p_Adapter->m_dhcp_enabled) + { + if ((p_Adapter->m_dhcp_server_ip & p_Adapter->m_remoteNetmask) == p_Adapter->m_remoteNetwork) + { + COPY_MAC (p_Adapter->m_dhcp_server_mac, p_Adapter->m_TapToUser.dest); + p_Adapter->m_dhcp_server_arp = FALSE; + } + } +#endif +} + +#if 0 +//=================================================== +// Generate an ARP reply message for specific kinds +// ARP queries. +//=================================================== +BOOLEAN +ProcessARP (TapAdapterPointer p_Adapter, + const PARP_PACKET src, + const IPADDR adapter_ip, + const IPADDR ip_network, + const IPADDR ip_netmask, + const MACADDR mac) +{ + //----------------------------------------------- + // Is this the kind of packet we are looking for? + //----------------------------------------------- + if (src->m_Proto == htons (ETH_P_ARP) + && MAC_EQUAL (src->m_MAC_Source, p_Adapter->m_MAC) + && MAC_EQUAL (src->m_ARP_MAC_Source, p_Adapter->m_MAC) + && MAC_EQUAL (src->m_MAC_Destination, p_Adapter->m_MAC_Broadcast) + && src->m_ARP_Operation == htons (ARP_REQUEST) + && src->m_MAC_AddressType == htons (MAC_ADDR_TYPE) + && src->m_MAC_AddressSize == sizeof (MACADDR) + && src->m_PROTO_AddressType == htons (ETH_P_IP) + && src->m_PROTO_AddressSize == sizeof (IPADDR) + && src->m_ARP_IP_Source == adapter_ip + && (src->m_ARP_IP_Destination & ip_netmask) == ip_network + && src->m_ARP_IP_Destination != adapter_ip) + { + ARP_PACKET *arp = (ARP_PACKET *) MemAlloc (sizeof (ARP_PACKET), TRUE); + if (arp) + { + //---------------------------------------------- + // Initialize ARP reply fields + //---------------------------------------------- + arp->m_Proto = htons (ETH_P_ARP); + arp->m_MAC_AddressType = htons (MAC_ADDR_TYPE); + arp->m_PROTO_AddressType = htons (ETH_P_IP); + arp->m_MAC_AddressSize = sizeof (MACADDR); + arp->m_PROTO_AddressSize = sizeof (IPADDR); + arp->m_ARP_Operation = htons (ARP_REPLY); + + //---------------------------------------------- + // ARP addresses + //---------------------------------------------- + COPY_MAC (arp->m_MAC_Source, mac); + COPY_MAC (arp->m_MAC_Destination, p_Adapter->m_MAC); + COPY_MAC (arp->m_ARP_MAC_Source, mac); + COPY_MAC (arp->m_ARP_MAC_Destination, p_Adapter->m_MAC); + arp->m_ARP_IP_Source = src->m_ARP_IP_Destination; + arp->m_ARP_IP_Destination = adapter_ip; + + DUMP_PACKET ("ProcessARP", + (unsigned char *) arp, + sizeof (ARP_PACKET)); + + InjectPacketDeferred (p_Adapter, (UCHAR *) arp, sizeof (ARP_PACKET)); + + MemFree (arp, sizeof (ARP_PACKET)); + } + + return TRUE; + } + else + return FALSE; +} +#endif + +//=============================================================== +// Used in cases where internally generated packets such as +// ARP or DHCP replies must be returned to the kernel, to be +// seen as an incoming packet "arriving" on the interface. +//=============================================================== + +// Defer packet injection till IRQL < DISPATCH_LEVEL +VOID +InjectPacketDeferred (TapAdapterPointer p_Adapter, + UCHAR *packet, + const unsigned int len) +{ + InjectPacketPointer l_InjectBuffer; + PVOID result; + + if (NdisAllocateMemoryWithTag (&l_InjectBuffer, + INJECT_PACKET_SIZE (len), + 'IPAT') == NDIS_STATUS_SUCCESS) + { + l_InjectBuffer->m_Size = len; + NdisMoveMemory (l_InjectBuffer->m_Data, packet, len); + NdisAcquireSpinLock (&p_Adapter->m_Extension.m_InjectLock); + result = QueuePush (p_Adapter->m_Extension.m_InjectQueue, l_InjectBuffer); + NdisReleaseSpinLock (&p_Adapter->m_Extension.m_InjectLock); + if (result) + KeInsertQueueDpc (&p_Adapter->m_Extension.m_InjectDpc, p_Adapter, NULL); + else + INJECT_PACKET_FREE(l_InjectBuffer); + } +} + +// Handle the injection of previously deferred packets +VOID +InjectPacketDpc(KDPC *Dpc, + PVOID DeferredContext, + PVOID SystemArgument1, + PVOID SystemArgument2) +{ + InjectPacketPointer l_InjectBuffer; + TapAdapterPointer l_Adapter = (TapAdapterPointer)SystemArgument1; + while (TRUE) + { + NdisAcquireSpinLock (&l_Adapter->m_Extension.m_InjectLock); + l_InjectBuffer = QueuePop (l_Adapter->m_Extension.m_InjectQueue); + NdisReleaseSpinLock (&l_Adapter->m_Extension.m_InjectLock); + if (l_InjectBuffer) + { + InjectPacketNow(l_Adapter, l_InjectBuffer->m_Data, l_InjectBuffer->m_Size); + INJECT_PACKET_FREE(l_InjectBuffer); + } + else + break; + } +} + +// Do packet injection now +VOID +InjectPacketNow (TapAdapterPointer p_Adapter, + UCHAR *packet, + const unsigned int len) +{ + MYASSERT (len >= ETHERNET_HEADER_SIZE); + + __try + { + //------------------------------------------------------------ + // NdisMEthIndicateReceive and NdisMEthIndicateReceiveComplete + // could potentially be called reentrantly both here and in + // TapDeviceHook/IRP_MJ_WRITE. + // + // The DDK docs imply that this is okay. + // + // Note that reentrant behavior could only occur if the + // non-deferred version of InjectPacket is used. + //------------------------------------------------------------ + NdisMEthIndicateReceive + (p_Adapter->m_MiniportAdapterHandle, + (NDIS_HANDLE) p_Adapter, + packet, + ETHERNET_HEADER_SIZE, + packet + ETHERNET_HEADER_SIZE, + len - ETHERNET_HEADER_SIZE, + len - ETHERNET_HEADER_SIZE); + + NdisMEthIndicateReceiveComplete (p_Adapter->m_MiniportAdapterHandle); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + DEBUGP (("[%s] NdisMEthIndicateReceive failed in InjectPacketNow\n", + NAME (p_Adapter))); + NOTE_ERROR (); + } +} + +//=================================================================== +// Go back to default TAP mode from Point-To-Point mode. +// Also reset (i.e. disable) DHCP Masq mode. +//=================================================================== +VOID ResetTapAdapterState (TapAdapterPointer p_Adapter) +{ +#if 0 + // Point-To-Point + p_Adapter->m_tun = FALSE; + p_Adapter->m_localIP = 0; + p_Adapter->m_remoteNetwork = 0; + p_Adapter->m_remoteNetmask = 0; + NdisZeroMemory (&p_Adapter->m_TapToUser, sizeof (p_Adapter->m_TapToUser)); + NdisZeroMemory (&p_Adapter->m_UserToTap, sizeof (p_Adapter->m_UserToTap)); + NdisZeroMemory (&p_Adapter->m_UserToTap_IPv6, sizeof (p_Adapter->m_UserToTap_IPv6)); + + // DHCP Masq + p_Adapter->m_dhcp_enabled = FALSE; + p_Adapter->m_dhcp_server_arp = FALSE; + p_Adapter->m_dhcp_user_supplied_options_buffer_len = 0; + p_Adapter->m_dhcp_addr = 0; + p_Adapter->m_dhcp_netmask = 0; + p_Adapter->m_dhcp_server_ip = 0; + p_Adapter->m_dhcp_lease_time = 0; + p_Adapter->m_dhcp_received_discover = FALSE; + p_Adapter->m_dhcp_bad_requests = 0; + NdisZeroMemory (p_Adapter->m_dhcp_server_mac, sizeof (MACADDR)); +#endif +} + +#if ENABLE_NONADMIN + +//=================================================================== +// Set TAP device handle to be accessible without admin privileges. +//=================================================================== +VOID AllowNonAdmin (TapExtensionPointer p_Extension) +{ + NTSTATUS stat; + SECURITY_DESCRIPTOR sd; + OBJECT_ATTRIBUTES oa; + IO_STATUS_BLOCK isb; + HANDLE hand = NULL; + + NdisZeroMemory (&sd, sizeof (sd)); + NdisZeroMemory (&oa, sizeof (oa)); + NdisZeroMemory (&isb, sizeof (isb)); + + if (!p_Extension->m_CreatedUnicodeLinkName) + { + DEBUGP (("[TAP] AllowNonAdmin: UnicodeLinkName is uninitialized\n")); + NOTE_ERROR (); + return; + } + + stat = RtlCreateSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION); + if (stat != STATUS_SUCCESS) + { + DEBUGP (("[TAP] AllowNonAdmin: RtlCreateSecurityDescriptor failed\n")); + NOTE_ERROR (); + return; + } + + InitializeObjectAttributes ( + &oa, + &p_Extension->m_UnicodeLinkName, + OBJ_KERNEL_HANDLE, + NULL, + NULL + ); + + stat = ZwOpenFile ( + &hand, + WRITE_DAC, + &oa, + &isb, + 0, + 0 + ); + if (stat != STATUS_SUCCESS) + { + DEBUGP (("[TAP] AllowNonAdmin: ZwOpenFile failed, status=0x%08x\n", (unsigned int)stat)); + NOTE_ERROR (); + return; + } + + stat = ZwSetSecurityObject (hand, DACL_SECURITY_INFORMATION, &sd); + if (stat != STATUS_SUCCESS) + { + DEBUGP (("[TAP] AllowNonAdmin: ZwSetSecurityObject failed\n")); + NOTE_ERROR (); + return; + } + + stat = ZwClose (hand); + if (stat != STATUS_SUCCESS) + { + DEBUGP (("[TAP] AllowNonAdmin: ZwClose failed\n")); + NOTE_ERROR (); + return; + } + + DEBUGP (("[TAP] AllowNonAdmin: SUCCEEDED\n")); +} + +#endif + +#if PACKET_TRUNCATION_CHECK + +VOID +IPv4PacketSizeVerify (const UCHAR *data, ULONG length, BOOLEAN tun, const char *prefix, LONG *counter) +{ + const IPHDR *ip; + int len = length; + + if (tun) + { + ip = (IPHDR *) data; + } + else + { + if (length >= sizeof (ETH_HEADER)) + { + const ETH_HEADER *eth = (ETH_HEADER *) data; + + if (eth->proto != htons (ETH_P_IP)) + return; + + ip = (IPHDR *) (data + sizeof (ETH_HEADER)); + len -= sizeof (ETH_HEADER); + } + else + return; + } + + if (len >= sizeof (IPHDR)) + { + const int totlen = ntohs (ip->tot_len); + + DEBUGP (("[TAP] IPv4PacketSizeVerify %s len=%d totlen=%d\n", prefix, len, totlen)); + + if (len != totlen) + ++(*counter); + } +} + +#endif + +//====================================================================== +// End of Source +//====================================================================== diff --git a/windows/TapDriver/testcert.pfx b/windows/TapDriver/testcert.pfx new file mode 100644 index 00000000..74f6b471 Binary files /dev/null and b/windows/TapDriver/testcert.pfx differ diff --git a/windows/TapDriver/types.h b/windows/TapDriver/types.h new file mode 100644 index 00000000..4867a3e4 --- /dev/null +++ b/windows/TapDriver/types.h @@ -0,0 +1,182 @@ +/* + * TAP-Windows -- A kernel driver to provide virtual tap + * device functionality on Windows. + * + * This code was inspired by the CIPE-Win32 driver by Damion K. Wilson. + * + * This source code is Copyright (C) 2002-2010 OpenVPN Technologies, Inc., + * and is released under the GPL version 2 (see below). + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef TAP_TYPES_DEFINED +#define TAP_TYPES_DEFINED + +typedef struct _Queue +{ + ULONG base; + ULONG size; + ULONG capacity; + ULONG max_size; + PVOID data[]; +} Queue; + +typedef struct _TapAdapter; +typedef struct _TapPacket; + +typedef union _TapAdapterQuery +{ + NDIS_HARDWARE_STATUS m_HardwareStatus; + NDIS_MEDIUM m_Medium; + NDIS_PHYSICAL_MEDIUM m_PhysicalMedium; + UCHAR m_MacAddress [6]; + UCHAR m_Buffer [256]; + ULONG m_Long; + USHORT m_Short; + UCHAR m_Byte; +} +TapAdapterQuery, *TapAdapterQueryPointer; + +typedef struct _TapExtension +{ + // TAP device object and packet queues + Queue *m_PacketQueue, *m_IrpQueue; + PDEVICE_OBJECT m_TapDevice; + NDIS_HANDLE m_TapDeviceHandle; + ULONG m_TapOpens; + + // Used to lock packet queues + NDIS_SPIN_LOCK m_QueueLock; + BOOLEAN m_AllocatedSpinlocks; + + // Used to bracket open/close + // state changes. + MUTEX m_OpenCloseMutex; + + // True if device has been permanently halted + BOOLEAN m_Halt; + + // TAP device name + unsigned char *m_TapName; + UNICODE_STRING m_UnicodeLinkName; + BOOLEAN m_CreatedUnicodeLinkName; + + // Used for device status ioctl only + const char *m_LastErrorFilename; + int m_LastErrorLineNumber; + LONG m_NumTapOpens; + + // Flags + BOOLEAN m_TapIsRunning; + BOOLEAN m_CalledTapDeviceFreeResources; + + // DPC queue for deferred packet injection + BOOLEAN m_InjectDpcInitialized; + KDPC m_InjectDpc; + NDIS_SPIN_LOCK m_InjectLock; + Queue *m_InjectQueue; +} +TapExtension, *TapExtensionPointer; + +typedef struct _TapPacket + { +# define TAP_PACKET_SIZE(data_size) (sizeof (TapPacket) + (data_size)) +# define TP_TUN 0x80000000 +# define TP_SIZE_MASK (~TP_TUN) + ULONG m_SizeFlags; + UCHAR m_Data []; // m_Data must be the last struct member + } +TapPacket, *TapPacketPointer; + +typedef struct _InjectPacket + { +# define INJECT_PACKET_SIZE(data_size) (sizeof (InjectPacket) + (data_size)) +# define INJECT_PACKET_FREE(ib) NdisFreeMemory ((ib), INJECT_PACKET_SIZE ((ib)->m_Size), 0) + ULONG m_Size; + UCHAR m_Data []; // m_Data must be the last struct member + } +InjectPacket, *InjectPacketPointer; + +typedef struct _TapAdapter +{ +# define NAME(a) ((a)->m_NameAnsi.Buffer) + ANSI_STRING m_NameAnsi; + MACADDR m_MAC; + BOOLEAN m_InterfaceIsRunning; + NDIS_HANDLE m_MiniportAdapterHandle; + LONG m_Rx, m_Tx, m_RxErr, m_TxErr; +#if PACKET_TRUNCATION_CHECK + LONG m_RxTrunc, m_TxTrunc; +#endif + NDIS_MEDIUM m_Medium; + ULONG m_Lookahead; + ULONG m_MTU; + + // TRUE if adapter should always be + // "connected" even when device node + // is not open by a userspace process. + BOOLEAN m_MediaStateAlwaysConnected; + + // TRUE if device is "connected" + BOOLEAN m_MediaState; + + // Adapter power state + char m_DeviceState; + +#if 0 + // Info for point-to-point mode + BOOLEAN m_tun; + IPADDR m_localIP; + IPADDR m_remoteNetwork; + IPADDR m_remoteNetmask; + ETH_HEADER m_TapToUser; + ETH_HEADER m_UserToTap; + ETH_HEADER m_UserToTap_IPv6; // same as UserToTap but proto=ipv6 + MACADDR m_MAC_Broadcast; +#endif + +#if 0 + // Used for DHCP server masquerade + BOOLEAN m_dhcp_enabled; + IPADDR m_dhcp_addr; + ULONG m_dhcp_netmask; + IPADDR m_dhcp_server_ip; + BOOLEAN m_dhcp_server_arp; + MACADDR m_dhcp_server_mac; + ULONG m_dhcp_lease_time; + UCHAR m_dhcp_user_supplied_options_buffer[DHCP_USER_SUPPLIED_OPTIONS_BUFFER_SIZE]; + ULONG m_dhcp_user_supplied_options_buffer_len; + BOOLEAN m_dhcp_received_discover; + ULONG m_dhcp_bad_requests; +#endif + + // Help to tear down the adapter by keeping + // some state information on allocated + // resources. + BOOLEAN m_CalledAdapterFreeResources; + BOOLEAN m_RegisteredAdapterShutdownHandler; + + // Multicast list info + NDIS_SPIN_LOCK m_MCLock; + BOOLEAN m_MCLockAllocated; + ULONG m_MCListSize; + MC_LIST m_MCList; + + // Information on the TAP device + TapExtension m_Extension; +} TapAdapter, *TapAdapterPointer; + +#endif diff --git a/windows/TapDriver/ztTap100.inf b/windows/TapDriver/ztTap100.inf new file mode 100644 index 00000000..cf31e9ff --- /dev/null +++ b/windows/TapDriver/ztTap100.inf @@ -0,0 +1,84 @@ +[Version] +Signature="$WINDOWS NT$" +Class=Net +ClassGuid={4d36e972-e325-11ce-bfc1-08002be10318} +Provider=%Provider% +CatalogFile=ztTap100.cat + + +[Strings] +DeviceDescription = "ZeroTier One Ethernet Tap" +Provider = "ZeroTier Networks" + +[Manufacturer] +%Provider%=ztTap100,NTamd64 + +[ztTap100] +%DeviceDescription%=ztTap100.ndi,ztTap100 + +[ztTap100.NTamd64] +%DeviceDescription%=ztTap100.ndi,ztTap100 + +[ztTap100.ndi] +CopyFiles = ztTap100.driver,ztTap100.files +AddReg = ztTap100.reg +AddReg = ztTap100.params.reg +Characteristics = 0x81 + +[ztTap100.ndi.Services] +AddService = ztTap100, 2, ztTap100.service + +[ztTap100.reg] +HKR, Ndi, Service, 0, "ztTap100" +HKR, Ndi\Interfaces, UpperRange, 0, "ndis5" +HKR, Ndi\Interfaces, LowerRange, 0, "ethernet" +HKR, , Manufacturer, 0, "%Provider%" +HKR, , ProductName, 0, "%DeviceDescription%" + +[ztTap100.params.reg] +HKR, Ndi\params\MTU, ParamDesc, 0, "MTU" +HKR, Ndi\params\MTU, Type, 0, "int" +HKR, Ndi\params\MTU, Default, 0, "2800" +HKR, Ndi\params\MTU, Optional, 0, "0" +HKR, Ndi\params\MTU, Min, 0, "100" +HKR, Ndi\params\MTU, Max, 0, "2800" +HKR, Ndi\params\MTU, Step, 0, "1" +HKR, Ndi\params\MediaStatus, ParamDesc, 0, "Media Status" +HKR, Ndi\params\MediaStatus, Type, 0, "enum" +HKR, Ndi\params\MediaStatus, Default, 0, "0" +HKR, Ndi\params\MediaStatus, Optional, 0, "0" +HKR, Ndi\params\MediaStatus\enum, "0", 0, "Application Controlled" +HKR, Ndi\params\MediaStatus\enum, "1", 0, "Always Connected" +HKR, Ndi\params\MAC, ParamDesc, 0, "MAC Address" +HKR, Ndi\params\MAC, Type, 0, "edit" +HKR, Ndi\params\MAC, Optional, 0, "1" +HKR, Ndi\params\AllowNonAdmin, ParamDesc, 0, "Non-Admin Access" +HKR, Ndi\params\AllowNonAdmin, Type, 0, "enum" +HKR, Ndi\params\AllowNonAdmin, Default, 0, "0" +HKR, Ndi\params\AllowNonAdmin, Optional, 0, "0" +HKR, Ndi\params\AllowNonAdmin\enum, "0", 0, "Not Allowed" +HKR, Ndi\params\AllowNonAdmin\enum, "1", 0, "Allowed" + +[ztTap100.service] +DisplayName = %DeviceDescription% +ServiceType = 1 +StartType = 3 +ErrorControl = 1 +LoadOrderGroup = NDIS +ServiceBinary = %12%\ztTap100.sys + +[SourceDisksNames] +1 = %DeviceDescription%, ztTap100.sys + +[SourceDisksFiles] +ztTap100.sys = 1 + +[DestinationDirs] +ztTap100.files = 11 +ztTap100.driver = 12 + +[ztTap100.files] +; + +[ztTap100.driver] +ztTap100.sys,,,6 ; COPYFLG_NOSKIP | COPYFLG_NOVERSIONCHECK diff --git a/windows/ZeroTierOne.sln b/windows/ZeroTierOne.sln new file mode 100644 index 00000000..80c9c9d3 --- /dev/null +++ b/windows/ZeroTierOne.sln @@ -0,0 +1,390 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SelfTest", "SelfTest\SelfTest.vcxproj", "{DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TapDriver", "TapDriver\TapDriver.vcxproj", "{689210B1-467C-4850-BB7D-2E10D5B4A3DA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TapDriver Package", "TapDriver Package\TapDriver Package.vcxproj", "{FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}" + ProjectSection(ProjectDependencies) = postProject + {689210B1-467C-4850-BB7D-2E10D5B4A3DA} = {689210B1-467C-4850-BB7D-2E10D5B4A3DA} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZeroTierOne", "ZeroTierOne\ZeroTierOne.vcxproj", "{B00A4957-5977-4AC1-9EF4-571DC27EADA2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Any CPU = Release|Any CPU + Release|Mixed Platforms = Release|Mixed Platforms + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Vista Debug|Any CPU = Vista Debug|Any CPU + Vista Debug|Mixed Platforms = Vista Debug|Mixed Platforms + Vista Debug|Win32 = Vista Debug|Win32 + Vista Debug|x64 = Vista Debug|x64 + Vista Release|Any CPU = Vista Release|Any CPU + Vista Release|Mixed Platforms = Vista Release|Mixed Platforms + Vista Release|Win32 = Vista Release|Win32 + Vista Release|x64 = Vista Release|x64 + Win7 Debug|Any CPU = Win7 Debug|Any CPU + Win7 Debug|Mixed Platforms = Win7 Debug|Mixed Platforms + Win7 Debug|Win32 = Win7 Debug|Win32 + Win7 Debug|x64 = Win7 Debug|x64 + Win7 Release|Any CPU = Win7 Release|Any CPU + Win7 Release|Mixed Platforms = Win7 Release|Mixed Platforms + Win7 Release|Win32 = Win7 Release|Win32 + Win7 Release|x64 = Win7 Release|x64 + Win8 Debug|Any CPU = Win8 Debug|Any CPU + Win8 Debug|Mixed Platforms = Win8 Debug|Mixed Platforms + Win8 Debug|Win32 = Win8 Debug|Win32 + Win8 Debug|x64 = Win8 Debug|x64 + Win8 Release|Any CPU = Win8 Release|Any CPU + Win8 Release|Mixed Platforms = Win8 Release|Mixed Platforms + Win8 Release|Win32 = Win8 Release|Win32 + Win8 Release|x64 = Win8 Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Debug|Win32.ActiveCfg = Release|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Debug|Win32.Build.0 = Release|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Debug|x64.ActiveCfg = Debug|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Release|Any CPU.ActiveCfg = Release|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Release|Win32.ActiveCfg = Release|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Release|Win32.Build.0 = Release|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Release|x64.ActiveCfg = Release|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Debug|Any CPU.ActiveCfg = Debug|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Debug|Win32.ActiveCfg = Debug|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Debug|Win32.Build.0 = Debug|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Debug|Win32.Deploy.0 = Debug|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Debug|x64.ActiveCfg = Debug|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Release|Any CPU.ActiveCfg = Release|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Release|Mixed Platforms.ActiveCfg = Release|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Release|Win32.ActiveCfg = Release|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Release|Win32.Build.0 = Release|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Release|Win32.Deploy.0 = Release|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Vista Release|x64.ActiveCfg = Release|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Debug|Any CPU.ActiveCfg = Debug|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Debug|Win32.ActiveCfg = Debug|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Debug|Win32.Build.0 = Debug|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Debug|Win32.Deploy.0 = Debug|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Debug|x64.ActiveCfg = Debug|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Release|Any CPU.ActiveCfg = Release|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Release|Mixed Platforms.ActiveCfg = Release|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Release|Win32.ActiveCfg = Release|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Release|Win32.Build.0 = Release|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Release|Win32.Deploy.0 = Release|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win7 Release|x64.ActiveCfg = Release|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Debug|Any CPU.ActiveCfg = Debug|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Debug|Win32.ActiveCfg = Debug|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Debug|Win32.Build.0 = Debug|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Debug|Win32.Deploy.0 = Debug|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Debug|x64.ActiveCfg = Debug|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Release|Any CPU.ActiveCfg = Release|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Release|Mixed Platforms.ActiveCfg = Release|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Release|Win32.ActiveCfg = Release|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Release|Win32.Build.0 = Release|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Release|Win32.Deploy.0 = Release|Win32 + {DCD73B97-0F44-4044-8BA4-95B59CCAB4BD}.Win8 Release|x64.ActiveCfg = Release|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Debug|Any CPU.ActiveCfg = Win8 Debug|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Debug|Mixed Platforms.ActiveCfg = Win8 Debug|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Debug|Win32.ActiveCfg = Win7 Debug|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Debug|Win32.Build.0 = Win7 Debug|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Debug|Win32.Deploy.0 = Win7 Debug|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Debug|x64.ActiveCfg = Win7 Debug|x64 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Debug|x64.Build.0 = Win7 Debug|x64 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Debug|x64.Deploy.0 = Win7 Debug|x64 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Release|Any CPU.ActiveCfg = Win7 Release|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Release|Mixed Platforms.ActiveCfg = Win7 Release|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Release|Win32.ActiveCfg = Win8 Release|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Release|Win32.Build.0 = Win8 Release|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Release|Win32.Deploy.0 = Win8 Release|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Release|x64.ActiveCfg = Win7 Release|x64 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Release|x64.Build.0 = Win7 Release|x64 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Release|x64.Deploy.0 = Win7 Release|x64 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Debug|Any CPU.ActiveCfg = Vista Debug|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Debug|Mixed Platforms.ActiveCfg = Vista Debug|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Debug|Win32.ActiveCfg = Vista Debug|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Debug|Win32.Build.0 = Vista Debug|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Debug|Win32.Deploy.0 = Vista Debug|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Debug|x64.ActiveCfg = Vista Debug|x64 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Debug|x64.Build.0 = Vista Debug|x64 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Debug|x64.Deploy.0 = Vista Debug|x64 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Release|Any CPU.ActiveCfg = Vista Release|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Release|Mixed Platforms.ActiveCfg = Vista Release|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Release|Win32.ActiveCfg = Vista Release|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Release|Win32.Build.0 = Vista Release|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Release|Win32.Deploy.0 = Vista Release|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Release|x64.ActiveCfg = Vista Release|x64 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Release|x64.Build.0 = Vista Release|x64 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Vista Release|x64.Deploy.0 = Vista Release|x64 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Debug|Any CPU.ActiveCfg = Win7 Debug|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Debug|Mixed Platforms.ActiveCfg = Win7 Debug|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Debug|Win32.ActiveCfg = Win7 Debug|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Debug|Win32.Build.0 = Win7 Debug|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Debug|Win32.Deploy.0 = Win7 Debug|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Debug|x64.ActiveCfg = Win7 Debug|x64 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Debug|x64.Build.0 = Win7 Debug|x64 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Debug|x64.Deploy.0 = Win7 Debug|x64 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Release|Any CPU.ActiveCfg = Win7 Release|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Release|Mixed Platforms.ActiveCfg = Win7 Release|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Release|Win32.ActiveCfg = Win7 Release|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Release|Win32.Build.0 = Win7 Release|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Release|Win32.Deploy.0 = Win7 Release|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Release|x64.ActiveCfg = Win7 Release|x64 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Release|x64.Build.0 = Win7 Release|x64 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win7 Release|x64.Deploy.0 = Win7 Release|x64 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Debug|Any CPU.ActiveCfg = Win8 Debug|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Debug|Mixed Platforms.ActiveCfg = Win8 Debug|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Debug|Win32.ActiveCfg = Win8 Debug|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Debug|Win32.Build.0 = Win8 Debug|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Debug|Win32.Deploy.0 = Win8 Debug|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Debug|x64.ActiveCfg = Win8 Debug|x64 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Debug|x64.Build.0 = Win8 Debug|x64 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Debug|x64.Deploy.0 = Win8 Debug|x64 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Release|Any CPU.ActiveCfg = Win8 Release|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Release|Mixed Platforms.ActiveCfg = Win8 Release|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Release|Win32.ActiveCfg = Win8 Release|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Release|Win32.Build.0 = Win8 Release|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Release|Win32.Deploy.0 = Win8 Release|Win32 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Release|x64.ActiveCfg = Win8 Release|x64 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Release|x64.Build.0 = Win8 Release|x64 + {689210B1-467C-4850-BB7D-2E10D5B4A3DA}.Win8 Release|x64.Deploy.0 = Win8 Release|x64 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Debug|Any CPU.ActiveCfg = Win8 Debug|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Debug|Mixed Platforms.ActiveCfg = Win8 Debug|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Debug|Win32.ActiveCfg = Win7 Debug|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Debug|Win32.Build.0 = Win7 Debug|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Debug|Win32.Deploy.0 = Win7 Debug|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Debug|x64.ActiveCfg = Win7 Debug|x64 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Debug|x64.Build.0 = Win7 Debug|x64 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Debug|x64.Deploy.0 = Win7 Debug|x64 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Release|Any CPU.ActiveCfg = Win7 Release|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Release|Mixed Platforms.ActiveCfg = Win7 Release|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Release|Win32.ActiveCfg = Win8 Release|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Release|Win32.Build.0 = Win8 Release|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Release|Win32.Deploy.0 = Win8 Release|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Release|x64.ActiveCfg = Win7 Release|x64 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Release|x64.Build.0 = Win7 Release|x64 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Release|x64.Deploy.0 = Win7 Release|x64 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Debug|Any CPU.ActiveCfg = Vista Debug|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Debug|Mixed Platforms.ActiveCfg = Vista Debug|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Debug|Win32.ActiveCfg = Vista Debug|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Debug|Win32.Build.0 = Vista Debug|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Debug|Win32.Deploy.0 = Vista Debug|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Debug|x64.ActiveCfg = Vista Debug|x64 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Debug|x64.Build.0 = Vista Debug|x64 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Debug|x64.Deploy.0 = Vista Debug|x64 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Release|Any CPU.ActiveCfg = Vista Release|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Release|Mixed Platforms.ActiveCfg = Vista Release|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Release|Win32.ActiveCfg = Vista Release|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Release|Win32.Build.0 = Vista Release|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Release|Win32.Deploy.0 = Vista Release|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Release|x64.ActiveCfg = Vista Release|x64 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Release|x64.Build.0 = Vista Release|x64 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Vista Release|x64.Deploy.0 = Vista Release|x64 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Debug|Any CPU.ActiveCfg = Win7 Debug|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Debug|Mixed Platforms.ActiveCfg = Win7 Debug|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Debug|Win32.ActiveCfg = Win7 Debug|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Debug|Win32.Build.0 = Win7 Debug|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Debug|Win32.Deploy.0 = Win7 Debug|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Debug|x64.ActiveCfg = Win7 Debug|x64 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Debug|x64.Build.0 = Win7 Debug|x64 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Debug|x64.Deploy.0 = Win7 Debug|x64 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Release|Any CPU.ActiveCfg = Win7 Release|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Release|Mixed Platforms.ActiveCfg = Win7 Release|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Release|Win32.ActiveCfg = Win7 Release|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Release|Win32.Build.0 = Win7 Release|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Release|Win32.Deploy.0 = Win7 Release|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Release|x64.ActiveCfg = Win7 Release|x64 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Release|x64.Build.0 = Win7 Release|x64 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win7 Release|x64.Deploy.0 = Win7 Release|x64 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Debug|Any CPU.ActiveCfg = Win8 Debug|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Debug|Mixed Platforms.ActiveCfg = Win8 Debug|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Debug|Win32.ActiveCfg = Win8 Debug|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Debug|Win32.Build.0 = Win8 Debug|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Debug|Win32.Deploy.0 = Win8 Debug|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Debug|x64.ActiveCfg = Win8 Debug|x64 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Debug|x64.Build.0 = Win8 Debug|x64 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Debug|x64.Deploy.0 = Win8 Debug|x64 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Release|Any CPU.ActiveCfg = Win8 Release|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Release|Mixed Platforms.ActiveCfg = Win8 Release|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Release|Win32.ActiveCfg = Win8 Release|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Release|Win32.Build.0 = Win8 Release|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Release|Win32.Deploy.0 = Win8 Release|Win32 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Release|x64.ActiveCfg = Win8 Release|x64 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Release|x64.Build.0 = Win8 Release|x64 + {FDA1DD8D-1D56-4BC1-B402-FCC0B550D946}.Win8 Release|x64.Deploy.0 = Win8 Release|x64 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Debug|Mixed Platforms.Deploy.0 = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Debug|Win32.ActiveCfg = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Debug|Win32.Build.0 = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Debug|Win32.Deploy.0 = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Debug|x64.ActiveCfg = Debug|x64 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Debug|x64.Build.0 = Debug|x64 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Release|Any CPU.ActiveCfg = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Release|Mixed Platforms.Build.0 = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Release|Mixed Platforms.Deploy.0 = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Release|Win32.ActiveCfg = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Release|Win32.Build.0 = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Release|Win32.Deploy.0 = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Release|x64.ActiveCfg = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Debug|Any CPU.ActiveCfg = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Debug|Mixed Platforms.Build.0 = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Debug|Mixed Platforms.Deploy.0 = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Debug|Win32.ActiveCfg = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Debug|Win32.Build.0 = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Debug|Win32.Deploy.0 = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Debug|x64.ActiveCfg = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Release|Any CPU.ActiveCfg = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Release|Mixed Platforms.ActiveCfg = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Release|Mixed Platforms.Build.0 = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Release|Mixed Platforms.Deploy.0 = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Release|Win32.ActiveCfg = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Release|Win32.Build.0 = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Release|Win32.Deploy.0 = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Vista Release|x64.ActiveCfg = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Debug|Any CPU.ActiveCfg = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Debug|Mixed Platforms.Build.0 = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Debug|Mixed Platforms.Deploy.0 = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Debug|Win32.ActiveCfg = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Debug|Win32.Build.0 = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Debug|Win32.Deploy.0 = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Debug|x64.ActiveCfg = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Release|Any CPU.ActiveCfg = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Release|Mixed Platforms.ActiveCfg = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Release|Mixed Platforms.Build.0 = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Release|Mixed Platforms.Deploy.0 = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Release|Win32.ActiveCfg = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Release|Win32.Build.0 = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Release|Win32.Deploy.0 = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win7 Release|x64.ActiveCfg = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Debug|Any CPU.ActiveCfg = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Debug|Mixed Platforms.Build.0 = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Debug|Mixed Platforms.Deploy.0 = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Debug|Win32.ActiveCfg = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Debug|Win32.Build.0 = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Debug|Win32.Deploy.0 = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Debug|x64.ActiveCfg = Debug|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Release|Any CPU.ActiveCfg = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Release|Mixed Platforms.ActiveCfg = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Release|Mixed Platforms.Build.0 = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Release|Mixed Platforms.Deploy.0 = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Release|Win32.ActiveCfg = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Release|Win32.Build.0 = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Release|Win32.Deploy.0 = Release|Win32 + {B00A4957-5977-4AC1-9EF4-571DC27EADA2}.Win8 Release|x64.ActiveCfg = Release|Win32 + {079E8119-388C-4676-964E-0B8C5324F770}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Debug|Any CPU.Build.0 = Debug|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Debug|Win32.ActiveCfg = Debug|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Debug|x64.ActiveCfg = Debug|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Release|Any CPU.ActiveCfg = Release|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Release|Any CPU.Build.0 = Release|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Release|Win32.ActiveCfg = Release|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Release|x64.ActiveCfg = Release|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Vista Debug|Any CPU.ActiveCfg = Debug|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Vista Debug|Any CPU.Build.0 = Debug|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Vista Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Vista Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Vista Debug|Win32.ActiveCfg = Debug|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Vista Debug|x64.ActiveCfg = Debug|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Vista Release|Any CPU.ActiveCfg = Release|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Vista Release|Any CPU.Build.0 = Release|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Vista Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Vista Release|Mixed Platforms.Build.0 = Release|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Vista Release|Win32.ActiveCfg = Release|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Vista Release|x64.ActiveCfg = Release|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Win7 Debug|Any CPU.ActiveCfg = Debug|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Win7 Debug|Any CPU.Build.0 = Debug|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Win7 Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Win7 Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Win7 Debug|Win32.ActiveCfg = Debug|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Win7 Debug|x64.ActiveCfg = Debug|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Win7 Release|Any CPU.ActiveCfg = Release|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Win7 Release|Any CPU.Build.0 = Release|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Win7 Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Win7 Release|Mixed Platforms.Build.0 = Release|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Win7 Release|Win32.ActiveCfg = Release|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Win7 Release|x64.ActiveCfg = Release|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Win8 Debug|Any CPU.ActiveCfg = Debug|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Win8 Debug|Any CPU.Build.0 = Debug|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Win8 Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Win8 Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Win8 Debug|Win32.ActiveCfg = Debug|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Win8 Debug|x64.ActiveCfg = Debug|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Win8 Release|Any CPU.ActiveCfg = Release|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Win8 Release|Any CPU.Build.0 = Release|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Win8 Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Win8 Release|Mixed Platforms.Build.0 = Release|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Win8 Release|Win32.ActiveCfg = Release|Any CPU + {079E8119-388C-4676-964E-0B8C5324F770}.Win8 Release|x64.ActiveCfg = Release|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Debug|Win32.ActiveCfg = Debug|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Debug|x64.ActiveCfg = Debug|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Release|Any CPU.Build.0 = Release|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Release|Win32.ActiveCfg = Release|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Release|x64.ActiveCfg = Release|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Vista Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Vista Debug|Any CPU.Build.0 = Debug|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Vista Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Vista Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Vista Debug|Win32.ActiveCfg = Debug|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Vista Debug|x64.ActiveCfg = Debug|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Vista Release|Any CPU.ActiveCfg = Release|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Vista Release|Any CPU.Build.0 = Release|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Vista Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Vista Release|Mixed Platforms.Build.0 = Release|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Vista Release|Win32.ActiveCfg = Release|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Vista Release|x64.ActiveCfg = Release|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win7 Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win7 Debug|Any CPU.Build.0 = Debug|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win7 Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win7 Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win7 Debug|Win32.ActiveCfg = Debug|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win7 Debug|x64.ActiveCfg = Debug|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win7 Release|Any CPU.ActiveCfg = Release|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win7 Release|Any CPU.Build.0 = Release|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win7 Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win7 Release|Mixed Platforms.Build.0 = Release|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win7 Release|Win32.ActiveCfg = Release|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win7 Release|x64.ActiveCfg = Release|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win8 Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win8 Debug|Any CPU.Build.0 = Debug|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win8 Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win8 Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win8 Debug|Win32.ActiveCfg = Debug|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win8 Debug|x64.ActiveCfg = Debug|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win8 Release|Any CPU.ActiveCfg = Release|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win8 Release|Any CPU.Build.0 = Release|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win8 Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win8 Release|Mixed Platforms.Build.0 = Release|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win8 Release|Win32.ActiveCfg = Release|Any CPU + {B2A5CD75-E0FF-42A3-833A-0C6B0278CFEA}.Win8 Release|x64.ActiveCfg = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/windows/ZeroTierOne/ZeroTierOne.vcxproj b/windows/ZeroTierOne/ZeroTierOne.vcxproj new file mode 100644 index 00000000..2d01154d --- /dev/null +++ b/windows/ZeroTierOne/ZeroTierOne.vcxproj @@ -0,0 +1,228 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {B00A4957-5977-4AC1-9EF4-571DC27EADA2} + ZeroTierOne + + + + Application + true + v110 + MultiByte + + + Application + true + v110 + MultiByte + + + Application + false + v110 + true + MultiByte + + + Application + false + v110 + true + MultiByte + + + + + + + + + + + + + + + + + + + .exe + $(SolutionDir)\Build\$(Platform)\$(Configuration)\ + zerotier-one-x86 + + + .exe + $(SolutionDir)\Build\$(Platform)\$(Configuration)\ + zerotier-one-x86 + + + .exe + $(SolutionDir)\Build\$(Platform)\$(Configuration)\ + zerotier-one-x64 + + + .exe + $(SolutionDir)\Build\$(Platform)\$(Configuration)\ + zerotier-one-x64 + + + + Level3 + Disabled + true + $(SolutionDir)\ext\bin\libcrypto\include + ZT_LOG_STDOUT;ZT_TRACE;%(PreprocessorDefinitions) + + + true + wsock32.lib;ws2_32.lib;iphlpapi.lib;rpcrt4.lib;$(SolutionDir)\ext\bin\libcrypto\win32-vs2012\libeay32.lib;%(AdditionalDependencies) + false + + + + + Level3 + Disabled + true + $(SolutionDir)\ext\bin\libcrypto\include + ZT_LOG_STDOUT;ZT_TRACE;%(PreprocessorDefinitions) + + + true + wsock32.lib;ws2_32.lib;iphlpapi.lib;rpcrt4.lib;$(SolutionDir)\ext\bin\libcrypto\win64-vs2012\libeay32.lib;%(AdditionalDependencies) + false + + + + + Level3 + MaxSpeed + true + true + true + $(SolutionDir)\ext\bin\libcrypto\include + ZT_LOG_STDOUT;ZT_TRACE;%(PreprocessorDefinitions) + + + true + true + true + wsock32.lib;ws2_32.lib;iphlpapi.lib;rpcrt4.lib;$(SolutionDir)\ext\bin\libcrypto\win32-vs2012\libeay32.lib;%(AdditionalDependencies) + false + + + + + Level3 + MaxSpeed + true + true + true + $(SolutionDir)\ext\bin\libcrypto\include + ZT_LOG_STDOUT;ZT_TRACE;%(PreprocessorDefinitions) + + + true + true + true + wsock32.lib;ws2_32.lib;iphlpapi.lib;rpcrt4.lib;$(SolutionDir)\ext\bin\libcrypto\win64-vs2012\libeay32.lib;%(AdditionalDependencies) + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/windows/ZeroTierOne/ZeroTierOne.vcxproj.filters b/windows/ZeroTierOne/ZeroTierOne.vcxproj.filters new file mode 100644 index 00000000..67e668e1 --- /dev/null +++ b/windows/ZeroTierOne/ZeroTierOne.vcxproj.filters @@ -0,0 +1,228 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file -- cgit v1.2.3