1 // SoftEther VPN Source Code - Stable Edition Repository 2 // Windows Filtering Platform Callout Driver for Capturing IPsec Packets on Windows Vista / 7 / Server 2008 3 // 4 // SoftEther VPN Server, Client and Bridge are free software under the Apache License, Version 2.0. 5 // 6 // Copyright (c) Daiyuu Nobori. 7 // Copyright (c) SoftEther VPN Project, University of Tsukuba, Japan. 8 // Copyright (c) SoftEther Corporation. 9 // Copyright (c) all contributors on SoftEther VPN project in GitHub. 10 // 11 // All Rights Reserved. 12 // 13 // http://www.softether.org/ 14 // 15 // This stable branch is officially managed by Daiyuu Nobori, the owner of SoftEther VPN Project. 16 // Pull requests should be sent to the Developer Edition Master Repository on https://github.com/SoftEtherVPN/SoftEtherVPN 17 // 18 // License: The Apache License, Version 2.0 19 // https://www.apache.org/licenses/LICENSE-2.0 20 // 21 // DISCLAIMER 22 // ========== 23 // 24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 29 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 // SOFTWARE. 31 // 32 // THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN, UNDER 33 // JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY, MERGE, PUBLISH, 34 // DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS SOFTWARE, THAT ANY 35 // JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS SOFTWARE OR ITS CONTENTS, 36 // AGAINST US (SOFTETHER PROJECT, SOFTETHER CORPORATION, DAIYUU NOBORI OR OTHER 37 // SUPPLIERS), OR ANY JURIDICAL DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND 38 // OF USING, COPYING, MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, 39 // AND/OR SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND 40 // CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO EXCLUSIVE 41 // JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO, JAPAN. YOU MUST WAIVE 42 // ALL DEFENSES OF LACK OF PERSONAL JURISDICTION AND FORUM NON CONVENIENS. 43 // PROCESS MAY BE SERVED ON EITHER PARTY IN THE MANNER AUTHORIZED BY APPLICABLE 44 // LAW OR COURT RULE. 45 // 46 // USE ONLY IN JAPAN. DO NOT USE THIS SOFTWARE IN ANOTHER COUNTRY UNLESS YOU HAVE 47 // A CONFIRMATION THAT THIS SOFTWARE DOES NOT VIOLATE ANY CRIMINAL LAWS OR CIVIL 48 // RIGHTS IN THAT PARTICULAR COUNTRY. USING THIS SOFTWARE IN OTHER COUNTRIES IS 49 // COMPLETELY AT YOUR OWN RISK. THE SOFTETHER VPN PROJECT HAS DEVELOPED AND 50 // DISTRIBUTED THIS SOFTWARE TO COMPLY ONLY WITH THE JAPANESE LAWS AND EXISTING 51 // CIVIL RIGHTS INCLUDING PATENTS WHICH ARE SUBJECTS APPLY IN JAPAN. OTHER 52 // COUNTRIES' LAWS OR CIVIL RIGHTS ARE NONE OF OUR CONCERNS NOR RESPONSIBILITIES. 53 // WE HAVE NEVER INVESTIGATED ANY CRIMINAL REGULATIONS, CIVIL LAWS OR 54 // INTELLECTUAL PROPERTY RIGHTS INCLUDING PATENTS IN ANY OF OTHER 200+ COUNTRIES 55 // AND TERRITORIES. BY NATURE, THERE ARE 200+ REGIONS IN THE WORLD, WITH 56 // DIFFERENT LAWS. IT IS IMPOSSIBLE TO VERIFY EVERY COUNTRIES' LAWS, REGULATIONS 57 // AND CIVIL RIGHTS TO MAKE THE SOFTWARE COMPLY WITH ALL COUNTRIES' LAWS BY THE 58 // PROJECT. EVEN IF YOU WILL BE SUED BY A PRIVATE ENTITY OR BE DAMAGED BY A 59 // PUBLIC SERVANT IN YOUR COUNTRY, THE DEVELOPERS OF THIS SOFTWARE WILL NEVER BE 60 // LIABLE TO RECOVER OR COMPENSATE SUCH DAMAGES, CRIMINAL OR CIVIL 61 // RESPONSIBILITIES. NOTE THAT THIS LINE IS NOT LICENSE RESTRICTION BUT JUST A 62 // STATEMENT FOR WARNING AND DISCLAIMER. 63 // 64 // READ AND UNDERSTAND THE 'WARNING.TXT' FILE BEFORE USING THIS SOFTWARE. 65 // SOME SOFTWARE PROGRAMS FROM THIRD PARTIES ARE INCLUDED ON THIS SOFTWARE WITH 66 // LICENSE CONDITIONS WHICH ARE DESCRIBED ON THE 'THIRD_PARTY.TXT' FILE. 67 // 68 // 69 // SOURCE CODE CONTRIBUTION 70 // ------------------------ 71 // 72 // Your contribution to SoftEther VPN Project is much appreciated. 73 // Please send patches to us through GitHub. 74 // Read the SoftEther VPN Patch Acceptance Policy in advance: 75 // http://www.softether.org/5-download/src/9.patch 76 // 77 // 78 // DEAR SECURITY EXPERTS 79 // --------------------- 80 // 81 // If you find a bug or a security vulnerability please kindly inform us 82 // about the problem immediately so that we can fix the security problem 83 // to protect a lot of users around the world as soon as possible. 84 // 85 // Our e-mail address for security reports is: 86 // softether-vpn-security [at] softether.org 87 // 88 // Please note that the above e-mail address is not a technical support 89 // inquiry address. If you need technical assistance, please visit 90 // http://www.softether.org/ and ask your question on the users forum. 91 // 92 // Thank you for your cooperation. 93 // 94 // 95 // NO MEMORY OR RESOURCE LEAKS 96 // --------------------------- 97 // 98 // The memory-leaks and resource-leaks verification under the stress 99 // test has been passed before release this source code. 100 101 102 // WfpInner.h 103 // Header File for WFP Callout Driver 104 105 #ifndef WFPINNER_H 106 #define WFPINNER_H 107 108 // Win32 DDK related 109 #ifndef CPU_64 110 #define _X86_ 111 #define i386 112 #else // CPU_64 113 #define _AMD64_ 114 #define AMD64 115 #define x64 116 #endif // CPU_64 117 118 #define STD_CALL 119 #define CONDITION_HANDLING 1 120 #define NT_UP 1 121 #define NT_INST 0 122 #define _NT1X_ 100 123 #define _WIN32_WINNT 0x0600 124 #define WINNT 1 125 #define WINVER 0x0600 126 #define _WIN32_IE 0x0700 127 #define WIN32_LEAN_AND_MEAN 1 128 #define DEVL 1 129 #define __BUILDMACHINE__ WinDDK 130 #define FPO 0 131 #define BINARY_COMPATIBLE 0 132 #define NT 133 #define NDIS60 1 134 #define NDIS_SUPPORT_NDIS6 1 135 #define NTDDI_VERSION 0x06000100 136 137 #define KMDF_MAJOR_VERSION_STRING 01 138 #define KMDF_MINOR_VERSION_STRING 009 139 140 #include <ntddk.h> 141 #include <fwpsk.h> 142 #include <fwpmk.h> 143 #include <ndis.h> 144 #include <ws2ipdef.h> 145 #include <in6addr.h> 146 #include <ip2string.h> 147 #include <stdio.h> 148 #include <string.h> 149 #define INITGUID 150 #include <guiddef.h> 151 152 #define TRUE 1 153 #define FALSE 0 154 typedef unsigned long bool; 155 #define true 1 156 #define false 0 157 typedef unsigned long long UINT64; 158 typedef signed long long INT64; 159 typedef unsigned short WORD; 160 typedef unsigned short USHORT; 161 typedef signed short SHORT; 162 typedef unsigned char BYTE; 163 typedef unsigned char UCHAR; 164 typedef signed char CHAR; 165 typedef unsigned long DWORD; 166 #define INFINITE 0xFFFFFFFF 167 168 #define LESS(a, max_value) ((a) < (max_value) ? (a) : (max_value)) 169 #define MORE(a, min_value) ((a) > (min_value) ? (a) : (min_value)) 170 #define INNER(a, b, c) (((b) <= (c) && (a) >= (b) && (a) <= (c)) || ((b) >= (c) && (a) >= (c) && (a) <= (b))) 171 #define OUTER(a, b, c) (!INNER((a), (b), (c))) 172 #define MAKESURE(a, b, c) (((b) <= (c)) ? (MORE(LESS((a), (c)), (b))) : (MORE(LESS((a), (b)), (c)))) 173 #define MIN(a, b) ((a) >= (b) ? (b) : (a)) 174 #define MAX(a, b) ((a) >= (b) ? (a) : (b)) 175 176 // Error checking macro 177 #define OK(val) (val == STATUS_SUCCESS) 178 #define NG(val) (!OK(val)) 179 #define CRUSH_WHERE //Crush(0xaaaaaaaa, __LINE__, __LINE__, __LINE__) 180 181 // Constants 182 #define MEMPOOL_TAG 'wpfx' 183 #define WFP_MAX_LOCAL_IP_COUNT 4096 184 185 // Tag constant 186 #define WFP_ESP_PACKET_TAG_1 0x19841117 187 #define WFP_ESP_PACKET_TAG_2 0x1accafe1 188 189 // ESP protocol number 190 #define WFP_ESP_RAW_PROTOCOL_ID 50 191 #define WFP_ESP_RAW_PROTOCOL_ID_DST 52 192 193 // Event 194 typedef struct EVENT 195 { 196 KEVENT *EventObj; 197 HANDLE Handle; 198 } EVENT; 199 200 // Spin lock 201 typedef struct SPINLOCK 202 { 203 KSPIN_LOCK SpinLock; 204 KIRQL OldIrql; 205 } SPINLOCK; 206 207 // Instance data 208 typedef struct WFP_CTX 209 { 210 DEVICE_OBJECT *DeviceObject; 211 UNICODE_STRING DeviceName; 212 UNICODE_STRING DeviceNameWin32; 213 EVENT *Event; 214 HANDLE hEngine; 215 bool Halting; 216 UINT CalloutIdIPv4; 217 UINT CalloutIdIPv6; 218 UINT CalloutObjIdIPv4; 219 UINT CalloutObjIdIPv6; 220 SPINLOCK *LocalIPListLock; 221 UCHAR *LocalIPListData; 222 UINT LocalIPListSize; 223 HANDLE hInjectionIPv4, hInjectionIPv6; 224 NDIS_HANDLE hNdis; 225 } WFP_CTX; 226 227 #pragma pack(push, 1) 228 229 #define WFP_IP_PROTO_UDP 0x11 // UDP protocol 230 231 // IPv4 header 232 typedef struct WFP_IPV4_HEADER 233 { 234 UCHAR VersionAndHeaderLength; // Version and header size 235 UCHAR TypeOfService; // Service Type 236 USHORT TotalLength; // Total size 237 USHORT Identification; // Identifier 238 UCHAR FlagsAndFlagmentOffset[2]; // The flag and fragment offset 239 UCHAR TimeToLive; // TTL 240 UCHAR Protocol; // Protocol 241 USHORT Checksum; // Checksum 242 UINT SrcIP; // Source IP address 243 UINT DstIP; // Destination IP address 244 } WFP_IPV4_HEADER; 245 246 // IPv6 header 247 typedef struct WFP_IPV6_HEADER 248 { 249 UCHAR VersionAndTrafficClass1; // Version Number (4 bit) and Traffic Class 1 (4 bit) 250 UCHAR TrafficClass2AndFlowLabel1; // Traffic Class 2 (4 bit) and Flow Label 1 (4 bit) 251 UCHAR FlowLabel2; // Flow Label 2 (8 bit) 252 UCHAR FlowLabel3; // Flow Label 3 (8 bit) 253 USHORT PayloadLength; // Length of the payload (including extension header) 254 UCHAR NextHeader; // The next header 255 UCHAR HopLimit; // Hop limit 256 UCHAR SrcAddress[16]; // Source address 257 UCHAR DestAddress[16]; // Destination address 258 } WFP_IPV6_HEADER; 259 260 // UDP header 261 typedef struct WFP_UDP_HEADER 262 { 263 USHORT SrcPort; // Source port number 264 USHORT DstPort; // Destination port number 265 USHORT PacketLength; // Data length 266 USHORT Checksum; // Checksum 267 } WFP_UDP_HEADER; 268 269 // Context of injected packet 270 typedef struct WFP_INJECTED_PACKET_CONTEXT 271 { 272 NET_BUFFER OriginalNetBufferData; // Data of the original NET_BUFFER 273 NET_BUFFER *CurrentNetBuffer; // Pointer of the current NET_BUFFER 274 NET_BUFFER_LIST *AllocatedNetBufferList; // Newly allocated NET_BUFFER_LIST 275 MDL *AllocatedMdl; // MDL that newly allocated 276 void *AllocatedMemory; // Newly allocated memory 277 } WFP_INJECTED_PACKET_CONTEXT; 278 279 280 #pragma pack(pop) 281 282 283 // Function prototype 284 NTSTATUS DriverEntry(DRIVER_OBJECT *driver_object, UNICODE_STRING *registry_path); 285 void DriverUnload(DRIVER_OBJECT *driver_object); 286 NTSTATUS DriverDispatch(DEVICE_OBJECT *device_object, IRP *irp); 287 288 void NTAPI CalloutClassify(const FWPS_INCOMING_VALUES0* inFixedValues, 289 const FWPS_INCOMING_METADATA_VALUES0* inMetaValues, 290 void* layerData, 291 const FWPS_FILTER0* filter, 292 UINT64 flowContext, 293 FWPS_CLASSIFY_OUT0* classifyOut); 294 NTSTATUS NTAPI CalloutNotify(FWPS_CALLOUT_NOTIFY_TYPE notifyType, 295 const GUID* filterKey, FWPS_FILTER0* filter); 296 bool IsIPAddressInList(struct WFP_LOCAL_IP *ip); 297 bool IsIPv4AddressInList(void *addr); 298 bool IsIPv6AddressInList(void *addr); 299 void FreeInjectionCtx(WFP_INJECTED_PACKET_CONTEXT *ctx); 300 UCHAR *ModificationOfIPsecESPPacket(UCHAR *ip_packet, UINT ip_packet_size, UINT ip_header_size, UINT *dst_size_ptr, bool isv6); 301 USHORT IpChecksum(void *buf, UINT size); 302 bool InjectPacket(HANDLE hInjection, NET_BUFFER_LIST *nbl, UCHAR *dst_data, UINT dst_size, const FWPS_INCOMING_VALUES0* inFixedValues, const FWPS_INCOMING_METADATA_VALUES0* inMetaValues); 303 304 void *Malloc(UINT size); 305 void *ZeroMalloc(UINT size); 306 void Free(void *p); 307 void *ReAlloc(void *p, UINT size); 308 void Copy(void *dst, void *src, UINT size); 309 UINT GetMemSize(void *p); 310 void Zero(void *p, UINT size); 311 UINT Cmp(void *p1, void *p2, UINT size); 312 SPINLOCK *NewSpinLock(); 313 void SpinLock(SPINLOCK *s); 314 void SpinUnlock(SPINLOCK *s); 315 void FreeSpinLock(SPINLOCK *s); 316 EVENT *NewEvent(wchar_t *name); 317 void FreeEvent(EVENT *e); 318 void SetEvent(EVENT *e); 319 void ResetEvent(EVENT *e); 320 void Sleep(int milliSeconds); 321 USHORT Swap16(USHORT value); 322 UINT Swap32(UINT value); 323 UINT64 Swap64(UINT64 value); 324 USHORT Endian16(USHORT src); 325 UINT Endian32(UINT src); 326 UINT64 Endian64(UINT64 src); 327 328 void Crush(); 329 330 331 #endif // WFPINNER_H 332 333