diff --git a/CHANGELOG b/CHANGELOG index ba6bbc3..d3273a4 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -18,3 +18,17 @@ WinDivert 1.0.4 WinDivert 1.0.5 - Fix the DIVERT_NETWORK_FORWARD_LAYER implementation. - Upgrade Visual Studio support to 2012. +WinDivert 1.1.0 + - Re-brand "DIVERT" to "WINDIVERT" throughout the code-base. + - New flags: + * WINDIVERT_FLAG_PASSTHRU: Do not drop nor capture packets. Useful + for injection-only handles. + * WINDIVERT_FLAG_NO_CHECKSUM: Do not guarantee that diverted packets + have a correct checksum. + - New default values and limits for various WinDivert parameters, + including WINDIVERT_PARAM_QUEUE_LEN, WINDIVERT_PARAM_QUEUE_TIME, and + the maximum filter length. + - New extended WinDivert functions that support asynchronous I/O: + * WinDivertRecvEx(..) + * WinDivertSendEx(..) + - The WinDivert driver now services reads (receives) out-of-band. diff --git a/README b/README index aad5569..824b48f 100644 --- a/README +++ b/README @@ -1,11 +1,11 @@ -WinDivert 1.0: Windows Packet Divert +WinDivert 1.1: Windows Packet Divert ==================================== 1. Introduction --------------- Windows Packet Divert (WinDivert) is a user-mode packet capture-and-divert -package for Windows Vista, Windows 2008, and Windows 7. +package for Windows Vista, Windows 2008, Windows 7, and Windows 8. With WinDivert developers can write user-mode programs that capture and modify or drop network packets sent to/from the Windows network stack. @@ -99,7 +99,7 @@ following then happens sh mingw-build.sh -For more detailed build instructions, see doc\divert.html +For more detailed build instructions, see doc\windivert.html 5. License ---------- diff --git a/VERSION b/VERSION index 90a27f9..9084fa2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.5 +1.1.0 diff --git a/dll/divert.def b/dll/divert.def deleted file mode 100644 index 74ccd52..0000000 --- a/dll/divert.def +++ /dev/null @@ -1,13 +0,0 @@ -LIBRARY WinDivert -EXPORTS - DivertDllEntry - DivertOpen - DivertRecv - DivertSend - DivertClose - DivertSetParam - DivertGetParam - DivertHelperCalcChecksums - DivertHelperParsePacket - DivertHelperParseIPv4Address - DivertHelperParseIPv6Address diff --git a/dll/sources b/dll/sources index 3325a4d..693c1ee 100644 --- a/dll/sources +++ b/dll/sources @@ -1,5 +1,5 @@ # sources -# (C) 2012, all rights reserved, +# (C) 2013, all rights reserved, # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by @@ -24,9 +24,9 @@ TARGETLIBS=\ $(SDK_LIB_PATH)\kernel32.lib \ $(SDK_LIB_PATH)\ws2_32.lib C_DEFINES=/DWIN32 /D_WINDOWS /D_USRDLL /DUSE_STDAFX /DUNICODE /D_UNICODE -DLLENTRY=DivertDllEntry -DLLDEF=divert.def +DLLENTRY=WinDivertDllEntry +DLLDEF=windivert.def USE_MSVCRT=1 INCLUDES=$(DDK_INC_PATH);$(KMDF_INC_PATH)\$(KMDF_VER_PATH);..\include -SOURCES=divert.c +SOURCES=windivert.c diff --git a/dll/divert.c b/dll/windivert.c similarity index 64% rename from dll/divert.c rename to dll/windivert.c index 2102798..e8c1d51 100644 --- a/dll/divert.c +++ b/dll/windivert.c @@ -1,6 +1,6 @@ /* - * divert.c - * (C) 2012, all rights reserved, + * windivert.c + * (C) 2013, all rights reserved, * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -29,8 +29,8 @@ #include #ifdef __MINGW32__ -#define wcscpy_s(s1, l, s2) divert_wcscpy_s((s1), (l), (s2)) -static int divert_wcscpy_s(wchar_t *dst, size_t len, wchar_t *src) +#define wcscpy_s(s1, l, s2) windivert_wcscpy_s((s1), (l), (s2)) +static int windivert_wcscpy_s(wchar_t *dst, size_t len, wchar_t *src) { wcscpy(dst, src); return 0; @@ -70,17 +70,17 @@ typedef ULONG (WINAPI *PFN_WDFPOSTDEVICEREMOVE)( LPCWSTR inf_sec_name ); -// #define DIVERT_DEBUG +// #define WINDIVERT_DEBUG -#define DIVERTEXPORT -#include "divert.h" -#include "divert_device.h" +#define WINDIVERTEXPORT +#include "windivert.h" +#include "windivert_device.h" -#define DIVERT_DRIVER_NAME L"WinDivert" -#define DIVERT_DRIVER_SYS L"\\" DIVERT_DRIVER_NAME L".sys" -#define DIVERT_DRIVER_INF L"\\" DIVERT_DRIVER_NAME L".inf" -#define DIVERT_DRIVER_SECTION L"divert.NT.Wdf" -#define DIVERT_DRIVER_MATCH_DLL L"\\WdfCoInstaller*.dll" +#define WINDIVERT_DRIVER_NAME L"WinDivert" +#define WINDIVERT_DRIVER_SYS L"\\" WINDIVERT_DRIVER_NAME L".sys" +#define WINDIVERT_DRIVER_INF L"\\" WINDIVERT_DRIVER_NAME L".inf" +#define WINDIVERT_DRIVER_SECTION L"windivert.NT.Wdf" +#define WINDIVERT_DRIVER_MATCH_DLL L"\\WdfCoInstaller*.dll" /* * ntoh and hton implementation to remove winsock dependency. @@ -198,7 +198,7 @@ typedef struct UINT8 Zero; UINT8 Protocol; UINT16 Length; -} DIVERT_PSEUDOHDR, *PDIVERT_PSEUDOHDR; +} WINDIVERT_PSEUDOHDR, *PWINDIVERT_PSEUDOHDR; typedef struct { @@ -207,7 +207,7 @@ typedef struct UINT32 Length; UINT32 NextHdr:8; UINT32 Zero:24; -} DIVERT_PSEUDOV6HDR, *PDIVERT_PSEUDOV6HDR; +} WINDIVERT_PSEUDOV6HDR, *PWINDIVERT_PSEUDOV6HDR; /* * Misc. @@ -231,31 +231,34 @@ static BOOLEAN installed = FALSE; /* * Prototypes. */ -static HMODULE DivertLoadCoInstaller(LPWSTR divert_dll); -static BOOLEAN DivertDriverFiles(LPWSTR *dir_str_ptr, LPWSTR *sys_str_ptr, +static HMODULE WinDivertLoadCoInstaller(LPWSTR windivert_dll); +static BOOLEAN WinDivertDriverFiles(LPWSTR *dir_str_ptr, LPWSTR *sys_str_ptr, LPWSTR *inf_str_ptr, LPWSTR *dll_str_ptr); -static BOOLEAN DivertDriverInstall(VOID); -static BOOLEAN DivertDriverUnInstall(VOID); -static BOOL DivertIoControl(HANDLE handle, DWORD code, UINT8 arg8, UINT64 arg, - PVOID buf, UINT len, UINT *iolen); -static BOOL DivertCompileFilter(const char *filter_str, DIVERT_LAYER layer, - divert_ioctl_filter_t filter, UINT16 *fp); -static int __cdecl DivertFilterTokenNameCompare(const void *a, const void *b); -static BOOL DivertTokenizeFilter(const char *filter, DIVERT_LAYER layer, +static BOOLEAN WinDivertDriverInstall(VOID); +static BOOLEAN WinDivertDriverUnInstall(VOID); +static BOOL WinDivertIoControl(HANDLE handle, DWORD code, UINT8 arg8, + UINT64 arg, PVOID buf, UINT len, UINT *iolen); +static BOOL WinDivertIoControlEx(HANDLE handle, DWORD code, UINT8 arg8, + UINT64 arg, PVOID buf, UINT len, UINT *iolen, LPOVERLAPPED overlapped); +static BOOL WinDivertCompileFilter(const char *filter_str, + WINDIVERT_LAYER layer, windivert_ioctl_filter_t filter, UINT16 *fp); +static int __cdecl WinDivertFilterTokenNameCompare(const void *a, + const void *b); +static BOOL WinDivertTokenizeFilter(const char *filter, WINDIVERT_LAYER layer, FILTER_TOKEN *tokens, UINT tokensmax); -static BOOL DivertParseFilter(FILTER_TOKEN *tokens, UINT16 *tp, - divert_ioctl_filter_t filter, UINT16 *fp, FILTER_TOKEN_KIND op); -static void DivertFilterUpdate(divert_ioctl_filter_t filter, UINT16 s, +static BOOL WinDivertParseFilter(FILTER_TOKEN *tokens, UINT16 *tp, + windivert_ioctl_filter_t filter, UINT16 *fp, FILTER_TOKEN_KIND op); +static void WinDivertFilterUpdate(windivert_ioctl_filter_t filter, UINT16 s, UINT16 e, UINT16 success, UINT16 failure); -static void DivertInitPseudoHeader(PDIVERT_IPHDR ip_header, - PDIVERT_PSEUDOHDR pseudo_header, UINT8 protocol, UINT len); -static void DivertInitPseudoHeaderV6(PDIVERT_IPV6HDR ipv6_header, - PDIVERT_PSEUDOV6HDR pseudov6_header, UINT8 protocol, UINT len); -static UINT16 DivertHelperCalcChecksum(PVOID pseudo_header, +static void WinDivertInitPseudoHeader(PWINDIVERT_IPHDR ip_header, + PWINDIVERT_PSEUDOHDR pseudo_header, UINT8 protocol, UINT len); +static void WinDivertInitPseudoHeaderV6(PWINDIVERT_IPV6HDR ipv6_header, + PWINDIVERT_PSEUDOV6HDR pseudov6_header, UINT8 protocol, UINT len); +static UINT16 WinDivertHelperCalcChecksum(PVOID pseudo_header, UINT16 pseudo_header_len, PVOID data, UINT len); -#ifdef DIVERT_DEBUG -static void DivertFilterDump(divert_ioctl_filter_t filter, UINT16 len); +#ifdef WINDIVERT_DEBUG +static void WinDivertFilterDump(windivert_ioctl_filter_t filter, UINT16 len); #endif /* @@ -269,19 +272,19 @@ PFN_WDFPOSTDEVICEREMOVE pfnWdfPostDeviceRemove = NULL; /* * Thread local. */ -static DWORD divert_tls_idx; +static DWORD windivert_tls_idx; /* * Dll Entry */ -extern BOOL APIENTRY DivertDllEntry(HANDLE module, DWORD reason, +extern BOOL APIENTRY WinDivertDllEntry(HANDLE module, DWORD reason, LPVOID reserved) { HANDLE event; switch (reason) { case DLL_PROCESS_ATTACH: - if ((divert_tls_idx = TlsAlloc()) == TLS_OUT_OF_INDEXES) + if ((windivert_tls_idx = TlsAlloc()) == TLS_OUT_OF_INDEXES) { return FALSE; } @@ -292,21 +295,21 @@ extern BOOL APIENTRY DivertDllEntry(HANDLE module, DWORD reason, { return FALSE; } - TlsSetValue(divert_tls_idx, (LPVOID)event); + TlsSetValue(windivert_tls_idx, (LPVOID)event); break; case DLL_PROCESS_DETACH: - event = (HANDLE)TlsGetValue(divert_tls_idx); + event = (HANDLE)TlsGetValue(windivert_tls_idx); if (event != (HANDLE)NULL) { CloseHandle(event); } - TlsFree(divert_tls_idx); - DivertDriverUnInstall(); + TlsFree(windivert_tls_idx); + WinDivertDriverUnInstall(); break; case DLL_THREAD_DETACH: - event = (HANDLE)TlsGetValue(divert_tls_idx); + event = (HANDLE)TlsGetValue(windivert_tls_idx); if (event != (HANDLE)NULL) { CloseHandle(event); @@ -319,7 +322,7 @@ extern BOOL APIENTRY DivertDllEntry(HANDLE module, DWORD reason, /* * Load the co-installer functions. */ -static HMODULE DivertLoadCoInstaller(LPWSTR divert_dll) +static HMODULE WinDivertLoadCoInstaller(LPWSTR windivert_dll) { static HMODULE library = NULL; @@ -328,7 +331,7 @@ static HMODULE DivertLoadCoInstaller(LPWSTR divert_dll) return library; } - library = LoadLibrary(divert_dll); + library = LoadLibrary(windivert_dll); if (library == NULL) { return NULL; @@ -338,30 +341,30 @@ static HMODULE DivertLoadCoInstaller(LPWSTR divert_dll) library, "WdfPreDeviceInstallEx"); if (pfnWdfPreDeviceInstallEx == NULL) { - goto DivertLoadInstallerError; + goto WinDivertLoadInstallerError; } pfnWdfPostDeviceInstall = (PFN_WDFPOSTDEVICEINSTALL)GetProcAddress( library, "WdfPostDeviceInstall"); if (pfnWdfPostDeviceInstall == NULL) { - goto DivertLoadInstallerError; + goto WinDivertLoadInstallerError; } pfnWdfPreDeviceRemove = (PFN_WDFPREDEVICEREMOVE)GetProcAddress( library, "WdfPreDeviceRemove"); if (pfnWdfPreDeviceRemove == NULL) { - goto DivertLoadInstallerError; + goto WinDivertLoadInstallerError; } pfnWdfPostDeviceRemove = (PFN_WDFPOSTDEVICEREMOVE)GetProcAddress( library, "WdfPostDeviceRemove"); if (pfnWdfPostDeviceRemove == NULL) { - goto DivertLoadInstallerError; + goto WinDivertLoadInstallerError; } return library; -DivertLoadInstallerError: +WinDivertLoadInstallerError: FreeLibrary(library); pfnWdfPreDeviceInstallEx = NULL; @@ -372,9 +375,9 @@ DivertLoadInstallerError: } /* - * Locate the Divert driver files. + * Locate the WinDivert driver files. */ -static BOOLEAN DivertDriverFiles(LPWSTR *dir_str_ptr, LPWSTR *sys_str_ptr, +static BOOLEAN WinDivertDriverFiles(LPWSTR *dir_str_ptr, LPWSTR *sys_str_ptr, LPWSTR *inf_str_ptr, LPWSTR *dll_str_ptr) { DWORD err; @@ -389,61 +392,61 @@ static BOOLEAN DivertDriverFiles(LPWSTR *dir_str_ptr, LPWSTR *sys_str_ptr, dir_len = GetCurrentDirectory(0, NULL); if (dir_len == 0) { - goto DivertDriverFilesError; + goto WinDivertDriverFilesError; } dir_len--; - sys_len = dir_len + wcslen(DIVERT_DRIVER_SYS); - inf_len = dir_len + wcslen(DIVERT_DRIVER_INF); - dll_len = dir_len + wcslen(DIVERT_DRIVER_MATCH_DLL); + sys_len = dir_len + wcslen(WINDIVERT_DRIVER_SYS); + inf_len = dir_len + wcslen(WINDIVERT_DRIVER_INF); + dll_len = dir_len + wcslen(WINDIVERT_DRIVER_MATCH_DLL); dir_str = (WCHAR *)malloc((dir_len+1)*sizeof(WCHAR)); if (dir_str == NULL) { - goto DivertDriverFilesError; + goto WinDivertDriverFilesError; } if (GetCurrentDirectory(dir_len+1, dir_str) != dir_len) { SetLastError(ERROR_FILE_NOT_FOUND); - goto DivertDriverFilesError; + goto WinDivertDriverFilesError; } sys_str = (WCHAR *)malloc((sys_len+1)*sizeof(WCHAR)); if (sys_str == NULL) { - goto DivertDriverFilesError; + goto WinDivertDriverFilesError; } inf_str = (WCHAR *)malloc((inf_len+1)*sizeof(WCHAR)); if (inf_str == NULL) { - goto DivertDriverFilesError; + goto WinDivertDriverFilesError; } dll_str = (WCHAR *)malloc((dll_len+1)*sizeof(WCHAR)); if (dll_str == NULL) { - goto DivertDriverFilesError; + goto WinDivertDriverFilesError; } if (wcscpy_s(sys_str, sys_len+1, dir_str) != 0 || wcscpy_s(inf_str, inf_len+1, dir_str) != 0 || wcscpy_s(dll_str, dll_len+1, dir_str) != 0 || wcscpy_s(sys_str + dir_len, sys_len+1-dir_len, - DIVERT_DRIVER_SYS) != 0 || + WINDIVERT_DRIVER_SYS) != 0 || wcscpy_s(inf_str + dir_len, inf_len+1-dir_len, - DIVERT_DRIVER_INF) != 0 || + WINDIVERT_DRIVER_INF) != 0 || wcscpy_s(dll_str + dir_len, dll_len+1-dir_len, - DIVERT_DRIVER_MATCH_DLL)) + WINDIVERT_DRIVER_MATCH_DLL)) { - goto DivertDriverFilesError; + goto WinDivertDriverFilesError; } // Check the the files exist; and find the co-installer filename. find = FindFirstFile(sys_str, &find_data); if (find == INVALID_HANDLE_VALUE) { - goto DivertDriverFilesError; + goto WinDivertDriverFilesError; } FindClose(find); find = FindFirstFile(inf_str, &find_data); if (find == INVALID_HANDLE_VALUE) { - goto DivertDriverFilesError; + goto WinDivertDriverFilesError; } FindClose(find); find = FindFirstFile(dll_str, &find_data); @@ -451,24 +454,24 @@ static BOOLEAN DivertDriverFiles(LPWSTR *dir_str_ptr, LPWSTR *sys_str_ptr, dll_str = NULL; if (find == INVALID_HANDLE_VALUE) { - goto DivertDriverFilesError; + goto WinDivertDriverFilesError; } FindClose(find); dll_len = dir_len + 1 + wcslen(find_data.cFileName) + 1; dll_str = (WCHAR *)malloc((dll_len+1)*sizeof(WCHAR)); if (dll_str == NULL) { - goto DivertDriverFilesError; + goto WinDivertDriverFilesError; } if (wcscpy_s(dll_str, dll_len+1, dir_str) != 0) { - goto DivertDriverFilesError; + goto WinDivertDriverFilesError; } dll_str[dir_len] = L'\\'; if (wcscpy_s(dll_str + dir_len + 1, dll_len+1-dir_len-1, find_data.cFileName) != 0) { - goto DivertDriverFilesError; + goto WinDivertDriverFilesError; } *dir_str_ptr = dir_str; @@ -477,7 +480,7 @@ static BOOLEAN DivertDriverFiles(LPWSTR *dir_str_ptr, LPWSTR *sys_str_ptr, *dll_str_ptr = dll_str; return TRUE; -DivertDriverFilesError: +WinDivertDriverFilesError: err = GetLastError(); free(dir_str); free(sys_str); @@ -491,15 +494,15 @@ DivertDriverFilesError: } /* - * Install the Divert driver. + * Install the WinDivert driver. */ -static BOOLEAN DivertDriverInstall(VOID) +static BOOLEAN WinDivertDriverInstall(VOID) { DWORD err; SC_HANDLE manager = NULL, service = NULL; WDF_COINSTALLER_INSTALL_OPTIONS client_options; - LPWSTR divert_dir = NULL, divert_sys = NULL, divert_inf = NULL, - divert_dll = NULL; + LPWSTR windivert_dir = NULL, windivert_sys = NULL, windivert_inf = NULL, + windivert_dll = NULL; // Do nothing if the driver is already installed: if (installed) @@ -511,60 +514,62 @@ static BOOLEAN DivertDriverInstall(VOID) manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (manager == NULL) { - goto DivertDriverInstallExit; + goto WinDivertDriverInstallExit; } - // Check if the divert service already exists; if so, start it. - service = OpenService(manager, DIVERT_DEVICE_NAME, SERVICE_ALL_ACCESS); + // Check if the WinDivert service already exists; if so, start it. + service = OpenService(manager, WINDIVERT_DEVICE_NAME, SERVICE_ALL_ACCESS); if (service != NULL) { if (!StartService(service, 0, NULL)) { err = GetLastError(); installed = (err == ERROR_SERVICE_ALREADY_RUNNING); - goto DivertDriverInstallExit; + goto WinDivertDriverInstallExit; } installed = TRUE; - goto DivertDriverInstallExit; + goto WinDivertDriverInstallExit; } // Get driver files: - if (!DivertDriverFiles(&divert_dir, &divert_sys, &divert_inf, &divert_dll)) + if (!WinDivertDriverFiles(&windivert_dir, &windivert_sys, &windivert_inf, + &windivert_dll)) { return FALSE; } // Load the co-installer: - if (DivertLoadCoInstaller(divert_dll) == NULL) + if (WinDivertLoadCoInstaller(windivert_dll) == NULL) { return FALSE; } // Pre-install: WDF_COINSTALLER_INSTALL_OPTIONS_INIT(&client_options); - err = pfnWdfPreDeviceInstallEx(divert_inf, DIVERT_DRIVER_SECTION, + err = pfnWdfPreDeviceInstallEx(windivert_inf, WINDIVERT_DRIVER_SECTION, &client_options); if (err != ERROR_SUCCESS) { SetLastError(err); - goto DivertDriverInstallExit; + goto WinDivertDriverInstallExit; } // Create the service: - service = CreateService(manager, DIVERT_DEVICE_NAME, DIVERT_DEVICE_NAME, - SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, - SERVICE_ERROR_NORMAL, divert_sys, NULL, NULL, NULL, NULL, NULL); + service = CreateService(manager, WINDIVERT_DEVICE_NAME, + WINDIVERT_DEVICE_NAME, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, + SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, windivert_sys, NULL, NULL, + NULL, NULL, NULL); if (service == NULL) { if (GetLastError() == ERROR_SERVICE_EXISTS) { installed = TRUE; } - goto DivertDriverInstallExit; + goto WinDivertDriverInstallExit; } // Post-install: - err = pfnWdfPostDeviceInstall(divert_inf, NULL); + err = pfnWdfPostDeviceInstall(windivert_inf, NULL); if (err == ERROR_INVALID_PARAMETER) { // We ignore ERROR_INVALID_PARAMETER. WdfPostDeviceInstall sometimes @@ -575,7 +580,7 @@ static BOOLEAN DivertDriverInstall(VOID) if (err != ERROR_SUCCESS) { SetLastError(err); - goto DivertDriverInstallExit; + goto WinDivertDriverInstallExit; } // Start the service: @@ -583,17 +588,17 @@ static BOOLEAN DivertDriverInstall(VOID) { err = GetLastError(); installed = (err == ERROR_SERVICE_ALREADY_RUNNING); - goto DivertDriverInstallExit; + goto WinDivertDriverInstallExit; } installed = TRUE; -DivertDriverInstallExit: +WinDivertDriverInstallExit: err = GetLastError(); - free(divert_dir); - free(divert_sys); - free(divert_inf); - free(divert_dll); + free(windivert_dir); + free(windivert_sys); + free(windivert_inf); + free(windivert_dll); if (service != NULL) { CloseServiceHandle(service); @@ -607,14 +612,14 @@ DivertDriverInstallExit: } /* - * Uninstall the Divert driver. + * Uninstall the WinDivert driver. */ -static BOOLEAN DivertDriverUnInstall(VOID) +static BOOLEAN WinDivertDriverUnInstall(VOID) { DWORD err; SC_HANDLE manager = NULL, service = NULL; - LPWSTR divert_dir = NULL, divert_sys = NULL, divert_inf = NULL, - divert_dll = NULL; + LPWSTR windivert_dir = NULL, windivert_sys = NULL, windivert_inf = NULL, + windivert_dll = NULL; // Do nothing if the driver is not installed: if (!installed) @@ -623,59 +628,60 @@ static BOOLEAN DivertDriverUnInstall(VOID) } // Get driver files: - if (!DivertDriverFiles(&divert_dir, &divert_sys, &divert_inf, &divert_dll)) + if (!WinDivertDriverFiles(&windivert_dir, &windivert_sys, &windivert_inf, + &windivert_dll)) { return FALSE; } // Load the co-installer: - if (DivertLoadCoInstaller(divert_dll) == NULL) + if (WinDivertLoadCoInstaller(windivert_dll) == NULL) { return FALSE; } // Pre-uninstall: - err = pfnWdfPreDeviceRemove(divert_inf, DIVERT_DRIVER_SECTION); + err = pfnWdfPreDeviceRemove(windivert_inf, WINDIVERT_DRIVER_SECTION); if (err != ERROR_SUCCESS) { - goto DivertDriverUnInstallExit; + goto WinDivertDriverUnInstallExit; } // Open the service manager: manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (manager == NULL) { - goto DivertDriverUnInstallExit; + goto WinDivertDriverUnInstallExit; } // Open the service: - service = OpenService(manager, DIVERT_DEVICE_NAME, SERVICE_ALL_ACCESS); + service = OpenService(manager, WINDIVERT_DEVICE_NAME, SERVICE_ALL_ACCESS); if (service == NULL) { - goto DivertDriverUnInstallExit; + goto WinDivertDriverUnInstallExit; } // Delete the service: if (!DeleteService(service)) { - goto DivertDriverUnInstallExit; + goto WinDivertDriverUnInstallExit; } // Post-uninstall: - err = pfnWdfPostDeviceRemove(divert_inf, DIVERT_DRIVER_SECTION); + err = pfnWdfPostDeviceRemove(windivert_inf, WINDIVERT_DRIVER_SECTION); if (err != ERROR_SUCCESS) { SetLastError(err); - goto DivertDriverUnInstallExit; + goto WinDivertDriverUnInstallExit; } installed = FALSE; -DivertDriverUnInstallExit: - free(divert_dir); - free(divert_sys); - free(divert_inf); - free(divert_dll); +WinDivertDriverUnInstallExit: + free(windivert_dir); + free(windivert_sys); + free(windivert_inf); + free(windivert_dll); if (service != NULL) { CloseServiceHandle(service); @@ -690,15 +696,14 @@ DivertDriverUnInstallExit: /* * Perform a DeviceIoControl. */ -static BOOL DivertIoControl(HANDLE handle, DWORD code, UINT8 arg8, UINT64 arg, - PVOID buf, UINT len, UINT *iolen) +static BOOL WinDivertIoControl(HANDLE handle, DWORD code, UINT8 arg8, + UINT64 arg, PVOID buf, UINT len, UINT *iolen) { - struct divert_ioctl_s ioctl; - DWORD iolen0; OVERLAPPED overlapped; + DWORD iolen0; HANDLE event; - event = (HANDLE)TlsGetValue(divert_tls_idx); + event = (HANDLE)TlsGetValue(windivert_tls_idx); if (event == (HANDLE)NULL) { event = CreateEvent(NULL, FALSE, FALSE, NULL); @@ -706,64 +711,83 @@ static BOOL DivertIoControl(HANDLE handle, DWORD code, UINT8 arg8, UINT64 arg, { return FALSE; } - TlsSetValue(divert_tls_idx, (LPVOID)event); + TlsSetValue(windivert_tls_idx, (LPVOID)event); } - ioctl.version = DIVERT_IOCTL_VERSION; - ioctl.magic = DIVERT_IOCTL_MAGIC; - ioctl.arg8 = arg8; - ioctl.arg = arg; overlapped.Offset = 0; overlapped.OffsetHigh = 0; overlapped.hEvent = event; - if (!DeviceIoControl(handle, code, &ioctl, sizeof(ioctl), buf, (DWORD)len, - &iolen0, &overlapped)) + if (!WinDivertIoControlEx(handle, code, arg8, arg, buf, len, iolen, + &overlapped)) { if (GetLastError() != ERROR_IO_PENDING || !GetOverlappedResult(handle, &overlapped, &iolen0, TRUE)) { return FALSE; } - } - if (iolen != NULL) - { - *iolen = (UINT)iolen0; + if (iolen != NULL) + { + *iolen = (UINT)iolen0; + } } return TRUE; } /* - * Open a divert handle. + * Perform an (overlapped) DeviceIoControl. */ -extern HANDLE DivertOpen(const char *filter, DIVERT_LAYER layer, +static BOOL WinDivertIoControlEx(HANDLE handle, DWORD code, UINT8 arg8, + UINT64 arg, PVOID buf, UINT len, UINT *iolen, LPOVERLAPPED overlapped) +{ + struct windivert_ioctl_s ioctl; + BOOL result; + DWORD iolen0; + + ioctl.version = WINDIVERT_IOCTL_VERSION; + ioctl.magic = WINDIVERT_IOCTL_MAGIC; + ioctl.arg8 = arg8; + ioctl.arg = arg; + result = DeviceIoControl(handle, code, &ioctl, sizeof(ioctl), buf, + (DWORD)len, &iolen0, overlapped); + if (result && iolen != NULL) + { + *iolen = (UINT)iolen0; + } + return result; +} + +/* + * Open a WinDivert handle. + */ +extern HANDLE WinDivertOpen(const char *filter, WINDIVERT_LAYER layer, INT16 priority, UINT64 flags) { - struct divert_ioctl_filter_s ioctl_filter[DIVERT_FILTER_MAXLEN]; + struct windivert_ioctl_filter_s ioctl_filter[WINDIVERT_FILTER_MAXLEN]; UINT16 filter_len; DWORD err; HANDLE handle; UINT32 priority32; // Parameter checking. - if (flags > DIVERT_FLAGS_MAX || layer > DIVERT_LAYER_MAX) + if (!WINDIVERT_FLAGS_VALID(flags) || layer > WINDIVERT_LAYER_MAX) { SetLastError(ERROR_INVALID_PARAMETER); return INVALID_HANDLE_VALUE; } // Parse the filter: - if (!DivertCompileFilter(filter, layer, ioctl_filter, &filter_len)) + if (!WinDivertCompileFilter(filter, layer, ioctl_filter, &filter_len)) { SetLastError(ERROR_INVALID_PARAMETER); return INVALID_HANDLE_VALUE; } -#ifdef DIVERT_DEBUG - DivertFilterDump(ioctl_filter, filter_len); +#ifdef WINDIVERT_DEBUG + WinDivertFilterDump(ioctl_filter, filter_len); #endif - // Attempt to open the Divert device: - handle = CreateFile(L"\\\\.\\" DIVERT_DEVICE_NAME, + // Attempt to open the WinDivert device: + handle = CreateFile(L"\\\\.\\" WINDIVERT_DEVICE_NAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, INVALID_HANDLE_VALUE); if (handle == INVALID_HANDLE_VALUE) @@ -776,7 +800,7 @@ extern HANDLE DivertOpen(const char *filter, DIVERT_LAYER layer, // Open failed because the device isn't installed; install it now. SetLastError(0); - if (!DivertDriverInstall()) + if (!WinDivertDriverInstall()) { if (GetLastError() == 0) { @@ -784,7 +808,7 @@ extern HANDLE DivertOpen(const char *filter, DIVERT_LAYER layer, } return INVALID_HANDLE_VALUE; } - handle = CreateFile(L"\\\\.\\" DIVERT_DEVICE_NAME, + handle = CreateFile(L"\\\\.\\" WINDIVERT_DEVICE_NAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, INVALID_HANDLE_VALUE); @@ -799,10 +823,10 @@ extern HANDLE DivertOpen(const char *filter, DIVERT_LAYER layer, } // Set the layer: - if (layer != DIVERT_LAYER_DEFAULT) + if (layer != WINDIVERT_LAYER_DEFAULT) { - if (!DivertIoControl(handle, IOCTL_DIVERT_SET_LAYER, 0, (UINT64)layer, - NULL, 0, NULL)) + if (!WinDivertIoControl(handle, IOCTL_WINDIVERT_SET_LAYER, 0, + (UINT64)layer, NULL, 0, NULL)) { CloseHandle(handle); return INVALID_HANDLE_VALUE; @@ -812,8 +836,8 @@ extern HANDLE DivertOpen(const char *filter, DIVERT_LAYER layer, // Set the flags: if (flags != 0) { - if (!DivertIoControl(handle, IOCTL_DIVERT_SET_FLAGS, 0, (UINT64)flags, - NULL, 0, NULL)) + if (!WinDivertIoControl(handle, IOCTL_WINDIVERT_SET_FLAGS, 0, + (UINT64)flags, NULL, 0, NULL)) { CloseHandle(handle); return INVALID_HANDLE_VALUE; @@ -821,10 +845,10 @@ extern HANDLE DivertOpen(const char *filter, DIVERT_LAYER layer, } // Set the priority: - priority32 = DIVERT_PRIORITY(priority); - if (priority32 != DIVERT_PRIORITY_DEFAULT) + priority32 = WINDIVERT_PRIORITY(priority); + if (priority32 != WINDIVERT_PRIORITY_DEFAULT) { - if (!DivertIoControl(handle, IOCTL_DIVERT_SET_PRIORITY, 0, + if (!WinDivertIoControl(handle, IOCTL_WINDIVERT_SET_PRIORITY, 0, (UINT64)priority32, NULL, 0, NULL)) { CloseHandle(handle); @@ -833,8 +857,8 @@ extern HANDLE DivertOpen(const char *filter, DIVERT_LAYER layer, } // Start the filter: - if (!DivertIoControl(handle, IOCTL_DIVERT_START_FILTER, 0, 0, - ioctl_filter, filter_len*sizeof(struct divert_ioctl_filter_s), + if (!WinDivertIoControl(handle, IOCTL_WINDIVERT_START_FILTER, 0, 0, + ioctl_filter, filter_len*sizeof(struct windivert_ioctl_filter_s), NULL)) { CloseHandle(handle); @@ -846,51 +870,100 @@ extern HANDLE DivertOpen(const char *filter, DIVERT_LAYER layer, } /* - * Receive a divert packet. + * Receive a WinDivert packet. */ -extern BOOL DivertRecv(HANDLE handle, PVOID pPacket, UINT packetLen, - PDIVERT_ADDRESS addr, UINT *readlen) +extern BOOL WinDivertRecv(HANDLE handle, PVOID pPacket, UINT packetLen, + PWINDIVERT_ADDRESS addr, UINT *readlen) { - return DivertIoControl(handle, IOCTL_DIVERT_RECV, 0, (UINT64)addr, pPacket, - packetLen, readlen); + return WinDivertIoControl(handle, IOCTL_WINDIVERT_RECV, 0, (UINT64)addr, + pPacket, packetLen, readlen); } /* - * Send a divert packet. + * Receive a WinDivert packet. */ -extern BOOL DivertSend(HANDLE handle, PVOID pPacket, UINT packetLen, - PDIVERT_ADDRESS addr, UINT *writelen) +extern BOOL WinDivertRecvEx(HANDLE handle, PVOID pPacket, UINT packetLen, + UINT64 flags, PWINDIVERT_ADDRESS addr, UINT *readlen, + LPOVERLAPPED overlapped) { - return DivertIoControl(handle, IOCTL_DIVERT_SEND, 0, (UINT64)addr, pPacket, - packetLen, writelen); + if (flags != 0) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + if (overlapped == NULL) + { + return WinDivertIoControl(handle, IOCTL_WINDIVERT_RECV, 0, + (UINT64)addr, pPacket, packetLen, readlen); + } + else + { + return WinDivertIoControlEx(handle, IOCTL_WINDIVERT_RECV, 0, + (UINT64)addr, pPacket, packetLen, readlen, overlapped); + } } /* - * Close a divert handle. + * Send a WinDivert packet. */ -extern BOOL DivertClose(HANDLE handle) +extern BOOL WinDivertSend(HANDLE handle, PVOID pPacket, UINT packetLen, + PWINDIVERT_ADDRESS addr, UINT *writelen) +{ + return WinDivertIoControl(handle, IOCTL_WINDIVERT_SEND, 0, (UINT64)addr, + pPacket, packetLen, writelen); +} + +/* + * Send a WinDivert packet. + */ +extern BOOL WinDivertSendEx(HANDLE handle, PVOID pPacket, UINT packetLen, + UINT64 flags, PWINDIVERT_ADDRESS addr, UINT *writelen, + LPOVERLAPPED overlapped) +{ + if (flags != 0) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + if (overlapped == NULL) + { + return WinDivertIoControl(handle, IOCTL_WINDIVERT_SEND, 0, + (UINT64)addr, pPacket, packetLen, writelen); + } + else + { + return WinDivertIoControlEx(handle, IOCTL_WINDIVERT_SEND, 0, + (UINT64)addr, pPacket, packetLen, writelen, overlapped); + } +} + +/* + * Close a WinDivert handle. + */ +extern BOOL WinDivertClose(HANDLE handle) { return CloseHandle(handle); } /* - * Set a divert parameter. + * Set a WinDivert parameter. */ -extern BOOL DivertSetParam(HANDLE handle, DIVERT_PARAM param, UINT64 value) +extern BOOL WinDivertSetParam(HANDLE handle, WINDIVERT_PARAM param, + UINT64 value) { switch ((int)param) { - case DIVERT_PARAM_QUEUE_LEN: - if (value < DIVERT_PARAM_QUEUE_LEN_MIN || - value > DIVERT_PARAM_QUEUE_LEN_MAX) + case WINDIVERT_PARAM_QUEUE_LEN: + if (value < WINDIVERT_PARAM_QUEUE_LEN_MIN || + value > WINDIVERT_PARAM_QUEUE_LEN_MAX) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } break; - case DIVERT_PARAM_QUEUE_TIME: - if (value < DIVERT_PARAM_QUEUE_TIME_MIN || - value > DIVERT_PARAM_QUEUE_TIME_MAX) + case WINDIVERT_PARAM_QUEUE_TIME: + if (value < WINDIVERT_PARAM_QUEUE_TIME_MIN || + value > WINDIVERT_PARAM_QUEUE_TIME_MAX) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; @@ -900,45 +973,46 @@ extern BOOL DivertSetParam(HANDLE handle, DIVERT_PARAM param, UINT64 value) SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - return DivertIoControl(handle, IOCTL_DIVERT_SET_PARAM, (UINT8)param, + return WinDivertIoControl(handle, IOCTL_WINDIVERT_SET_PARAM, (UINT8)param, value, NULL, 0, NULL); } /* - * Get a divert parameter. + * Get a WinDivert parameter. */ -extern BOOL DivertGetParam(HANDLE handle, DIVERT_PARAM param, UINT64 *pValue) +extern BOOL WinDivertGetParam(HANDLE handle, WINDIVERT_PARAM param, + UINT64 *pValue) { switch ((int)param) { - case DIVERT_PARAM_QUEUE_LEN: case DIVERT_PARAM_QUEUE_TIME: + case WINDIVERT_PARAM_QUEUE_LEN: case WINDIVERT_PARAM_QUEUE_TIME: break; default: SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - return DivertIoControl(handle, IOCTL_DIVERT_GET_PARAM, (UINT8)param, + return WinDivertIoControl(handle, IOCTL_WINDIVERT_GET_PARAM, (UINT8)param, 0, pValue, sizeof(UINT64), NULL); } /* * Compile a filter. */ -static BOOL DivertCompileFilter(const char *filter_str, DIVERT_LAYER layer, - divert_ioctl_filter_t filter, UINT16 *fp) +static BOOL WinDivertCompileFilter(const char *filter_str, + WINDIVERT_LAYER layer, windivert_ioctl_filter_t filter, UINT16 *fp) { - FILTER_TOKEN tokens[DIVERT_FILTER_MAXLEN*3]; + FILTER_TOKEN tokens[WINDIVERT_FILTER_MAXLEN*3]; UINT16 tp; - if (!DivertTokenizeFilter(filter_str, layer, tokens, - DIVERT_FILTER_MAXLEN*3-1)) + if (!WinDivertTokenizeFilter(filter_str, layer, tokens, + WINDIVERT_FILTER_MAXLEN*3-1)) { return FALSE; } tp = 0; *fp = 0; - if (!DivertParseFilter(tokens, &tp, filter, fp, FILTER_TOKEN_AND)) + if (!WinDivertParseFilter(tokens, &tp, filter, fp, FILTER_TOKEN_AND)) { return FALSE; } @@ -952,7 +1026,8 @@ static BOOL DivertCompileFilter(const char *filter_str, DIVERT_LAYER layer, /* * Compare two FILTER_TOKEN_NAMEs. */ -static int __cdecl DivertFilterTokenNameCompare(const void *a, const void *b) +static int __cdecl WinDivertFilterTokenNameCompare(const void *a, + const void *b) { PFILTER_TOKEN_NAME na = (PFILTER_TOKEN_NAME)a; PFILTER_TOKEN_NAME nb = (PFILTER_TOKEN_NAME)b; @@ -962,7 +1037,7 @@ static int __cdecl DivertFilterTokenNameCompare(const void *a, const void *b) /* * Tokenize the given filter string. */ -static BOOL DivertTokenizeFilter(const char *filter, DIVERT_LAYER layer, +static BOOL WinDivertTokenizeFilter(const char *filter, WINDIVERT_LAYER layer, FILTER_TOKEN *tokens, UINT tokensmax) { static const FILTER_TOKEN_NAME token_names[] = @@ -1136,12 +1211,12 @@ static BOOL DivertTokenizeFilter(const char *filter, DIVERT_LAYER layer, key.name = token; result = (PFILTER_TOKEN_NAME)bsearch((const void *)&key, token_names, sizeof(token_names) / sizeof(FILTER_TOKEN_NAME), - sizeof(FILTER_TOKEN_NAME), DivertFilterTokenNameCompare); + sizeof(FILTER_TOKEN_NAME), WinDivertFilterTokenNameCompare); if (result != NULL) { switch (layer) { - case DIVERT_LAYER_NETWORK_FORWARD: + case WINDIVERT_LAYER_NETWORK_FORWARD: if (result->kind == FILTER_TOKEN_INBOUND || result->kind == FILTER_TOKEN_OUTBOUND) { @@ -1178,7 +1253,7 @@ static BOOL DivertTokenizeFilter(const char *filter, DIVERT_LAYER layer, } // Check for IPv4 address: - if (DivertHelperParseIPv4Address(token, tokens[tp].val)) + if (WinDivertHelperParseIPv4Address(token, tokens[tp].val)) { tokens[tp].kind = FILTER_TOKEN_NUMBER; tp++; @@ -1187,7 +1262,7 @@ static BOOL DivertTokenizeFilter(const char *filter, DIVERT_LAYER layer, // Check for IPv6 address: SetLastError(0); - if (DivertHelperParseIPv6Address(token, tokens[tp].val)) + if (WinDivertHelperParseIPv6Address(token, tokens[tp].val)) { tokens[tp].kind = FILTER_TOKEN_NUMBER; tp++; @@ -1206,15 +1281,15 @@ static BOOL DivertTokenizeFilter(const char *filter, DIVERT_LAYER layer, /* * Parse the given filter. */ -static BOOL DivertParseFilter(FILTER_TOKEN *tokens, UINT16 *tp, - divert_ioctl_filter_t filter, UINT16 *fp, FILTER_TOKEN_KIND op) +static BOOL WinDivertParseFilter(FILTER_TOKEN *tokens, UINT16 *tp, + windivert_ioctl_filter_t filter, UINT16 *fp, FILTER_TOKEN_KIND op) { BOOL testop, fused, result, negate; FILTER_TOKEN token; UINT16 f, s; s = *fp; -DivertParseFilterNext: +WinDivertParseFilterNext: testop = TRUE; fused = TRUE; @@ -1223,12 +1298,12 @@ DivertParseFilterNext: *tp = *tp + 1; f = *fp; - if (f >= DIVERT_FILTER_MAXLEN) + if (f >= WINDIVERT_FILTER_MAXLEN) { return FALSE; } - filter[f].success = DIVERT_FILTER_RESULT_ACCEPT; - filter[f].failure = DIVERT_FILTER_RESULT_REJECT; + filter[f].success = WINDIVERT_FILTER_RESULT_ACCEPT; + filter[f].failure = WINDIVERT_FILTER_RESULT_REJECT; filter[f].arg[1] = 0; filter[f].arg[2] = 0; filter[f].arg[3] = 0; @@ -1241,7 +1316,7 @@ DivertParseFilterNext: switch (token.kind) { case FILTER_TOKEN_OPEN: - result = DivertParseFilter(tokens, tp, filter, fp, + result = WinDivertParseFilter(tokens, tp, filter, fp, FILTER_TOKEN_AND); result = (result? (tokens[*tp].kind == FILTER_TOKEN_CLOSE): FALSE); if (!result) @@ -1253,181 +1328,181 @@ DivertParseFilterNext: fused = FALSE; break; case FILTER_TOKEN_TRUE: case FILTER_TOKEN_FALSE: - filter[f].field = DIVERT_FILTER_FIELD_ZERO; - filter[f].test = DIVERT_FILTER_TEST_EQ; + filter[f].field = WINDIVERT_FILTER_FIELD_ZERO; + filter[f].test = WINDIVERT_FILTER_TEST_EQ; filter[f].arg[0] = (token.kind == FILTER_TOKEN_FALSE); testop = FALSE; break; case FILTER_TOKEN_OUTBOUND: - filter[f].field = DIVERT_FILTER_FIELD_OUTBOUND; + filter[f].field = WINDIVERT_FILTER_FIELD_OUTBOUND; break; case FILTER_TOKEN_INBOUND: - filter[f].field = DIVERT_FILTER_FIELD_INBOUND; + filter[f].field = WINDIVERT_FILTER_FIELD_INBOUND; break; case FILTER_TOKEN_IF_IDX: - filter[f].field = DIVERT_FILTER_FIELD_IFIDX; + filter[f].field = WINDIVERT_FILTER_FIELD_IFIDX; break; case FILTER_TOKEN_SUB_IF_IDX: - filter[f].field = DIVERT_FILTER_FIELD_SUBIFIDX; + filter[f].field = WINDIVERT_FILTER_FIELD_SUBIFIDX; break; case FILTER_TOKEN_IP: - filter[f].field = DIVERT_FILTER_FIELD_IP; + filter[f].field = WINDIVERT_FILTER_FIELD_IP; break; case FILTER_TOKEN_IPV6: - filter[f].field = DIVERT_FILTER_FIELD_IPV6; + filter[f].field = WINDIVERT_FILTER_FIELD_IPV6; break; case FILTER_TOKEN_ICMP: - filter[f].field = DIVERT_FILTER_FIELD_ICMP; + filter[f].field = WINDIVERT_FILTER_FIELD_ICMP; break; case FILTER_TOKEN_ICMPV6: - filter[f].field = DIVERT_FILTER_FIELD_ICMPV6; + filter[f].field = WINDIVERT_FILTER_FIELD_ICMPV6; break; case FILTER_TOKEN_TCP: - filter[f].field = DIVERT_FILTER_FIELD_TCP; + filter[f].field = WINDIVERT_FILTER_FIELD_TCP; break; case FILTER_TOKEN_UDP: - filter[f].field = DIVERT_FILTER_FIELD_UDP; + filter[f].field = WINDIVERT_FILTER_FIELD_UDP; break; case FILTER_TOKEN_IP_HDR_LENGTH: - filter[f].field = DIVERT_FILTER_FIELD_IP_HDRLENGTH; + filter[f].field = WINDIVERT_FILTER_FIELD_IP_HDRLENGTH; break; case FILTER_TOKEN_IP_TOS: - filter[f].field = DIVERT_FILTER_FIELD_IP_TOS; + filter[f].field = WINDIVERT_FILTER_FIELD_IP_TOS; break; case FILTER_TOKEN_IP_LENGTH: - filter[f].field = DIVERT_FILTER_FIELD_IP_LENGTH; + filter[f].field = WINDIVERT_FILTER_FIELD_IP_LENGTH; break; case FILTER_TOKEN_IP_ID: - filter[f].field = DIVERT_FILTER_FIELD_IP_ID; + filter[f].field = WINDIVERT_FILTER_FIELD_IP_ID; break; case FILTER_TOKEN_IP_DF: - filter[f].field = DIVERT_FILTER_FIELD_IP_DF; + filter[f].field = WINDIVERT_FILTER_FIELD_IP_DF; break; case FILTER_TOKEN_IP_MF: - filter[f].field = DIVERT_FILTER_FIELD_IP_MF; + filter[f].field = WINDIVERT_FILTER_FIELD_IP_MF; break; case FILTER_TOKEN_IP_FRAG_OFF: - filter[f].field = DIVERT_FILTER_FIELD_IP_FRAGOFF; + filter[f].field = WINDIVERT_FILTER_FIELD_IP_FRAGOFF; break; case FILTER_TOKEN_IP_TTL: - filter[f].field = DIVERT_FILTER_FIELD_IP_TTL; + filter[f].field = WINDIVERT_FILTER_FIELD_IP_TTL; break; case FILTER_TOKEN_IP_PROTOCOL: - filter[f].field = DIVERT_FILTER_FIELD_IP_PROTOCOL; + filter[f].field = WINDIVERT_FILTER_FIELD_IP_PROTOCOL; break; case FILTER_TOKEN_IP_CHECKSUM: - filter[f].field = DIVERT_FILTER_FIELD_IP_CHECKSUM; + filter[f].field = WINDIVERT_FILTER_FIELD_IP_CHECKSUM; break; case FILTER_TOKEN_IP_SRC_ADDR: - filter[f].field = DIVERT_FILTER_FIELD_IP_SRCADDR; + filter[f].field = WINDIVERT_FILTER_FIELD_IP_SRCADDR; break; case FILTER_TOKEN_IP_DST_ADDR: - filter[f].field = DIVERT_FILTER_FIELD_IP_DSTADDR; + filter[f].field = WINDIVERT_FILTER_FIELD_IP_DSTADDR; break; case FILTER_TOKEN_IPV6_TRAFFIC_CLASS: - filter[f].field = DIVERT_FILTER_FIELD_IPV6_TRAFFICCLASS; + filter[f].field = WINDIVERT_FILTER_FIELD_IPV6_TRAFFICCLASS; break; case FILTER_TOKEN_IPV6_FLOW_LABEL: - filter[f].field = DIVERT_FILTER_FIELD_IPV6_FLOWLABEL; + filter[f].field = WINDIVERT_FILTER_FIELD_IPV6_FLOWLABEL; break; case FILTER_TOKEN_IPV6_LENGTH: - filter[f].field = DIVERT_FILTER_FIELD_IPV6_LENGTH; + filter[f].field = WINDIVERT_FILTER_FIELD_IPV6_LENGTH; break; case FILTER_TOKEN_IPV6_NEXT_HDR: - filter[f].field = DIVERT_FILTER_FIELD_IPV6_NEXTHDR; + filter[f].field = WINDIVERT_FILTER_FIELD_IPV6_NEXTHDR; break; case FILTER_TOKEN_IPV6_HOP_LIMIT: - filter[f].field = DIVERT_FILTER_FIELD_IPV6_HOPLIMIT; + filter[f].field = WINDIVERT_FILTER_FIELD_IPV6_HOPLIMIT; break; case FILTER_TOKEN_IPV6_SRC_ADDR: - filter[f].field = DIVERT_FILTER_FIELD_IPV6_SRCADDR; + filter[f].field = WINDIVERT_FILTER_FIELD_IPV6_SRCADDR; break; case FILTER_TOKEN_IPV6_DST_ADDR: - filter[f].field = DIVERT_FILTER_FIELD_IPV6_DSTADDR; + filter[f].field = WINDIVERT_FILTER_FIELD_IPV6_DSTADDR; break; case FILTER_TOKEN_ICMP_TYPE: - filter[f].field = DIVERT_FILTER_FIELD_ICMP_TYPE; + filter[f].field = WINDIVERT_FILTER_FIELD_ICMP_TYPE; break; case FILTER_TOKEN_ICMP_CODE: - filter[f].field = DIVERT_FILTER_FIELD_ICMP_CODE; + filter[f].field = WINDIVERT_FILTER_FIELD_ICMP_CODE; break; case FILTER_TOKEN_ICMP_CHECKSUM: - filter[f].field = DIVERT_FILTER_FIELD_ICMP_CHECKSUM; + filter[f].field = WINDIVERT_FILTER_FIELD_ICMP_CHECKSUM; break; case FILTER_TOKEN_ICMP_BODY: - filter[f].field = DIVERT_FILTER_FIELD_ICMP_BODY; + filter[f].field = WINDIVERT_FILTER_FIELD_ICMP_BODY; break; case FILTER_TOKEN_ICMPV6_TYPE: - filter[f].field = DIVERT_FILTER_FIELD_ICMPV6_TYPE; + filter[f].field = WINDIVERT_FILTER_FIELD_ICMPV6_TYPE; break; case FILTER_TOKEN_ICMPV6_CODE: - filter[f].field = DIVERT_FILTER_FIELD_ICMPV6_CODE; + filter[f].field = WINDIVERT_FILTER_FIELD_ICMPV6_CODE; break; case FILTER_TOKEN_ICMPV6_CHECKSUM: - filter[f].field = DIVERT_FILTER_FIELD_ICMPV6_CHECKSUM; + filter[f].field = WINDIVERT_FILTER_FIELD_ICMPV6_CHECKSUM; break; case FILTER_TOKEN_ICMPV6_BODY: - filter[f].field = DIVERT_FILTER_FIELD_ICMPV6_BODY; + filter[f].field = WINDIVERT_FILTER_FIELD_ICMPV6_BODY; break; case FILTER_TOKEN_TCP_SRC_PORT: - filter[f].field = DIVERT_FILTER_FIELD_TCP_SRCPORT; + filter[f].field = WINDIVERT_FILTER_FIELD_TCP_SRCPORT; break; case FILTER_TOKEN_TCP_DST_PORT: - filter[f].field = DIVERT_FILTER_FIELD_TCP_DSTPORT; + filter[f].field = WINDIVERT_FILTER_FIELD_TCP_DSTPORT; break; case FILTER_TOKEN_TCP_SEQ_NUM: - filter[f].field = DIVERT_FILTER_FIELD_TCP_SEQNUM; + filter[f].field = WINDIVERT_FILTER_FIELD_TCP_SEQNUM; break; case FILTER_TOKEN_TCP_ACK_NUM: - filter[f].field = DIVERT_FILTER_FIELD_TCP_ACKNUM; + filter[f].field = WINDIVERT_FILTER_FIELD_TCP_ACKNUM; break; case FILTER_TOKEN_TCP_HDR_LENGTH: - filter[f].field = DIVERT_FILTER_FIELD_TCP_HDRLENGTH; + filter[f].field = WINDIVERT_FILTER_FIELD_TCP_HDRLENGTH; break; case FILTER_TOKEN_TCP_URG: - filter[f].field = DIVERT_FILTER_FIELD_TCP_URG; + filter[f].field = WINDIVERT_FILTER_FIELD_TCP_URG; break; case FILTER_TOKEN_TCP_ACK: - filter[f].field = DIVERT_FILTER_FIELD_TCP_ACK; + filter[f].field = WINDIVERT_FILTER_FIELD_TCP_ACK; break; case FILTER_TOKEN_TCP_PSH: - filter[f].field = DIVERT_FILTER_FIELD_TCP_PSH; + filter[f].field = WINDIVERT_FILTER_FIELD_TCP_PSH; break; case FILTER_TOKEN_TCP_RST: - filter[f].field = DIVERT_FILTER_FIELD_TCP_RST; + filter[f].field = WINDIVERT_FILTER_FIELD_TCP_RST; break; case FILTER_TOKEN_TCP_SYN: - filter[f].field = DIVERT_FILTER_FIELD_TCP_SYN; + filter[f].field = WINDIVERT_FILTER_FIELD_TCP_SYN; break; case FILTER_TOKEN_TCP_FIN: - filter[f].field = DIVERT_FILTER_FIELD_TCP_FIN; + filter[f].field = WINDIVERT_FILTER_FIELD_TCP_FIN; break; case FILTER_TOKEN_TCP_WINDOW: - filter[f].field = DIVERT_FILTER_FIELD_TCP_WINDOW; + filter[f].field = WINDIVERT_FILTER_FIELD_TCP_WINDOW; break; case FILTER_TOKEN_TCP_CHECKSUM: - filter[f].field = DIVERT_FILTER_FIELD_TCP_CHECKSUM; + filter[f].field = WINDIVERT_FILTER_FIELD_TCP_CHECKSUM; break; case FILTER_TOKEN_TCP_URG_PTR: - filter[f].field = DIVERT_FILTER_FIELD_TCP_URGPTR; + filter[f].field = WINDIVERT_FILTER_FIELD_TCP_URGPTR; break; case FILTER_TOKEN_TCP_PAYLOAD_LENGTH: - filter[f].field = DIVERT_FILTER_FIELD_TCP_PAYLOADLENGTH; + filter[f].field = WINDIVERT_FILTER_FIELD_TCP_PAYLOADLENGTH; break; case FILTER_TOKEN_UDP_SRC_PORT: - filter[f].field = DIVERT_FILTER_FIELD_UDP_SRCPORT; + filter[f].field = WINDIVERT_FILTER_FIELD_UDP_SRCPORT; break; case FILTER_TOKEN_UDP_DST_PORT: - filter[f].field = DIVERT_FILTER_FIELD_UDP_DSTPORT; + filter[f].field = WINDIVERT_FILTER_FIELD_UDP_DSTPORT; break; case FILTER_TOKEN_UDP_LENGTH: - filter[f].field = DIVERT_FILTER_FIELD_UDP_LENGTH; + filter[f].field = WINDIVERT_FILTER_FIELD_UDP_LENGTH; break; case FILTER_TOKEN_UDP_CHECKSUM: - filter[f].field = DIVERT_FILTER_FIELD_UDP_CHECKSUM; + filter[f].field = WINDIVERT_FILTER_FIELD_UDP_CHECKSUM; break; case FILTER_TOKEN_UDP_PAYLOAD_LENGTH: - filter[f].field = DIVERT_FILTER_FIELD_UDP_PAYLOADLENGTH; + filter[f].field = WINDIVERT_FILTER_FIELD_UDP_PAYLOADLENGTH; break; default: return FALSE; @@ -1446,25 +1521,25 @@ DivertParseFilterNext: switch (token.kind) { case FILTER_TOKEN_EQ: - filter[f].test = DIVERT_FILTER_TEST_EQ; + filter[f].test = WINDIVERT_FILTER_TEST_EQ; break; case FILTER_TOKEN_NEQ: - filter[f].test = DIVERT_FILTER_TEST_NEQ; + filter[f].test = WINDIVERT_FILTER_TEST_NEQ; break; case FILTER_TOKEN_LT: - filter[f].test = DIVERT_FILTER_TEST_LT; + filter[f].test = WINDIVERT_FILTER_TEST_LT; break; case FILTER_TOKEN_LEQ: - filter[f].test = DIVERT_FILTER_TEST_LEQ; + filter[f].test = WINDIVERT_FILTER_TEST_LEQ; break; case FILTER_TOKEN_GT: - filter[f].test = DIVERT_FILTER_TEST_GT; + filter[f].test = WINDIVERT_FILTER_TEST_GT; break; case FILTER_TOKEN_GEQ: - filter[f].test = DIVERT_FILTER_TEST_GEQ; + filter[f].test = WINDIVERT_FILTER_TEST_GEQ; break; default: - filter[f].test = DIVERT_FILTER_TEST_NEQ; + filter[f].test = WINDIVERT_FILTER_TEST_NEQ; filter[f].arg[0] = 0; testop = FALSE; break; @@ -1475,25 +1550,25 @@ DivertParseFilterNext: switch (token.kind) { case FILTER_TOKEN_EQ: - filter[f].test = DIVERT_FILTER_TEST_NEQ; + filter[f].test = WINDIVERT_FILTER_TEST_NEQ; break; case FILTER_TOKEN_NEQ: - filter[f].test = DIVERT_FILTER_TEST_EQ; + filter[f].test = WINDIVERT_FILTER_TEST_EQ; break; case FILTER_TOKEN_LT: - filter[f].test = DIVERT_FILTER_TEST_GEQ; + filter[f].test = WINDIVERT_FILTER_TEST_GEQ; break; case FILTER_TOKEN_LEQ: - filter[f].test = DIVERT_FILTER_TEST_GT; + filter[f].test = WINDIVERT_FILTER_TEST_GT; break; case FILTER_TOKEN_GT: - filter[f].test = DIVERT_FILTER_TEST_LEQ; + filter[f].test = WINDIVERT_FILTER_TEST_LEQ; break; case FILTER_TOKEN_GEQ: - filter[f].test = DIVERT_FILTER_TEST_LT; + filter[f].test = WINDIVERT_FILTER_TEST_LT; break; default: - filter[f].test = DIVERT_FILTER_TEST_EQ; + filter[f].test = WINDIVERT_FILTER_TEST_EQ; filter[f].arg[0] = 0; testop = FALSE; break; @@ -1530,13 +1605,13 @@ DivertParseFilterNext: switch (token.kind) { case FILTER_TOKEN_AND: - DivertFilterUpdate(filter, f, *fp, *fp, - DIVERT_FILTER_RESULT_REJECT); - goto DivertParseFilterNext; + WinDivertFilterUpdate(filter, f, *fp, *fp, + WINDIVERT_FILTER_RESULT_REJECT); + goto WinDivertParseFilterNext; case FILTER_TOKEN_OR: - DivertFilterUpdate(filter, f, *fp, DIVERT_FILTER_RESULT_ACCEPT, - *fp); - goto DivertParseFilterNext; + WinDivertFilterUpdate(filter, f, *fp, + WINDIVERT_FILTER_RESULT_ACCEPT, *fp); + goto WinDivertParseFilterNext; default: break; } @@ -1546,7 +1621,7 @@ DivertParseFilterNext: /* * Update success. */ -static void DivertFilterUpdate(divert_ioctl_filter_t filter, UINT16 s, +static void WinDivertFilterUpdate(windivert_ioctl_filter_t filter, UINT16 s, UINT16 e, UINT16 success, UINT16 failure) { UINT16 i; @@ -1555,290 +1630,44 @@ static void DivertFilterUpdate(divert_ioctl_filter_t filter, UINT16 s, { switch (filter[i].success) { - case DIVERT_FILTER_RESULT_ACCEPT: + case WINDIVERT_FILTER_RESULT_ACCEPT: filter[i].success = success; break; - case DIVERT_FILTER_RESULT_REJECT: + case WINDIVERT_FILTER_RESULT_REJECT: filter[i].success = failure; break; } switch (filter[i].failure) { - case DIVERT_FILTER_RESULT_ACCEPT: + case WINDIVERT_FILTER_RESULT_ACCEPT: filter[i].failure = success; break; - case DIVERT_FILTER_RESULT_REJECT: + case WINDIVERT_FILTER_RESULT_REJECT: filter[i].failure = failure; break; } } } -#ifdef DIVERT_DEBUG -/* - * Print a filter (debugging). - */ -static void DivertFilterDump(divert_ioctl_filter_t filter, UINT16 len) -{ - UINT16 i; - - for (i = 0; i < len; i++) - { - printf("label_%u:\n\tif (", i); - switch (filter[i].field) - { - case DIVERT_FILTER_FIELD_ZERO: - printf("zero "); - break; - case DIVERT_FILTER_FIELD_INBOUND: - printf("inbound "); - break; - case DIVERT_FILTER_FIELD_OUTBOUND: - printf("outbound "); - break; - case DIVERT_FILTER_FIELD_IFIDX: - printf("ifIdx "); - break; - case DIVERT_FILTER_FIELD_SUBIFIDX: - printf("subIfIdx "); - break; - case DIVERT_FILTER_FIELD_IP: - printf("ip "); - break; - case DIVERT_FILTER_FIELD_IPV6: - printf("ipv6 "); - break; - case DIVERT_FILTER_FIELD_ICMP: - printf("icmp "); - break; - case DIVERT_FILTER_FIELD_ICMPV6: - printf("icmpv6 "); - break; - case DIVERT_FILTER_FIELD_TCP: - printf("tcp "); - break; - case DIVERT_FILTER_FIELD_UDP: - printf("udp "); - break; - case DIVERT_FILTER_FIELD_IP_HDRLENGTH: - printf("ip.HdrLength "); - break; - case DIVERT_FILTER_FIELD_IP_TOS: - printf("ip.TOS "); - break; - case DIVERT_FILTER_FIELD_IP_LENGTH: - printf("ip.Length "); - break; - case DIVERT_FILTER_FIELD_IP_ID: - printf("ip.Id "); - break; - case DIVERT_FILTER_FIELD_IP_DF: - printf("ip.DF "); - break; - case DIVERT_FILTER_FIELD_IP_MF: - printf("ip.MF "); - break; - case DIVERT_FILTER_FIELD_IP_FRAGOFF: - printf("ip.FragOff "); - break; - case DIVERT_FILTER_FIELD_IP_TTL: - printf("ip.TTL "); - break; - case DIVERT_FILTER_FIELD_IP_PROTOCOL: - printf("ip.Protocol "); - break; - case DIVERT_FILTER_FIELD_IP_CHECKSUM: - printf("ip.Checksum "); - break; - case DIVERT_FILTER_FIELD_IP_SRCADDR: - printf("ip.SrcAddr "); - break; - case DIVERT_FILTER_FIELD_IP_DSTADDR: - printf("ip.DstAddr "); - break; - case DIVERT_FILTER_FIELD_IPV6_TRAFFICCLASS: - printf("ipv6.TrafficClass "); - break; - case DIVERT_FILTER_FIELD_IPV6_FLOWLABEL: - printf("ipv6.FlowLabel "); - break; - case DIVERT_FILTER_FIELD_IPV6_LENGTH: - printf("ipv6.Length "); - break; - case DIVERT_FILTER_FIELD_IPV6_NEXTHDR: - printf("ipv6.NextHdr "); - break; - case DIVERT_FILTER_FIELD_IPV6_HOPLIMIT: - printf("ipv6.HopLimit "); - break; - case DIVERT_FILTER_FIELD_IPV6_SRCADDR: - printf("ipv6.SrcAddr "); - break; - case DIVERT_FILTER_FIELD_IPV6_DSTADDR: - printf("ipv6.DstAddr "); - break; - case DIVERT_FILTER_FIELD_ICMP_TYPE: - printf("icmp.Type "); - break; - case DIVERT_FILTER_FIELD_ICMP_CODE: - printf("icmp.Code "); - break; - case DIVERT_FILTER_FIELD_ICMP_CHECKSUM: - printf("icmp.Checksum "); - break; - case DIVERT_FILTER_FIELD_ICMP_BODY: - printf("icmp.Body "); - break; - case DIVERT_FILTER_FIELD_ICMPV6_TYPE: - printf("icmpv6.Type "); - break; - case DIVERT_FILTER_FIELD_ICMPV6_CODE: - printf("icmpv6.Code "); - break; - case DIVERT_FILTER_FIELD_ICMPV6_CHECKSUM: - printf("icmpv6.Checksum "); - break; - case DIVERT_FILTER_FIELD_ICMPV6_BODY: - printf("icmpv6.Body "); - break; - case DIVERT_FILTER_FIELD_TCP_SRCPORT: - printf("tcp.SrcPort "); - break; - case DIVERT_FILTER_FIELD_TCP_DSTPORT: - printf("tcp.DstPort "); - break; - case DIVERT_FILTER_FIELD_TCP_SEQNUM: - printf("tcp.SeqNum "); - break; - case DIVERT_FILTER_FIELD_TCP_ACKNUM: - printf("tcp.AckNum "); - break; - case DIVERT_FILTER_FIELD_TCP_HDRLENGTH: - printf("tcp.HdrLength "); - break; - case DIVERT_FILTER_FIELD_TCP_URG: - printf("tcp.Urg "); - break; - case DIVERT_FILTER_FIELD_TCP_ACK: - printf("tcp.Ack "); - break; - case DIVERT_FILTER_FIELD_TCP_PSH: - printf("tcp.Psh "); - break; - case DIVERT_FILTER_FIELD_TCP_RST: - printf("tcp.Rst "); - break; - case DIVERT_FILTER_FIELD_TCP_SYN: - printf("tcp.Syn "); - break; - case DIVERT_FILTER_FIELD_TCP_FIN: - printf("tcp.Fin "); - break; - case DIVERT_FILTER_FIELD_TCP_WINDOW: - printf("tcp.Window "); - break; - case DIVERT_FILTER_FIELD_TCP_CHECKSUM: - printf("tcp.Checksum "); - break; - case DIVERT_FILTER_FIELD_TCP_URGPTR: - printf("tcp.UrgPtr "); - break; - case DIVERT_FILTER_FIELD_TCP_PAYLOADLENGTH: - printf("tcp.PayloadLength " ); - break; - case DIVERT_FILTER_FIELD_UDP_SRCPORT: - printf("udp.SrcPort "); - break; - case DIVERT_FILTER_FIELD_UDP_DSTPORT: - printf("udp.DstPort "); - break; - case DIVERT_FILTER_FIELD_UDP_LENGTH: - printf("udp.Length "); - break; - case DIVERT_FILTER_FIELD_UDP_CHECKSUM: - printf("udp.Checksum "); - break; - case DIVERT_FILTER_FIELD_UDP_PAYLOADLENGTH: - printf("udp.PayloadLength "); - break; - default: - printf("unknown.Field "); - break; - } - switch (filter[i].test) - { - case DIVERT_FILTER_TEST_EQ: - printf("== "); - break; - case DIVERT_FILTER_TEST_NEQ: - printf("!= "); - break; - case DIVERT_FILTER_TEST_LT: - printf("< "); - break; - case DIVERT_FILTER_TEST_LEQ: - printf("<= "); - break; - case DIVERT_FILTER_TEST_GT: - printf("> "); - break; - case DIVERT_FILTER_TEST_GEQ: - printf(">= "); - break; - default: - printf("?? "); - break; - } - printf("%u)\n", filter[i].arg[0]); - switch (filter[i].success) - { - case DIVERT_FILTER_RESULT_ACCEPT: - printf("\t\treturn ACCEPT;\n"); - break; - case DIVERT_FILTER_RESULT_REJECT: - printf("\t\treturn REJECT;\n"); - break; - default: - printf("\t\tgoto label_%u;\n", filter[i].success); - break; - } - printf("\telse\n"); - switch (filter[i].failure) - { - case DIVERT_FILTER_RESULT_ACCEPT: - printf("\t\treturn ACCEPT;\n"); - break; - case DIVERT_FILTER_RESULT_REJECT: - printf("\t\treturn REJECT;\n"); - break; - default: - printf("\t\tgoto label_%u;\n", filter[i].failure); - break; - } - } -} - -#endif /* DIVERT_DEBUG */ - /****************************************************************************/ -/* DIVERT HELPER IMPLEMENTATION */ +/* WINDIVERT HELPER IMPLEMENTATION */ /****************************************************************************/ /* * Parse IPv4/IPv6/ICMP/ICMPv6/TCP/UDP headers from a raw packet. */ -extern BOOL DivertHelperParsePacket(PVOID pPacket, UINT packetLen, - PDIVERT_IPHDR *ppIpHdr, PDIVERT_IPV6HDR *ppIpv6Hdr, - PDIVERT_ICMPHDR *ppIcmpHdr, PDIVERT_ICMPV6HDR *ppIcmpv6Hdr, - PDIVERT_TCPHDR *ppTcpHdr, PDIVERT_UDPHDR *ppUdpHdr, PVOID *ppData, +extern BOOL WinDivertHelperParsePacket(PVOID pPacket, UINT packetLen, + PWINDIVERT_IPHDR *ppIpHdr, PWINDIVERT_IPV6HDR *ppIpv6Hdr, + PWINDIVERT_ICMPHDR *ppIcmpHdr, PWINDIVERT_ICMPV6HDR *ppIcmpv6Hdr, + PWINDIVERT_TCPHDR *ppTcpHdr, PWINDIVERT_UDPHDR *ppUdpHdr, PVOID *ppData, UINT *pDataLen) { - PDIVERT_IPHDR ip_header = NULL; - PDIVERT_IPV6HDR ipv6_header = NULL; - PDIVERT_ICMPHDR icmp_header = NULL; - PDIVERT_ICMPV6HDR icmpv6_header = NULL; - PDIVERT_TCPHDR tcp_header = NULL; - PDIVERT_UDPHDR udp_header = NULL; + PWINDIVERT_IPHDR ip_header = NULL; + PWINDIVERT_IPV6HDR ipv6_header = NULL; + PWINDIVERT_ICMPHDR icmp_header = NULL; + PWINDIVERT_ICMPV6HDR icmpv6_header = NULL; + PWINDIVERT_TCPHDR tcp_header = NULL; + PWINDIVERT_UDPHDR udp_header = NULL; UINT16 header_len; UINT8 trans_proto; PVOID data = NULL; @@ -1847,22 +1676,22 @@ extern BOOL DivertHelperParsePacket(PVOID pPacket, UINT packetLen, if (pPacket == NULL || packetLen < sizeof(UINT8)) { - goto DivertHelperParsePacketExit; + goto WinDivertHelperParsePacketExit; } data = pPacket; data_len = packetLen; - ip_header = (PDIVERT_IPHDR)data; + ip_header = (PWINDIVERT_IPHDR)data; switch (ip_header->Version) { case 4: - if (data_len < sizeof(DIVERT_IPHDR) || + if (data_len < sizeof(WINDIVERT_IPHDR) || ip_header->HdrLength < 5 || data_len < ip_header->HdrLength*sizeof(UINT32) || ntohs(ip_header->Length) != data_len) { ip_header = NULL; - goto DivertHelperParsePacketExit; + goto WinDivertHelperParsePacketExit; } trans_proto = ip_header->Protocol; header_len = ip_header->HdrLength*sizeof(UINT32); @@ -1871,70 +1700,70 @@ extern BOOL DivertHelperParsePacket(PVOID pPacket, UINT packetLen, break; case 6: ip_header = NULL; - ipv6_header = (PDIVERT_IPV6HDR)data; - if (data_len < sizeof(DIVERT_IPV6HDR) || + ipv6_header = (PWINDIVERT_IPV6HDR)data; + if (data_len < sizeof(WINDIVERT_IPV6HDR) || ntohs(ipv6_header->Length) != - data_len - sizeof(DIVERT_IPV6HDR)) + data_len - sizeof(WINDIVERT_IPV6HDR)) { ipv6_header = NULL; - goto DivertHelperParsePacketExit; + goto WinDivertHelperParsePacketExit; } trans_proto = ipv6_header->NextHdr; - data = (PVOID)((UINT8 *)data + sizeof(DIVERT_IPV6HDR)); - data_len -= sizeof(DIVERT_IPV6HDR); + data = (PVOID)((UINT8 *)data + sizeof(WINDIVERT_IPV6HDR)); + data_len -= sizeof(WINDIVERT_IPV6HDR); break; default: ip_header = NULL; - goto DivertHelperParsePacketExit; + goto WinDivertHelperParsePacketExit; } switch (trans_proto) { case IPPROTO_TCP: - tcp_header = (PDIVERT_TCPHDR)data; - if (data_len < sizeof(DIVERT_TCPHDR) || + tcp_header = (PWINDIVERT_TCPHDR)data; + if (data_len < sizeof(WINDIVERT_TCPHDR) || tcp_header->HdrLength < 5 || data_len < tcp_header->HdrLength*sizeof(UINT32)) { tcp_header = NULL; - goto DivertHelperParsePacketExit; + goto WinDivertHelperParsePacketExit; } header_len = tcp_header->HdrLength*sizeof(UINT32); data = ((UINT8 *)data + header_len); data_len -= header_len; break; case IPPROTO_UDP: - udp_header = (PDIVERT_UDPHDR)data; - if (data_len < sizeof(DIVERT_UDPHDR) || + udp_header = (PWINDIVERT_UDPHDR)data; + if (data_len < sizeof(WINDIVERT_UDPHDR) || ntohs(udp_header->Length) != data_len) { udp_header = NULL; - goto DivertHelperParsePacketExit; + goto WinDivertHelperParsePacketExit; } - data = ((UINT8 *)data + sizeof(DIVERT_UDPHDR)); - data_len -= sizeof(DIVERT_UDPHDR); + data = ((UINT8 *)data + sizeof(WINDIVERT_UDPHDR)); + data_len -= sizeof(WINDIVERT_UDPHDR); break; case IPPROTO_ICMP: - icmp_header = (PDIVERT_ICMPHDR)data; + icmp_header = (PWINDIVERT_ICMPHDR)data; if (ip_header == NULL || - data_len < sizeof(DIVERT_ICMPHDR)) + data_len < sizeof(WINDIVERT_ICMPHDR)) { icmp_header = NULL; - goto DivertHelperParsePacketExit; + goto WinDivertHelperParsePacketExit; } - data = ((UINT8 *)data + sizeof(DIVERT_ICMPHDR)); - data_len -= sizeof(DIVERT_ICMPHDR); + data = ((UINT8 *)data + sizeof(WINDIVERT_ICMPHDR)); + data_len -= sizeof(WINDIVERT_ICMPHDR); break; case IPPROTO_ICMPV6: - icmpv6_header = (PDIVERT_ICMPV6HDR)data; + icmpv6_header = (PWINDIVERT_ICMPV6HDR)data; if (ipv6_header == NULL || - data_len < sizeof(DIVERT_ICMPV6HDR)) + data_len < sizeof(WINDIVERT_ICMPV6HDR)) { icmpv6_header = NULL; - goto DivertHelperParsePacketExit; + goto WinDivertHelperParsePacketExit; } - data = ((UINT8 *)data + sizeof(DIVERT_ICMPV6HDR)); - data_len -= sizeof(DIVERT_ICMPV6HDR); + data = ((UINT8 *)data + sizeof(WINDIVERT_ICMPV6HDR)); + data_len -= sizeof(WINDIVERT_ICMPV6HDR); break; default: break; @@ -1945,7 +1774,7 @@ extern BOOL DivertHelperParsePacket(PVOID pPacket, UINT packetLen, data = NULL; } -DivertHelperParsePacketExit: +WinDivertHelperParsePacketExit: success = TRUE; if (ppIpHdr != NULL) { @@ -1992,56 +1821,56 @@ DivertHelperParsePacketExit: /* * Calculate IPv4/IPv6/ICMP/ICMPv6/TCP/UDP checksums. */ -extern UINT DivertHelperCalcChecksums(PVOID pPacket, UINT packetLen, +extern UINT WinDivertHelperCalcChecksums(PVOID pPacket, UINT packetLen, UINT64 flags) { - DIVERT_PSEUDOHDR pseudo_header; - DIVERT_PSEUDOV6HDR pseudov6_header; - PDIVERT_IPHDR ip_header; - PDIVERT_IPV6HDR ipv6_header; - PDIVERT_ICMPHDR icmp_header; - PDIVERT_ICMPV6HDR icmpv6_header; - PDIVERT_TCPHDR tcp_header; - PDIVERT_UDPHDR udp_header; + WINDIVERT_PSEUDOHDR pseudo_header; + WINDIVERT_PSEUDOV6HDR pseudov6_header; + PWINDIVERT_IPHDR ip_header; + PWINDIVERT_IPV6HDR ipv6_header; + PWINDIVERT_ICMPHDR icmp_header; + PWINDIVERT_ICMPV6HDR icmpv6_header; + PWINDIVERT_TCPHDR tcp_header; + PWINDIVERT_UDPHDR udp_header; UINT payload_len, checksum_len; UINT count = 0; - DivertHelperParsePacket(pPacket, packetLen, &ip_header, &ipv6_header, + WinDivertHelperParsePacket(pPacket, packetLen, &ip_header, &ipv6_header, &icmp_header, &icmpv6_header, &tcp_header, &udp_header, NULL, &payload_len); - if (ip_header != NULL && !(flags & DIVERT_HELPER_NO_IP_CHECKSUM)) + if (ip_header != NULL && !(flags & WINDIVERT_HELPER_NO_IP_CHECKSUM)) { ip_header->Checksum = 0; - ip_header->Checksum = DivertHelperCalcChecksum(NULL, 0, + ip_header->Checksum = WinDivertHelperCalcChecksum(NULL, 0, ip_header, ip_header->HdrLength*sizeof(UINT32)); count++; } if (icmp_header != NULL) { - if (flags & DIVERT_HELPER_NO_ICMP_CHECKSUM) + if (flags & WINDIVERT_HELPER_NO_ICMP_CHECKSUM) { return count; } icmp_header->Checksum = 0; - icmp_header->Checksum = DivertHelperCalcChecksum(NULL, 0, - icmp_header, payload_len + sizeof(DIVERT_ICMPHDR)); + icmp_header->Checksum = WinDivertHelperCalcChecksum(NULL, 0, + icmp_header, payload_len + sizeof(WINDIVERT_ICMPHDR)); count++; return count; } if (icmpv6_header != NULL) { - if (flags & DIVERT_HELPER_NO_ICMPV6_CHECKSUM) + if (flags & WINDIVERT_HELPER_NO_ICMPV6_CHECKSUM) { return count; } - checksum_len = payload_len + sizeof(DIVERT_ICMPV6HDR); - DivertInitPseudoHeaderV6(ipv6_header, &pseudov6_header, + checksum_len = payload_len + sizeof(WINDIVERT_ICMPV6HDR); + WinDivertInitPseudoHeaderV6(ipv6_header, &pseudov6_header, IPPROTO_ICMPV6, checksum_len); icmpv6_header->Checksum = 0; - icmpv6_header->Checksum = DivertHelperCalcChecksum(&pseudov6_header, + icmpv6_header->Checksum = WinDivertHelperCalcChecksum(&pseudov6_header, sizeof(pseudov6_header), icmpv6_header, checksum_len); count++; return count; @@ -2049,25 +1878,25 @@ extern UINT DivertHelperCalcChecksums(PVOID pPacket, UINT packetLen, if (tcp_header != NULL) { - if (flags & DIVERT_HELPER_NO_TCP_CHECKSUM) + if (flags & WINDIVERT_HELPER_NO_TCP_CHECKSUM) { return count; } checksum_len = payload_len + tcp_header->HdrLength*sizeof(UINT32); if (ip_header != NULL) { - DivertInitPseudoHeader(ip_header, &pseudo_header, IPPROTO_TCP, + WinDivertInitPseudoHeader(ip_header, &pseudo_header, IPPROTO_TCP, checksum_len); tcp_header->Checksum = 0; - tcp_header->Checksum = DivertHelperCalcChecksum(&pseudo_header, + tcp_header->Checksum = WinDivertHelperCalcChecksum(&pseudo_header, sizeof(pseudo_header), tcp_header, checksum_len); } else { - DivertInitPseudoHeaderV6(ipv6_header, &pseudov6_header, + WinDivertInitPseudoHeaderV6(ipv6_header, &pseudov6_header, IPPROTO_TCP, checksum_len); tcp_header->Checksum = 0; - tcp_header->Checksum = DivertHelperCalcChecksum(&pseudov6_header, + tcp_header->Checksum = WinDivertHelperCalcChecksum(&pseudov6_header, sizeof(pseudov6_header), tcp_header, checksum_len); } count++; @@ -2076,17 +1905,17 @@ extern UINT DivertHelperCalcChecksums(PVOID pPacket, UINT packetLen, if (udp_header != NULL) { - if (flags & DIVERT_HELPER_NO_UDP_CHECKSUM) + if (flags & WINDIVERT_HELPER_NO_UDP_CHECKSUM) { return count; } - checksum_len = payload_len + sizeof(DIVERT_UDPHDR); + checksum_len = payload_len + sizeof(WINDIVERT_UDPHDR); if (ip_header != NULL) { - DivertInitPseudoHeader(ip_header, &pseudo_header, IPPROTO_UDP, + WinDivertInitPseudoHeader(ip_header, &pseudo_header, IPPROTO_UDP, checksum_len); udp_header->Checksum = 0; - udp_header->Checksum = DivertHelperCalcChecksum(&pseudo_header, + udp_header->Checksum = WinDivertHelperCalcChecksum(&pseudo_header, sizeof(pseudo_header), udp_header, checksum_len); if (udp_header->Checksum == 0) { @@ -2095,10 +1924,10 @@ extern UINT DivertHelperCalcChecksums(PVOID pPacket, UINT packetLen, } else { - DivertInitPseudoHeaderV6(ipv6_header, &pseudov6_header, + WinDivertInitPseudoHeaderV6(ipv6_header, &pseudov6_header, IPPROTO_UDP, checksum_len); udp_header->Checksum = 0; - udp_header->Checksum = DivertHelperCalcChecksum(&pseudov6_header, + udp_header->Checksum = WinDivertHelperCalcChecksum(&pseudov6_header, sizeof(pseudov6_header), udp_header, checksum_len); } count++; @@ -2109,8 +1938,8 @@ extern UINT DivertHelperCalcChecksums(PVOID pPacket, UINT packetLen, /* * Initialize the IP pseudo header. */ -static void DivertInitPseudoHeader(PDIVERT_IPHDR ip_header, - PDIVERT_PSEUDOHDR pseudo_header, UINT8 protocol, UINT len) +static void WinDivertInitPseudoHeader(PWINDIVERT_IPHDR ip_header, + PWINDIVERT_PSEUDOHDR pseudo_header, UINT8 protocol, UINT len) { pseudo_header->SrcAddr = ip_header->SrcAddr; pseudo_header->DstAddr = ip_header->DstAddr; @@ -2122,8 +1951,8 @@ static void DivertInitPseudoHeader(PDIVERT_IPHDR ip_header, /* * Initialize the IPv6 pseudo header. */ -static void DivertInitPseudoHeaderV6(PDIVERT_IPV6HDR ipv6_header, - PDIVERT_PSEUDOV6HDR pseudov6_header, UINT8 protocol, UINT len) +static void WinDivertInitPseudoHeaderV6(PWINDIVERT_IPV6HDR ipv6_header, + PWINDIVERT_PSEUDOV6HDR pseudov6_header, UINT8 protocol, UINT len) { memcpy(pseudov6_header->SrcAddr, ipv6_header->SrcAddr, sizeof(pseudov6_header->SrcAddr)); @@ -2137,7 +1966,7 @@ static void DivertInitPseudoHeaderV6(PDIVERT_IPV6HDR ipv6_header, /* * Generic checksum computation. */ -static UINT16 DivertHelperCalcChecksum(PVOID pseudo_header, +static UINT16 WinDivertHelperCalcChecksum(PVOID pseudo_header, UINT16 pseudo_header_len, PVOID data, UINT len) { register const UINT16 *data16 = (const UINT16 *)pseudo_header; @@ -2174,7 +2003,7 @@ static UINT16 DivertHelperCalcChecksum(PVOID pseudo_header, /* * Parse an IPv4 address. */ -extern BOOL DivertHelperParseIPv4Address(const char *str, UINT32 *addr_ptr) +extern BOOL WinDivertHelperParseIPv4Address(const char *str, UINT32 *addr_ptr) { UINT32 addr = 0; UINT part, i; @@ -2210,7 +2039,7 @@ extern BOOL DivertHelperParseIPv4Address(const char *str, UINT32 *addr_ptr) /* * Parse an IPv6 address. */ -extern BOOL DivertHelperParseIPv6Address(const char *str, UINT32 *addr_ptr) +extern BOOL WinDivertHelperParseIPv6Address(const char *str, UINT32 *addr_ptr) { UINT16 addr[8] = {0}; UINT part; @@ -2311,3 +2140,253 @@ extern BOOL DivertHelperParseIPv6Address(const char *str, UINT32 *addr_ptr) return TRUE; } +/***************************************************************************/ +/* DEBUGGING */ +/***************************************************************************/ + +#ifdef WINDIVERT_DEBUG +/* + * Print a filter (debugging). + */ +static void WinDivertFilterDump(windivert_ioctl_filter_t filter, UINT16 len) +{ + UINT16 i; + + for (i = 0; i < len; i++) + { + printf("label_%u:\n\tif (", i); + switch (filter[i].field) + { + case WINDIVERT_FILTER_FIELD_ZERO: + printf("zero "); + break; + case WINDIVERT_FILTER_FIELD_INBOUND: + printf("inbound "); + break; + case WINDIVERT_FILTER_FIELD_OUTBOUND: + printf("outbound "); + break; + case WINDIVERT_FILTER_FIELD_IFIDX: + printf("ifIdx "); + break; + case WINDIVERT_FILTER_FIELD_SUBIFIDX: + printf("subIfIdx "); + break; + case WINDIVERT_FILTER_FIELD_IP: + printf("ip "); + break; + case WINDIVERT_FILTER_FIELD_IPV6: + printf("ipv6 "); + break; + case WINDIVERT_FILTER_FIELD_ICMP: + printf("icmp "); + break; + case WINDIVERT_FILTER_FIELD_ICMPV6: + printf("icmpv6 "); + break; + case WINDIVERT_FILTER_FIELD_TCP: + printf("tcp "); + break; + case WINDIVERT_FILTER_FIELD_UDP: + printf("udp "); + break; + case WINDIVERT_FILTER_FIELD_IP_HDRLENGTH: + printf("ip.HdrLength "); + break; + case WINDIVERT_FILTER_FIELD_IP_TOS: + printf("ip.TOS "); + break; + case WINDIVERT_FILTER_FIELD_IP_LENGTH: + printf("ip.Length "); + break; + case WINDIVERT_FILTER_FIELD_IP_ID: + printf("ip.Id "); + break; + case WINDIVERT_FILTER_FIELD_IP_DF: + printf("ip.DF "); + break; + case WINDIVERT_FILTER_FIELD_IP_MF: + printf("ip.MF "); + break; + case WINDIVERT_FILTER_FIELD_IP_FRAGOFF: + printf("ip.FragOff "); + break; + case WINDIVERT_FILTER_FIELD_IP_TTL: + printf("ip.TTL "); + break; + case WINDIVERT_FILTER_FIELD_IP_PROTOCOL: + printf("ip.Protocol "); + break; + case WINDIVERT_FILTER_FIELD_IP_CHECKSUM: + printf("ip.Checksum "); + break; + case WINDIVERT_FILTER_FIELD_IP_SRCADDR: + printf("ip.SrcAddr "); + break; + case WINDIVERT_FILTER_FIELD_IP_DSTADDR: + printf("ip.DstAddr "); + break; + case WINDIVERT_FILTER_FIELD_IPV6_TRAFFICCLASS: + printf("ipv6.TrafficClass "); + break; + case WINDIVERT_FILTER_FIELD_IPV6_FLOWLABEL: + printf("ipv6.FlowLabel "); + break; + case WINDIVERT_FILTER_FIELD_IPV6_LENGTH: + printf("ipv6.Length "); + break; + case WINDIVERT_FILTER_FIELD_IPV6_NEXTHDR: + printf("ipv6.NextHdr "); + break; + case WINDIVERT_FILTER_FIELD_IPV6_HOPLIMIT: + printf("ipv6.HopLimit "); + break; + case WINDIVERT_FILTER_FIELD_IPV6_SRCADDR: + printf("ipv6.SrcAddr "); + break; + case WINDIVERT_FILTER_FIELD_IPV6_DSTADDR: + printf("ipv6.DstAddr "); + break; + case WINDIVERT_FILTER_FIELD_ICMP_TYPE: + printf("icmp.Type "); + break; + case WINDIVERT_FILTER_FIELD_ICMP_CODE: + printf("icmp.Code "); + break; + case WINDIVERT_FILTER_FIELD_ICMP_CHECKSUM: + printf("icmp.Checksum "); + break; + case WINDIVERT_FILTER_FIELD_ICMP_BODY: + printf("icmp.Body "); + break; + case WINDIVERT_FILTER_FIELD_ICMPV6_TYPE: + printf("icmpv6.Type "); + break; + case WINDIVERT_FILTER_FIELD_ICMPV6_CODE: + printf("icmpv6.Code "); + break; + case WINDIVERT_FILTER_FIELD_ICMPV6_CHECKSUM: + printf("icmpv6.Checksum "); + break; + case WINDIVERT_FILTER_FIELD_ICMPV6_BODY: + printf("icmpv6.Body "); + break; + case WINDIVERT_FILTER_FIELD_TCP_SRCPORT: + printf("tcp.SrcPort "); + break; + case WINDIVERT_FILTER_FIELD_TCP_DSTPORT: + printf("tcp.DstPort "); + break; + case WINDIVERT_FILTER_FIELD_TCP_SEQNUM: + printf("tcp.SeqNum "); + break; + case WINDIVERT_FILTER_FIELD_TCP_ACKNUM: + printf("tcp.AckNum "); + break; + case WINDIVERT_FILTER_FIELD_TCP_HDRLENGTH: + printf("tcp.HdrLength "); + break; + case WINDIVERT_FILTER_FIELD_TCP_URG: + printf("tcp.Urg "); + break; + case WINDIVERT_FILTER_FIELD_TCP_ACK: + printf("tcp.Ack "); + break; + case WINDIVERT_FILTER_FIELD_TCP_PSH: + printf("tcp.Psh "); + break; + case WINDIVERT_FILTER_FIELD_TCP_RST: + printf("tcp.Rst "); + break; + case WINDIVERT_FILTER_FIELD_TCP_SYN: + printf("tcp.Syn "); + break; + case WINDIVERT_FILTER_FIELD_TCP_FIN: + printf("tcp.Fin "); + break; + case WINDIVERT_FILTER_FIELD_TCP_WINDOW: + printf("tcp.Window "); + break; + case WINDIVERT_FILTER_FIELD_TCP_CHECKSUM: + printf("tcp.Checksum "); + break; + case WINDIVERT_FILTER_FIELD_TCP_URGPTR: + printf("tcp.UrgPtr "); + break; + case WINDIVERT_FILTER_FIELD_TCP_PAYLOADLENGTH: + printf("tcp.PayloadLength " ); + break; + case WINDIVERT_FILTER_FIELD_UDP_SRCPORT: + printf("udp.SrcPort "); + break; + case WINDIVERT_FILTER_FIELD_UDP_DSTPORT: + printf("udp.DstPort "); + break; + case WINDIVERT_FILTER_FIELD_UDP_LENGTH: + printf("udp.Length "); + break; + case WINDIVERT_FILTER_FIELD_UDP_CHECKSUM: + printf("udp.Checksum "); + break; + case WINDIVERT_FILTER_FIELD_UDP_PAYLOADLENGTH: + printf("udp.PayloadLength "); + break; + default: + printf("unknown.Field "); + break; + } + switch (filter[i].test) + { + case WINDIVERT_FILTER_TEST_EQ: + printf("== "); + break; + case WINDIVERT_FILTER_TEST_NEQ: + printf("!= "); + break; + case WINDIVERT_FILTER_TEST_LT: + printf("< "); + break; + case WINDIVERT_FILTER_TEST_LEQ: + printf("<= "); + break; + case WINDIVERT_FILTER_TEST_GT: + printf("> "); + break; + case WINDIVERT_FILTER_TEST_GEQ: + printf(">= "); + break; + default: + printf("?? "); + break; + } + printf("%u)\n", filter[i].arg[0]); + switch (filter[i].success) + { + case WINDIVERT_FILTER_RESULT_ACCEPT: + printf("\t\treturn ACCEPT;\n"); + break; + case WINDIVERT_FILTER_RESULT_REJECT: + printf("\t\treturn REJECT;\n"); + break; + default: + printf("\t\tgoto label_%u;\n", filter[i].success); + break; + } + printf("\telse\n"); + switch (filter[i].failure) + { + case WINDIVERT_FILTER_RESULT_ACCEPT: + printf("\t\treturn ACCEPT;\n"); + break; + case WINDIVERT_FILTER_RESULT_REJECT: + printf("\t\treturn REJECT;\n"); + break; + default: + printf("\t\tgoto label_%u;\n", filter[i].failure); + break; + } + } +} + +#endif /* WINDIVERT_DEBUG */ + diff --git a/dll/windivert.def b/dll/windivert.def new file mode 100644 index 0000000..d6db928 --- /dev/null +++ b/dll/windivert.def @@ -0,0 +1,15 @@ +LIBRARY WinDivert +EXPORTS + WinDivertDllEntry + WinDivertOpen + WinDivertRecv + WinDivertRecvEx + WinDivertSend + WinDivertSendEx + WinDivertClose + WinDivertSetParam + WinDivertGetParam + WinDivertHelperCalcChecksums + WinDivertHelperParsePacket + WinDivertHelperParseIPv4Address + WinDivertHelperParseIPv6Address diff --git a/dll/divert.vcxproj b/dll/windivert.vcxproj similarity index 92% rename from dll/divert.vcxproj rename to dll/windivert.vcxproj index 1b5502c..5151e16 100644 --- a/dll/divert.vcxproj +++ b/dll/windivert.vcxproj @@ -28,7 +28,7 @@ ..\include;%(AdditionalIncludeDirectories) - divert.def + windivert.def @@ -52,10 +52,10 @@ - + - + diff --git a/doc/divert.html b/doc/windivert.html similarity index 100% rename from doc/divert.html rename to doc/windivert.html diff --git a/examples/netdump/netdump.c b/examples/netdump/netdump.c index 26ded3c..91aa672 100644 --- a/examples/netdump/netdump.c +++ b/examples/netdump/netdump.c @@ -1,6 +1,6 @@ /* * netdump.c - * (C) 2012, all rights reserved, + * (C) 2013, all rights reserved, * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -18,10 +18,10 @@ /* * DESCRIPTION: - * This is a simple traffic monitor. It uses a divert handle in SNIFF mode. + * This is a simple traffic monitor. It uses a WinDivert handle in SNIFF mode. * The SNIFF mode copies packets and does not block the original. * - * usage: netdump.exe divert-filter [priority] + * usage: netdump.exe windivert-filter [priority] * */ @@ -31,7 +31,7 @@ #include #include -#include "divert.h" +#include "windivert.h" #define MAXBUF 0xFFFF @@ -45,13 +45,13 @@ int __cdecl main(int argc, char **argv) INT16 priority = 0; char packet[MAXBUF]; UINT packet_len; - DIVERT_ADDRESS addr; - PDIVERT_IPHDR ip_header; - PDIVERT_IPV6HDR ipv6_header; - PDIVERT_ICMPHDR icmp_header; - PDIVERT_ICMPV6HDR icmpv6_header; - PDIVERT_TCPHDR tcp_header; - PDIVERT_UDPHDR udp_header; + WINDIVERT_ADDRESS addr; + PWINDIVERT_IPHDR ip_header; + PWINDIVERT_IPV6HDR ipv6_header; + PWINDIVERT_ICMPHDR icmp_header; + PWINDIVERT_ICMPV6HDR icmpv6_header; + PWINDIVERT_TCPHDR tcp_header; + PWINDIVERT_UDPHDR udp_header; // Check arguments. switch (argc) @@ -62,7 +62,7 @@ int __cdecl main(int argc, char **argv) priority = (INT16)atoi(argv[2]); break; default: - fprintf(stderr, "usage: %s divert-filter [priority]\n", + fprintf(stderr, "usage: %s windivert-filter [priority]\n", argv[0]); fprintf(stderr, "examples:\n"); fprintf(stderr, "\t%s true\n", argv[0]); @@ -76,7 +76,8 @@ int __cdecl main(int argc, char **argv) console = GetStdHandle(STD_OUTPUT_HANDLE); // Divert traffic matching the filter: - handle = DivertOpen(argv[1], (DIVERT_LAYER)0, priority, DIVERT_FLAG_SNIFF); + handle = WinDivertOpen(argv[1], WINDIVERT_LAYER_NETWORK, priority, + WINDIVERT_FLAG_SNIFF); if (handle == INVALID_HANDLE_VALUE) { if (GetLastError() == ERROR_INVALID_PARAMETER) @@ -84,19 +85,19 @@ int __cdecl main(int argc, char **argv) fprintf(stderr, "error: filter syntax error\n"); exit(EXIT_FAILURE); } - fprintf(stderr, "error: failed to open Divert device (%d)\n", + fprintf(stderr, "error: failed to open the WinDivert device (%d)\n", GetLastError()); exit(EXIT_FAILURE); } // Max-out the packet queue: - if (!DivertSetParam(handle, DIVERT_PARAM_QUEUE_LEN, 8192)) + if (!WinDivertSetParam(handle, WINDIVERT_PARAM_QUEUE_LEN, 8192)) { fprintf(stderr, "error: failed to set packet queue length (%d)\n", GetLastError()); exit(EXIT_FAILURE); } - if (!DivertSetParam(handle, DIVERT_PARAM_QUEUE_TIME, 1024)) + if (!WinDivertSetParam(handle, WINDIVERT_PARAM_QUEUE_TIME, 2048)) { fprintf(stderr, "error: failed to set packet queue time (%d)\n", GetLastError()); @@ -107,7 +108,7 @@ int __cdecl main(int argc, char **argv) while (TRUE) { // Read a matching packet. - if (!DivertRecv(handle, packet, sizeof(packet), &addr, &packet_len)) + if (!WinDivertRecv(handle, packet, sizeof(packet), &addr, &packet_len)) { fprintf(stderr, "warning: failed to read packet (%d)\n", GetLastError()); @@ -115,9 +116,9 @@ int __cdecl main(int argc, char **argv) } // Print info about the matching packet. - DivertHelperParse(packet, packet_len, &ip_header, &ipv6_header, - &icmp_header, &icmpv6_header, &tcp_header, &udp_header, NULL, - NULL); + WinDivertHelperParsePacket(packet, packet_len, &ip_header, + &ipv6_header, &icmp_header, &icmpv6_header, &tcp_header, + &udp_header, NULL, NULL); if (ip_header == NULL && ipv6_header == NULL) { fprintf(stderr, "warning: junk packet\n"); @@ -139,9 +140,10 @@ int __cdecl main(int argc, char **argv) "Checksum=0x%.4X SrcAddr=%u.%u.%u.%u DstAddr=%u.%u.%u.%u]\n", ip_header->Version, ip_header->HdrLength, ntohs(ip_header->TOS), ntohs(ip_header->Length), - ntohs(ip_header->Id), DIVERT_IPHDR_GET_RESERVED(ip_header), - DIVERT_IPHDR_GET_DF(ip_header), DIVERT_IPHDR_GET_MF(ip_header), - ntohs(DIVERT_IPHDR_GET_FRAGOFF(ip_header)), ip_header->TTL, + ntohs(ip_header->Id), WINDIVERT_IPHDR_GET_RESERVED(ip_header), + WINDIVERT_IPHDR_GET_DF(ip_header), + WINDIVERT_IPHDR_GET_MF(ip_header), + ntohs(WINDIVERT_IPHDR_GET_FRAGOFF(ip_header)), ip_header->TTL, ip_header->Protocol, ntohs(ip_header->Checksum), src_addr[0], src_addr[1], src_addr[2], src_addr[3], dst_addr[0], dst_addr[1], dst_addr[2], dst_addr[3]); @@ -155,8 +157,8 @@ int __cdecl main(int argc, char **argv) printf("IPv6 [Version=%u TrafficClass=%u FlowLabel=%u Length=%u " "NextHdr=%u HopLimit=%u SrcAddr=", ipv6_header->Version, - DIVERT_IPV6HDR_GET_TRAFFICCLASS(ipv6_header), - ntohl(DIVERT_IPV6HDR_GET_FLOWLABEL(ipv6_header)), + WINDIVERT_IPV6HDR_GET_TRAFFICCLASS(ipv6_header), + ntohl(WINDIVERT_IPV6HDR_GET_FLOWLABEL(ipv6_header)), ntohs(ipv6_header->Length), ipv6_header->NextHdr, ipv6_header->HopLimit); for (i = 0; i < 8; i++) diff --git a/examples/netdump/sources b/examples/netdump/sources index 661ca52..d2e86b7 100644 --- a/examples/netdump/sources +++ b/examples/netdump/sources @@ -1,5 +1,5 @@ # sources -# (C) 2012, all rights reserved, +# (C) 2013, all rights reserved, # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by diff --git a/examples/netfilter/netfilter.c b/examples/netfilter/netfilter.c index 805f39d..914058c 100644 --- a/examples/netfilter/netfilter.c +++ b/examples/netfilter/netfilter.c @@ -1,6 +1,6 @@ /* * netfilter.c - * (C) 2012, all rights reserved, + * (C) 2013, all rights reserved, * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -20,9 +20,9 @@ * DESCRIPTION: * This is a simple traffic filter/firewall using WinDivert. * - * usage: netfilter.exe divert-filter [priority] + * usage: netfilter.exe windivert-filter [priority] * - * Any traffic that matches the divert-filter will be blocked using one of + * Any traffic that matches the windivert-filter will be blocked using one of * the following methods: * - TCP: send a TCP RST to the packet's source. * - UDP: send a ICMP(v6) "destination unreachable" to the packet's source. @@ -37,7 +37,7 @@ #include #include -#include "divert.h" +#include "windivert.h" #define MAXBUF 0xFFFF @@ -46,37 +46,37 @@ */ typedef struct { - DIVERT_IPHDR ip; - DIVERT_TCPHDR tcp; + WINDIVERT_IPHDR ip; + WINDIVERT_TCPHDR tcp; } TCPPACKET, *PTCPPACKET; typedef struct { - DIVERT_IPV6HDR ipv6; - DIVERT_TCPHDR tcp; + WINDIVERT_IPV6HDR ipv6; + WINDIVERT_TCPHDR tcp; } TCPV6PACKET, *PTCPV6PACKET; typedef struct { - DIVERT_IPHDR ip; - DIVERT_ICMPHDR icmp; + WINDIVERT_IPHDR ip; + WINDIVERT_ICMPHDR icmp; UINT8 data[]; } ICMPPACKET, *PICMPPACKET; typedef struct { - DIVERT_IPV6HDR ipv6; - DIVERT_ICMPV6HDR icmpv6; + WINDIVERT_IPV6HDR ipv6; + WINDIVERT_ICMPV6HDR icmpv6; UINT8 data[]; } ICMPV6PACKET, *PICMPV6PACKET; /* * Prototypes. */ -static void PacketIpInit(PDIVERT_IPHDR packet); +static void PacketIpInit(PWINDIVERT_IPHDR packet); static void PacketIpTcpInit(PTCPPACKET packet); static void PacketIpIcmpInit(PICMPPACKET packet); -static void PacketIpv6Init(PDIVERT_IPV6HDR packet); +static void PacketIpv6Init(PWINDIVERT_IPV6HDR packet); static void PacketIpv6TcpInit(PTCPV6PACKET packet); static void PacketIpv6Icmpv6Init(PICMPV6PACKET packet); @@ -90,13 +90,13 @@ int __cdecl main(int argc, char **argv) INT16 priority = 0; char packet[MAXBUF]; UINT packet_len; - DIVERT_ADDRESS recv_addr, send_addr; - PDIVERT_IPHDR ip_header; - PDIVERT_IPV6HDR ipv6_header; - PDIVERT_ICMPHDR icmp_header; - PDIVERT_ICMPV6HDR icmpv6_header; - PDIVERT_TCPHDR tcp_header; - PDIVERT_UDPHDR udp_header; + WINDIVERT_ADDRESS recv_addr, send_addr; + PWINDIVERT_IPHDR ip_header; + PWINDIVERT_IPV6HDR ipv6_header; + PWINDIVERT_ICMPHDR icmp_header; + PWINDIVERT_ICMPV6HDR icmpv6_header; + PWINDIVERT_TCPHDR tcp_header; + PWINDIVERT_UDPHDR udp_header; UINT payload_len; TCPPACKET reset0; @@ -106,8 +106,8 @@ int __cdecl main(int argc, char **argv) TCPV6PACKET resetv6_0; PTCPV6PACKET resetv6 = &resetv6_0; - UINT8 dnrv6_0[sizeof(ICMPV6PACKET) + sizeof(DIVERT_IPV6HDR) + - sizeof(DIVERT_TCPHDR)]; + UINT8 dnrv6_0[sizeof(ICMPV6PACKET) + sizeof(WINDIVERT_IPV6HDR) + + sizeof(WINDIVERT_TCPHDR)]; PICMPV6PACKET dnrv6 = (PICMPV6PACKET)dnrv6_0; // Check arguments. @@ -119,7 +119,7 @@ int __cdecl main(int argc, char **argv) priority = (INT16)atoi(argv[2]); break; default: - fprintf(stderr, "usage: %s divert-filter [priority]\n", + fprintf(stderr, "usage: %s windivert-filter [priority]\n", argv[0]); fprintf(stderr, "examples:\n"); fprintf(stderr, "\t%s true\n", argv[0]); @@ -140,8 +140,8 @@ int __cdecl main(int argc, char **argv) resetv6->tcp.Rst = 1; resetv6->tcp.Ack = 1; PacketIpv6Icmpv6Init(dnrv6); - dnrv6->ipv6.Length = htons(sizeof(DIVERT_ICMPV6HDR) + 4 + - sizeof(DIVERT_IPV6HDR) + sizeof(DIVERT_TCPHDR)); + dnrv6->ipv6.Length = htons(sizeof(WINDIVERT_ICMPV6HDR) + 4 + + sizeof(WINDIVERT_IPV6HDR) + sizeof(WINDIVERT_TCPHDR)); dnrv6->icmpv6.Type = 1; // Destination not reachable. dnrv6->icmpv6.Code = 4; // Port not reachable. @@ -149,7 +149,7 @@ int __cdecl main(int argc, char **argv) console = GetStdHandle(STD_OUTPUT_HANDLE); // Divert traffic matching the filter: - handle = DivertOpen(argv[1], (DIVERT_LAYER)0, priority, 0); + handle = WinDivertOpen(argv[1], WINDIVERT_LAYER_NETWORK, priority, 0); if (handle == INVALID_HANDLE_VALUE) { if (GetLastError() == ERROR_INVALID_PARAMETER) @@ -157,7 +157,7 @@ int __cdecl main(int argc, char **argv) fprintf(stderr, "error: filter syntax error\n"); exit(EXIT_FAILURE); } - fprintf(stderr, "error: failed to open Divert device (%d)\n", + fprintf(stderr, "error: failed to open the WinDivert device (%d)\n", GetLastError()); exit(EXIT_FAILURE); } @@ -166,7 +166,7 @@ int __cdecl main(int argc, char **argv) while (TRUE) { // Read a matching packet. - if (!DivertRecv(handle, packet, sizeof(packet), &recv_addr, + if (!WinDivertRecv(handle, packet, sizeof(packet), &recv_addr, &packet_len)) { fprintf(stderr, "warning: failed to read packet\n"); @@ -174,9 +174,9 @@ int __cdecl main(int argc, char **argv) } // Print info about the matching packet. - DivertHelperParse(packet, packet_len, &ip_header, &ipv6_header, - &icmp_header, &icmpv6_header, &tcp_header, &udp_header, NULL, - &payload_len); + WinDivertHelperParsePacket(packet, packet_len, &ip_header, + &ipv6_header, &icmp_header, &icmpv6_header, &tcp_header, + &udp_header, NULL, &payload_len); if (ip_header == NULL && ipv6_header == NULL) { continue; @@ -267,11 +267,12 @@ int __cdecl main(int argc, char **argv) htonl(ntohl(tcp_header->SeqNum) + 1): htonl(ntohl(tcp_header->SeqNum) + payload_len)); - DivertHelperCalcChecksums((PVOID)reset, sizeof(TCPPACKET), 0); + WinDivertHelperCalcChecksums((PVOID)reset, sizeof(TCPPACKET), + 0); memcpy(&send_addr, &recv_addr, sizeof(send_addr)); send_addr.Direction = !recv_addr.Direction; - if (!DivertSend(handle, (PVOID)reset, sizeof(TCPPACKET), + if (!WinDivertSend(handle, (PVOID)reset, sizeof(TCPPACKET), &send_addr, NULL)) { fprintf(stderr, "warning: failed to send TCP reset (%d)\n", @@ -294,12 +295,12 @@ int __cdecl main(int argc, char **argv) htonl(ntohl(tcp_header->SeqNum) + 1): htonl(ntohl(tcp_header->SeqNum) + payload_len)); - DivertHelperCalcChecksums((PVOID)resetv6, sizeof(TCPV6PACKET), - 0); + WinDivertHelperCalcChecksums((PVOID)resetv6, + sizeof(TCPV6PACKET), 0); memcpy(&send_addr, &recv_addr, sizeof(send_addr)); send_addr.Direction = !recv_addr.Direction; - if (!DivertSend(handle, (PVOID)resetv6, sizeof(TCPV6PACKET), + if (!WinDivertSend(handle, (PVOID)resetv6, sizeof(TCPV6PACKET), &send_addr, NULL)) { fprintf(stderr, "warning: failed to send TCP (IPV6) " @@ -324,11 +325,11 @@ int __cdecl main(int argc, char **argv) dnr->ip.SrcAddr = ip_header->DstAddr; dnr->ip.DstAddr = ip_header->SrcAddr; - DivertHelperCalcChecksums((PVOID)dnr, icmp_length, 0); + WinDivertHelperCalcChecksums((PVOID)dnr, icmp_length, 0); memcpy(&send_addr, &recv_addr, sizeof(send_addr)); - send_addr.Direction = DIVERT_DIRECTION_OUTBOUND; - if (!DivertSend(handle, (PVOID)dnr, icmp_length, &send_addr, + send_addr.Direction = WINDIVERT_DIRECTION_OUTBOUND; + if (!WinDivertSend(handle, (PVOID)dnr, icmp_length, &send_addr, NULL)) { fprintf(stderr, "warning: failed to send ICMP message " @@ -338,8 +339,8 @@ int __cdecl main(int argc, char **argv) if (ipv6_header != NULL) { - UINT icmpv6_length = sizeof(DIVERT_IPV6HDR) + - sizeof(DIVERT_TCPHDR); + UINT icmpv6_length = sizeof(WINDIVERT_IPV6HDR) + + sizeof(WINDIVERT_TCPHDR); memcpy(dnrv6->data, ipv6_header, icmpv6_length); icmpv6_length += sizeof(ICMPV6PACKET); memcpy(dnrv6->ipv6.SrcAddr, ipv6_header->DstAddr, @@ -347,11 +348,11 @@ int __cdecl main(int argc, char **argv) memcpy(dnrv6->ipv6.DstAddr, ipv6_header->SrcAddr, sizeof(dnrv6->ipv6.DstAddr)); - DivertHelperCalcChecksums((PVOID)dnrv6, icmpv6_length, 0); + WinDivertHelperCalcChecksums((PVOID)dnrv6, icmpv6_length, 0); memcpy(&send_addr, &recv_addr, sizeof(send_addr)); - send_addr.Direction = DIVERT_DIRECTION_OUTBOUND; - if (!DivertSend(handle, (PVOID)dnrv6, icmpv6_length, + send_addr.Direction = WINDIVERT_DIRECTION_OUTBOUND; + if (!WinDivertSend(handle, (PVOID)dnrv6, icmpv6_length, &send_addr, NULL)) { fprintf(stderr, "warning: failed to send ICMPv6 message " @@ -366,11 +367,11 @@ int __cdecl main(int argc, char **argv) /* * Initialize a PACKET. */ -static void PacketIpInit(PDIVERT_IPHDR packet) +static void PacketIpInit(PWINDIVERT_IPHDR packet) { - memset(packet, 0, sizeof(DIVERT_IPHDR)); + memset(packet, 0, sizeof(WINDIVERT_IPHDR)); packet->Version = 4; - packet->HdrLength = sizeof(DIVERT_IPHDR) / sizeof(UINT32); + packet->HdrLength = sizeof(WINDIVERT_IPHDR) / sizeof(UINT32); packet->Id = ntohs(0xDEAD); packet->TTL = 64; } @@ -384,7 +385,7 @@ static void PacketIpTcpInit(PTCPPACKET packet) PacketIpInit(&packet->ip); packet->ip.Length = htons(sizeof(TCPPACKET)); packet->ip.Protocol = IPPROTO_TCP; - packet->tcp.HdrLength = sizeof(DIVERT_TCPHDR) / sizeof(UINT32); + packet->tcp.HdrLength = sizeof(WINDIVERT_TCPHDR) / sizeof(UINT32); } /* @@ -400,9 +401,9 @@ static void PacketIpIcmpInit(PICMPPACKET packet) /* * Initialize a PACKETV6. */ -static void PacketIpv6Init(PDIVERT_IPV6HDR packet) +static void PacketIpv6Init(PWINDIVERT_IPV6HDR packet) { - memset(packet, 0, sizeof(DIVERT_IPV6HDR)); + memset(packet, 0, sizeof(WINDIVERT_IPV6HDR)); packet->Version = 6; packet->HopLimit = 64; } @@ -414,9 +415,9 @@ static void PacketIpv6TcpInit(PTCPV6PACKET packet) { memset(packet, 0, sizeof(TCPV6PACKET)); PacketIpv6Init(&packet->ipv6); - packet->ipv6.Length = htons(sizeof(DIVERT_TCPHDR)); + packet->ipv6.Length = htons(sizeof(WINDIVERT_TCPHDR)); packet->ipv6.NextHdr = IPPROTO_TCP; - packet->tcp.HdrLength = sizeof(DIVERT_TCPHDR) / sizeof(UINT32); + packet->tcp.HdrLength = sizeof(WINDIVERT_TCPHDR) / sizeof(UINT32); } /* diff --git a/examples/netfilter/sources b/examples/netfilter/sources index 8eb8fc6..cca1007 100644 --- a/examples/netfilter/sources +++ b/examples/netfilter/sources @@ -1,5 +1,5 @@ # sources -# (C) 2012, all rights reserved, +# (C) 2013, all rights reserved, # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by diff --git a/examples/passthru/passthru.c b/examples/passthru/passthru.c index 0b8adbd..dc9acfc 100644 --- a/examples/passthru/passthru.c +++ b/examples/passthru/passthru.c @@ -1,6 +1,6 @@ /* * passthru.c - * (C) 2012, all rights reserved, + * (C) 2013, all rights reserved, * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -21,7 +21,7 @@ * This program does nothing except divert packets and re-inject them. This is * useful for performance testing. * - * usage: netdump.exe divert-filter num-threads + * usage: netdump.exe windivert-filter num-threads */ #include @@ -29,7 +29,7 @@ #include #include -#include "divert.h" +#include "windivert.h" #define MAXBUF 0xFFFF @@ -56,7 +56,7 @@ int __cdecl main(int argc, char **argv) } // Divert traffic matching the filter: - handle = DivertOpen(argv[1], (DIVERT_LAYER)0, 0, 0); + handle = WinDivertOpen(argv[1], WINDIVERT_LAYER_NETWORK, 0, 0); if (handle == INVALID_HANDLE_VALUE) { if (GetLastError() == ERROR_INVALID_PARAMETER) @@ -64,7 +64,7 @@ int __cdecl main(int argc, char **argv) fprintf(stderr, "error: filter syntax error\n"); exit(EXIT_FAILURE); } - fprintf(stderr, "error: failed to open Divert device (%d)\n", + fprintf(stderr, "error: failed to open the WinDivert device (%d)\n", GetLastError()); exit(EXIT_FAILURE); } @@ -93,14 +93,14 @@ static DWORD passthru(LPVOID arg) { char packet[MAXBUF]; UINT packet_len; - DIVERT_ADDRESS addr; + WINDIVERT_ADDRESS addr; HANDLE handle = (HANDLE)arg; // Main loop: while (TRUE) { // Read a matching packet. - if (!DivertRecv(handle, packet, sizeof(packet), &addr, &packet_len)) + if (!WinDivertRecv(handle, packet, sizeof(packet), &addr, &packet_len)) { fprintf(stderr, "warning: failed to read packet (%d)\n", GetLastError()); @@ -108,7 +108,7 @@ static DWORD passthru(LPVOID arg) } // Re-inject the matching packet. - if (!DivertSend(handle, packet, packet_len, &addr, NULL)) + if (!WinDivertSend(handle, packet, packet_len, &addr, NULL)) { fprintf(stderr, "warning: failed to reinject packet (%d)\n", GetLastError()); diff --git a/examples/passthru/sources b/examples/passthru/sources index 6f2f84e..2be9edc 100644 --- a/examples/passthru/sources +++ b/examples/passthru/sources @@ -1,5 +1,5 @@ # sources -# (C) 2012, all rights reserved, +# (C) 2013, all rights reserved, # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by diff --git a/examples/webfilter/sources b/examples/webfilter/sources index 1a6e470..800faa9 100644 --- a/examples/webfilter/sources +++ b/examples/webfilter/sources @@ -1,5 +1,5 @@ # sources -# (C) 2012, all rights reserved, +# (C) 2013, all rights reserved, # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by diff --git a/examples/webfilter/webfilter.c b/examples/webfilter/webfilter.c index 061bcda..bb880f5 100644 --- a/examples/webfilter/webfilter.c +++ b/examples/webfilter/webfilter.c @@ -1,6 +1,6 @@ /* * webfilter.c - * (C) 2012, all rights reserved, + * (C) 2013, all rights reserved, * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -31,7 +31,7 @@ #include #include -#include "divert.h" +#include "windivert.h" #define MAXBUF 0xFFFF #define MAXURL 4096 @@ -56,8 +56,8 @@ typedef struct */ typedef struct { - DIVERT_IPHDR ip; - DIVERT_TCPHDR tcp; + WINDIVERT_IPHDR ip; + WINDIVERT_TCPHDR tcp; } PACKET, *PPACKET; typedef struct { @@ -105,11 +105,11 @@ static BOOL BlackListPayloadMatch(PBLACKLIST blacklist, char *data, int __cdecl main(int argc, char **argv) { HANDLE handle; - DIVERT_ADDRESS addr; + WINDIVERT_ADDRESS addr; UINT8 packet[MAXBUF]; UINT packet_len; - PDIVERT_IPHDR ip_header; - PDIVERT_TCPHDR tcp_header; + PWINDIVERT_IPHDR ip_header; + PWINDIVERT_TCPHDR tcp_header; PVOID payload; UINT payload_len; PACKET reset0; @@ -158,37 +158,37 @@ int __cdecl main(int argc, char **argv) finish->tcp.Ack = 1; // Open the Divert device: - handle = DivertOpen( + handle = WinDivertOpen( "outbound && " // Outbound traffic only "ip && " // Only IPv4 supported "tcp.DstPort == 80 && " // HTTP (port 80) only "tcp.PayloadLength > 0", // TCP data packets only - (DIVERT_LAYER)0, priority, 0 + WINDIVERT_LAYER_NETWORK, priority, 0 ); if (handle == INVALID_HANDLE_VALUE) { - fprintf(stderr, "error: failed to open Divert device (%d)\n", + fprintf(stderr, "error: failed to open the WinDivert device (%d)\n", GetLastError()); exit(EXIT_FAILURE); } - printf("OPENED divert\n"); + printf("OPENED WinDivert\n"); // Main loop: while (TRUE) { - if (!DivertRecv(handle, packet, sizeof(packet), &addr, &packet_len)) + if (!WinDivertRecv(handle, packet, sizeof(packet), &addr, &packet_len)) { fprintf(stderr, "warning: failed to read packet (%d)\n", GetLastError()); continue; } - if (!DivertHelperParse(packet, packet_len, &ip_header, NULL, NULL, - NULL, &tcp_header, NULL, &payload, &payload_len) || + if (!WinDivertHelperParsePacket(packet, packet_len, &ip_header, NULL, + NULL, NULL, &tcp_header, NULL, &payload, &payload_len) || !BlackListPayloadMatch(blacklist, payload, (UINT16)payload_len)) { // Packet does not match the blacklist; simply reinject it. - if (!DivertSend(handle, packet, packet_len, &addr, NULL)) + if (!WinDivertSend(handle, packet, packet_len, &addr, NULL)) { fprintf(stderr, "warning: failed to reinject packet (%d)\n", GetLastError()); @@ -207,8 +207,8 @@ int __cdecl main(int argc, char **argv) reset->tcp.DstPort = htons(80); reset->tcp.SeqNum = tcp_header->SeqNum; reset->tcp.AckNum = tcp_header->AckNum; - DivertHelperCalcChecksums((PVOID)reset, sizeof(PACKET), 0); - if (!DivertSend(handle, (PVOID)reset, sizeof(PACKET), &addr, NULL)) + WinDivertHelperCalcChecksums((PVOID)reset, sizeof(PACKET), 0); + if (!WinDivertSend(handle, (PVOID)reset, sizeof(PACKET), &addr, NULL)) { fprintf(stderr, "warning: failed to send reset packet (%d)\n", GetLastError()); @@ -221,9 +221,10 @@ int __cdecl main(int argc, char **argv) blockpage->header.tcp.SeqNum = tcp_header->AckNum; blockpage->header.tcp.AckNum = htonl(ntohl(tcp_header->SeqNum) + payload_len); - DivertHelperCalcChecksums((PVOID)blockpage, blockpage_len, 0); + WinDivertHelperCalcChecksums((PVOID)blockpage, blockpage_len, 0); addr.Direction = !addr.Direction; // Reverse direction. - if (!DivertSend(handle, (PVOID)blockpage, blockpage_len, &addr, NULL)) + if (!WinDivertSend(handle, (PVOID)blockpage, blockpage_len, &addr, + NULL)) { fprintf(stderr, "warning: failed to send block page packet (%d)\n", GetLastError()); @@ -239,8 +240,8 @@ int __cdecl main(int argc, char **argv) htonl(ntohl(tcp_header->AckNum) + sizeof(block_data) - 1); finish->tcp.AckNum = htonl(ntohl(tcp_header->SeqNum) + payload_len); - DivertHelperCalcChecksums((PVOID)finish, sizeof(PACKET), 0); - if (!DivertSend(handle, (PVOID)finish, sizeof(PACKET), &addr, NULL)) + WinDivertHelperCalcChecksums((PVOID)finish, sizeof(PACKET), 0); + if (!WinDivertSend(handle, (PVOID)finish, sizeof(PACKET), &addr, NULL)) { fprintf(stderr, "warning: failed to send finish packet (%d)\n", GetLastError()); @@ -255,11 +256,11 @@ static void PacketInit(PPACKET packet) { memset(packet, 0, sizeof(PACKET)); packet->ip.Version = 4; - packet->ip.HdrLength = sizeof(DIVERT_IPHDR) / sizeof(UINT32); + packet->ip.HdrLength = sizeof(WINDIVERT_IPHDR) / sizeof(UINT32); packet->ip.Length = htons(sizeof(PACKET)); packet->ip.TTL = 64; packet->ip.Protocol = IPPROTO_TCP; - packet->tcp.HdrLength = sizeof(DIVERT_TCPHDR) / sizeof(UINT32); + packet->tcp.HdrLength = sizeof(WINDIVERT_TCPHDR) / sizeof(UINT32); } /* diff --git a/include/divert_device.h b/include/divert_device.h deleted file mode 100644 index 68462ce..0000000 --- a/include/divert_device.h +++ /dev/null @@ -1,199 +0,0 @@ -/* - * divert_device.h - * (C) 2012, all rights reserved, - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -#ifndef __DIVERT_DEVICE_H -#define __DIVERT_DEVICE_H - -/* - * NOTE: This is the low-level interface to the divert device driver. - * This interface should not be used directly, instead use the high-level - * interface provided by the divert API. - */ - -#define DIVERT_KERNEL -#include "divert.h" - -#define DIVERT_VERSION 1 -#define DIVERT_VERSION_MINOR 0 - -#define DIVERT_STR2(s) #s -#define DIVERT_STR(s) DIVERT_STR2(s) -#define DIVERT_LSTR2(s) L ## #s -#define DIVERT_LSTR(s) DIVERT_LSTR2(s) - -#define DIVERT_VERSION_LSTR \ - DIVERT_LSTR(DIVERT_VERSION) L"." DIVERT_LSTR(DIVERT_VERSION_MINOR) - -#define DIVERT_DEVICE_NAME \ - L"WinDivert" DIVERT_VERSION_LSTR - -#define DIVERT_IOCTL_VERSION 2 -#define DIVERT_IOCTL_MAGIC 0xE8D3 - -#define DIVERT_FILTER_FIELD_ZERO 0 -#define DIVERT_FILTER_FIELD_INBOUND 1 -#define DIVERT_FILTER_FIELD_OUTBOUND 2 -#define DIVERT_FILTER_FIELD_IFIDX 3 -#define DIVERT_FILTER_FIELD_SUBIFIDX 4 -#define DIVERT_FILTER_FIELD_IP 5 -#define DIVERT_FILTER_FIELD_IPV6 6 -#define DIVERT_FILTER_FIELD_ICMP 7 -#define DIVERT_FILTER_FIELD_TCP 8 -#define DIVERT_FILTER_FIELD_UDP 9 -#define DIVERT_FILTER_FIELD_ICMPV6 10 -#define DIVERT_FILTER_FIELD_IP_HDRLENGTH 11 -#define DIVERT_FILTER_FIELD_IP_TOS 12 -#define DIVERT_FILTER_FIELD_IP_LENGTH 13 -#define DIVERT_FILTER_FIELD_IP_ID 14 -#define DIVERT_FILTER_FIELD_IP_DF 15 -#define DIVERT_FILTER_FIELD_IP_MF 16 -#define DIVERT_FILTER_FIELD_IP_FRAGOFF 17 -#define DIVERT_FILTER_FIELD_IP_TTL 18 -#define DIVERT_FILTER_FIELD_IP_PROTOCOL 19 -#define DIVERT_FILTER_FIELD_IP_CHECKSUM 20 -#define DIVERT_FILTER_FIELD_IP_SRCADDR 21 -#define DIVERT_FILTER_FIELD_IP_DSTADDR 22 -#define DIVERT_FILTER_FIELD_IPV6_TRAFFICCLASS 23 -#define DIVERT_FILTER_FIELD_IPV6_FLOWLABEL 24 -#define DIVERT_FILTER_FIELD_IPV6_LENGTH 25 -#define DIVERT_FILTER_FIELD_IPV6_NEXTHDR 26 -#define DIVERT_FILTER_FIELD_IPV6_HOPLIMIT 27 -#define DIVERT_FILTER_FIELD_IPV6_SRCADDR 28 -#define DIVERT_FILTER_FIELD_IPV6_DSTADDR 29 -#define DIVERT_FILTER_FIELD_ICMP_TYPE 30 -#define DIVERT_FILTER_FIELD_ICMP_CODE 31 -#define DIVERT_FILTER_FIELD_ICMP_CHECKSUM 32 -#define DIVERT_FILTER_FIELD_ICMP_BODY 33 -#define DIVERT_FILTER_FIELD_ICMPV6_TYPE 34 -#define DIVERT_FILTER_FIELD_ICMPV6_CODE 35 -#define DIVERT_FILTER_FIELD_ICMPV6_CHECKSUM 36 -#define DIVERT_FILTER_FIELD_ICMPV6_BODY 37 -#define DIVERT_FILTER_FIELD_TCP_SRCPORT 38 -#define DIVERT_FILTER_FIELD_TCP_DSTPORT 39 -#define DIVERT_FILTER_FIELD_TCP_SEQNUM 40 -#define DIVERT_FILTER_FIELD_TCP_ACKNUM 41 -#define DIVERT_FILTER_FIELD_TCP_HDRLENGTH 42 -#define DIVERT_FILTER_FIELD_TCP_URG 43 -#define DIVERT_FILTER_FIELD_TCP_ACK 44 -#define DIVERT_FILTER_FIELD_TCP_PSH 45 -#define DIVERT_FILTER_FIELD_TCP_RST 46 -#define DIVERT_FILTER_FIELD_TCP_SYN 47 -#define DIVERT_FILTER_FIELD_TCP_FIN 48 -#define DIVERT_FILTER_FIELD_TCP_WINDOW 49 -#define DIVERT_FILTER_FIELD_TCP_CHECKSUM 50 -#define DIVERT_FILTER_FIELD_TCP_URGPTR 51 -#define DIVERT_FILTER_FIELD_TCP_PAYLOADLENGTH 52 -#define DIVERT_FILTER_FIELD_UDP_SRCPORT 53 -#define DIVERT_FILTER_FIELD_UDP_DSTPORT 54 -#define DIVERT_FILTER_FIELD_UDP_LENGTH 55 -#define DIVERT_FILTER_FIELD_UDP_CHECKSUM 56 -#define DIVERT_FILTER_FIELD_UDP_PAYLOADLENGTH 57 -#define DIVERT_FILTER_FIELD_MAX \ - DIVERT_FILTER_FIELD_UDP_PAYLOADLENGTH - -#define DIVERT_FILTER_TEST_EQ 0 -#define DIVERT_FILTER_TEST_NEQ 1 -#define DIVERT_FILTER_TEST_LT 2 -#define DIVERT_FILTER_TEST_LEQ 3 -#define DIVERT_FILTER_TEST_GT 4 -#define DIVERT_FILTER_TEST_GEQ 5 -#define DIVERT_FILTER_TEST_MAX DIVERT_FILTER_TEST_GEQ - -#define DIVERT_FILTER_MAXLEN 512 - -#define DIVERT_FILTER_RESULT_ACCEPT (DIVERT_FILTER_MAXLEN+1) -#define DIVERT_FILTER_RESULT_REJECT (DIVERT_FILTER_MAXLEN+2) - -/* - * Divert layers. - */ -#define DIVERT_LAYER_DEFAULT DIVERT_LAYER_NETWORK -#define DIVERT_LAYER_MAX DIVERT_LAYER_NETWORK_FORWARD - -/* - * Divert flags. - */ -#define DIVERT_FLAGS_MAX \ - (DIVERT_FLAG_SNIFF | DIVERT_FLAG_DROP) - -/* - * Divert priorities. - */ -#define DIVERT_PRIORITY(priority16) \ - ((UINT32)((INT32)(priority16) + 0x7FFF + 1)) -#define DIVERT_PRIORITY_DEFAULT DIVERT_PRIORITY(0) -#define DIVERT_PRIORITY_MAX DIVERT_PRIORITY(1000) - -/* - * Divert parameters. - */ -#define DIVERT_PARAM_QUEUE_LEN_DEFAULT 512 -#define DIVERT_PARAM_QUEUE_LEN_MIN 1 -#define DIVERT_PARAM_QUEUE_LEN_MAX 8192 -#define DIVERT_PARAM_QUEUE_TIME_DEFAULT 256 -#define DIVERT_PARAM_QUEUE_TIME_MIN 32 -#define DIVERT_PARAM_QUEUE_TIME_MAX 1024 - -/* - * Message definitions. - */ -#pragma pack(push, 1) -struct divert_ioctl_s -{ - UINT16 magic; // DIVERT_IOCTL_MAGIC - UINT8 version; // DIVERT_IOCTL_VERSION - UINT8 arg8; // 8-bit argument - UINT64 arg; // 64-bit argument -}; -typedef struct divert_ioctl_s *divert_ioctl_t; - -/* - * IOCTL structures. - */ -struct divert_ioctl_filter_s -{ - UINT8 field; // DIVERT_FILTER_FIELD_IP_* - UINT8 test; // DIVERT_FILTER_TEST_* - UINT16 success; // Success continuation. - UINT16 failure; // Fail continuation. - UINT32 arg[4]; // Argument. -}; -typedef struct divert_ioctl_filter_s *divert_ioctl_filter_t; -#pragma pack(pop) - -/* - * IOCTL codes. - */ -#define IOCTL_DIVERT_RECV \ - CTL_CODE(FILE_DEVICE_NETWORK, 0x908, METHOD_OUT_DIRECT, FILE_ANY_ACCESS) -#define IOCTL_DIVERT_SEND \ - CTL_CODE(FILE_DEVICE_NETWORK, 0x909, METHOD_IN_DIRECT, FILE_ANY_ACCESS) -#define IOCTL_DIVERT_START_FILTER \ - CTL_CODE(FILE_DEVICE_NETWORK, 0x90A, METHOD_IN_DIRECT, FILE_ANY_ACCESS) -#define IOCTL_DIVERT_SET_LAYER \ - CTL_CODE(FILE_DEVICE_NETWORK, 0x90B, METHOD_IN_DIRECT, FILE_ANY_ACCESS) -#define IOCTL_DIVERT_SET_PRIORITY \ - CTL_CODE(FILE_DEVICE_NETWORK, 0x90C, METHOD_IN_DIRECT, FILE_ANY_ACCESS) -#define IOCTL_DIVERT_SET_FLAGS \ - CTL_CODE(FILE_DEVICE_NETWORK, 0x90D, METHOD_IN_DIRECT, FILE_ANY_ACCESS) -#define IOCTL_DIVERT_SET_PARAM \ - CTL_CODE(FILE_DEVICE_NETWORK, 0x90E, METHOD_IN_DIRECT, FILE_ANY_ACCESS) -#define IOCTL_DIVERT_GET_PARAM \ - CTL_CODE(FILE_DEVICE_NETWORK, 0x90F, METHOD_OUT_DIRECT, FILE_ANY_ACCESS) - -#endif // __DIVERT_DEVICE_H diff --git a/include/divert.h b/include/windivert.h similarity index 59% rename from include/divert.h rename to include/windivert.h index 743d795..fc8a3d6 100644 --- a/include/divert.h +++ b/include/windivert.h @@ -1,6 +1,6 @@ /* - * divert.h - * (C) 2012, all rights reserved, + * windivert.h + * (C) 2013, all rights reserved, * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -16,16 +16,16 @@ * along with this program. If not, see . */ -#ifndef __DIVERT_H -#define __DIVERT_H +#ifndef __WINDIVERT_H +#define __WINDIVERT_H -#ifndef DIVERT_KERNEL +#ifndef WINDIVERT_KERNEL #include -#endif /* DIVERT_KERNEL */ +#endif /* WINDIVERT_KERNEL */ -#ifndef DIVERTEXPORT -#define DIVERTEXPORT __declspec(dllimport) -#endif /* DIVERTEXPORT */ +#ifndef WINDIVERTEXPORT +#define WINDIVERTEXPORT __declspec(dllimport) +#endif /* WINDIVERTEXPORT */ #ifdef __MINGW32__ #define __in @@ -48,7 +48,7 @@ extern "C" { #endif /****************************************************************************/ -/* DIVERT API */ +/* WINDIVERT API */ /****************************************************************************/ /* @@ -59,101 +59,119 @@ typedef struct UINT32 IfIdx; /* Packet's interface index. */ UINT32 SubIfIdx; /* Packet's sub-interface index. */ UINT8 Direction; /* Packet's direction. */ -} DIVERT_ADDRESS, *PDIVERT_ADDRESS; +} WINDIVERT_ADDRESS, *PWINDIVERT_ADDRESS; -#define DIVERT_DIRECTION_OUTBOUND 0 -#define DIVERT_DIRECTION_INBOUND 1 - -/* - * Old names (deprecated). - */ -#define DIVERT_PACKET_DIRECTION_OUTBOUND \ - DIVERT_DIRECTION_OUTBOUND -#define DIVERT_PACKET_DIRECTION_INBOUND \ - DIVERT_DIRECTION_INBOUND +#define WINDIVERT_DIRECTION_OUTBOUND 0 +#define WINDIVERT_DIRECTION_INBOUND 1 /* * Divert layers. */ typedef enum { - DIVERT_LAYER_NETWORK = 0, /* Network layer. */ - DIVERT_LAYER_NETWORK_FORWARD = 1 /* Network layer (forwarded packets) */ -} DIVERT_LAYER, *PDIVERT_LAYER; + WINDIVERT_LAYER_NETWORK = 0, /* Network layer. */ + WINDIVERT_LAYER_NETWORK_FORWARD = 1 /* Network layer (forwarded packets) */ +} WINDIVERT_LAYER, *PWINDIVERT_LAYER; /* * Divert flags. */ -#define DIVERT_FLAG_SNIFF 1 -#define DIVERT_FLAG_DROP 2 +#define WINDIVERT_FLAG_SNIFF 1 +#define WINDIVERT_FLAG_DROP 2 +#define WINDIVERT_FLAG_PASSTHRU 4 +#define WINDIVERT_FLAG_NO_CHECKSUM 1024 /* * Divert parameters. */ typedef enum { - DIVERT_PARAM_QUEUE_LEN = 0, /* Packet queue length. */ - DIVERT_PARAM_QUEUE_TIME = 1 /* Packet queue time. */ -} DIVERT_PARAM, *PDIVERT_PARAM; -#define DIVERT_PARAM_MAX DIVERT_PARAM_QUEUE_TIME + WINDIVERT_PARAM_QUEUE_LEN = 0, /* Packet queue length. */ + WINDIVERT_PARAM_QUEUE_TIME = 1 /* Packet queue time. */ +} WINDIVERT_PARAM, *PWINDIVERT_PARAM; +#define WINDIVERT_PARAM_MAX WINDIVERT_PARAM_QUEUE_TIME + +#ifndef WINDIVERT_KERNEL /* - * Open a divert handle. + * Open a WinDivert handle. */ -extern DIVERTEXPORT HANDLE DivertOpen( +extern WINDIVERTEXPORT HANDLE WinDivertOpen( __in const char *filter, - __in DIVERT_LAYER layer, + __in WINDIVERT_LAYER layer, __in INT16 priority, __in UINT64 flags); /* - * Receive (read) a packet from a divert handle. + * Receive (read) a packet from a WinDivert handle. */ -extern DIVERTEXPORT BOOL DivertRecv( +extern WINDIVERTEXPORT BOOL WinDivertRecv( __in HANDLE handle, __out PVOID pPacket, __in UINT packetLen, - __out_opt PDIVERT_ADDRESS pAddr, + __out_opt PWINDIVERT_ADDRESS pAddr, __out_opt UINT *readLen); /* - * Send (write/inject) a packet to a divert handle. + * Receive (read) a packet from a WinDivert handle. */ -extern DIVERTEXPORT BOOL DivertSend( +extern WINDIVERTEXPORT BOOL WinDivertRecvEx( + __in HANDLE handle, + __out PVOID pPacket, + __in UINT packetLen, + __in UINT64 flags, + __out_opt PWINDIVERT_ADDRESS pAddr, + __out_opt UINT *readLen, + __inout_opt LPOVERLAPPED lpOverlapped); + +/* + * Send (write/inject) a packet to a WinDivert handle. + */ +extern WINDIVERTEXPORT BOOL WinDivertSend( __in HANDLE handle, __in PVOID pPacket, __in UINT packetLen, - __in PDIVERT_ADDRESS pAddr, + __in PWINDIVERT_ADDRESS pAddr, __out_opt UINT *writeLen); /* - * Close a divert handle. + * Send (write/inject) a packet to a WinDivert handle. */ -extern DIVERTEXPORT BOOL DivertClose( +extern WINDIVERTEXPORT BOOL WinDivertSendEx( + __in HANDLE handle, + __in PVOID pPacket, + __in UINT packetLen, + __in UINT64 flags, + __in PWINDIVERT_ADDRESS pAddr, + __out_opt UINT *writeLen, + __inout_opt LPOVERLAPPED lpOverlapped); + +/* + * Close a WinDivert handle. + */ +extern WINDIVERTEXPORT BOOL WinDivertClose( __in HANDLE handle); /* - * Set a divert handle parameter. + * Set a WinDivert handle parameter. */ -extern DIVERTEXPORT BOOL DivertSetParam( +extern WINDIVERTEXPORT BOOL WinDivertSetParam( __in HANDLE handle, - __in DIVERT_PARAM param, + __in WINDIVERT_PARAM param, __in UINT64 value); /* - * Get a divert handle parameter. + * Get a WinDivert handle parameter. */ -extern DIVERTEXPORT BOOL DivertGetParam( +extern WINDIVERTEXPORT BOOL WinDivertGetParam( __in HANDLE handle, - __in DIVERT_PARAM param, + __in WINDIVERT_PARAM param, __out UINT64 *pValue); /****************************************************************************/ -/* DIVERT HELPER API */ +/* WINDIVERT HELPER API */ /****************************************************************************/ -#ifndef DIVERT_NO_HELPER_API - /* * IPv4/IPv6/ICMP/ICMPv6/TCP/UDP header definitions. */ @@ -170,39 +188,39 @@ typedef struct UINT16 Checksum; UINT32 SrcAddr; UINT32 DstAddr; -} DIVERT_IPHDR, *PDIVERT_IPHDR; +} WINDIVERT_IPHDR, *PWINDIVERT_IPHDR; -#define DIVERT_IPHDR_GET_FRAGOFF(hdr) \ +#define WINDIVERT_IPHDR_GET_FRAGOFF(hdr) \ (((hdr)->FragOff0) & 0xFF1F) -#define DIVERT_IPHDR_GET_MF(hdr) \ +#define WINDIVERT_IPHDR_GET_MF(hdr) \ ((((hdr)->FragOff0) & 0x0020) != 0) -#define DIVERT_IPHDR_GET_DF(hdr) \ +#define WINDIVERT_IPHDR_GET_DF(hdr) \ ((((hdr)->FragOff0) & 0x0040) != 0) -#define DIVERT_IPHDR_GET_RESERVED(hdr) \ +#define WINDIVERT_IPHDR_GET_RESERVED(hdr) \ ((((hdr)->FragOff0) & 0x0080) != 0) -#define DIVERT_IPHDR_SET_FRAGOFF(hdr, val) \ +#define WINDIVERT_IPHDR_SET_FRAGOFF(hdr, val) \ do \ { \ (hdr)->FragOff0 = (((hdr)->FragOff0) & 0x00E0) | \ ((val) & 0xFF1F); \ } \ while (FALSE) -#define DIVERT_IPHDR_SET_MF(hdr, val) \ +#define WINDIVERT_IPHDR_SET_MF(hdr, val) \ do \ { \ (hdr)->FragOff0 = (((hdr)->FragOff0) & 0xFFDF) | \ (((val) & 0x0001) << 5); \ } \ while (FALSE) -#define DIVERT_IPHDR_SET_DF(hdr, val) \ +#define WINDIVERT_IPHDR_SET_DF(hdr, val) \ do \ { \ (hdr)->FragOff0 = (((hdr)->FragOff0) & 0xFFBF) | \ (((val) & 0x0001) << 6); \ } \ while (FALSE) -#define DIVERT_IPHDR_SET_RESERVED(hdr, val) \ +#define WINDIVERT_IPHDR_SET_RESERVED(hdr, val) \ do \ { \ (hdr)->FragOff0 = (((hdr)->FragOff0) & 0xFF7F) | \ @@ -222,21 +240,21 @@ typedef struct UINT8 HopLimit; UINT32 SrcAddr[4]; UINT32 DstAddr[4]; -} DIVERT_IPV6HDR, *PDIVERT_IPV6HDR; +} WINDIVERT_IPV6HDR, *PWINDIVERT_IPV6HDR; -#define DIVERT_IPV6HDR_GET_TRAFFICCLASS(hdr) \ +#define WINDIVERT_IPV6HDR_GET_TRAFFICCLASS(hdr) \ ((((hdr)->TrafficClass0) << 4) | ((hdr)->TrafficClass1)) -#define DIVERT_IPV6HDR_GET_FLOWLABEL(hdr) \ +#define WINDIVERT_IPV6HDR_GET_FLOWLABEL(hdr) \ ((((UINT32)(hdr)->FlowLabel0) << 16) | ((UINT32)(hdr)->FlowLabel1)) -#define DIVERT_IPV6HDR_SET_TRAFFICCLASS(hdr, val) \ +#define WINDIVERT_IPV6HDR_SET_TRAFFICCLASS(hdr, val) \ do \ { \ (hdr)->TrafficClass0 = ((UINT8)(val) >> 4); \ (hdr)->TrafficClass1 = (UINT8)(val); \ } \ while (FALSE) -#define DIVERT_IPV6HDR_SET_FLOWLABEL(hdr, val) \ +#define WINDIVERT_IPV6HDR_SET_FLOWLABEL(hdr, val) \ do \ { \ (hdr)->FlowLabel0 = (UINT8)((val) >> 16); \ @@ -250,7 +268,7 @@ typedef struct UINT8 Code; UINT16 Checksum; UINT32 Body; -} DIVERT_ICMPHDR, *PDIVERT_ICMPHDR; +} WINDIVERT_ICMPHDR, *PWINDIVERT_ICMPHDR; typedef struct { @@ -258,7 +276,7 @@ typedef struct UINT8 Code; UINT16 Checksum; UINT32 Body; -} DIVERT_ICMPV6HDR, *PDIVERT_ICMPV6HDR; +} WINDIVERT_ICMPV6HDR, *PWINDIVERT_ICMPV6HDR; typedef struct { @@ -278,7 +296,7 @@ typedef struct UINT16 Window; UINT16 Checksum; UINT16 UrgPtr; -} DIVERT_TCPHDR, *PDIVERT_TCPHDR; +} WINDIVERT_TCPHDR, *PWINDIVERT_TCPHDR; typedef struct { @@ -286,65 +304,58 @@ typedef struct UINT16 DstPort; UINT16 Length; UINT16 Checksum; -} DIVERT_UDPHDR, *PDIVERT_UDPHDR; +} WINDIVERT_UDPHDR, *PWINDIVERT_UDPHDR; /* * Flags for DivertHelperCalcChecksums() */ -#define DIVERT_HELPER_NO_IP_CHECKSUM 1 -#define DIVERT_HELPER_NO_ICMP_CHECKSUM 2 -#define DIVERT_HELPER_NO_ICMPV6_CHECKSUM 4 -#define DIVERT_HELPER_NO_TCP_CHECKSUM 8 -#define DIVERT_HELPER_NO_UDP_CHECKSUM 16 +#define WINDIVERT_HELPER_NO_IP_CHECKSUM 1 +#define WINDIVERT_HELPER_NO_ICMP_CHECKSUM 2 +#define WINDIVERT_HELPER_NO_ICMPV6_CHECKSUM 4 +#define WINDIVERT_HELPER_NO_TCP_CHECKSUM 8 +#define WINDIVERT_HELPER_NO_UDP_CHECKSUM 16 /* * Parse IPv4/IPv6/ICMP/ICMPv6/TCP/UDP headers from a raw packet. */ -extern DIVERTEXPORT BOOL DivertHelperParsePacket( +extern WINDIVERTEXPORT BOOL WinDivertHelperParsePacket( __in PVOID pPacket, __in UINT packetLen, - __out_opt PDIVERT_IPHDR *ppIpHdr, - __out_opt PDIVERT_IPV6HDR *ppIpv6Hdr, - __out_opt PDIVERT_ICMPHDR *ppIcmpHdr, - __out_opt PDIVERT_ICMPV6HDR *ppIcmpv6Hdr, - __out_opt PDIVERT_TCPHDR *ppTcpHdr, - __out_opt PDIVERT_UDPHDR *ppUdpHdr, + __out_opt PWINDIVERT_IPHDR *ppIpHdr, + __out_opt PWINDIVERT_IPV6HDR *ppIpv6Hdr, + __out_opt PWINDIVERT_ICMPHDR *ppIcmpHdr, + __out_opt PWINDIVERT_ICMPV6HDR *ppIcmpv6Hdr, + __out_opt PWINDIVERT_TCPHDR *ppTcpHdr, + __out_opt PWINDIVERT_UDPHDR *ppUdpHdr, __out_opt PVOID *ppData, __out_opt UINT *pDataLen); -/* - * Old name (deprecated). - */ -#define DivertHelperParse(p, pl, ip, ip6, icmp, icmp6, tcp, udp, d, dl) \ - DivertHelperParsePacket((p), (pl), (ip), (ip6), (icmp), (icmp6), (tcp), \ - (udp), (d), (dl)) - /* * Parse an IPv4 address. */ -extern DIVERTEXPORT BOOL DivertHelperParseIPv4Address( +extern WINDIVERTEXPORT BOOL WinDivertHelperParseIPv4Address( __in const char *addrStr, __out_opt UINT32 *pAddr); /* * Parse an IPv6 address. */ -extern DIVERTEXPORT BOOL DivertHelperParseIPv6Address( +extern WINDIVERTEXPORT BOOL WinDivertHelperParseIPv6Address( __in const char *addrStr, __out_opt UINT32 *pAddr); /* * Calculate IPv4/IPv6/ICMP/ICMPv6/TCP/UDP checksums. */ -extern DIVERTEXPORT UINT DivertHelperCalcChecksums( +extern WINDIVERTEXPORT UINT WinDivertHelperCalcChecksums( __inout PVOID pPacket, __in UINT packetLen, __in UINT64 flags); -#endif /* DIVERT_NO_HELPER_API */ +#endif /* WINDIVERT_KERNEL */ #ifdef __cplusplus } #endif -#endif /* __DIVERT_H */ +#endif /* __WINDIVERT_H */ diff --git a/include/windivert_device.h b/include/windivert_device.h new file mode 100644 index 0000000..36fdbf4 --- /dev/null +++ b/include/windivert_device.h @@ -0,0 +1,211 @@ +/* + * windivert_device.h + * (C) 2013, all rights reserved, + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef __WINDIVERT_DEVICE_H +#define __WINDIVERT_DEVICE_H + +/* + * NOTE: This is the low-level interface to the divert device driver. + * This interface should not be used directly, instead use the high-level + * interface provided by the divert API. + */ + +#define WINDIVERT_KERNEL +#include "windivert.h" + +#define WINDIVERT_VERSION 1 +#define WINDIVERT_VERSION_MINOR 1 + +#define WINDIVERT_STR2(s) #s +#define WINDIVERT_STR(s) WINDIVERT_STR2(s) +#define WINDIVERT_LSTR2(s) L ## #s +#define WINDIVERT_LSTR(s) WINDIVERT_LSTR2(s) + +#define WINDIVERT_VERSION_LSTR \ + WINDIVERT_LSTR(WINDIVERT_VERSION) L"." \ + WINDIVERT_LSTR(WINDIVERT_VERSION_MINOR) + +#define WINDIVERT_DEVICE_NAME \ + L"WinDivert" WINDIVERT_VERSION_LSTR + +#define WINDIVERT_IOCTL_VERSION 3 +#define WINDIVERT_IOCTL_MAGIC 0xE8D3 + +#define WINDIVERT_FILTER_FIELD_ZERO 0 +#define WINDIVERT_FILTER_FIELD_INBOUND 1 +#define WINDIVERT_FILTER_FIELD_OUTBOUND 2 +#define WINDIVERT_FILTER_FIELD_IFIDX 3 +#define WINDIVERT_FILTER_FIELD_SUBIFIDX 4 +#define WINDIVERT_FILTER_FIELD_IP 5 +#define WINDIVERT_FILTER_FIELD_IPV6 6 +#define WINDIVERT_FILTER_FIELD_ICMP 7 +#define WINDIVERT_FILTER_FIELD_TCP 8 +#define WINDIVERT_FILTER_FIELD_UDP 9 +#define WINDIVERT_FILTER_FIELD_ICMPV6 10 +#define WINDIVERT_FILTER_FIELD_IP_HDRLENGTH 11 +#define WINDIVERT_FILTER_FIELD_IP_TOS 12 +#define WINDIVERT_FILTER_FIELD_IP_LENGTH 13 +#define WINDIVERT_FILTER_FIELD_IP_ID 14 +#define WINDIVERT_FILTER_FIELD_IP_DF 15 +#define WINDIVERT_FILTER_FIELD_IP_MF 16 +#define WINDIVERT_FILTER_FIELD_IP_FRAGOFF 17 +#define WINDIVERT_FILTER_FIELD_IP_TTL 18 +#define WINDIVERT_FILTER_FIELD_IP_PROTOCOL 19 +#define WINDIVERT_FILTER_FIELD_IP_CHECKSUM 20 +#define WINDIVERT_FILTER_FIELD_IP_SRCADDR 21 +#define WINDIVERT_FILTER_FIELD_IP_DSTADDR 22 +#define WINDIVERT_FILTER_FIELD_IPV6_TRAFFICCLASS 23 +#define WINDIVERT_FILTER_FIELD_IPV6_FLOWLABEL 24 +#define WINDIVERT_FILTER_FIELD_IPV6_LENGTH 25 +#define WINDIVERT_FILTER_FIELD_IPV6_NEXTHDR 26 +#define WINDIVERT_FILTER_FIELD_IPV6_HOPLIMIT 27 +#define WINDIVERT_FILTER_FIELD_IPV6_SRCADDR 28 +#define WINDIVERT_FILTER_FIELD_IPV6_DSTADDR 29 +#define WINDIVERT_FILTER_FIELD_ICMP_TYPE 30 +#define WINDIVERT_FILTER_FIELD_ICMP_CODE 31 +#define WINDIVERT_FILTER_FIELD_ICMP_CHECKSUM 32 +#define WINDIVERT_FILTER_FIELD_ICMP_BODY 33 +#define WINDIVERT_FILTER_FIELD_ICMPV6_TYPE 34 +#define WINDIVERT_FILTER_FIELD_ICMPV6_CODE 35 +#define WINDIVERT_FILTER_FIELD_ICMPV6_CHECKSUM 36 +#define WINDIVERT_FILTER_FIELD_ICMPV6_BODY 37 +#define WINDIVERT_FILTER_FIELD_TCP_SRCPORT 38 +#define WINDIVERT_FILTER_FIELD_TCP_DSTPORT 39 +#define WINDIVERT_FILTER_FIELD_TCP_SEQNUM 40 +#define WINDIVERT_FILTER_FIELD_TCP_ACKNUM 41 +#define WINDIVERT_FILTER_FIELD_TCP_HDRLENGTH 42 +#define WINDIVERT_FILTER_FIELD_TCP_URG 43 +#define WINDIVERT_FILTER_FIELD_TCP_ACK 44 +#define WINDIVERT_FILTER_FIELD_TCP_PSH 45 +#define WINDIVERT_FILTER_FIELD_TCP_RST 46 +#define WINDIVERT_FILTER_FIELD_TCP_SYN 47 +#define WINDIVERT_FILTER_FIELD_TCP_FIN 48 +#define WINDIVERT_FILTER_FIELD_TCP_WINDOW 49 +#define WINDIVERT_FILTER_FIELD_TCP_CHECKSUM 50 +#define WINDIVERT_FILTER_FIELD_TCP_URGPTR 51 +#define WINDIVERT_FILTER_FIELD_TCP_PAYLOADLENGTH 52 +#define WINDIVERT_FILTER_FIELD_UDP_SRCPORT 53 +#define WINDIVERT_FILTER_FIELD_UDP_DSTPORT 54 +#define WINDIVERT_FILTER_FIELD_UDP_LENGTH 55 +#define WINDIVERT_FILTER_FIELD_UDP_CHECKSUM 56 +#define WINDIVERT_FILTER_FIELD_UDP_PAYLOADLENGTH 57 +#define WINDIVERT_FILTER_FIELD_MAX \ + WINDIVERT_FILTER_FIELD_UDP_PAYLOADLENGTH + +#define WINDIVERT_FILTER_TEST_EQ 0 +#define WINDIVERT_FILTER_TEST_NEQ 1 +#define WINDIVERT_FILTER_TEST_LT 2 +#define WINDIVERT_FILTER_TEST_LEQ 3 +#define WINDIVERT_FILTER_TEST_GT 4 +#define WINDIVERT_FILTER_TEST_GEQ 5 +#define WINDIVERT_FILTER_TEST_MAX WINDIVERT_FILTER_TEST_GEQ + +#define WINDIVERT_FILTER_MAXLEN 32 + +#define WINDIVERT_FILTER_RESULT_ACCEPT (WINDIVERT_FILTER_MAXLEN+1) +#define WINDIVERT_FILTER_RESULT_REJECT (WINDIVERT_FILTER_MAXLEN+2) + +/* + * WinDivert layers. + */ +#define WINDIVERT_LAYER_DEFAULT WINDIVERT_LAYER_NETWORK +#define WINDIVERT_LAYER_MAX \ + WINDIVERT_LAYER_NETWORK_FORWARD + +/* + * WinDivert flags. + */ +#define WINDIVERT_FLAGS_ALL \ + (WINDIVERT_FLAG_SNIFF | WINDIVERT_FLAG_DROP | WINDIVERT_FLAG_PASSTHRU | \ + WINDIVERT_FLAG_NO_CHECKSUM) +#define WINDIVERT_FLAGS_EXCLUDE(flags, flag1, flag2) \ + (((flags) & ((flag1) | (flag2))) != ((flag1) | (flag2))) +#define WINDIVERT_FLAGS_VALID(flags) \ + ((((flags) & ~WINDIVERT_FLAGS_ALL) == 0) && \ + WINDIVERT_FLAGS_EXCLUDE(flags, WINDIVERT_FLAG_SNIFF, \ + WINDIVERT_FLAG_DROP) && \ + WINDIVERT_FLAGS_EXCLUDE(flags, WINDIVERT_FLAG_SNIFF, \ + WINDIVERT_FLAG_PASSTHRU) && \ + WINDIVERT_FLAGS_EXCLUDE(flags, WINDIVERT_FLAG_DROP, \ + WINDIVERT_FLAG_PASSTHRU)) +/* + * WinDivert priorities. + */ +#define WINDIVERT_PRIORITY(priority16) \ + ((UINT32)((INT32)(priority16) + 0x7FFF + 1)) +#define WINDIVERT_PRIORITY_DEFAULT WINDIVERT_PRIORITY(0) +#define WINDIVERT_PRIORITY_MAX WINDIVERT_PRIORITY(1000) + +/* + * WinDivert parameters. + */ +#define WINDIVERT_PARAM_QUEUE_LEN_DEFAULT 1024 +#define WINDIVERT_PARAM_QUEUE_LEN_MIN 1 +#define WINDIVERT_PARAM_QUEUE_LEN_MAX 8192 +#define WINDIVERT_PARAM_QUEUE_TIME_DEFAULT 512 +#define WINDIVERT_PARAM_QUEUE_TIME_MIN 128 +#define WINDIVERT_PARAM_QUEUE_TIME_MAX 2048 + +/* + * WinDivert message definitions. + */ +#pragma pack(push, 1) +struct windivert_ioctl_s +{ + UINT16 magic; // WINDIVERT_IOCTL_MAGIC + UINT8 version; // WINDIVERT_IOCTL_VERSION + UINT8 arg8; // 8-bit argument + UINT64 arg; // 64-bit argument +}; +typedef struct windivert_ioctl_s *windivert_ioctl_t; + +/* + * WinDivert IOCTL structures. + */ +struct windivert_ioctl_filter_s +{ + UINT8 field; // WINDIVERT_FILTER_FIELD_IP_* + UINT8 test; // WINDIVERT_FILTER_TEST_* + UINT16 success; // Success continuation. + UINT16 failure; // Fail continuation. + UINT32 arg[4]; // Argument. +}; +typedef struct windivert_ioctl_filter_s *windivert_ioctl_filter_t; +#pragma pack(pop) + +/* + * IOCTL codes. + */ +#define IOCTL_WINDIVERT_RECV \ + CTL_CODE(FILE_DEVICE_NETWORK, 0x908, METHOD_OUT_DIRECT, FILE_ANY_ACCESS) +#define IOCTL_WINDIVERT_SEND \ + CTL_CODE(FILE_DEVICE_NETWORK, 0x909, METHOD_IN_DIRECT, FILE_ANY_ACCESS) +#define IOCTL_WINDIVERT_START_FILTER \ + CTL_CODE(FILE_DEVICE_NETWORK, 0x90A, METHOD_IN_DIRECT, FILE_ANY_ACCESS) +#define IOCTL_WINDIVERT_SET_LAYER \ + CTL_CODE(FILE_DEVICE_NETWORK, 0x90B, METHOD_IN_DIRECT, FILE_ANY_ACCESS) +#define IOCTL_WINDIVERT_SET_PRIORITY \ + CTL_CODE(FILE_DEVICE_NETWORK, 0x90C, METHOD_IN_DIRECT, FILE_ANY_ACCESS) +#define IOCTL_WINDIVERT_SET_FLAGS \ + CTL_CODE(FILE_DEVICE_NETWORK, 0x90D, METHOD_IN_DIRECT, FILE_ANY_ACCESS) +#define IOCTL_WINDIVERT_SET_PARAM \ + CTL_CODE(FILE_DEVICE_NETWORK, 0x90E, METHOD_IN_DIRECT, FILE_ANY_ACCESS) +#define IOCTL_WINDIVERT_GET_PARAM \ + CTL_CODE(FILE_DEVICE_NETWORK, 0x90F, METHOD_OUT_DIRECT, FILE_ANY_ACCESS) + +#endif /* __WINDIVERT_DEVICE_H */ diff --git a/mingw-build.sh b/mingw-build.sh index 931a56a..5ab145c 100644 --- a/mingw-build.sh +++ b/mingw-build.sh @@ -1,7 +1,7 @@ #!/bin/bash # # mingw-build.sh -# (C) 2012, all rights reserved, +# (C) 2013, all rights reserved, # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by @@ -45,8 +45,8 @@ do echo "\tmake install/MINGW/$CPU..." mkdir -p "install/MINGW/$CPU" echo "\tbuild install/MINGW/$CPU/WinDivert.dll..." - $CC -Wall -O2 -Iinclude/ -c dll/divert.c -o dll/divert.o - $CC -Wall -shared -o "install/MINGW/$CPU/WinDivert.dll" dll/divert.o + $CC -Wall -O2 -Iinclude/ -c dll/windivert.c -o dll/windivert.o + $CC -Wall -shared -o "install/MINGW/$CPU/WinDivert.dll" dll/windivert.o $STRIP --strip-debug "install/MINGW/$CPU/WinDivert.dll" echo "\tbuild install/MINGW/$CPU/netdump.exe..." $CC -s -O2 -Iinclude/ examples/netdump/netdump.c \ diff --git a/msvc-build.bat b/msvc-build.bat index 8477f25..1c297fe 100644 --- a/msvc-build.bat +++ b/msvc-build.bat @@ -1,5 +1,5 @@ :: msvc-build.bat -:: (C) 2012, all rights reserved, +:: (C) 2013, all rights reserved, :: :: This program is free software: you can redistribute it and/or modify :: it under the terms of the GNU Lesser General Public License as published by diff --git a/release-build.sh b/release-build.sh index 007a699..3922b79 100644 --- a/release-build.sh +++ b/release-build.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# (C) 2012, all rights reserved, +# (C) 2013, all rights reserved, # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by @@ -44,16 +44,16 @@ do cp VERSION $INSTALL echo "\tmake $INSTALL/include..." mkdir -p $INSTALL/include - echo "\tcopy $INSTALL/include/divert.h..." - cp include/divert.h $INSTALL/include + echo "\tcopy $INSTALL/include/windivert.h..." + cp include/windivert.h $INSTALL/include echo "\tmake $INSTALL/doc..." mkdir -p $INSTALL/doc echo "\tcopy $INSTALL/doc/WinDivert.html..." - cp doc/divert.html $INSTALL/doc/WinDivert.html + cp doc/windivert.html $INSTALL/doc/WinDivert.html echo "\tmake $INSTALL/x86..." mkdir -p $INSTALL/x86 echo "\tcopy $INSTALL/x86/WinDivert.inf..." - cp sys/divert.inf $INSTALL/x86/WinDivert.inf + cp sys/windivert.inf $INSTALL/x86/WinDivert.inf echo "\tcopy $INSTALL/x86/WinDivert.sys..." cp install/$TARGET/i386/WinDivert.sys $INSTALL/x86 if ! grep "DigiCert High Assurance EV Root" $INSTALL/x86/WinDivert.sys \ @@ -88,7 +88,7 @@ do echo "\tmake $INSTALL/amd64..." mkdir -p $INSTALL/amd64 echo "\tcopy $INSTALL/amd64/WinDivert.inf..." - cp sys/divert.inf $INSTALL/amd64/WinDivert.inf + cp sys/windivert.inf $INSTALL/amd64/WinDivert.inf echo "\tcopy $INSTALL/amd64/WinDivert.sys..." cp install/$TARGET/amd64/WinDivert.sys $INSTALL/amd64 if ! grep "DigiCert High Assurance EV Root" \ diff --git a/sys/Makefile.inc b/sys/Makefile.inc index 8bfda6c..2a2feeb 100644 --- a/sys/Makefile.inc +++ b/sys/Makefile.inc @@ -4,7 +4,7 @@ CPU=i386 CPU=$(_BUILDARCH) !ENDIF -$(TARGETPATH)\$(CPU)\WinDivert.inf: divert.inf - copy /y divert.inf $@ +$(TARGETPATH)\$(CPU)\WinDivert.inf: windivert.inf + copy /y windivert.inf $@ $(TARGETPATH)\$(CPU)\WdfCoInstaller01009.dll: copy /y $(BASEDIR)\redist\wdf\$(_BUILDARCH)\WdfCoInstaller01009.dll $@ diff --git a/sys/divert.inf b/sys/divert.inf deleted file mode 100644 index db4fbd8..0000000 --- a/sys/divert.inf +++ /dev/null @@ -1,9 +0,0 @@ -[Version] -Signature="$WINDOWS NT$" - -[divert.NT.Wdf] -KmdfService = divert, divert_WdfSection - -[divert_WdfSection] -KmdfLibraryVersion = 1.9 - diff --git a/sys/sources b/sys/sources index 9c7cd22..eeaf21b 100644 --- a/sys/sources +++ b/sys/sources @@ -1,5 +1,5 @@ # sources -# (C) 2012, all rights reserved, +# (C) 2013, all rights reserved, # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by @@ -35,5 +35,5 @@ KMDF_VERSION_MAJOR=1 C_DEFINES=$(C_DEFINES) -DBINARY_COMPATIBLE=0 -DNT -DUNICODE -D_UNICODE \ -DNDIS60 -DNDIS_SUPPORT_NDIS60 INCLUDES=$(DDK_INC_PATH);..\include -SOURCES=divert.rc divert.c +SOURCES=windivert.rc windivert.c diff --git a/sys/divert.c b/sys/windivert.c similarity index 64% rename from sys/divert.c rename to sys/windivert.c index 4cbbf3f..8abcdcf 100644 --- a/sys/divert.c +++ b/sys/windivert.c @@ -1,6 +1,6 @@ /* - * divert.c - * (C) 2012, all rights reserved, + * windivert.c + * (C) 2013, all rights reserved, * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by @@ -23,19 +23,19 @@ #include #include -#include "divert_device.h" +#include "windivert_device.h" /* * WDK function declaration cruft. */ DRIVER_INITIALIZE DriverEntry; -EVT_WDF_DRIVER_UNLOAD divert_unload; -EVT_WDF_IO_IN_CALLER_CONTEXT divert_caller_context; -EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL divert_ioctl; -EVT_WDF_DEVICE_FILE_CREATE divert_create; -EVT_WDF_TIMER divert_timer; -EVT_WDF_FILE_CLEANUP divert_cleanup; -EVT_WDF_FILE_CLOSE divert_close; +EVT_WDF_DRIVER_UNLOAD windivert_unload; +EVT_WDF_IO_IN_CALLER_CONTEXT windivert_caller_context; +EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL windivert_ioctl; +EVT_WDF_DEVICE_FILE_CREATE windivert_create; +EVT_WDF_TIMER windivert_timer; +EVT_WDF_FILE_CLEANUP windivert_cleanup; +EVT_WDF_FILE_CLOSE windivert_close; /* * Debugging macros. @@ -48,18 +48,26 @@ static void DEBUG(PCCH format, ...) { va_list args; char buf[DEBUG_BUFSIZE+1]; + if (KeGetCurrentIrql() != PASSIVE_LEVEL) + { + return; + } va_start(args, format); RtlStringCbVPrintfA(buf, DEBUG_BUFSIZE, format, args); - DbgPrint("DIVERT: %s", buf); + DbgPrint("WINDIVERT: %s\n", buf); va_end(args); } static void DEBUG_ERROR(PCCH format, NTSTATUS status, ...) { va_list args; char buf[DEBUG_BUFSIZE+1]; + if (KeGetCurrentIrql() != PASSIVE_LEVEL) + { + return; + } va_start(args, status); RtlStringCbVPrintfA(buf, DEBUG_BUFSIZE, format, args); - DbgPrint("DIVERT: *** ERROR ***: (status = %x): %s", status, buf); + DbgPrint("WINDIVERT: *** ERROR ***: (status = %x): %s\n", status, buf); va_end(args); } #else // DEBUG_ON @@ -68,84 +76,86 @@ static void DEBUG_ERROR(PCCH format, NTSTATUS status, ...) #endif // DEBUG_ON /* - * Packet filter. + * WinDivert packet filter. */ struct filter_s { - UINT8 protocol:4; // field's protocol - UINT8 test:4; // Filter test - UINT8 field; // Field of interest - UINT16 success; // Success continuation - UINT16 failure; // Fail continuation - UINT32 arg[4]; // Comparison argument + UINT8 protocol:4; // field's protocol + UINT8 test:4; // Filter test + UINT8 field; // Field of interest + UINT16 success; // Success continuation + UINT16 failure; // Fail continuation + UINT32 arg[4]; // Comparison argument }; typedef struct filter_s *filter_t; -#define DIVERT_FILTER_PROTOCOL_NONE 0 -#define DIVERT_FILTER_PROTOCOL_IP 1 -#define DIVERT_FILTER_PROTOCOL_IPV6 2 -#define DIVERT_FILTER_PROTOCOL_ICMP 3 -#define DIVERT_FILTER_PROTOCOL_ICMPV6 4 -#define DIVERT_FILTER_PROTOCOL_TCP 5 -#define DIVERT_FILTER_PROTOCOL_UDP 6 -#define DIVERT_FILTER_TAG 'Fvid' +#define WINDIVERT_FILTER_PROTOCOL_NONE 0 +#define WINDIVERT_FILTER_PROTOCOL_IP 1 +#define WINDIVERT_FILTER_PROTOCOL_IPV6 2 +#define WINDIVERT_FILTER_PROTOCOL_ICMP 3 +#define WINDIVERT_FILTER_PROTOCOL_ICMPV6 4 +#define WINDIVERT_FILTER_PROTOCOL_TCP 5 +#define WINDIVERT_FILTER_PROTOCOL_UDP 6 +#define WINDIVERT_FILTER_TAG 'Fvid' /* - * Context information. + * WinDivert context information. */ -#define DIVERT_CONTEXT_MAGIC 0xB75D18F185A65197ull -#define DIVERT_CONTEXT_SIZE (sizeof(struct context_s)) -#define DIVERT_CONTEXT_MAXLAYERS 4 -#define DIVERT_CONTEXT_OUTBOUND_IPV4_LAYER 0 -#define DIVERT_CONTEXT_INBOUND_IPV4_LAYER 1 -#define DIVERT_CONTEXT_OUTBOUND_IPV6_LAYER 2 -#define DIVERT_CONTEXT_INBOUND_IPV6_LAYER 3 +#define WINDIVERT_CONTEXT_MAGIC 0xAA5D1C5BC439AA72ull +#define WINDIVERT_CONTEXT_SIZE (sizeof(struct context_s)) +#define WINDIVERT_CONTEXT_MAXLAYERS 4 +#define WINDIVERT_CONTEXT_OUTBOUND_IPV4_LAYER 0 +#define WINDIVERT_CONTEXT_INBOUND_IPV4_LAYER 1 +#define WINDIVERT_CONTEXT_OUTBOUND_IPV6_LAYER 2 +#define WINDIVERT_CONTEXT_INBOUND_IPV6_LAYER 3 typedef enum { - DIVERT_CONTEXT_STATE_OPENING = 0xA0, // Context is opening. - DIVERT_CONTEXT_STATE_OPEN = 0xB1, // Context is open. - DIVERT_CONTEXT_STATE_CLOSING = 0xC2, // Context is closing. - DIVERT_CONTEXT_STATE_CLOSED = 0xD3, // Context is closed. - DIVERT_CONTEXT_STATE_INVALID = 0xE4 // Context is invalid. + WINDIVERT_CONTEXT_STATE_OPENING = 0xA0, // Context is opening. + WINDIVERT_CONTEXT_STATE_OPEN = 0xB1, // Context is open. + WINDIVERT_CONTEXT_STATE_CLOSING = 0xC2, // Context is closing. + WINDIVERT_CONTEXT_STATE_CLOSED = 0xD3, // Context is closed. + WINDIVERT_CONTEXT_STATE_INVALID = 0xE4 // Context is invalid. } context_state_t; struct context_s { - UINT64 magic; // DIVERT_CONTEXT_MAGIC - context_state_t state; // Context's state. - KSPIN_LOCK lock; // Context-wide lock. - WDFDEVICE device; // Context's device. - LIST_ENTRY packet_queue; // Packet queue. - ULONG packet_queue_length; // Packet queue length. - ULONG packet_queue_maxlength; // Packet queue max length. - WDFTIMER timer; // Packet timer. - UINT timer_timeout; // Packet timeout (in ms). - BOOL timer_ticktock; // Packet timer ticktock. - WDFQUEUE read_queue; // Read queue. - UINT8 layer_0; // Context's layer (initial). - UINT8 layer; // Context's layer. - UINT64 flags_0; // Context's flags (initial). - UINT64 flags; // Context's flags. - UINT32 priority_0; // Context's priority (initial). - UINT32 priority; // Context's priority. - GUID sublayer_guid[DIVERT_CONTEXT_MAXLAYERS]; - // Sublayer GUIDs. - GUID callout_guid[DIVERT_CONTEXT_MAXLAYERS]; - // Callout GUIDs. - GUID filter_guid[DIVERT_CONTEXT_MAXLAYERS]; - // Filter GUIDs. - BOOL registered[DIVERT_CONTEXT_MAXLAYERS]; - // What is registered? - HANDLE engine_handle; // WFP engine handle. - LONG filter_on; // Is filter on? - filter_t filter; // Packet filter. + UINT64 magic; // WINDIVERT_CONTEXT_MAGIC + context_state_t state; // Context's state. + KSPIN_LOCK lock; // Context-wide lock. + WDFDEVICE device; // Context's device. + LIST_ENTRY packet_queue; // Packet queue. + ULONG packet_queue_length; // Packet queue length. + ULONG packet_queue_maxlength; // Packet queue max length. + WDFTIMER timer; // Packet timer. + UINT timer_timeout; // Packet timeout (in ms). + BOOL timer_ticktock; // Packet timer ticktock. + WDFQUEUE read_queue; // Read queue. + KEVENT read_event; // Read event. + void *read_thread; // Read thread. + UINT8 layer_0; // Context's layer (initial). + UINT8 layer; // Context's layer. + UINT64 flags_0; // Context's flags (initial). + UINT64 flags; // Context's flags. + UINT32 priority_0; // Context's priority (initial). + UINT32 priority; // Context's priority. + GUID sublayer_guid[WINDIVERT_CONTEXT_MAXLAYERS]; + // Sublayer GUIDs. + GUID callout_guid[WINDIVERT_CONTEXT_MAXLAYERS]; + // Callout GUIDs. + GUID filter_guid[WINDIVERT_CONTEXT_MAXLAYERS]; + // Filter GUIDs. + BOOL registered[WINDIVERT_CONTEXT_MAXLAYERS]; + // What is registered? + HANDLE engine_handle; // WFP engine handle. + LONG filter_on; // Is filter on? + filter_t filter; // Packet filter. }; typedef struct context_s context_s; typedef struct context_s *context_t; -WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(context_s, divert_context_get); +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(context_s, windivert_context_get); /* - * Divert Layer information. + * WinDivert Layer information. */ -typedef void (*divert_callout_t)( +typedef void (*windivert_callout_t)( IN const FWPS_INCOMING_VALUES0 *fixed_vals, IN const FWPS_INCOMING_METADATA_VALUES0 *meta_vals, IN OUT void *data, const FWPS_FILTER0 *filter, IN UINT64 flow_context, @@ -159,27 +169,26 @@ struct layer_s wchar_t *filter_name; // Filter name. wchar_t *filter_desc; // Filter description. GUID guid; // WFP layer GUID. - divert_callout_t callout; // Call-out. + windivert_callout_t callout; // Call-out. }; typedef struct layer_s *layer_t; /* - * Request context. + * WinDivert request context. */ struct req_context_s { - struct divert_addr_s *addr; // Pointer to address structure. + struct windivert_addr_s *addr; // Pointer to address structure. }; typedef struct req_context_s req_context_s; typedef struct req_context_s *req_context_t; -WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(req_context_s, divert_req_context_get); +WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(req_context_s, windivert_req_context_get); /* - * Packets + * WinDivert packet structure. */ -#define DIVERT_PACKET_TAG 'Pvid' -#define DIVERT_PACKET_SIZE (sizeof(struct packet_s)) -#define DIVERT_PACKET_TIMEOUT 128 +#define WINDIVERT_PACKET_TAG 'Pvid' +#define WINDIVERT_PACKET_SIZE (sizeof(struct packet_s)) struct packet_s { LIST_ENTRY entry; // Entry for queue @@ -195,18 +204,18 @@ struct packet_s BOOL timer_ticktock; // Time-out ticktock }; typedef struct packet_s *packet_t; -#define DIVERT_NET_BUFFER_LIST_TAG 'Lvid' +#define WINDIVERT_NET_BUFFER_LIST_TAG 'Lvid' /* - * Address definition. + * WinDivert address definition. */ -struct divert_addr_s +struct windivert_addr_s { UINT32 IfIdx; UINT32 SubIfIdx; UINT8 Direction; }; -typedef struct divert_addr_s *divert_addr_t; +typedef struct windivert_addr_s *windivert_addr_t; /* * Header definitions. @@ -303,81 +312,83 @@ NDIS_HANDLE pool_handle; /* * Prototypes. */ -extern VOID divert_ioctl(IN WDFQUEUE queue, IN WDFREQUEST request, +extern VOID windivert_ioctl(IN WDFQUEUE queue, IN WDFREQUEST request, IN size_t in_length, IN size_t out_len, IN ULONG code); -extern NTSTATUS divert_read(context_t context, WDFREQUEST request); -static void divert_read_service(context_t context); -static BOOLEAN divert_context_verify(context_t context, context_state_t state); -extern VOID divert_create(IN WDFDEVICE device, IN WDFREQUEST request, +extern NTSTATUS windivert_read(context_t context, WDFREQUEST request); +static void windivert_read_service_worker(PVOID context_0); +static void windivert_read_service(context_t context); +static BOOLEAN windivert_context_verify(context_t context, + context_state_t state); +extern VOID windivert_create(IN WDFDEVICE device, IN WDFREQUEST request, IN WDFFILEOBJECT object); -static NTSTATUS divert_register_callouts(context_t context, BOOL is_inbound, +static NTSTATUS windivert_register_callouts(context_t context, BOOL is_inbound, BOOL is_outbound, BOOL is_ipv4, BOOL is_ipv6); -static NTSTATUS divert_register_callout(context_t context, UINT idx, +static NTSTATUS windivert_register_callout(context_t context, UINT idx, layer_t layer); -extern VOID divert_timer(IN WDFTIMER timer); -extern VOID divert_cleanup(IN WDFFILEOBJECT object); -extern VOID divert_close(IN WDFFILEOBJECT object); -extern NTSTATUS divert_write(context_t context, WDFREQUEST request, - divert_addr_t addr); -extern void NTAPI divert_inject_complete(VOID *context, +extern VOID windivert_timer(IN WDFTIMER timer); +extern VOID windivert_cleanup(IN WDFFILEOBJECT object); +extern VOID windivert_close(IN WDFFILEOBJECT object); +extern NTSTATUS windivert_write(context_t context, WDFREQUEST request, + windivert_addr_t addr); +extern void NTAPI windivert_inject_complete(VOID *context, NET_BUFFER_LIST *packets, BOOLEAN dispatch_level); -static NTSTATUS divert_notify_callout(IN FWPS_CALLOUT_NOTIFY_TYPE type, +static NTSTATUS windivert_notify_callout(IN FWPS_CALLOUT_NOTIFY_TYPE type, IN const GUID *filter_key, IN const FWPS_FILTER0 *filter); -static void divert_classify_outbound_network_v4_callout( +static void windivert_classify_outbound_network_v4_callout( IN const FWPS_INCOMING_VALUES0 *fixed_vals, IN const FWPS_INCOMING_METADATA_VALUES0 *meta_vals, IN OUT void *data, const FWPS_FILTER0 *filter, IN UINT64 flow_context, OUT FWPS_CLASSIFY_OUT0 *result); -static void divert_classify_inbound_network_v4_callout( +static void windivert_classify_inbound_network_v4_callout( IN const FWPS_INCOMING_VALUES0 *fixed_vals, IN const FWPS_INCOMING_METADATA_VALUES0 *meta_vals, IN OUT void *data, const FWPS_FILTER0 *filter, IN UINT64 flow_context, OUT FWPS_CLASSIFY_OUT0 *result); -static void divert_classify_outbound_network_v6_callout( +static void windivert_classify_outbound_network_v6_callout( IN const FWPS_INCOMING_VALUES0 *fixed_vals, IN const FWPS_INCOMING_METADATA_VALUES0 *meta_vals, IN OUT void *data, const FWPS_FILTER0 *filter, IN UINT64 flow_context, OUT FWPS_CLASSIFY_OUT0 *result); -static void divert_classify_inbound_network_v6_callout( +static void windivert_classify_inbound_network_v6_callout( IN const FWPS_INCOMING_VALUES0 *fixed_vals, IN const FWPS_INCOMING_METADATA_VALUES0 *meta_vals, IN OUT void *data, const FWPS_FILTER0 *filter, IN UINT64 flow_context, OUT FWPS_CLASSIFY_OUT0 *result); -static void divert_classify_forward_network_v4_callout( +static void windivert_classify_forward_network_v4_callout( IN const FWPS_INCOMING_VALUES0 *fixed_vals, IN const FWPS_INCOMING_METADATA_VALUES0 *meta_vals, IN OUT void *data, const FWPS_FILTER0 *filter, IN UINT64 flow_context, OUT FWPS_CLASSIFY_OUT0 *result); -static void divert_classify_forward_network_v6_callout( +static void windivert_classify_forward_network_v6_callout( IN const FWPS_INCOMING_VALUES0 *fixed_vals, IN const FWPS_INCOMING_METADATA_VALUES0 *meta_vals, IN OUT void *data, const FWPS_FILTER0 *filter, IN UINT64 flow_context, OUT FWPS_CLASSIFY_OUT0 *result); -static void divert_classify_callout(IN UINT8 direction, IN UINT32 if_idx, +static void windivert_classify_callout(IN UINT8 direction, IN UINT32 if_idx, IN UINT32 sub_if_idx, IN BOOL isipv4, IN const FWPS_INCOMING_VALUES0 *fixed_vals, IN const FWPS_INCOMING_METADATA_VALUES0 *meta_vals, IN OUT void *data, const FWPS_FILTER0 *filter, IN UINT64 flow_context, OUT FWPS_CLASSIFY_OUT0 *result); -static BOOL divert_reinject_packet(context_t context, UINT8 direction, +static BOOL windivert_reinject_packet(context_t context, UINT8 direction, BOOL isipv4, UINT32 if_idx, UINT32 sub_if_idx, UINT32 priority, PNET_BUFFER_LIST buffers, PNET_BUFFER buffer); -static void NTAPI divert_reinject_complete(VOID *context, +static void NTAPI windivert_reinject_complete(VOID *context, NET_BUFFER_LIST *buffers_cpy, BOOLEAN dispatch_level); -static BOOL divert_queue_packet(context_t context, PNET_BUFFER_LIST buffers, +static BOOL windivert_queue_packet(context_t context, PNET_BUFFER_LIST buffers, PNET_BUFFER buffer, UINT8 direction, UINT32 if_idx, UINT32 sub_if_idx); -static void divert_free_packet(packet_t packet); -static UINT16 divert_checksum(const void *pseudo_header, +static void windivert_free_packet(packet_t packet); +static UINT16 windivert_checksum(const void *pseudo_header, size_t pseudo_header_len, const void *data, size_t size); -static void divert_update_checksums(void *header, size_t len, +static void windivert_update_checksums(void *header, size_t len, BOOL update_ip, BOOL update_tcp, BOOL update_udp); -static BOOL divert_filter(PNET_BUFFER buffer, UINT32 if_idx, UINT32 sub_if_idx, - BOOL outbound, filter_t filter); -static filter_t divert_filter_compile(divert_ioctl_filter_t ioctl_filter, +static BOOL windivert_filter(PNET_BUFFER buffer, UINT32 if_idx, + UINT32 sub_if_idx, BOOL outbound, filter_t filter); +static filter_t windivert_filter_compile(windivert_ioctl_filter_t ioctl_filter, size_t ioctl_filter_len); -static void divert_filter_analyze(filter_t filter, BOOL *is_inbound, +static void windivert_filter_analyze(filter_t filter, BOOL *is_inbound, BOOL *is_outbound, BOOL *ip_ipv4, BOOL *is_ipv6); -static BOOL divert_filter_test(filter_t filter, UINT16 ip, UINT8 protocol, +static BOOL windivert_filter_test(filter_t filter, UINT16 ip, UINT8 protocol, UINT8 field, UINT32 arg); /* @@ -385,84 +396,84 @@ static BOOL divert_filter_test(filter_t filter, UINT16 ip, UINT8 protocol, */ static struct layer_s layer_inbound_network_ipv4_0 = { - L"" DIVERT_DEVICE_NAME L"SubLayerInboundNetworkIPv4", - L"" DIVERT_DEVICE_NAME L" sublayer network (inbound IPv4)", - L"" DIVERT_DEVICE_NAME L"CalloutInboundNetworkIPv4", - L"" DIVERT_DEVICE_NAME L" callout network (inbound IPv4)", - L"" DIVERT_DEVICE_NAME L"FilterInboundNetworkIPv4", - L"" DIVERT_DEVICE_NAME L" filter network (inbound IPv4)", + L"" WINDIVERT_DEVICE_NAME L"_SubLayerInboundNetworkIPv4", + L"" WINDIVERT_DEVICE_NAME L" sublayer network (inbound IPv4)", + L"" WINDIVERT_DEVICE_NAME L"_CalloutInboundNetworkIPv4", + L"" WINDIVERT_DEVICE_NAME L" callout network (inbound IPv4)", + L"" WINDIVERT_DEVICE_NAME L"_FilterInboundNetworkIPv4", + L"" WINDIVERT_DEVICE_NAME L" filter network (inbound IPv4)", {0}, - divert_classify_inbound_network_v4_callout, + windivert_classify_inbound_network_v4_callout, }; static layer_t layer_inbound_network_ipv4 = &layer_inbound_network_ipv4_0; static struct layer_s layer_outbound_network_ipv4_0 = { - L"" DIVERT_DEVICE_NAME L"SubLayerOutboundNetworkIPv4", - L"" DIVERT_DEVICE_NAME L" sublayer network (outbound IPv4)", - L"" DIVERT_DEVICE_NAME L"CalloutOutboundNetworkIPv4", - L"" DIVERT_DEVICE_NAME L" callout network (outbound IPv4)", - L"" DIVERT_DEVICE_NAME L"FilterOutboundNetworkIPv4", - L"" DIVERT_DEVICE_NAME L" filter network (outbound IPv4)", + L"" WINDIVERT_DEVICE_NAME L"_SubLayerOutboundNetworkIPv4", + L"" WINDIVERT_DEVICE_NAME L" sublayer network (outbound IPv4)", + L"" WINDIVERT_DEVICE_NAME L"_CalloutOutboundNetworkIPv4", + L"" WINDIVERT_DEVICE_NAME L" callout network (outbound IPv4)", + L"" WINDIVERT_DEVICE_NAME L"_FilterOutboundNetworkIPv4", + L"" WINDIVERT_DEVICE_NAME L" filter network (outbound IPv4)", {0}, - divert_classify_outbound_network_v4_callout, + windivert_classify_outbound_network_v4_callout, }; static layer_t layer_outbound_network_ipv4 = &layer_outbound_network_ipv4_0; static struct layer_s layer_inbound_network_ipv6_0 = { - L"" DIVERT_DEVICE_NAME L"SubLayerInboundNetworkIPv6", - L"" DIVERT_DEVICE_NAME L" sublayer network (inbound IPv6)", - L"" DIVERT_DEVICE_NAME L"CalloutInboundNetworkIPv6", - L"" DIVERT_DEVICE_NAME L" callout network (inbound IPv6)", - L"" DIVERT_DEVICE_NAME L"FilterInboundNetworkIPv6", - L"" DIVERT_DEVICE_NAME L" filter network (inbound IPv6)", + L"" WINDIVERT_DEVICE_NAME L"_SubLayerInboundNetworkIPv6", + L"" WINDIVERT_DEVICE_NAME L" sublayer network (inbound IPv6)", + L"" WINDIVERT_DEVICE_NAME L"_CalloutInboundNetworkIPv6", + L"" WINDIVERT_DEVICE_NAME L" callout network (inbound IPv6)", + L"" WINDIVERT_DEVICE_NAME L"_FilterInboundNetworkIPv6", + L"" WINDIVERT_DEVICE_NAME L" filter network (inbound IPv6)", {0}, - divert_classify_inbound_network_v6_callout, + windivert_classify_inbound_network_v6_callout, }; static layer_t layer_inbound_network_ipv6 = &layer_inbound_network_ipv6_0; static struct layer_s layer_outbound_network_ipv6_0 = { - L"" DIVERT_DEVICE_NAME L"SubLayerOutboundNetworkIPv6", - L"" DIVERT_DEVICE_NAME L" sublayer network (outbound IPv6)", - L"" DIVERT_DEVICE_NAME L"CalloutOutboundNetworkIPv6", - L"" DIVERT_DEVICE_NAME L" callout network (outbound IPv6)", - L"" DIVERT_DEVICE_NAME L"FilterOutboundNetworkIPv6", - L"" DIVERT_DEVICE_NAME L" filter network (outbound IPv6)", + L"" WINDIVERT_DEVICE_NAME L"_SubLayerOutboundNetworkIPv6", + L"" WINDIVERT_DEVICE_NAME L" sublayer network (outbound IPv6)", + L"" WINDIVERT_DEVICE_NAME L"_CalloutOutboundNetworkIPv6", + L"" WINDIVERT_DEVICE_NAME L" callout network (outbound IPv6)", + L"" WINDIVERT_DEVICE_NAME L"_FilterOutboundNetworkIPv6", + L"" WINDIVERT_DEVICE_NAME L" filter network (outbound IPv6)", {0}, - divert_classify_outbound_network_v6_callout, + windivert_classify_outbound_network_v6_callout, }; static layer_t layer_outbound_network_ipv6 = &layer_outbound_network_ipv6_0; static struct layer_s layer_forward_network_ipv4_0 = { - L"" DIVERT_DEVICE_NAME L"SubLayerForwardNetworkIPv4", - L"" DIVERT_DEVICE_NAME L" sublayer network (forward IPv4)", - L"" DIVERT_DEVICE_NAME L"CalloutForwardNetworkIPv4", - L"" DIVERT_DEVICE_NAME L" callout network (forward IPv4)", - L"" DIVERT_DEVICE_NAME L"FilterForwardNetworkIPv4", - L"" DIVERT_DEVICE_NAME L" filter network (forward IPv4)", + L"" WINDIVERT_DEVICE_NAME L"_SubLayerForwardNetworkIPv4", + L"" WINDIVERT_DEVICE_NAME L" sublayer network (forward IPv4)", + L"" WINDIVERT_DEVICE_NAME L"_CalloutForwardNetworkIPv4", + L"" WINDIVERT_DEVICE_NAME L" callout network (forward IPv4)", + L"" WINDIVERT_DEVICE_NAME L"_FilterForwardNetworkIPv4", + L"" WINDIVERT_DEVICE_NAME L" filter network (forward IPv4)", {0}, - divert_classify_forward_network_v4_callout, + windivert_classify_forward_network_v4_callout, }; static layer_t layer_forward_network_ipv4 = &layer_forward_network_ipv4_0; static struct layer_s layer_forward_network_ipv6_0 = { - L"" DIVERT_DEVICE_NAME L"SubLayerForwardNetworkIPv6", - L"" DIVERT_DEVICE_NAME L" sublayer network (forward IPv6)", - L"" DIVERT_DEVICE_NAME L"CalloutForwardNetworkIPv6", - L"" DIVERT_DEVICE_NAME L" callout network (forward IPv6)", - L"" DIVERT_DEVICE_NAME L"FilterForwardNetworkIPv6", - L"" DIVERT_DEVICE_NAME L" filter network (forward IPv6)", + L"" WINDIVERT_DEVICE_NAME L"_SubLayerForwardNetworkIPv6", + L"" WINDIVERT_DEVICE_NAME L" sublayer network (forward IPv6)", + L"" WINDIVERT_DEVICE_NAME L"_CalloutForwardNetworkIPv6", + L"" WINDIVERT_DEVICE_NAME L" callout network (forward IPv6)", + L"" WINDIVERT_DEVICE_NAME L"_FilterForwardNetworkIPv6", + L"" WINDIVERT_DEVICE_NAME L" filter network (forward IPv6)", {0}, - divert_classify_forward_network_v6_callout, + windivert_classify_forward_network_v6_callout, }; static layer_t layer_forward_network_ipv6 = &layer_forward_network_ipv6_0; /* - * Driver entry routine. + * WinDivert driver entry routine. */ extern NTSTATUS DriverEntry(IN PDRIVER_OBJECT driver_obj, IN PUNICODE_STRING reg_path) @@ -478,11 +489,11 @@ extern NTSTATUS DriverEntry(IN PDRIVER_OBJECT driver_obj, NET_BUFFER_LIST_POOL_PARAMETERS pool_params; NTSTATUS status; DECLARE_CONST_UNICODE_STRING(device_name, - L"\\Device\\" DIVERT_DEVICE_NAME); + L"\\Device\\" WINDIVERT_DEVICE_NAME); DECLARE_CONST_UNICODE_STRING(dos_device_name, - L"\\??\\" DIVERT_DEVICE_NAME); + L"\\??\\" WINDIVERT_DEVICE_NAME); - DEBUG("LOAD: loading divert driver"); + DEBUG("LOAD: loading WinDivert driver"); // Initialize the layers. layer_inbound_network_ipv4->guid = FWPM_LAYER_INBOUND_IPPACKET_V4; @@ -495,7 +506,7 @@ extern NTSTATUS DriverEntry(IN PDRIVER_OBJECT driver_obj, // Configure ourself as a non-PnP driver: WDF_DRIVER_CONFIG_INIT(&config, WDF_NO_EVENT_CALLBACK); config.DriverInitFlags |= WdfDriverInitNonPnpDriver; - config.EvtDriverUnload = divert_unload; + config.EvtDriverUnload = windivert_unload; status = WdfDriverCreate(driver_obj, reg_path, WDF_NO_OBJECT_ATTRIBUTES, &config, &driver); if (!NT_SUCCESS(status)) @@ -521,12 +532,12 @@ extern NTSTATUS DriverEntry(IN PDRIVER_OBJECT driver_obj, WdfDeviceInitFree(device_init); return status; } - WDF_FILEOBJECT_CONFIG_INIT(&file_config, divert_create, divert_close, - divert_cleanup); + WDF_FILEOBJECT_CONFIG_INIT(&file_config, windivert_create, windivert_close, + windivert_cleanup); WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&obj_attrs, context_s); WdfDeviceInitSetFileObjectConfig(device_init, &file_config, &obj_attrs); WdfDeviceInitSetIoInCallerContextCallback(device_init, - divert_caller_context); + windivert_caller_context); WDF_OBJECT_ATTRIBUTES_INIT(&obj_attrs); status = WdfDeviceCreate(&device_init, &obj_attrs, &device); if (!NT_SUCCESS(status)) @@ -539,7 +550,7 @@ extern NTSTATUS DriverEntry(IN PDRIVER_OBJECT driver_obj, WdfIoQueueDispatchParallel); queue_config.EvtIoRead = NULL; queue_config.EvtIoWrite = NULL; - queue_config.EvtIoDeviceControl = divert_ioctl; + queue_config.EvtIoDeviceControl = windivert_ioctl; WDF_OBJECT_ATTRIBUTES_INIT(&obj_attrs); status = WdfIoQueueCreate(device, &queue_config, &obj_attrs, &queue); if (!NT_SUCCESS(status)) @@ -580,7 +591,7 @@ extern NTSTATUS DriverEntry(IN PDRIVER_OBJECT driver_obj, pool_params.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; pool_params.Header.Size = sizeof(pool_params); pool_params.fAllocateNetBuffer = TRUE; - pool_params.PoolTag = DIVERT_NET_BUFFER_LIST_TAG; + pool_params.PoolTag = WINDIVERT_NET_BUFFER_LIST_TAG; pool_params.DataSize = 0; pool_handle = NdisAllocateNetBufferListPool(NULL, &pool_params); if (pool_handle == NULL) @@ -594,20 +605,21 @@ extern NTSTATUS DriverEntry(IN PDRIVER_OBJECT driver_obj, } /* - * Driver unload routine. + * WinDivert driver unload routine. */ -extern VOID divert_unload(IN WDFDRIVER Driver) +extern VOID windivert_unload(IN WDFDRIVER Driver) { - DEBUG("UNLOAD: unloading the divert driver"); + DEBUG("UNLOAD: unloading the WinDivert driver"); FwpsInjectionHandleDestroy0(inject_handle); FwpsInjectionHandleDestroy0(injectv6_handle); NdisFreeNetBufferPool(pool_handle); } /* - * Divert context verify. + * WinDivert context verify. */ -static BOOLEAN divert_context_verify(context_t context, context_state_t state) +static BOOLEAN windivert_context_verify(context_t context, + context_state_t state) { if (context == NULL) { @@ -615,7 +627,7 @@ static BOOLEAN divert_context_verify(context_t context, context_state_t state) STATUS_INVALID_HANDLE); return FALSE; } - if (context->magic != DIVERT_CONTEXT_MAGIC) + if (context->magic != WINDIVERT_CONTEXT_MAGIC) { DEBUG_ERROR("failed to verify context; invalid magic number", STATUS_INVALID_HANDLE); @@ -632,9 +644,9 @@ static BOOLEAN divert_context_verify(context_t context, context_state_t state) } /* - * Divert create routine. + * WinDivert create routine. */ -extern VOID divert_create(IN WDFDEVICE device, IN WDFREQUEST request, +extern VOID windivert_create(IN WDFDEVICE device, IN WDFREQUEST request, IN WDFFILEOBJECT object) { NET_BUFFER_LIST_POOL_PARAMETERS pool_params; @@ -642,52 +654,54 @@ extern VOID divert_create(IN WDFDEVICE device, IN WDFREQUEST request, WDF_TIMER_CONFIG timer_config; WDF_OBJECT_ATTRIBUTES timer_attributes; FWPM_SESSION0 session; + HANDLE thread; NTSTATUS status = STATUS_SUCCESS; UINT8 i; - context_t context = divert_context_get(object); + context_t context = windivert_context_get(object); - DEBUG("CREATE: creating a new divert context (context=%p)", context); + DEBUG("CREATE: creating a new WinDivert context (context=%p)", context); // Initialise the new context: - context->magic = DIVERT_CONTEXT_MAGIC; - context->state = DIVERT_CONTEXT_STATE_OPENING; + context->magic = WINDIVERT_CONTEXT_MAGIC; + context->state = WINDIVERT_CONTEXT_STATE_OPENING; context->device = device; context->packet_queue_length = 0; - context->packet_queue_maxlength = DIVERT_PARAM_QUEUE_LEN_DEFAULT; - context->timer_timeout = DIVERT_PARAM_QUEUE_TIME_DEFAULT; - context->layer_0 = DIVERT_LAYER_DEFAULT; - context->layer = DIVERT_LAYER_DEFAULT; - context->flags_0 = 0; - context->flags = 0; - context->priority_0 = DIVERT_PRIORITY_DEFAULT; - context->priority = DIVERT_PRIORITY_DEFAULT; - context->filter = NULL; - for (i = 0; i < DIVERT_CONTEXT_MAXLAYERS; i++) + context->packet_queue_maxlength = WINDIVERT_PARAM_QUEUE_LEN_DEFAULT; + context->timer_timeout = WINDIVERT_PARAM_QUEUE_TIME_DEFAULT; + context->layer_0 = WINDIVERT_LAYER_DEFAULT; + context->layer = WINDIVERT_LAYER_DEFAULT; + context->flags_0 = 0; + context->flags = 0; + context->priority_0 = WINDIVERT_PRIORITY_DEFAULT; + context->priority = WINDIVERT_PRIORITY_DEFAULT; + context->read_thread = NULL; + context->filter = NULL; + for (i = 0; i < WINDIVERT_CONTEXT_MAXLAYERS; i++) { context->registered[i] = FALSE; } context->filter_on = FALSE; KeInitializeSpinLock(&context->lock); InitializeListHead(&context->packet_queue); - for (i = 0; i < DIVERT_CONTEXT_MAXLAYERS; i++) + for (i = 0; i < WINDIVERT_CONTEXT_MAXLAYERS; i++) { status = ExUuidCreate(&context->sublayer_guid[i]); if (!NT_SUCCESS(status)) { DEBUG_ERROR("failed to create sub-layer GUID", status); - goto divert_create_exit; + goto windivert_create_exit; } status = ExUuidCreate(&context->callout_guid[i]); if (!NT_SUCCESS(status)) { DEBUG_ERROR("failed to create callout GUID", status); - goto divert_create_exit; + goto windivert_create_exit; } status = ExUuidCreate(&context->filter_guid[i]); if (!NT_SUCCESS(status)) { DEBUG_ERROR("failed to create filter GUID", status); - goto divert_create_exit; + goto windivert_create_exit; } } RtlZeroMemory(&pool_params, sizeof(pool_params)); @@ -695,7 +709,7 @@ extern VOID divert_create(IN WDFDEVICE device, IN WDFREQUEST request, pool_params.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; pool_params.Header.Size = sizeof(pool_params); pool_params.fAllocateNetBuffer = TRUE; - pool_params.PoolTag = DIVERT_NET_BUFFER_LIST_TAG; + pool_params.PoolTag = WINDIVERT_NET_BUFFER_LIST_TAG; pool_params.DataSize = 0; WDF_IO_QUEUE_CONFIG_INIT(&queue_config, WdfIoQueueDispatchManual); status = WdfIoQueueCreate(device, &queue_config, WDF_NO_OBJECT_ATTRIBUTES, @@ -703,9 +717,24 @@ extern VOID divert_create(IN WDFDEVICE device, IN WDFREQUEST request, if (!NT_SUCCESS(status)) { DEBUG_ERROR("failed to create I/O read queue", status); - goto divert_create_exit; + goto windivert_create_exit; } - WDF_TIMER_CONFIG_INIT(&timer_config, divert_timer); + KeInitializeEvent(&context->read_event, NotificationEvent, FALSE); + status = PsCreateSystemThread(&thread, THREAD_ALL_ACCESS, NULL, NULL, + NULL, windivert_read_service_worker, (PVOID)context); + if (!NT_SUCCESS(status)) + { + DEBUG_ERROR("failed to create read service thread", status); + goto windivert_create_exit; + } + status = ObReferenceObjectByHandle(thread, 0, NULL, KernelMode, + &context->read_thread, NULL); + if (!NT_SUCCESS(status)) + { + DEBUG_ERROR("failed to create read service thread object", status); + goto windivert_create_exit; + } + WDF_TIMER_CONFIG_INIT(&timer_config, windivert_timer); timer_config.AutomaticSerialization = TRUE; WDF_OBJECT_ATTRIBUTES_INIT(&timer_attributes); timer_attributes.ParentObject = (WDFOBJECT)object; @@ -713,7 +742,7 @@ extern VOID divert_create(IN WDFDEVICE device, IN WDFREQUEST request, if (!NT_SUCCESS(status)) { DEBUG_ERROR("failed to create packet time-out timer", status); - goto divert_create_exit; + goto windivert_create_exit; } RtlZeroMemory(&session, sizeof(session)); session.flags |= FWPM_SESSION_FLAG_DYNAMIC; @@ -722,15 +751,16 @@ extern VOID divert_create(IN WDFDEVICE device, IN WDFREQUEST request, if (!NT_SUCCESS(status)) { DEBUG_ERROR("failed to create WFP engine handle", status); - goto divert_create_exit; + goto windivert_create_exit; } - context->state = DIVERT_CONTEXT_STATE_OPEN; + context->state = WINDIVERT_CONTEXT_STATE_OPEN; -divert_create_exit: +windivert_create_exit: // Clean-up on error: if (!NT_SUCCESS(status)) { + context->state = WINDIVERT_CONTEXT_STATE_INVALID; if (context->read_queue != NULL) { WdfObjectDelete(context->read_queue); @@ -743,7 +773,13 @@ divert_create_exit: { FwpmEngineClose0(context->engine_handle); } - context->state = DIVERT_CONTEXT_STATE_INVALID; + if (context->read_thread != NULL) + { + KeSetEvent(&context->read_event, IO_NO_INCREMENT, FALSE); + KeWaitForSingleObject(context->read_thread, Executive, + KernelMode, FALSE, NULL); + ObDereferenceObject(context->read_thread); + } } WdfRequestComplete(request, status); @@ -752,17 +788,17 @@ divert_create_exit: /* * Register all WFP callouts. */ -static NTSTATUS divert_register_callouts(context_t context, BOOL is_inbound, +static NTSTATUS windivert_register_callouts(context_t context, BOOL is_inbound, BOOL is_outbound, BOOL is_ipv4, BOOL is_ipv6) { UINT8 i, j; - layer_t layers[DIVERT_CONTEXT_MAXLAYERS]; + layer_t layers[WINDIVERT_CONTEXT_MAXLAYERS]; NTSTATUS status; i = 0; switch (context->layer) { - case DIVERT_LAYER_NETWORK: + case WINDIVERT_LAYER_NETWORK: if (is_inbound && is_ipv4) { layers[i++] = layer_inbound_network_ipv4; @@ -781,7 +817,7 @@ static NTSTATUS divert_register_callouts(context_t context, BOOL is_inbound, } break; - case DIVERT_LAYER_NETWORK_FORWARD: + case WINDIVERT_LAYER_NETWORK_FORWARD: if (is_ipv4) { layers[i++] = layer_forward_network_ipv4; @@ -800,25 +836,25 @@ static NTSTATUS divert_register_callouts(context_t context, BOOL is_inbound, if (!NT_SUCCESS(status)) { DEBUG_ERROR("failed to begin WFP transaction", status); - goto divert_register_callouts_exit; + goto windivert_register_callouts_exit; } for (j = 0; j < i; j++) { - status = divert_register_callout(context, j, layers[j]); + status = windivert_register_callout(context, j, layers[j]); if (!NT_SUCCESS(status)) { FwpmTransactionAbort0(context->engine_handle); - goto divert_register_callouts_exit; + goto windivert_register_callouts_exit; } } status = FwpmTransactionCommit0(context->engine_handle); if (!NT_SUCCESS(status)) { DEBUG_ERROR("failed to commit WFP transaction", status); - goto divert_register_callouts_exit; + goto windivert_register_callouts_exit; } -divert_register_callouts_exit: +windivert_register_callouts_exit: if (!NT_SUCCESS(status)) { @@ -838,7 +874,7 @@ divert_register_callouts_exit: /* * Register a WFP callout. */ -static NTSTATUS divert_register_callout(context_t context, UINT idx, +static NTSTATUS windivert_register_callout(context_t context, UINT idx, layer_t layer) { FWPM_SUBLAYER0 sublayer; @@ -853,11 +889,11 @@ static NTSTATUS divert_register_callout(context_t context, UINT idx, sublayer.displayData.name = layer->sublayer_name; sublayer.displayData.description = layer->sublayer_desc; sublayer.weight = - (UINT16)(DIVERT_PRIORITY_MAX - context->priority); + (UINT16)(WINDIVERT_PRIORITY_MAX - context->priority); RtlZeroMemory(&scallout, sizeof(scallout)); scallout.calloutKey = context->callout_guid[idx]; scallout.classifyFn = layer->callout; - scallout.notifyFn = divert_notify_callout; + scallout.notifyFn = windivert_notify_callout; scallout.flowDeleteFn = NULL; RtlZeroMemory(&mcallout, sizeof(mcallout)); mcallout.calloutKey = context->callout_guid[idx]; @@ -878,33 +914,33 @@ static NTSTATUS divert_register_callout(context_t context, UINT idx, if (!NT_SUCCESS(status)) { DEBUG_ERROR("failed to add WFP sub-layer", status); - goto divert_register_callout_error; + goto windivert_register_callout_error; } status = FwpsCalloutRegister0(WdfDeviceWdmGetDeviceObject(context->device), &scallout, NULL); if (!NT_SUCCESS(status)) { DEBUG_ERROR("failed to register WFP callout", status); - goto divert_register_callout_error; + goto windivert_register_callout_error; } registered = TRUE; status = FwpmCalloutAdd0(context->engine_handle, &mcallout, NULL, NULL); if (!NT_SUCCESS(status)) { DEBUG_ERROR("failed to add WFP callout", status); - goto divert_register_callout_error; + goto windivert_register_callout_error; } status = FwpmFilterAdd0(context->engine_handle, &filter, NULL, NULL); if (!NT_SUCCESS(status)) { DEBUG_ERROR("failed to add WFP filter", status); - goto divert_register_callout_error; + goto windivert_register_callout_error; } context->registered[idx] = TRUE; return STATUS_SUCCESS; -divert_register_callout_error: +windivert_register_callout_error: if (registered) { FwpsCalloutUnregisterByKey0(&context->callout_guid[idx]); @@ -913,17 +949,17 @@ divert_register_callout_error: } /* - * Divert old-packet cleanup routine. + * WinDivert old-packet cleanup routine. */ -extern VOID divert_timer(IN WDFTIMER timer) +extern VOID windivert_timer(IN WDFTIMER timer) { KLOCK_QUEUE_HANDLE lock_handle; PLIST_ENTRY entry; WDFFILEOBJECT object = (WDFFILEOBJECT)WdfTimerGetParentObject(timer); - context_t context = divert_context_get(object); + context_t context = windivert_context_get(object); packet_t packet; - if (!divert_context_verify(context, DIVERT_CONTEXT_STATE_OPEN)) + if (!windivert_context_verify(context, WINDIVERT_CONTEXT_STATE_OPEN)) { return; } @@ -947,7 +983,7 @@ extern VOID divert_timer(IN WDFTIMER timer) // Packet is old, dispose of it. DEBUG("TIMEOUT (context=%p, packet=%p)", context, packet); - divert_free_packet(packet); + windivert_free_packet(packet); KeAcquireInStackQueuedSpinLock(&context->lock, &lock_handle); } @@ -962,30 +998,31 @@ extern VOID divert_timer(IN WDFTIMER timer) /* * Divert cleanup routine. */ -extern VOID divert_cleanup(IN WDFFILEOBJECT object) +extern VOID windivert_cleanup(IN WDFFILEOBJECT object) { KLOCK_QUEUE_HANDLE lock_handle; PLIST_ENTRY entry; UINT i; - context_t context = divert_context_get(object); + context_t context = windivert_context_get(object); packet_t packet; NTSTATUS status; - DEBUG("CLEANUP: cleaning up divert context (context=%p)", context); + DEBUG("CLEANUP: cleaning up WinDivert context (context=%p)", context); - if (!divert_context_verify(context, DIVERT_CONTEXT_STATE_OPEN)) + if (!windivert_context_verify(context, WINDIVERT_CONTEXT_STATE_OPEN)) { return; } WdfTimerStop(context->timer, TRUE); KeAcquireInStackQueuedSpinLock(&context->lock, &lock_handle); - context->state = DIVERT_CONTEXT_STATE_CLOSING; + context->state = WINDIVERT_CONTEXT_STATE_CLOSING; + KeSetEvent(&context->read_event, IO_NO_INCREMENT, FALSE); while (!IsListEmpty(&context->packet_queue)) { entry = RemoveHeadList(&context->packet_queue); KeReleaseInStackQueuedSpinLock(&lock_handle); packet = CONTAINING_RECORD(entry, struct packet_s, entry); - divert_free_packet(packet); + windivert_free_packet(packet); KeAcquireInStackQueuedSpinLock(&context->lock, &lock_handle); } KeReleaseInStackQueuedSpinLock(&lock_handle); @@ -997,21 +1034,21 @@ extern VOID divert_cleanup(IN WDFFILEOBJECT object) if (!NT_SUCCESS(status)) { DEBUG_ERROR("failed to begin WFP transaction", status); - goto divert_cleanup_exit; + goto windivert_cleanup_exit; } - for (i = 0; i < DIVERT_CONTEXT_MAXLAYERS; i++) + for (i = 0; i < WINDIVERT_CONTEXT_MAXLAYERS; i++) { - if (!context->registered[i]) - { - continue; - } + if (!context->registered[i]) + { + continue; + } status = FwpmFilterDeleteByKey0(context->engine_handle, context->filter_guid+i); if (!NT_SUCCESS(status)) { DEBUG_ERROR("failed delete WFP filter", status); FwpmTransactionAbort0(context->engine_handle); - goto divert_cleanup_exit; + goto windivert_cleanup_exit; } status = FwpmSubLayerDeleteByKey0(context->engine_handle, context->sublayer_guid+i); @@ -1019,19 +1056,19 @@ extern VOID divert_cleanup(IN WDFFILEOBJECT object) { DEBUG_ERROR("failed delete WFP sub-layer", status); FwpmTransactionAbort0(context->engine_handle); - goto divert_cleanup_exit; + goto windivert_cleanup_exit; } } status = FwpmTransactionCommit0(context->engine_handle); if (!NT_SUCCESS(status)) { DEBUG_ERROR("failed to commit WFP transaction", status); - goto divert_cleanup_exit; + goto windivert_cleanup_exit; } -divert_cleanup_exit: +windivert_cleanup_exit: FwpmEngineClose0(context->engine_handle); - for (i = 0; i < DIVERT_CONTEXT_MAXLAYERS; i++) + for (i = 0; i < WINDIVERT_CONTEXT_MAXLAYERS; i++) { if (context->registered[i]) { @@ -1040,31 +1077,34 @@ divert_cleanup_exit: } if (context->filter != NULL) { - ExFreePoolWithTag(context->filter, DIVERT_FILTER_TAG); + ExFreePoolWithTag(context->filter, WINDIVERT_FILTER_TAG); context->filter = NULL; } + KeWaitForSingleObject(context->read_thread, Executive, KernelMode, FALSE, + NULL); + ObDereferenceObject(context->read_thread); } /* - * Divert close routine. + * WinDivert close routine. */ -extern VOID divert_close(IN WDFFILEOBJECT object) +extern VOID windivert_close(IN WDFFILEOBJECT object) { - context_t context = divert_context_get(object); + context_t context = windivert_context_get(object); - DEBUG("CLOSE: closing divert context (context=%p)", context); + DEBUG("CLOSE: closing WinDivert context (context=%p)", context); - if (!divert_context_verify(context, DIVERT_CONTEXT_STATE_CLOSING)) + if (!windivert_context_verify(context, WINDIVERT_CONTEXT_STATE_CLOSING)) { return; } - context->state = DIVERT_CONTEXT_STATE_CLOSED; + context->state = WINDIVERT_CONTEXT_STATE_CLOSED; } /* - * Divert read routine. + * WinDivert read routine. */ -static NTSTATUS divert_read(context_t context, WDFREQUEST request) +static NTSTATUS windivert_read(context_t context, WDFREQUEST request) { NTSTATUS status = STATUS_SUCCESS; @@ -1080,15 +1120,49 @@ static NTSTATUS divert_read(context_t context, WDFREQUEST request) } // Service the read request: - divert_read_service(context); + windivert_read_service(context); return STATUS_SUCCESS; } /* - * Divert read request service. + * Handle windivert_read_service worker. */ -static void divert_read_service(context_t context) +static void windivert_read_service_worker(PVOID context_0) +{ + KLOCK_QUEUE_HANDLE lock_handle; + context_t context = (context_t)context_0; + + /* + * NOTE: We cannot verify the context because we do not know what state + * it is in. + */ + + while (TRUE) + { + KeWaitForSingleObject(&context->read_event, Executive, KernelMode, + FALSE, NULL); + + KeAcquireInStackQueuedSpinLock(&context->lock, &lock_handle); + KeClearEvent(&context->read_event); + if (context->state != WINDIVERT_CONTEXT_STATE_OPEN) + { + break; + } + KeReleaseInStackQueuedSpinLock(&lock_handle); + + // Service reads: + windivert_read_service(context); + } + + KeReleaseInStackQueuedSpinLock(&lock_handle); + PsTerminateSystemThread(STATUS_SUCCESS); +} + +/* + * WinDivert read request service. + */ +static void windivert_read_service(context_t context) { KLOCK_QUEUE_HANDLE lock_handle; WDFREQUEST request; @@ -1099,12 +1173,12 @@ static void divert_read_service(context_t context) NTSTATUS status; packet_t packet; req_context_t req_context; - divert_addr_t addr; + windivert_addr_t addr; - DEBUG("divert_read_service"); + DEBUG("windivert_read_service"); KeAcquireInStackQueuedSpinLock(&context->lock, &lock_handle); - while (context->state == DIVERT_CONTEXT_STATE_OPEN && + while (context->state == WINDIVERT_CONTEXT_STATE_OPEN && !IsListEmpty(&context->packet_queue)) { status = WdfIoQueueRetrieveNextRequest(context->read_queue, &request); @@ -1126,14 +1200,14 @@ static void divert_read_service(context_t context) if (!NT_SUCCESS(status)) { DEBUG_ERROR("failed to retrieve output MDL", status); - goto divert_read_service_complete; + goto windivert_read_service_complete; } dst = MmGetSystemAddressForMdlSafe(dst_mdl, NormalPagePriority); if (dst == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; DEBUG_ERROR("failed to get address of output MDL", status); - goto divert_read_service_complete; + goto windivert_read_service_complete; } dst_len = MmGetMdlByteCount(dst_mdl); src_len = NET_BUFFER_DATA_LENGTH(packet->buffer); @@ -1149,7 +1223,7 @@ static void divert_read_service(context_t context) } // Write the address information. - req_context = divert_req_context_get(request); + req_context = windivert_req_context_get(request); addr = req_context->addr; if (addr != NULL) { @@ -1158,14 +1232,17 @@ static void divert_read_service(context_t context) addr->Direction = packet->direction; } - // Compute the IP/TCP/UDP checksums here if required. - divert_update_checksums(dst, dst_len, packet->ip_checksum, - packet->tcp_checksum, packet->udp_checksum); - + // Compute the IP/TCP/UDP checksums here (if required). + if ((context->flags & WINDIVERT_FLAG_NO_CHECKSUM) == 0) + { + windivert_update_checksums(dst, dst_len, packet->ip_checksum, + packet->tcp_checksum, packet->udp_checksum); + } + status = STATUS_SUCCESS; -divert_read_service_complete: - divert_free_packet(packet); +windivert_read_service_complete: + windivert_free_packet(packet); if (NT_SUCCESS(status)) { WdfRequestCompleteWithInformation(request, status, dst_len); @@ -1180,10 +1257,10 @@ divert_read_service_complete: } /* - * Divert write routine. + * WinDivert write routine. */ -static NTSTATUS divert_write(context_t context, WDFREQUEST request, - divert_addr_t addr) +static NTSTATUS windivert_write(context_t context, WDFREQUEST request, + windivert_addr_t addr) { PMDL mdl = NULL; PVOID data; @@ -1197,25 +1274,25 @@ static NTSTATUS divert_write(context_t context, WDFREQUEST request, DEBUG("WRITE: writing/injecting a packet (context=%p, request=%p)", context, request); - if (!divert_context_verify(context, DIVERT_CONTEXT_STATE_OPEN)) + if (!windivert_context_verify(context, WINDIVERT_CONTEXT_STATE_OPEN)) { status = STATUS_INVALID_DEVICE_STATE; - goto divert_write_exit; + goto windivert_write_exit; } - if (addr->Direction != DIVERT_DIRECTION_INBOUND && - addr->Direction != DIVERT_DIRECTION_OUTBOUND) + if (addr->Direction != WINDIVERT_DIRECTION_INBOUND && + addr->Direction != WINDIVERT_DIRECTION_OUTBOUND) { status = STATUS_INVALID_PARAMETER; DEBUG_ERROR("failed to inject packet; invalid direction", status); - goto divert_write_exit; + goto windivert_write_exit; } status = WdfRequestRetrieveOutputWdmMdl(request, &mdl); if (!NT_SUCCESS(status)) { DEBUG_ERROR("failed to retrieve input MDL", status); - goto divert_write_exit; + goto windivert_write_exit; } data = MmGetSystemAddressForMdlSafe(mdl, NormalPagePriority); @@ -1223,7 +1300,7 @@ static NTSTATUS divert_write(context_t context, WDFREQUEST request, { status = STATUS_INSUFFICIENT_RESOURCES; DEBUG_ERROR("failed to get MDL address", status); - goto divert_write_exit; + goto windivert_write_exit; } data_len = MmGetMdlByteCount(mdl); @@ -1231,7 +1308,7 @@ static NTSTATUS divert_write(context_t context, WDFREQUEST request, { status = STATUS_BUFFER_TOO_SMALL; DEBUG_ERROR("write buffer too small, cannot read ip header", status); - goto divert_write_exit; + goto windivert_write_exit; } ip_header = (struct iphdr *)data; @@ -1246,7 +1323,7 @@ static NTSTATUS divert_write(context_t context, WDFREQUEST request, default: status = STATUS_INVALID_PARAMETER; DEBUG_ERROR("failed to inject packet; not IPv4 nor IPv6", status); - goto divert_write_exit; + goto windivert_write_exit; } status = FwpsAllocateNetBufferAndNetBufferList0(pool_handle, 0, 0, mdl, @@ -1255,31 +1332,31 @@ static NTSTATUS divert_write(context_t context, WDFREQUEST request, { DEBUG_ERROR("failed to create NET_BUFFER_LIST for injected packet", status); - goto divert_write_exit; + goto windivert_write_exit; } handle = (isipv4? inject_handle: injectv6_handle); - if (context->layer == DIVERT_LAYER_NETWORK_FORWARD) + if (context->layer == WINDIVERT_LAYER_NETWORK_FORWARD) { status = FwpsInjectForwardAsync0(handle, (HANDLE)context->priority, 0, (isipv4? AF_INET: AF_INET6), UNSPECIFIED_COMPARTMENT_ID, - addr->IfIdx, buffers, divert_inject_complete, (HANDLE)request); + addr->IfIdx, buffers, windivert_inject_complete, (HANDLE)request); } - else if (addr->Direction == DIVERT_DIRECTION_OUTBOUND) + else if (addr->Direction == WINDIVERT_DIRECTION_OUTBOUND) { status = FwpsInjectNetworkSendAsync0(handle, (HANDLE)context->priority, 0, UNSPECIFIED_COMPARTMENT_ID, buffers, - divert_inject_complete, (HANDLE)request); + windivert_inject_complete, (HANDLE)request); } else { status = FwpsInjectNetworkReceiveAsync0(handle, (HANDLE)context->priority, 0, UNSPECIFIED_COMPARTMENT_ID, - addr->IfIdx, addr->SubIfIdx, buffers, divert_inject_complete, + addr->IfIdx, addr->SubIfIdx, buffers, windivert_inject_complete, (HANDLE)request); } -divert_write_exit: +windivert_write_exit: if (!NT_SUCCESS(status)) { @@ -1294,9 +1371,9 @@ divert_write_exit: } /* - * Divert inject complete routine. + * WinDivert inject complete routine. */ -static void NTAPI divert_inject_complete(VOID *context, +static void NTAPI windivert_inject_complete(VOID *context, NET_BUFFER_LIST *buffers, BOOLEAN dispatch_level) { WDFREQUEST request = (WDFREQUEST)context; @@ -1322,16 +1399,16 @@ static void NTAPI divert_inject_complete(VOID *context, } /* - * Divert caller context preprocessing. + * WinDivert caller context preprocessing. */ -VOID divert_caller_context(IN WDFDEVICE device, IN WDFREQUEST request) +VOID windivert_caller_context(IN WDFDEVICE device, IN WDFREQUEST request) { PCHAR inbuf; size_t inbuflen; WDF_REQUEST_PARAMETERS params; WDFMEMORY memobj; - divert_addr_t addr = NULL; - divert_ioctl_t ioctl; + windivert_addr_t addr = NULL; + windivert_ioctl_t ioctl; WDF_OBJECT_ATTRIBUTES attributes; req_context_t req_context = NULL; NTSTATUS status; @@ -1341,7 +1418,7 @@ VOID divert_caller_context(IN WDFDEVICE device, IN WDFREQUEST request) if (params.Type != WdfRequestTypeDeviceControl) { - goto divert_caller_context_exit; + goto windivert_caller_context_exit; } // Get and verify the input buffer. @@ -1349,24 +1426,24 @@ VOID divert_caller_context(IN WDFDEVICE device, IN WDFREQUEST request) if (!NT_SUCCESS(status)) { DEBUG_ERROR("failed to retrieve input buffer", status); - goto divert_caller_context_error; + goto windivert_caller_context_error; } - if (inbuflen != sizeof(struct divert_ioctl_s)) + if (inbuflen != sizeof(struct windivert_ioctl_s)) { status = STATUS_INVALID_DEVICE_REQUEST; DEBUG_ERROR("input buffer not an ioctl message header", status); - goto divert_caller_context_error; + goto windivert_caller_context_error; } - ioctl = (divert_ioctl_t)inbuf; - if (ioctl->version != DIVERT_IOCTL_VERSION || - ioctl->magic != DIVERT_IOCTL_MAGIC) + ioctl = (windivert_ioctl_t)inbuf; + if (ioctl->version != WINDIVERT_IOCTL_VERSION || + ioctl->magic != WINDIVERT_IOCTL_MAGIC) { status = STATUS_INVALID_DEVICE_REQUEST; DEBUG_ERROR("input buffer contained a bad ioctl message header", status); - goto divert_caller_context_error; + goto windivert_caller_context_error; } // Probe and lock user buffers here (if required). @@ -1375,64 +1452,64 @@ VOID divert_caller_context(IN WDFDEVICE device, IN WDFREQUEST request) if (!NT_SUCCESS(status)) { DEBUG_ERROR("failed to allocate request context for ioctl", status); - goto divert_caller_context_error; + goto windivert_caller_context_error; } req_context->addr = NULL; if (ioctl->arg == (UINT64)NULL) { - goto divert_caller_context_exit; + goto windivert_caller_context_exit; } switch (params.Parameters.DeviceIoControl.IoControlCode) { - case IOCTL_DIVERT_RECV: + case IOCTL_WINDIVERT_RECV: status = WdfRequestProbeAndLockUserBufferForWrite(request, - (PVOID)ioctl->arg, sizeof(struct divert_addr_s), &memobj); + (PVOID)ioctl->arg, sizeof(struct windivert_addr_s), &memobj); if (!NT_SUCCESS(status)) { DEBUG_ERROR("invalid arg pointer for RECV ioctl", status); - goto divert_caller_context_error; + goto windivert_caller_context_error; } - addr = (divert_addr_t)WdfMemoryGetBuffer(memobj, NULL); + addr = (windivert_addr_t)WdfMemoryGetBuffer(memobj, NULL); break; - case IOCTL_DIVERT_SEND: + case IOCTL_WINDIVERT_SEND: status = WdfRequestProbeAndLockUserBufferForRead(request, - (PVOID)ioctl->arg, sizeof(struct divert_addr_s), &memobj); + (PVOID)ioctl->arg, sizeof(struct windivert_addr_s), &memobj); if (!NT_SUCCESS(status)) { DEBUG_ERROR("invalid arg pointer for SEND ioctl", status); - goto divert_caller_context_error; + goto windivert_caller_context_error; } - addr = (divert_addr_t)WdfMemoryGetBuffer(memobj, NULL); + addr = (windivert_addr_t)WdfMemoryGetBuffer(memobj, NULL); break; - case IOCTL_DIVERT_START_FILTER: + case IOCTL_WINDIVERT_START_FILTER: status = STATUS_INVALID_DEVICE_REQUEST; DEBUG_ERROR("arg pointer is non-NULL for SET_FILTER ioctl", status); - goto divert_caller_context_error; + goto windivert_caller_context_error; - case IOCTL_DIVERT_SET_LAYER: - case IOCTL_DIVERT_SET_PRIORITY: - case IOCTL_DIVERT_SET_FLAGS: - case IOCTL_DIVERT_SET_PARAM: - case IOCTL_DIVERT_GET_PARAM: + case IOCTL_WINDIVERT_SET_LAYER: + case IOCTL_WINDIVERT_SET_PRIORITY: + case IOCTL_WINDIVERT_SET_FLAGS: + case IOCTL_WINDIVERT_SET_PARAM: + case IOCTL_WINDIVERT_GET_PARAM: break; default: status = STATUS_INVALID_DEVICE_REQUEST; DEBUG_ERROR("failed to complete I/O control; invalid request", status); - goto divert_caller_context_error; + goto windivert_caller_context_error; } req_context->addr = addr; -divert_caller_context_exit: +windivert_caller_context_exit: status = WdfDeviceEnqueueRequest(device, request); -divert_caller_context_error: +windivert_caller_context_error: if (!NT_SUCCESS(status)) { @@ -1442,28 +1519,29 @@ divert_caller_context_error: } /* - * Divert I/O control. + * WinDivert I/O control. */ -extern VOID divert_ioctl(IN WDFQUEUE queue, IN WDFREQUEST request, +extern VOID windivert_ioctl(IN WDFQUEUE queue, IN WDFREQUEST request, IN size_t out_length, IN size_t in_length, IN ULONG code) { PCHAR inbuf, outbuf; size_t inbuflen, outbuflen, filter_len; - divert_ioctl_t ioctl; - divert_ioctl_filter_t filter; - divert_addr_t addr; + windivert_ioctl_t ioctl; + windivert_ioctl_filter_t filter; + windivert_addr_t addr; req_context_t req_context; NTSTATUS status = STATUS_SUCCESS; - context_t context = divert_context_get(WdfRequestGetFileObject(request)); + context_t context = + windivert_context_get(WdfRequestGetFileObject(request)); UINT64 value, *valptr; UNREFERENCED_PARAMETER(queue); DEBUG("IOCTL: I/O control request (context=%p)", context); - if (!divert_context_verify(context, DIVERT_CONTEXT_STATE_OPEN)) + if (!windivert_context_verify(context, WINDIVERT_CONTEXT_STATE_OPEN)) { status = STATUS_INVALID_DEVICE_STATE; - goto divert_ioctl_exit; + goto windivert_ioctl_exit; } // Get the buffers and do sanity checks. @@ -1471,17 +1549,17 @@ extern VOID divert_ioctl(IN WDFQUEUE queue, IN WDFREQUEST request, if (!NT_SUCCESS(status)) { DEBUG_ERROR("failed to retrieve input buffer", status); - goto divert_ioctl_exit; + goto windivert_ioctl_exit; } switch (code) { - case IOCTL_DIVERT_START_FILTER: case IOCTL_DIVERT_GET_PARAM: + case IOCTL_WINDIVERT_START_FILTER: case IOCTL_WINDIVERT_GET_PARAM: status = WdfRequestRetrieveOutputBuffer(request, 0, &outbuf, &outbuflen); if (!NT_SUCCESS(status)) { DEBUG_ERROR("failed to retrieve output buffer", status); - goto divert_ioctl_exit; + goto windivert_ioctl_exit; } break; default: @@ -1493,26 +1571,26 @@ extern VOID divert_ioctl(IN WDFQUEUE queue, IN WDFREQUEST request, // Handle the ioctl: switch (code) { - case IOCTL_DIVERT_RECV: - status = divert_read(context, request); + case IOCTL_WINDIVERT_RECV: + status = windivert_read(context, request); if (NT_SUCCESS(status)) { return; } break; - case IOCTL_DIVERT_SEND: + case IOCTL_WINDIVERT_SEND: - req_context = divert_req_context_get(request); + req_context = windivert_req_context_get(request); addr = req_context->addr; - status = divert_write(context, request, addr); + status = windivert_write(context, request, addr); if (NT_SUCCESS(status)) { return; } break; - case IOCTL_DIVERT_START_FILTER: + case IOCTL_WINDIVERT_START_FILTER: { BOOL is_inbound, is_outbound, is_ipv4, is_ipv6; @@ -1520,35 +1598,34 @@ extern VOID divert_ioctl(IN WDFQUEUE queue, IN WDFREQUEST request, { status = STATUS_INVALID_DEVICE_REQUEST; DEBUG_ERROR("duplicate SET_FILTER ioctl", status); - goto divert_ioctl_exit; + goto windivert_ioctl_exit; } context->layer = context->layer_0; context->flags = context->flags_0; context->priority = context->priority_0; - filter = (divert_ioctl_filter_t)outbuf; + filter = (windivert_ioctl_filter_t)outbuf; filter_len = outbuflen; - context->filter = divert_filter_compile(filter, filter_len); + context->filter = windivert_filter_compile(filter, filter_len); if (context->filter == NULL) { status = STATUS_INVALID_DEVICE_REQUEST; DEBUG_ERROR("failed to compile filter", status); - goto divert_ioctl_exit; + goto windivert_ioctl_exit; } - if ((context->flags & DIVERT_FLAG_SNIFF) != 0 && - (context->flags & DIVERT_FLAG_DROP) != 0) + if ((context->flags & WINDIVERT_FLAG_PASSTHRU) != 0) { // Passthru mode. is_inbound = is_outbound = is_ipv4 = is_ipv6 = FALSE; } else { - divert_filter_analyze(context->filter, &is_inbound, + windivert_filter_analyze(context->filter, &is_inbound, &is_outbound, &is_ipv4, &is_ipv6); } - status = divert_register_callouts(context, is_inbound, + status = windivert_register_callouts(context, is_inbound, is_outbound, is_ipv4, is_ipv6); // Start the timer. @@ -1558,65 +1635,65 @@ extern VOID divert_ioctl(IN WDFQUEUE queue, IN WDFREQUEST request, break; } - case IOCTL_DIVERT_SET_LAYER: - ioctl = (divert_ioctl_t)inbuf; - if (ioctl->arg > DIVERT_LAYER_MAX) + case IOCTL_WINDIVERT_SET_LAYER: + ioctl = (windivert_ioctl_t)inbuf; + if (ioctl->arg > WINDIVERT_LAYER_MAX) { status = STATUS_INVALID_DEVICE_REQUEST; DEBUG_ERROR("failed to set layer; value too big", status); - goto divert_ioctl_exit; + goto windivert_ioctl_exit; } context->layer_0 = (UINT8)ioctl->arg; break; - case IOCTL_DIVERT_SET_PRIORITY: - ioctl = (divert_ioctl_t)inbuf; - if (ioctl->arg > DIVERT_PRIORITY_MAX) + case IOCTL_WINDIVERT_SET_PRIORITY: + ioctl = (windivert_ioctl_t)inbuf; + if (ioctl->arg > WINDIVERT_PRIORITY_MAX) { status = STATUS_INVALID_DEVICE_REQUEST; DEBUG_ERROR("failed to set priority; value too big", status); - goto divert_ioctl_exit; + goto windivert_ioctl_exit; } context->priority_0 = (UINT16)ioctl->arg; break; - case IOCTL_DIVERT_SET_FLAGS: - ioctl = (divert_ioctl_t)inbuf; - if (ioctl->arg > DIVERT_FLAGS_MAX) + case IOCTL_WINDIVERT_SET_FLAGS: + ioctl = (windivert_ioctl_t)inbuf; + if (!WINDIVERT_FLAGS_VALID(ioctl->arg)) { status = STATUS_INVALID_DEVICE_REQUEST; DEBUG_ERROR("failed to set flags; invalid flags value", status); - goto divert_ioctl_exit; + goto windivert_ioctl_exit; } context->flags_0 = ioctl->arg; break; - case IOCTL_DIVERT_SET_PARAM: - ioctl = (divert_ioctl_t)inbuf; + case IOCTL_WINDIVERT_SET_PARAM: + ioctl = (windivert_ioctl_t)inbuf; value = ioctl->arg; - switch ((DIVERT_PARAM)ioctl->arg8) + switch ((WINDIVERT_PARAM)ioctl->arg8) { - case DIVERT_PARAM_QUEUE_LEN: - if (value < DIVERT_PARAM_QUEUE_LEN_MIN || - value > DIVERT_PARAM_QUEUE_LEN_MAX) + case WINDIVERT_PARAM_QUEUE_LEN: + if (value < WINDIVERT_PARAM_QUEUE_LEN_MIN || + value > WINDIVERT_PARAM_QUEUE_LEN_MAX) { status = STATUS_INVALID_DEVICE_REQUEST; DEBUG_ERROR("failed to set queue length; invalid " "value", status); - goto divert_ioctl_exit; + goto windivert_ioctl_exit; } context->packet_queue_maxlength = (ULONG)value; break; - case DIVERT_PARAM_QUEUE_TIME: - if (value < DIVERT_PARAM_QUEUE_TIME_MIN || - value > DIVERT_PARAM_QUEUE_TIME_MAX) + case WINDIVERT_PARAM_QUEUE_TIME: + if (value < WINDIVERT_PARAM_QUEUE_TIME_MIN || + value > WINDIVERT_PARAM_QUEUE_TIME_MAX) { status = STATUS_INVALID_DEVICE_REQUEST; DEBUG_ERROR("failed to set queue time; invalid " "value", status); - goto divert_ioctl_exit; + goto windivert_ioctl_exit; } context->timer_timeout = (UINT)value; break; @@ -1625,33 +1702,33 @@ extern VOID divert_ioctl(IN WDFQUEUE queue, IN WDFREQUEST request, status = STATUS_INVALID_DEVICE_REQUEST; DEBUG_ERROR("failed to set parameter; invalid parameter", status); - goto divert_ioctl_exit; + goto windivert_ioctl_exit; } break; - case IOCTL_DIVERT_GET_PARAM: - ioctl = (divert_ioctl_t)inbuf; + case IOCTL_WINDIVERT_GET_PARAM: + ioctl = (windivert_ioctl_t)inbuf; if (outbuflen != sizeof(UINT64)) { status = STATUS_INVALID_DEVICE_REQUEST; DEBUG_ERROR("failed to get parameter; invalid output " "buffer size", status); - goto divert_ioctl_exit; + goto windivert_ioctl_exit; } valptr = (UINT64 *)outbuf; - switch ((DIVERT_PARAM)ioctl->arg8) + switch ((WINDIVERT_PARAM)ioctl->arg8) { - case DIVERT_PARAM_QUEUE_LEN: + case WINDIVERT_PARAM_QUEUE_LEN: *valptr = context->packet_queue_maxlength; break; - case DIVERT_PARAM_QUEUE_TIME: + case WINDIVERT_PARAM_QUEUE_TIME: *valptr = context->timer_timeout; break; default: status = STATUS_INVALID_DEVICE_REQUEST; DEBUG_ERROR("failed to get parameter; invalid parameter", status); - goto divert_ioctl_exit; + goto windivert_ioctl_exit; } break; @@ -1662,14 +1739,14 @@ extern VOID divert_ioctl(IN WDFQUEUE queue, IN WDFREQUEST request, break; } -divert_ioctl_exit: +windivert_ioctl_exit: WdfRequestComplete(request, status); } /* - * Divert notify callout. + * WinDivert notify callout. */ -static NTSTATUS divert_notify_callout(IN FWPS_CALLOUT_NOTIFY_TYPE type, +static NTSTATUS windivert_notify_callout(IN FWPS_CALLOUT_NOTIFY_TYPE type, IN const GUID *filter_key, IN const FWPS_FILTER0 *filter) { UNREFERENCED_PARAMETER(type); @@ -1679,15 +1756,15 @@ static NTSTATUS divert_notify_callout(IN FWPS_CALLOUT_NOTIFY_TYPE type, } /* - * Divert classify outbound IPv4 callout. + * WinDivert classify outbound IPv4 callout. */ -static void divert_classify_outbound_network_v4_callout( +static void windivert_classify_outbound_network_v4_callout( IN const FWPS_INCOMING_VALUES0 *fixed_vals, IN const FWPS_INCOMING_METADATA_VALUES0 *meta_vals, IN OUT void *data, const FWPS_FILTER0 *filter, IN UINT64 flow_context, OUT FWPS_CLASSIFY_OUT0 *result) { - divert_classify_callout(DIVERT_DIRECTION_OUTBOUND, + windivert_classify_callout(WINDIVERT_DIRECTION_OUTBOUND, fixed_vals->incomingValue[ FWPS_FIELD_OUTBOUND_IPPACKET_V4_INTERFACE_INDEX].value.uint32, fixed_vals->incomingValue[ @@ -1696,15 +1773,15 @@ static void divert_classify_outbound_network_v4_callout( } /* - * Divert classify outbound IPv6 callout. + * WinDivert classify outbound IPv6 callout. */ -static void divert_classify_outbound_network_v6_callout( +static void windivert_classify_outbound_network_v6_callout( IN const FWPS_INCOMING_VALUES0 *fixed_vals, IN const FWPS_INCOMING_METADATA_VALUES0 *meta_vals, IN OUT void *data, const FWPS_FILTER0 *filter, IN UINT64 flow_context, OUT FWPS_CLASSIFY_OUT0 *result) { - divert_classify_callout(DIVERT_DIRECTION_OUTBOUND, + windivert_classify_callout(WINDIVERT_DIRECTION_OUTBOUND, fixed_vals->incomingValue[ FWPS_FIELD_OUTBOUND_IPPACKET_V6_INTERFACE_INDEX].value.uint32, fixed_vals->incomingValue[ @@ -1713,9 +1790,9 @@ static void divert_classify_outbound_network_v6_callout( } /* - * Divert classify inbound IPv4 callout. + * WinDivert classify inbound IPv4 callout. */ -static void divert_classify_inbound_network_v4_callout( +static void windivert_classify_inbound_network_v4_callout( IN const FWPS_INCOMING_VALUES0 *fixed_vals, IN const FWPS_INCOMING_METADATA_VALUES0 *meta_vals, IN OUT void *data, const FWPS_FILTER0 *filter, IN UINT64 flow_context, @@ -1738,7 +1815,7 @@ static void divert_classify_inbound_network_v4_callout( result->actionType = FWP_ACTION_PERMIT; return; } - divert_classify_callout(DIVERT_DIRECTION_INBOUND, + windivert_classify_callout(WINDIVERT_DIRECTION_INBOUND, fixed_vals->incomingValue[ FWPS_FIELD_INBOUND_IPPACKET_V4_INTERFACE_INDEX].value.uint32, fixed_vals->incomingValue[ @@ -1752,9 +1829,9 @@ static void divert_classify_inbound_network_v4_callout( } /* - * Divert classify inbound IPv6 callout. + * WinDivert classify inbound IPv6 callout. */ -static void divert_classify_inbound_network_v6_callout( +static void windivert_classify_inbound_network_v6_callout( IN const FWPS_INCOMING_VALUES0 *fixed_vals, IN const FWPS_INCOMING_METADATA_VALUES0 *meta_vals, IN OUT void *data, const FWPS_FILTER0 *filter, IN UINT64 flow_context, @@ -1777,7 +1854,7 @@ static void divert_classify_inbound_network_v6_callout( result->actionType = FWP_ACTION_PERMIT; return; } - divert_classify_callout(DIVERT_DIRECTION_INBOUND, + windivert_classify_callout(WINDIVERT_DIRECTION_INBOUND, fixed_vals->incomingValue[ FWPS_FIELD_INBOUND_IPPACKET_V6_INTERFACE_INDEX].value.uint32, fixed_vals->incomingValue[ @@ -1791,30 +1868,30 @@ static void divert_classify_inbound_network_v6_callout( } /* - * Divert classify forward IPv4 callout. + * WinDivert classify forward IPv4 callout. */ -static void divert_classify_forward_network_v4_callout( +static void windivert_classify_forward_network_v4_callout( IN const FWPS_INCOMING_VALUES0 *fixed_vals, IN const FWPS_INCOMING_METADATA_VALUES0 *meta_vals, IN OUT void *data, const FWPS_FILTER0 *filter, IN UINT64 flow_context, OUT FWPS_CLASSIFY_OUT0 *result) { - divert_classify_callout(DIVERT_DIRECTION_OUTBOUND, + windivert_classify_callout(WINDIVERT_DIRECTION_OUTBOUND, fixed_vals->incomingValue[ FWPS_FIELD_IPFORWARD_V4_DESTINATION_INTERFACE_INDEX].value.uint32, 0, TRUE, fixed_vals, meta_vals, data, filter, flow_context, result); } /* - * Divert classify forward IPv6 callout. + * WinDivert classify forward IPv6 callout. */ -static void divert_classify_forward_network_v6_callout( +static void windivert_classify_forward_network_v6_callout( IN const FWPS_INCOMING_VALUES0 *fixed_vals, IN const FWPS_INCOMING_METADATA_VALUES0 *meta_vals, IN OUT void *data, const FWPS_FILTER0 *filter, IN UINT64 flow_context, OUT FWPS_CLASSIFY_OUT0 *result) { - divert_classify_callout(DIVERT_DIRECTION_OUTBOUND, + windivert_classify_callout(WINDIVERT_DIRECTION_OUTBOUND, fixed_vals->incomingValue[ FWPS_FIELD_IPFORWARD_V6_DESTINATION_INTERFACE_INDEX].value.uint32, 0, FALSE, fixed_vals, meta_vals, data, filter, flow_context, result); @@ -1822,9 +1899,9 @@ static void divert_classify_forward_network_v6_callout( /* - * Divert classify callout. + * WinDivert classify callout. */ -static void divert_classify_callout(IN UINT8 direction, IN UINT32 if_idx, +static void windivert_classify_callout(IN UINT8 direction, IN UINT32 if_idx, IN UINT32 sub_if_idx, IN BOOL isipv4, IN const FWPS_INCOMING_VALUES0 *fixed_vals, IN const FWPS_INCOMING_METADATA_VALUES0 *meta_vals, IN OUT void *data, @@ -1858,7 +1935,8 @@ static void divert_classify_callout(IN UINT8 direction, IN UINT32 if_idx, packet_state = FwpsQueryPacketInjectionState0(injectv6_handle, buffers, &packet_context); } - if (!divert_context_verify(context, DIVERT_CONTEXT_STATE_OPEN)) + if (!windivert_context_verify(context, WINDIVERT_CONTEXT_STATE_OPEN) || + (context->flags & WINDIVERT_FLAG_PASSTHRU) != 0) { result->actionType = FWP_ACTION_PERMIT; return; @@ -1890,11 +1968,11 @@ static void divert_classify_callout(IN UINT8 direction, IN UINT32 if_idx, // Find the first NET_BUFFER we need to queue: buffers_fst = buffers; - outbound = (direction == DIVERT_DIRECTION_OUTBOUND); + outbound = (direction == WINDIVERT_DIRECTION_OUTBOUND); do { buffer = NET_BUFFER_LIST_FIRST_NB(buffers_fst); - if (divert_filter(buffer, if_idx, sub_if_idx, outbound, + if (windivert_filter(buffer, if_idx, sub_if_idx, outbound, context->filter)) { break; @@ -1910,17 +1988,17 @@ static void divert_classify_callout(IN UINT8 direction, IN UINT32 if_idx, return; } - if ((context->flags & DIVERT_FLAG_SNIFF) == 0) + if ((context->flags & WINDIVERT_FLAG_SNIFF) == 0) { // Re-inject all packets up to 'buffers_fst' buffers_itr = buffers; while (buffers_itr != buffers_fst) { buffer = NET_BUFFER_LIST_FIRST_NB(buffers_itr); - if (!divert_reinject_packet(context, direction, isipv4, if_idx, + if (!windivert_reinject_packet(context, direction, isipv4, if_idx, sub_if_idx, priority, buffers, buffer)) { - goto divert_classify_callout_exit; + goto windivert_classify_callout_exit; } buffers_itr = NET_BUFFER_LIST_NEXT_NBL(buffers_itr); } @@ -1932,10 +2010,10 @@ static void divert_classify_callout(IN UINT8 direction, IN UINT32 if_idx, // Queue buffers_itr = buffers_fst, which matched our filter. buffer = NET_BUFFER_LIST_FIRST_NB(buffers_itr); - if (!divert_queue_packet(context, buffers, buffer, direction, if_idx, + if (!windivert_queue_packet(context, buffers, buffer, direction, if_idx, sub_if_idx)) { - goto divert_classify_callout_exit; + goto windivert_classify_callout_exit; } buffers_itr = NET_BUFFER_LIST_NEXT_NBL(buffers_itr); @@ -1943,34 +2021,34 @@ static void divert_classify_callout(IN UINT8 direction, IN UINT32 if_idx, while (buffers_itr != NULL) { buffer = NET_BUFFER_LIST_FIRST_NB(buffers_itr); - if (divert_filter(buffer, if_idx, sub_if_idx, outbound, + if (windivert_filter(buffer, if_idx, sub_if_idx, outbound, context->filter)) { - if (!divert_queue_packet(context, buffers, buffer, direction, + if (!windivert_queue_packet(context, buffers, buffer, direction, if_idx, sub_if_idx)) { - goto divert_classify_callout_exit; + goto windivert_classify_callout_exit; } } - else if ((context->flags & DIVERT_FLAG_SNIFF) == 0) + else if ((context->flags & WINDIVERT_FLAG_SNIFF) == 0) { - if (!divert_reinject_packet(context, direction, isipv4, if_idx, + if (!windivert_reinject_packet(context, direction, isipv4, if_idx, sub_if_idx, priority, buffers, buffer)) { - goto divert_classify_callout_exit; + goto windivert_classify_callout_exit; } } } // Since new packets have been queued, service any read. - if ((context->flags & DIVERT_FLAG_DROP) == 0) + if ((context->flags & WINDIVERT_FLAG_DROP) == 0) { - divert_read_service(context); + KeSetEvent(&context->read_event, IO_NO_INCREMENT, FALSE); } -divert_classify_callout_exit: +windivert_classify_callout_exit: - if ((context->flags & DIVERT_FLAG_SNIFF) != 0) + if ((context->flags & WINDIVERT_FLAG_SNIFF) != 0) { result->actionType = FWP_ACTION_PERMIT; } @@ -1985,7 +2063,7 @@ divert_classify_callout_exit: /* * Queue a NET_BUFFER. */ -static BOOL divert_queue_packet(context_t context, PNET_BUFFER_LIST buffers, +static BOOL windivert_queue_packet(context_t context, PNET_BUFFER_LIST buffers, PNET_BUFFER buffer, UINT8 direction, UINT32 if_idx, UINT32 sub_if_idx) { KLOCK_QUEUE_HANDLE lock_handle; @@ -1994,19 +2072,19 @@ static BOOL divert_queue_packet(context_t context, PNET_BUFFER_LIST buffers, packet_t packet; NTSTATUS status; - if ((context->flags & DIVERT_FLAG_DROP) != 0) + if ((context->flags & WINDIVERT_FLAG_DROP) != 0) { return TRUE; } - packet = (packet_t)ExAllocatePoolWithTag(NonPagedPool, DIVERT_PACKET_SIZE, - DIVERT_PACKET_TAG); + packet = (packet_t)ExAllocatePoolWithTag(NonPagedPool, + WINDIVERT_PACKET_SIZE, WINDIVERT_PACKET_TAG); if (packet == NULL) { return FALSE; } - if ((context->flags & DIVERT_FLAG_SNIFF) != 0) + if ((context->flags & WINDIVERT_FLAG_SNIFF) != 0) { // Clone the buffer status = FwpsAllocateNetBufferAndNetBufferList0( @@ -2015,7 +2093,7 @@ static BOOL divert_queue_packet(context_t context, PNET_BUFFER_LIST buffers, &packet->clone); if (!NT_SUCCESS(status)) { - ExFreePoolWithTag(packet, DIVERT_PACKET_TAG); + ExFreePoolWithTag(packet, WINDIVERT_PACKET_TAG); return FALSE; } buffer = NET_BUFFER_LIST_FIRST_NB(packet->clone); @@ -2032,7 +2110,7 @@ static BOOL divert_queue_packet(context_t context, PNET_BUFFER_LIST buffers, packet->direction = direction; packet->if_idx = if_idx; packet->sub_if_idx = sub_if_idx; - if (direction == DIVERT_DIRECTION_OUTBOUND) + if (direction == WINDIVERT_DIRECTION_OUTBOUND) { // IPv4 Checksum is not calculated yet packet->ip_checksum = TRUE; @@ -2049,11 +2127,11 @@ static BOOL divert_queue_packet(context_t context, PNET_BUFFER_LIST buffers, entry = &packet->entry; FwpsReferenceNetBufferList0(buffers, FALSE); KeAcquireInStackQueuedSpinLock(&context->lock, &lock_handle); - if (context->state != DIVERT_CONTEXT_STATE_OPEN) + if (context->state != WINDIVERT_CONTEXT_STATE_OPEN) { // We are no longer open KeReleaseInStackQueuedSpinLock(&lock_handle); - divert_free_packet(packet); + windivert_free_packet(packet); return FALSE; } InsertTailList(&context->packet_queue, entry); @@ -2070,7 +2148,7 @@ static BOOL divert_queue_packet(context_t context, PNET_BUFFER_LIST buffers, // Queue is full; 'entry' contains a dropped packet. DEBUG("DROP: packet queue is full, dropping packet"); packet = CONTAINING_RECORD(entry, struct packet_s, entry); - divert_free_packet(packet); + windivert_free_packet(packet); } DEBUG("PACKET: diverting packet (packet=%p)", packet); @@ -2080,20 +2158,20 @@ static BOOL divert_queue_packet(context_t context, PNET_BUFFER_LIST buffers, /* * Free a packet. */ -static void divert_free_packet(packet_t packet) +static void windivert_free_packet(packet_t packet) { FwpsDereferenceNetBufferList0(packet->buffers, FALSE); if (packet->clone != NULL) { FwpsFreeNetBufferList0(packet->clone); } - ExFreePoolWithTag(packet, DIVERT_PACKET_TAG); + ExFreePoolWithTag(packet, WINDIVERT_PACKET_TAG); } /* * Re-inject a NET_BUFFER. */ -static BOOL divert_reinject_packet(context_t context, UINT8 direction, +static BOOL windivert_reinject_packet(context_t context, UINT8 direction, BOOL isipv4, UINT32 if_idx, UINT32 sub_if_idx, UINT32 priority, PNET_BUFFER_LIST buffers, PNET_BUFFER buffer) { @@ -2111,17 +2189,17 @@ static BOOL divert_reinject_packet(context_t context, UINT8 direction, } FwpsReferenceNetBufferList0(buffers, FALSE); handle = (isipv4? inject_handle: injectv6_handle); - if (context->layer == DIVERT_LAYER_NETWORK_FORWARD) + if (context->layer == WINDIVERT_LAYER_NETWORK_FORWARD) { status = FwpsInjectForwardAsync0(handle, (HANDLE)priority, 0, (isipv4? AF_INET: AF_INET6), UNSPECIFIED_COMPARTMENT_ID, - if_idx, buffers_cpy, divert_reinject_complete, (HANDLE)buffers); + if_idx, buffers_cpy, windivert_reinject_complete, (HANDLE)buffers); } - else if (direction == DIVERT_DIRECTION_OUTBOUND) + else if (direction == WINDIVERT_DIRECTION_OUTBOUND) { status = FwpsInjectNetworkSendAsync0(handle, (HANDLE)priority, 0, - UNSPECIFIED_COMPARTMENT_ID, buffers_cpy, divert_reinject_complete, - (HANDLE)buffers); + UNSPECIFIED_COMPARTMENT_ID, buffers_cpy, + windivert_reinject_complete, (HANDLE)buffers); } else { @@ -2129,7 +2207,7 @@ static BOOL divert_reinject_packet(context_t context, UINT8 direction, // ever contain one packet. We keep for completeness. status = FwpsInjectNetworkReceiveAsync0(handle, (HANDLE)priority, 0, UNSPECIFIED_COMPARTMENT_ID, if_idx, sub_if_idx, buffers_cpy, - divert_reinject_complete, (HANDLE)buffers); + windivert_reinject_complete, (HANDLE)buffers); } if (!NT_SUCCESS(status)) { @@ -2141,9 +2219,9 @@ static BOOL divert_reinject_packet(context_t context, UINT8 direction, } /* - * Divert (re)inject complete. + * WinDivert (re)inject complete. */ -static void NTAPI divert_reinject_complete(VOID *context, +static void NTAPI windivert_reinject_complete(VOID *context, NET_BUFFER_LIST *buffers_cpy, BOOLEAN dispatch_level) { PNET_BUFFER_LIST buffers; @@ -2157,7 +2235,7 @@ static void NTAPI divert_reinject_complete(VOID *context, /* * Generic checksum calculation. */ -static UINT16 divert_checksum(const void *pseudo_header, +static UINT16 windivert_checksum(const void *pseudo_header, size_t pseudo_header_len, const void *data, size_t len) { register const UINT16 *data16 = (const UINT16 *)pseudo_header; @@ -2193,7 +2271,7 @@ static UINT16 divert_checksum(const void *pseudo_header, * Given a well-formed packet, update the IP and/or TCP/UDP checksums if * required. */ -static void divert_update_checksums(void *header, size_t len, +static void windivert_update_checksums(void *header, size_t len, BOOL update_ip, BOOL update_tcp, BOOL update_udp) { struct @@ -2236,7 +2314,7 @@ static void divert_update_checksums(void *header, size_t len, if (update_ip) { ip_header->Checksum = 0; - ip_header->Checksum = divert_checksum(NULL, 0, ip_header, + ip_header->Checksum = windivert_checksum(NULL, 0, ip_header, ip_header_len); } @@ -2278,7 +2356,7 @@ static void divert_update_checksums(void *header, size_t len, pseudo_header.Protocol = ip_header->Protocol; pseudo_header.TransLength = RtlUshortByteSwap((UINT16)trans_len); *trans_check_ptr = 0x0; - sum = divert_checksum(&pseudo_header, sizeof(pseudo_header), + sum = windivert_checksum(&pseudo_header, sizeof(pseudo_header), trans_header, trans_len); if (sum == 0 && ip_header->Protocol == IPPROTO_UDP) { @@ -2293,8 +2371,8 @@ static void divert_update_checksums(void *header, size_t len, /* * Checks if the given packet is of interest. */ -static BOOL divert_filter(PNET_BUFFER buffer, UINT32 if_idx, UINT32 sub_if_idx, - BOOL outbound, filter_t filter) +static BOOL windivert_filter(PNET_BUFFER buffer, UINT32 if_idx, + UINT32 sub_if_idx, BOOL outbound, filter_t filter) { // Buffer contains enough space for a full size iphdr and tcphdr/udphdr // (without options) @@ -2400,7 +2478,7 @@ static BOOL divert_filter(PNET_BUFFER buffer, UINT32 if_idx, UINT32 sub_if_idx, // Execute the filter: ip = 0; - ttl = DIVERT_FILTER_MAXLEN+1; // Additional safety + ttl = WINDIVERT_FILTER_MAXLEN+1; // Additional safety while (ttl-- != 0) { BOOL result; @@ -2410,25 +2488,25 @@ static BOOL divert_filter(PNET_BUFFER buffer, UINT32 if_idx, UINT32 sub_if_idx, field[3] = 0; switch (filter[ip].protocol) { - case DIVERT_FILTER_PROTOCOL_NONE: + case WINDIVERT_FILTER_PROTOCOL_NONE: result = TRUE; break; - case DIVERT_FILTER_PROTOCOL_IP: + case WINDIVERT_FILTER_PROTOCOL_IP: result = (ip_header != NULL); break; - case DIVERT_FILTER_PROTOCOL_IPV6: + case WINDIVERT_FILTER_PROTOCOL_IPV6: result = (ipv6_header != NULL); break; - case DIVERT_FILTER_PROTOCOL_ICMP: + case WINDIVERT_FILTER_PROTOCOL_ICMP: result = (icmp_header != NULL); break; - case DIVERT_FILTER_PROTOCOL_ICMPV6: + case WINDIVERT_FILTER_PROTOCOL_ICMPV6: result = (icmpv6_header != NULL); break; - case DIVERT_FILTER_PROTOCOL_TCP: + case WINDIVERT_FILTER_PROTOCOL_TCP: result = (tcp_header != NULL); break; - case DIVERT_FILTER_PROTOCOL_UDP: + case WINDIVERT_FILTER_PROTOCOL_UDP: result = (udp_header != NULL); break; default: @@ -2439,93 +2517,93 @@ static BOOL divert_filter(PNET_BUFFER buffer, UINT32 if_idx, UINT32 sub_if_idx, { switch (filter[ip].field) { - case DIVERT_FILTER_FIELD_ZERO: + case WINDIVERT_FILTER_FIELD_ZERO: field[0] = 0; break; - case DIVERT_FILTER_FIELD_INBOUND: + case WINDIVERT_FILTER_FIELD_INBOUND: field[0] = (UINT32)(!outbound); break; - case DIVERT_FILTER_FIELD_OUTBOUND: + case WINDIVERT_FILTER_FIELD_OUTBOUND: field[0] = (UINT32)outbound; break; - case DIVERT_FILTER_FIELD_IFIDX: + case WINDIVERT_FILTER_FIELD_IFIDX: field[0] = (UINT32)if_idx; break; - case DIVERT_FILTER_FIELD_SUBIFIDX: + case WINDIVERT_FILTER_FIELD_SUBIFIDX: field[0] = (UINT32)sub_if_idx; break; - case DIVERT_FILTER_FIELD_IP: + case WINDIVERT_FILTER_FIELD_IP: field[0] = (UINT32)(ip_header != NULL); break; - case DIVERT_FILTER_FIELD_IPV6: + case WINDIVERT_FILTER_FIELD_IPV6: field[0] = (UINT32)(ipv6_header != NULL); break; - case DIVERT_FILTER_FIELD_ICMP: + case WINDIVERT_FILTER_FIELD_ICMP: field[0] = (UINT32)(icmp_header != NULL); break; - case DIVERT_FILTER_FIELD_ICMPV6: + case WINDIVERT_FILTER_FIELD_ICMPV6: field[0] = (UINT32)(icmpv6_header != NULL); break; - case DIVERT_FILTER_FIELD_TCP: + case WINDIVERT_FILTER_FIELD_TCP: field[0] = (UINT32)(tcp_header != NULL); break; - case DIVERT_FILTER_FIELD_UDP: + case WINDIVERT_FILTER_FIELD_UDP: field[0] = (UINT32)(udp_header != NULL); break; - case DIVERT_FILTER_FIELD_IP_HDRLENGTH: + case WINDIVERT_FILTER_FIELD_IP_HDRLENGTH: field[0] = (UINT32)ip_header->HdrLength; break; - case DIVERT_FILTER_FIELD_IP_TOS: + case WINDIVERT_FILTER_FIELD_IP_TOS: field[0] = (UINT32)RtlUshortByteSwap(ip_header->TOS); break; - case DIVERT_FILTER_FIELD_IP_LENGTH: + case WINDIVERT_FILTER_FIELD_IP_LENGTH: field[0] = (UINT32)RtlUshortByteSwap(ip_header->Length); break; - case DIVERT_FILTER_FIELD_IP_ID: + case WINDIVERT_FILTER_FIELD_IP_ID: field[0] = (UINT32)RtlUshortByteSwap(ip_header->Id); break; - case DIVERT_FILTER_FIELD_IP_DF: + case WINDIVERT_FILTER_FIELD_IP_DF: field[0] = (UINT32)IPHDR_GET_DF(ip_header); break; - case DIVERT_FILTER_FIELD_IP_MF: + case WINDIVERT_FILTER_FIELD_IP_MF: field[0] = (UINT32)IPHDR_GET_MF(ip_header); break; - case DIVERT_FILTER_FIELD_IP_FRAGOFF: + case WINDIVERT_FILTER_FIELD_IP_FRAGOFF: field[0] = (UINT32)RtlUshortByteSwap( IPHDR_GET_FRAGOFF(ip_header)); break; - case DIVERT_FILTER_FIELD_IP_TTL: + case WINDIVERT_FILTER_FIELD_IP_TTL: field[0] = (UINT32)ip_header->TTL; break; - case DIVERT_FILTER_FIELD_IP_PROTOCOL: + case WINDIVERT_FILTER_FIELD_IP_PROTOCOL: field[0] = (UINT32)ip_header->Protocol; break; - case DIVERT_FILTER_FIELD_IP_CHECKSUM: + case WINDIVERT_FILTER_FIELD_IP_CHECKSUM: field[0] = (UINT32)RtlUshortByteSwap(ip_header->Checksum); break; - case DIVERT_FILTER_FIELD_IP_SRCADDR: + case WINDIVERT_FILTER_FIELD_IP_SRCADDR: field[0] = (UINT32)RtlUlongByteSwap(ip_header->SrcAddr); break; - case DIVERT_FILTER_FIELD_IP_DSTADDR: + case WINDIVERT_FILTER_FIELD_IP_DSTADDR: field[0] = (UINT32)RtlUlongByteSwap(ip_header->DstAddr); break; - case DIVERT_FILTER_FIELD_IPV6_TRAFFICCLASS: + case WINDIVERT_FILTER_FIELD_IPV6_TRAFFICCLASS: field[0] = (UINT32)IPV6HDR_GET_TRAFFICCLASS(ipv6_header); break; - case DIVERT_FILTER_FIELD_IPV6_FLOWLABEL: + case WINDIVERT_FILTER_FIELD_IPV6_FLOWLABEL: field[0] = (UINT32)RtlUlongByteSwap( IPV6HDR_GET_FLOWLABEL(ipv6_header)); break; - case DIVERT_FILTER_FIELD_IPV6_LENGTH: + case WINDIVERT_FILTER_FIELD_IPV6_LENGTH: field[0] = (UINT32)RtlUshortByteSwap(ipv6_header->Length); break; - case DIVERT_FILTER_FIELD_IPV6_NEXTHDR: + case WINDIVERT_FILTER_FIELD_IPV6_NEXTHDR: field[0] = (UINT32)ipv6_header->NextHdr; break; - case DIVERT_FILTER_FIELD_IPV6_HOPLIMIT: + case WINDIVERT_FILTER_FIELD_IPV6_HOPLIMIT: field[0] = (UINT32)ipv6_header->HopLimit; break; - case DIVERT_FILTER_FIELD_IPV6_SRCADDR: + case WINDIVERT_FILTER_FIELD_IPV6_SRCADDR: field[0] = (UINT32)RtlUlongByteSwap(ipv6_header->SrcAddr[3]); field[1] = @@ -2535,7 +2613,7 @@ static BOOL divert_filter(PNET_BUFFER buffer, UINT32 if_idx, UINT32 sub_if_idx, field[3] = (UINT32)RtlUlongByteSwap(ipv6_header->SrcAddr[0]); break; - case DIVERT_FILTER_FIELD_IPV6_DSTADDR: + case WINDIVERT_FILTER_FIELD_IPV6_DSTADDR: field[0] = (UINT32)RtlUlongByteSwap(ipv6_header->DstAddr[3]); field[1] = @@ -2545,90 +2623,90 @@ static BOOL divert_filter(PNET_BUFFER buffer, UINT32 if_idx, UINT32 sub_if_idx, field[3] = (UINT32)RtlUlongByteSwap(ipv6_header->DstAddr[0]); break; - case DIVERT_FILTER_FIELD_ICMP_TYPE: + case WINDIVERT_FILTER_FIELD_ICMP_TYPE: field[0] = (UINT32)icmp_header->Type; break; - case DIVERT_FILTER_FIELD_ICMP_CODE: + case WINDIVERT_FILTER_FIELD_ICMP_CODE: field[0] = (UINT32)icmp_header->Code; break; - case DIVERT_FILTER_FIELD_ICMP_CHECKSUM: + case WINDIVERT_FILTER_FIELD_ICMP_CHECKSUM: field[0] = (UINT32)RtlUshortByteSwap(icmp_header->Checksum); break; - case DIVERT_FILTER_FIELD_ICMP_BODY: + case WINDIVERT_FILTER_FIELD_ICMP_BODY: field[0] = (UINT32)RtlUlongByteSwap(icmp_header->Body); break; - case DIVERT_FILTER_FIELD_ICMPV6_TYPE: + case WINDIVERT_FILTER_FIELD_ICMPV6_TYPE: field[0] = (UINT32)icmpv6_header->Type; break; - case DIVERT_FILTER_FIELD_ICMPV6_CODE: + case WINDIVERT_FILTER_FIELD_ICMPV6_CODE: field[0] = (UINT32)icmpv6_header->Code; break; - case DIVERT_FILTER_FIELD_ICMPV6_CHECKSUM: + case WINDIVERT_FILTER_FIELD_ICMPV6_CHECKSUM: field[0] = (UINT32)icmpv6_header->Checksum; break; - case DIVERT_FILTER_FIELD_ICMPV6_BODY: + case WINDIVERT_FILTER_FIELD_ICMPV6_BODY: field[0] = (UINT32)icmpv6_header->Body; break; - case DIVERT_FILTER_FIELD_TCP_SRCPORT: + case WINDIVERT_FILTER_FIELD_TCP_SRCPORT: field[0] = (UINT32)RtlUshortByteSwap(tcp_header->SrcPort); break; - case DIVERT_FILTER_FIELD_TCP_DSTPORT: + case WINDIVERT_FILTER_FIELD_TCP_DSTPORT: field[0] = (UINT32)RtlUshortByteSwap(tcp_header->DstPort); break; - case DIVERT_FILTER_FIELD_TCP_SEQNUM: + case WINDIVERT_FILTER_FIELD_TCP_SEQNUM: field[0] = (UINT32)RtlUlongByteSwap(tcp_header->SeqNum); break; - case DIVERT_FILTER_FIELD_TCP_ACKNUM: + case WINDIVERT_FILTER_FIELD_TCP_ACKNUM: field[0] = (UINT32)RtlUlongByteSwap(tcp_header->AckNum); break; - case DIVERT_FILTER_FIELD_TCP_HDRLENGTH: + case WINDIVERT_FILTER_FIELD_TCP_HDRLENGTH: field[0] = (UINT32)tcp_header->HdrLength; break; - case DIVERT_FILTER_FIELD_TCP_URG: + case WINDIVERT_FILTER_FIELD_TCP_URG: field[0] = (UINT32)tcp_header->Urg; break; - case DIVERT_FILTER_FIELD_TCP_ACK: + case WINDIVERT_FILTER_FIELD_TCP_ACK: field[0] = (UINT32)tcp_header->Ack; break; - case DIVERT_FILTER_FIELD_TCP_PSH: + case WINDIVERT_FILTER_FIELD_TCP_PSH: field[0] = (UINT32)tcp_header->Psh; break; - case DIVERT_FILTER_FIELD_TCP_RST: + case WINDIVERT_FILTER_FIELD_TCP_RST: field[0] = (UINT32)tcp_header->Rst; break; - case DIVERT_FILTER_FIELD_TCP_SYN: + case WINDIVERT_FILTER_FIELD_TCP_SYN: field[0] = (UINT32)tcp_header->Syn; break; - case DIVERT_FILTER_FIELD_TCP_FIN: + case WINDIVERT_FILTER_FIELD_TCP_FIN: field[0] = (UINT32)tcp_header->Fin; break; - case DIVERT_FILTER_FIELD_TCP_WINDOW: + case WINDIVERT_FILTER_FIELD_TCP_WINDOW: field[0] = (UINT32)RtlUshortByteSwap(tcp_header->Window); break; - case DIVERT_FILTER_FIELD_TCP_CHECKSUM: + case WINDIVERT_FILTER_FIELD_TCP_CHECKSUM: field[0] = (UINT32)RtlUshortByteSwap(tcp_header->Checksum); break; - case DIVERT_FILTER_FIELD_TCP_URGPTR: + case WINDIVERT_FILTER_FIELD_TCP_URGPTR: field[0] = (UINT32)RtlUshortByteSwap(tcp_header->UrgPtr); break; - case DIVERT_FILTER_FIELD_TCP_PAYLOADLENGTH: + case WINDIVERT_FILTER_FIELD_TCP_PAYLOADLENGTH: field[0] = (UINT32)(tot_len - ip_header_len - tcp_header->HdrLength*sizeof(UINT32)); break; - case DIVERT_FILTER_FIELD_UDP_SRCPORT: + case WINDIVERT_FILTER_FIELD_UDP_SRCPORT: field[0] = (UINT32)RtlUshortByteSwap(udp_header->SrcPort); break; - case DIVERT_FILTER_FIELD_UDP_DSTPORT: + case WINDIVERT_FILTER_FIELD_UDP_DSTPORT: field[0] = (UINT32)RtlUshortByteSwap(udp_header->DstPort); break; - case DIVERT_FILTER_FIELD_UDP_LENGTH: + case WINDIVERT_FILTER_FIELD_UDP_LENGTH: field[0] = (UINT32)RtlUshortByteSwap(udp_header->Length); break; - case DIVERT_FILTER_FIELD_UDP_CHECKSUM: + case WINDIVERT_FILTER_FIELD_UDP_CHECKSUM: field[0] = (UINT32)RtlUshortByteSwap(udp_header->Checksum); break; - case DIVERT_FILTER_FIELD_UDP_PAYLOADLENGTH: + case WINDIVERT_FILTER_FIELD_UDP_PAYLOADLENGTH: field[0] = (UINT32)(tot_len - ip_header_len - sizeof(struct udphdr)); break; @@ -2638,19 +2716,19 @@ static BOOL divert_filter(PNET_BUFFER buffer, UINT32 if_idx, UINT32 sub_if_idx, } switch (filter[ip].test) { - case DIVERT_FILTER_TEST_EQ: + case WINDIVERT_FILTER_TEST_EQ: result = (field[0] == filter[ip].arg[0] && field[1] == filter[ip].arg[1] && field[2] == filter[ip].arg[2] && field[3] == filter[ip].arg[3]); break; - case DIVERT_FILTER_TEST_NEQ: + case WINDIVERT_FILTER_TEST_NEQ: result = (field[0] != filter[ip].arg[0] || field[1] != filter[ip].arg[1] || field[2] != filter[ip].arg[2] || field[3] != filter[ip].arg[3]); break; - case DIVERT_FILTER_TEST_LT: + case WINDIVERT_FILTER_TEST_LT: result = (field[3] < filter[ip].arg[3] || (field[3] == filter[ip].arg[3] && field[2] < filter[ip].arg[2] || @@ -2659,7 +2737,7 @@ static BOOL divert_filter(PNET_BUFFER buffer, UINT32 if_idx, UINT32 sub_if_idx, (field[1] == filter[ip].arg[1] && field[0] < filter[ip].arg[0])))); break; - case DIVERT_FILTER_TEST_LEQ: + case WINDIVERT_FILTER_TEST_LEQ: result = (field[3] < filter[ip].arg[3] || (field[3] == filter[ip].arg[3] && field[2] < filter[ip].arg[2] || @@ -2668,7 +2746,7 @@ static BOOL divert_filter(PNET_BUFFER buffer, UINT32 if_idx, UINT32 sub_if_idx, (field[1] == filter[ip].arg[1] && field[0] <= filter[ip].arg[0])))); break; - case DIVERT_FILTER_TEST_GT: + case WINDIVERT_FILTER_TEST_GT: result = (field[3] > filter[ip].arg[3] || (field[3] == filter[ip].arg[3] && field[2] > filter[ip].arg[2] || @@ -2677,7 +2755,7 @@ static BOOL divert_filter(PNET_BUFFER buffer, UINT32 if_idx, UINT32 sub_if_idx, (field[1] == filter[ip].arg[1] && field[0] > filter[ip].arg[0])))); break; - case DIVERT_FILTER_TEST_GEQ: + case WINDIVERT_FILTER_TEST_GEQ: result = (field[3] > filter[ip].arg[3] || (field[3] == filter[ip].arg[3] && field[2] > filter[ip].arg[2] || @@ -2692,11 +2770,11 @@ static BOOL divert_filter(PNET_BUFFER buffer, UINT32 if_idx, UINT32 sub_if_idx, } } ip = (result? filter[ip].success: filter[ip].failure); - if (ip == DIVERT_FILTER_RESULT_ACCEPT) + if (ip == WINDIVERT_FILTER_RESULT_ACCEPT) { return TRUE; } - if (ip == DIVERT_FILTER_RESULT_REJECT) + if (ip == WINDIVERT_FILTER_RESULT_REJECT) { return FALSE; } @@ -2708,14 +2786,14 @@ static BOOL divert_filter(PNET_BUFFER buffer, UINT32 if_idx, UINT32 sub_if_idx, /* * Analyze the given filter. */ -static void divert_filter_analyze(filter_t filter, BOOL *is_inbound, +static void windivert_filter_analyze(filter_t filter, BOOL *is_inbound, BOOL *is_outbound, BOOL *is_ipv4, BOOL *is_ipv6) { BOOL result; // False filter? - result = divert_filter_test(filter, 0, DIVERT_FILTER_PROTOCOL_NONE, - DIVERT_FILTER_FIELD_ZERO, 0); + result = windivert_filter_test(filter, 0, WINDIVERT_FILTER_PROTOCOL_NONE, + WINDIVERT_FILTER_FIELD_ZERO, 0); if (!result) { *is_inbound = FALSE; @@ -2726,42 +2804,43 @@ static void divert_filter_analyze(filter_t filter, BOOL *is_inbound, } // Inbound? - result = divert_filter_test(filter, 0, DIVERT_FILTER_PROTOCOL_NONE, - DIVERT_FILTER_FIELD_INBOUND, 1); + result = windivert_filter_test(filter, 0, WINDIVERT_FILTER_PROTOCOL_NONE, + WINDIVERT_FILTER_FIELD_INBOUND, 1); if (result) { - result = divert_filter_test(filter, 0, DIVERT_FILTER_PROTOCOL_NONE, - DIVERT_FILTER_FIELD_OUTBOUND, 0); + result = windivert_filter_test(filter, 0, + WINDIVERT_FILTER_PROTOCOL_NONE, WINDIVERT_FILTER_FIELD_OUTBOUND, + 0); } *is_inbound = result; // Outbound? - result = divert_filter_test(filter, 0, DIVERT_FILTER_PROTOCOL_NONE, - DIVERT_FILTER_FIELD_OUTBOUND, 1); + result = windivert_filter_test(filter, 0, WINDIVERT_FILTER_PROTOCOL_NONE, + WINDIVERT_FILTER_FIELD_OUTBOUND, 1); if (result) { - result = divert_filter_test(filter, 0, DIVERT_FILTER_PROTOCOL_NONE, - DIVERT_FILTER_FIELD_INBOUND, 0); + result = windivert_filter_test(filter, 0, + WINDIVERT_FILTER_PROTOCOL_NONE, WINDIVERT_FILTER_FIELD_INBOUND, 0); } *is_outbound = result; // IPv4? - result = divert_filter_test(filter, 0, DIVERT_FILTER_PROTOCOL_NONE, - DIVERT_FILTER_FIELD_IP, 1); + result = windivert_filter_test(filter, 0, WINDIVERT_FILTER_PROTOCOL_NONE, + WINDIVERT_FILTER_FIELD_IP, 1); if (result) { - result = divert_filter_test(filter, 0, DIVERT_FILTER_PROTOCOL_NONE, - DIVERT_FILTER_FIELD_IPV6, 0); + result = windivert_filter_test(filter, 0, + WINDIVERT_FILTER_PROTOCOL_NONE, WINDIVERT_FILTER_FIELD_IPV6, 0); } *is_ipv4 = result; // Ipv6? - result = divert_filter_test(filter, 0, DIVERT_FILTER_PROTOCOL_NONE, - DIVERT_FILTER_FIELD_IPV6, 1); + result = windivert_filter_test(filter, 0, WINDIVERT_FILTER_PROTOCOL_NONE, + WINDIVERT_FILTER_FIELD_IPV6, 1); if (result) { - result = divert_filter_test(filter, 0, DIVERT_FILTER_PROTOCOL_NONE, - DIVERT_FILTER_FIELD_IP, 0); + result = windivert_filter_test(filter, 0, + WINDIVERT_FILTER_PROTOCOL_NONE, WINDIVERT_FILTER_FIELD_IP, 0); } *is_ipv6 = result; } @@ -2769,21 +2848,21 @@ static void divert_filter_analyze(filter_t filter, BOOL *is_inbound, /* * Test a filter for any packet where field = arg. */ -static BOOL divert_filter_test(filter_t filter, UINT16 ip, UINT8 protocol, +static BOOL windivert_filter_test(filter_t filter, UINT16 ip, UINT8 protocol, UINT8 field, UINT32 arg) { BOOL known = FALSE; BOOL result = FALSE; - if (ip == DIVERT_FILTER_RESULT_ACCEPT) + if (ip == WINDIVERT_FILTER_RESULT_ACCEPT) { return TRUE; } - if (ip == DIVERT_FILTER_RESULT_REJECT) + if (ip == WINDIVERT_FILTER_RESULT_REJECT) { return FALSE; } - if (ip > DIVERT_FILTER_MAXLEN) + if (ip > WINDIVERT_FILTER_MAXLEN) { return FALSE; } @@ -2794,22 +2873,22 @@ static BOOL divert_filter_test(filter_t filter, UINT16 ip, UINT8 protocol, known = TRUE; switch (filter[ip].test) { - case DIVERT_FILTER_TEST_EQ: + case WINDIVERT_FILTER_TEST_EQ: result = (arg == filter[ip].arg[0]); break; - case DIVERT_FILTER_TEST_NEQ: + case WINDIVERT_FILTER_TEST_NEQ: result = (arg != filter[ip].arg[0]); break; - case DIVERT_FILTER_TEST_LT: + case WINDIVERT_FILTER_TEST_LT: result = (arg < filter[ip].arg[0]); break; - case DIVERT_FILTER_TEST_LEQ: + case WINDIVERT_FILTER_TEST_LEQ: result = (arg <= filter[ip].arg[0]); break; - case DIVERT_FILTER_TEST_GT: + case WINDIVERT_FILTER_TEST_GT: result = (arg > filter[ip].arg[0]); break; - case DIVERT_FILTER_TEST_GEQ: + case WINDIVERT_FILTER_TEST_GEQ: result = (arg >= filter[ip].arg[0]); break; default: @@ -2820,171 +2899,173 @@ static BOOL divert_filter_test(filter_t filter, UINT16 ip, UINT8 protocol, if (!known) { - result = divert_filter_test(filter, filter[ip].success, protocol, + result = windivert_filter_test(filter, filter[ip].success, protocol, field, arg); if (result) { return TRUE; } - return divert_filter_test(filter, filter[ip].failure, protocol, field, - arg); + return windivert_filter_test(filter, filter[ip].failure, protocol, + field, arg); } else { ip = (result? filter[ip].success: filter[ip].failure); - return divert_filter_test(filter, ip, protocol, field, arg); + return windivert_filter_test(filter, ip, protocol, field, arg); } } /* - * Compile a divert filter from an IOCTL. + * Compile a WinDivert filter from an IOCTL. */ -static filter_t divert_filter_compile(divert_ioctl_filter_t ioctl_filter, +static filter_t windivert_filter_compile(windivert_ioctl_filter_t ioctl_filter, size_t ioctl_filter_len) { filter_t filter0 = NULL, result = NULL; UINT16 i; size_t length; - if (ioctl_filter_len % sizeof(struct divert_ioctl_filter_s) != 0) + if (ioctl_filter_len % sizeof(struct windivert_ioctl_filter_s) != 0) { - goto divert_filter_compile_exit; + goto windivert_filter_compile_exit; } - length = ioctl_filter_len / sizeof(struct divert_ioctl_filter_s); - if (length >= DIVERT_FILTER_MAXLEN) + length = ioctl_filter_len / sizeof(struct windivert_ioctl_filter_s); + if (length >= WINDIVERT_FILTER_MAXLEN) { - goto divert_filter_compile_exit; + goto windivert_filter_compile_exit; } // Do NOT use the stack (size = 12Kb on x86) for filter0. filter0 = (filter_t)ExAllocatePoolWithTag(NonPagedPool, - DIVERT_FILTER_MAXLEN*sizeof(struct filter_s), DIVERT_FILTER_TAG); + WINDIVERT_FILTER_MAXLEN*sizeof(struct filter_s), WINDIVERT_FILTER_TAG); if (filter0 == NULL) { - goto divert_filter_compile_exit; + goto windivert_filter_compile_exit; } for (i = 0; i < length; i++) { - if (ioctl_filter[i].field > DIVERT_FILTER_FIELD_MAX || - ioctl_filter[i].test > DIVERT_FILTER_TEST_MAX) + if (ioctl_filter[i].field > WINDIVERT_FILTER_FIELD_MAX || + ioctl_filter[i].test > WINDIVERT_FILTER_TEST_MAX) { - goto divert_filter_compile_exit; + goto windivert_filter_compile_exit; } switch (ioctl_filter[i].success) { - case DIVERT_FILTER_RESULT_ACCEPT: case DIVERT_FILTER_RESULT_REJECT: + case WINDIVERT_FILTER_RESULT_ACCEPT: + case WINDIVERT_FILTER_RESULT_REJECT: break; default: if (ioctl_filter[i].success <= i || ioctl_filter[i].success >= length) { - goto divert_filter_compile_exit; + goto windivert_filter_compile_exit; } break; } switch (ioctl_filter[i].failure) { - case DIVERT_FILTER_RESULT_ACCEPT: case DIVERT_FILTER_RESULT_REJECT: + case WINDIVERT_FILTER_RESULT_ACCEPT: + case WINDIVERT_FILTER_RESULT_REJECT: break; default: if (ioctl_filter[i].failure <= i || ioctl_filter[i].failure >= length) { - goto divert_filter_compile_exit; + goto windivert_filter_compile_exit; } break; } // Enforce size limits: - if (ioctl_filter[i].field != DIVERT_FILTER_FIELD_IPV6_SRCADDR && - ioctl_filter[i].field != DIVERT_FILTER_FIELD_IPV6_DSTADDR) + if (ioctl_filter[i].field != WINDIVERT_FILTER_FIELD_IPV6_SRCADDR && + ioctl_filter[i].field != WINDIVERT_FILTER_FIELD_IPV6_DSTADDR) { if (ioctl_filter[i].arg[1] != 0 || ioctl_filter[i].arg[2] != 0 || ioctl_filter[i].arg[3] != 0) { - goto divert_filter_compile_exit; + goto windivert_filter_compile_exit; } } switch (ioctl_filter[i].field) { - case DIVERT_FILTER_FIELD_ZERO: - case DIVERT_FILTER_FIELD_INBOUND: - case DIVERT_FILTER_FIELD_OUTBOUND: - case DIVERT_FILTER_FIELD_IP: - case DIVERT_FILTER_FIELD_IPV6: - case DIVERT_FILTER_FIELD_ICMP: - case DIVERT_FILTER_FIELD_ICMPV6: - case DIVERT_FILTER_FIELD_TCP: - case DIVERT_FILTER_FIELD_UDP: - case DIVERT_FILTER_FIELD_IP_DF: - case DIVERT_FILTER_FIELD_IP_MF: - case DIVERT_FILTER_FIELD_TCP_URG: - case DIVERT_FILTER_FIELD_TCP_ACK: - case DIVERT_FILTER_FIELD_TCP_PSH: - case DIVERT_FILTER_FIELD_TCP_RST: - case DIVERT_FILTER_FIELD_TCP_SYN: - case DIVERT_FILTER_FIELD_TCP_FIN: + case WINDIVERT_FILTER_FIELD_ZERO: + case WINDIVERT_FILTER_FIELD_INBOUND: + case WINDIVERT_FILTER_FIELD_OUTBOUND: + case WINDIVERT_FILTER_FIELD_IP: + case WINDIVERT_FILTER_FIELD_IPV6: + case WINDIVERT_FILTER_FIELD_ICMP: + case WINDIVERT_FILTER_FIELD_ICMPV6: + case WINDIVERT_FILTER_FIELD_TCP: + case WINDIVERT_FILTER_FIELD_UDP: + case WINDIVERT_FILTER_FIELD_IP_DF: + case WINDIVERT_FILTER_FIELD_IP_MF: + case WINDIVERT_FILTER_FIELD_TCP_URG: + case WINDIVERT_FILTER_FIELD_TCP_ACK: + case WINDIVERT_FILTER_FIELD_TCP_PSH: + case WINDIVERT_FILTER_FIELD_TCP_RST: + case WINDIVERT_FILTER_FIELD_TCP_SYN: + case WINDIVERT_FILTER_FIELD_TCP_FIN: if (ioctl_filter[i].arg[0] > 1) { - goto divert_filter_compile_exit; + goto windivert_filter_compile_exit; } break; - case DIVERT_FILTER_FIELD_IP_HDRLENGTH: - case DIVERT_FILTER_FIELD_TCP_HDRLENGTH: + case WINDIVERT_FILTER_FIELD_IP_HDRLENGTH: + case WINDIVERT_FILTER_FIELD_TCP_HDRLENGTH: if (ioctl_filter[i].arg[0] > 0x0F) { - goto divert_filter_compile_exit; + goto windivert_filter_compile_exit; } break; - case DIVERT_FILTER_FIELD_IP_TTL: - case DIVERT_FILTER_FIELD_IP_PROTOCOL: - case DIVERT_FILTER_FIELD_IPV6_TRAFFICCLASS: - case DIVERT_FILTER_FIELD_IPV6_NEXTHDR: - case DIVERT_FILTER_FIELD_IPV6_HOPLIMIT: - case DIVERT_FILTER_FIELD_ICMP_TYPE: - case DIVERT_FILTER_FIELD_ICMP_CODE: - case DIVERT_FILTER_FIELD_ICMPV6_TYPE: - case DIVERT_FILTER_FIELD_ICMPV6_CODE: + case WINDIVERT_FILTER_FIELD_IP_TTL: + case WINDIVERT_FILTER_FIELD_IP_PROTOCOL: + case WINDIVERT_FILTER_FIELD_IPV6_TRAFFICCLASS: + case WINDIVERT_FILTER_FIELD_IPV6_NEXTHDR: + case WINDIVERT_FILTER_FIELD_IPV6_HOPLIMIT: + case WINDIVERT_FILTER_FIELD_ICMP_TYPE: + case WINDIVERT_FILTER_FIELD_ICMP_CODE: + case WINDIVERT_FILTER_FIELD_ICMPV6_TYPE: + case WINDIVERT_FILTER_FIELD_ICMPV6_CODE: if (ioctl_filter[i].arg[0] > UINT8_MAX) { - goto divert_filter_compile_exit; + goto windivert_filter_compile_exit; } break; - case DIVERT_FILTER_FIELD_IP_FRAGOFF: + case WINDIVERT_FILTER_FIELD_IP_FRAGOFF: if (ioctl_filter[i].arg[0] > 0x1FFF) { - goto divert_filter_compile_exit; + goto windivert_filter_compile_exit; } break; - case DIVERT_FILTER_FIELD_IP_TOS: - case DIVERT_FILTER_FIELD_IP_LENGTH: - case DIVERT_FILTER_FIELD_IP_ID: - case DIVERT_FILTER_FIELD_IP_CHECKSUM: - case DIVERT_FILTER_FIELD_IPV6_LENGTH: - case DIVERT_FILTER_FIELD_ICMP_CHECKSUM: - case DIVERT_FILTER_FIELD_ICMPV6_CHECKSUM: - case DIVERT_FILTER_FIELD_TCP_SRCPORT: - case DIVERT_FILTER_FIELD_TCP_DSTPORT: - case DIVERT_FILTER_FIELD_TCP_WINDOW: - case DIVERT_FILTER_FIELD_TCP_CHECKSUM: - case DIVERT_FILTER_FIELD_TCP_URGPTR: - case DIVERT_FILTER_FIELD_TCP_PAYLOADLENGTH: - case DIVERT_FILTER_FIELD_UDP_SRCPORT: - case DIVERT_FILTER_FIELD_UDP_DSTPORT: - case DIVERT_FILTER_FIELD_UDP_LENGTH: - case DIVERT_FILTER_FIELD_UDP_CHECKSUM: - case DIVERT_FILTER_FIELD_UDP_PAYLOADLENGTH: + case WINDIVERT_FILTER_FIELD_IP_TOS: + case WINDIVERT_FILTER_FIELD_IP_LENGTH: + case WINDIVERT_FILTER_FIELD_IP_ID: + case WINDIVERT_FILTER_FIELD_IP_CHECKSUM: + case WINDIVERT_FILTER_FIELD_IPV6_LENGTH: + case WINDIVERT_FILTER_FIELD_ICMP_CHECKSUM: + case WINDIVERT_FILTER_FIELD_ICMPV6_CHECKSUM: + case WINDIVERT_FILTER_FIELD_TCP_SRCPORT: + case WINDIVERT_FILTER_FIELD_TCP_DSTPORT: + case WINDIVERT_FILTER_FIELD_TCP_WINDOW: + case WINDIVERT_FILTER_FIELD_TCP_CHECKSUM: + case WINDIVERT_FILTER_FIELD_TCP_URGPTR: + case WINDIVERT_FILTER_FIELD_TCP_PAYLOADLENGTH: + case WINDIVERT_FILTER_FIELD_UDP_SRCPORT: + case WINDIVERT_FILTER_FIELD_UDP_DSTPORT: + case WINDIVERT_FILTER_FIELD_UDP_LENGTH: + case WINDIVERT_FILTER_FIELD_UDP_CHECKSUM: + case WINDIVERT_FILTER_FIELD_UDP_PAYLOADLENGTH: if (ioctl_filter[i].arg[0] > UINT16_MAX) { - goto divert_filter_compile_exit; + goto windivert_filter_compile_exit; } break; - case DIVERT_FILTER_FIELD_IPV6_FLOWLABEL: + case WINDIVERT_FILTER_FIELD_IPV6_FLOWLABEL: if (ioctl_filter[i].arg[0] > 0x000FFFFF) { - goto divert_filter_compile_exit; + goto windivert_filter_compile_exit; } break; default: @@ -3002,95 +3083,95 @@ static filter_t divert_filter_compile(divert_ioctl_filter_t ioctl_filter, // Protocol selection: switch (ioctl_filter[i].field) { - case DIVERT_FILTER_FIELD_ZERO: - case DIVERT_FILTER_FIELD_INBOUND: - case DIVERT_FILTER_FIELD_OUTBOUND: - case DIVERT_FILTER_FIELD_IFIDX: - case DIVERT_FILTER_FIELD_SUBIFIDX: - case DIVERT_FILTER_FIELD_IP: - case DIVERT_FILTER_FIELD_IPV6: - case DIVERT_FILTER_FIELD_ICMP: - case DIVERT_FILTER_FIELD_ICMPV6: - case DIVERT_FILTER_FIELD_TCP: - case DIVERT_FILTER_FIELD_UDP: - filter0[i].protocol = DIVERT_FILTER_PROTOCOL_NONE; + case WINDIVERT_FILTER_FIELD_ZERO: + case WINDIVERT_FILTER_FIELD_INBOUND: + case WINDIVERT_FILTER_FIELD_OUTBOUND: + case WINDIVERT_FILTER_FIELD_IFIDX: + case WINDIVERT_FILTER_FIELD_SUBIFIDX: + case WINDIVERT_FILTER_FIELD_IP: + case WINDIVERT_FILTER_FIELD_IPV6: + case WINDIVERT_FILTER_FIELD_ICMP: + case WINDIVERT_FILTER_FIELD_ICMPV6: + case WINDIVERT_FILTER_FIELD_TCP: + case WINDIVERT_FILTER_FIELD_UDP: + filter0[i].protocol = WINDIVERT_FILTER_PROTOCOL_NONE; break; - case DIVERT_FILTER_FIELD_IP_HDRLENGTH: - case DIVERT_FILTER_FIELD_IP_TOS: - case DIVERT_FILTER_FIELD_IP_LENGTH: - case DIVERT_FILTER_FIELD_IP_ID: - case DIVERT_FILTER_FIELD_IP_DF: - case DIVERT_FILTER_FIELD_IP_MF: - case DIVERT_FILTER_FIELD_IP_FRAGOFF: - case DIVERT_FILTER_FIELD_IP_TTL: - case DIVERT_FILTER_FIELD_IP_PROTOCOL: - case DIVERT_FILTER_FIELD_IP_CHECKSUM: - case DIVERT_FILTER_FIELD_IP_SRCADDR: - case DIVERT_FILTER_FIELD_IP_DSTADDR: - filter0[i].protocol = DIVERT_FILTER_PROTOCOL_IP; + case WINDIVERT_FILTER_FIELD_IP_HDRLENGTH: + case WINDIVERT_FILTER_FIELD_IP_TOS: + case WINDIVERT_FILTER_FIELD_IP_LENGTH: + case WINDIVERT_FILTER_FIELD_IP_ID: + case WINDIVERT_FILTER_FIELD_IP_DF: + case WINDIVERT_FILTER_FIELD_IP_MF: + case WINDIVERT_FILTER_FIELD_IP_FRAGOFF: + case WINDIVERT_FILTER_FIELD_IP_TTL: + case WINDIVERT_FILTER_FIELD_IP_PROTOCOL: + case WINDIVERT_FILTER_FIELD_IP_CHECKSUM: + case WINDIVERT_FILTER_FIELD_IP_SRCADDR: + case WINDIVERT_FILTER_FIELD_IP_DSTADDR: + filter0[i].protocol = WINDIVERT_FILTER_PROTOCOL_IP; break; - case DIVERT_FILTER_FIELD_IPV6_TRAFFICCLASS: - case DIVERT_FILTER_FIELD_IPV6_FLOWLABEL: - case DIVERT_FILTER_FIELD_IPV6_LENGTH: - case DIVERT_FILTER_FIELD_IPV6_NEXTHDR: - case DIVERT_FILTER_FIELD_IPV6_HOPLIMIT: - case DIVERT_FILTER_FIELD_IPV6_SRCADDR: - case DIVERT_FILTER_FIELD_IPV6_DSTADDR: - filter0[i].protocol = DIVERT_FILTER_PROTOCOL_IPV6; + case WINDIVERT_FILTER_FIELD_IPV6_TRAFFICCLASS: + case WINDIVERT_FILTER_FIELD_IPV6_FLOWLABEL: + case WINDIVERT_FILTER_FIELD_IPV6_LENGTH: + case WINDIVERT_FILTER_FIELD_IPV6_NEXTHDR: + case WINDIVERT_FILTER_FIELD_IPV6_HOPLIMIT: + case WINDIVERT_FILTER_FIELD_IPV6_SRCADDR: + case WINDIVERT_FILTER_FIELD_IPV6_DSTADDR: + filter0[i].protocol = WINDIVERT_FILTER_PROTOCOL_IPV6; break; - case DIVERT_FILTER_FIELD_ICMP_TYPE: - case DIVERT_FILTER_FIELD_ICMP_CODE: - case DIVERT_FILTER_FIELD_ICMP_CHECKSUM: - case DIVERT_FILTER_FIELD_ICMP_BODY: - filter0[i].protocol = DIVERT_FILTER_PROTOCOL_ICMP; + case WINDIVERT_FILTER_FIELD_ICMP_TYPE: + case WINDIVERT_FILTER_FIELD_ICMP_CODE: + case WINDIVERT_FILTER_FIELD_ICMP_CHECKSUM: + case WINDIVERT_FILTER_FIELD_ICMP_BODY: + filter0[i].protocol = WINDIVERT_FILTER_PROTOCOL_ICMP; break; - case DIVERT_FILTER_FIELD_ICMPV6_TYPE: - case DIVERT_FILTER_FIELD_ICMPV6_CODE: - case DIVERT_FILTER_FIELD_ICMPV6_CHECKSUM: - case DIVERT_FILTER_FIELD_ICMPV6_BODY: - filter0[i].protocol = DIVERT_FILTER_PROTOCOL_ICMPV6; + case WINDIVERT_FILTER_FIELD_ICMPV6_TYPE: + case WINDIVERT_FILTER_FIELD_ICMPV6_CODE: + case WINDIVERT_FILTER_FIELD_ICMPV6_CHECKSUM: + case WINDIVERT_FILTER_FIELD_ICMPV6_BODY: + filter0[i].protocol = WINDIVERT_FILTER_PROTOCOL_ICMPV6; break; - case DIVERT_FILTER_FIELD_TCP_SRCPORT: - case DIVERT_FILTER_FIELD_TCP_DSTPORT: - case DIVERT_FILTER_FIELD_TCP_SEQNUM: - case DIVERT_FILTER_FIELD_TCP_ACKNUM: - case DIVERT_FILTER_FIELD_TCP_HDRLENGTH: - case DIVERT_FILTER_FIELD_TCP_URG: - case DIVERT_FILTER_FIELD_TCP_ACK: - case DIVERT_FILTER_FIELD_TCP_PSH: - case DIVERT_FILTER_FIELD_TCP_RST: - case DIVERT_FILTER_FIELD_TCP_SYN: - case DIVERT_FILTER_FIELD_TCP_FIN: - case DIVERT_FILTER_FIELD_TCP_WINDOW: - case DIVERT_FILTER_FIELD_TCP_CHECKSUM: - case DIVERT_FILTER_FIELD_TCP_URGPTR: - case DIVERT_FILTER_FIELD_TCP_PAYLOADLENGTH: - filter0[i].protocol = DIVERT_FILTER_PROTOCOL_TCP; + case WINDIVERT_FILTER_FIELD_TCP_SRCPORT: + case WINDIVERT_FILTER_FIELD_TCP_DSTPORT: + case WINDIVERT_FILTER_FIELD_TCP_SEQNUM: + case WINDIVERT_FILTER_FIELD_TCP_ACKNUM: + case WINDIVERT_FILTER_FIELD_TCP_HDRLENGTH: + case WINDIVERT_FILTER_FIELD_TCP_URG: + case WINDIVERT_FILTER_FIELD_TCP_ACK: + case WINDIVERT_FILTER_FIELD_TCP_PSH: + case WINDIVERT_FILTER_FIELD_TCP_RST: + case WINDIVERT_FILTER_FIELD_TCP_SYN: + case WINDIVERT_FILTER_FIELD_TCP_FIN: + case WINDIVERT_FILTER_FIELD_TCP_WINDOW: + case WINDIVERT_FILTER_FIELD_TCP_CHECKSUM: + case WINDIVERT_FILTER_FIELD_TCP_URGPTR: + case WINDIVERT_FILTER_FIELD_TCP_PAYLOADLENGTH: + filter0[i].protocol = WINDIVERT_FILTER_PROTOCOL_TCP; break; - case DIVERT_FILTER_FIELD_UDP_SRCPORT: - case DIVERT_FILTER_FIELD_UDP_DSTPORT: - case DIVERT_FILTER_FIELD_UDP_LENGTH: - case DIVERT_FILTER_FIELD_UDP_CHECKSUM: - case DIVERT_FILTER_FIELD_UDP_PAYLOADLENGTH: - filter0[i].protocol = DIVERT_FILTER_PROTOCOL_UDP; + case WINDIVERT_FILTER_FIELD_UDP_SRCPORT: + case WINDIVERT_FILTER_FIELD_UDP_DSTPORT: + case WINDIVERT_FILTER_FIELD_UDP_LENGTH: + case WINDIVERT_FILTER_FIELD_UDP_CHECKSUM: + case WINDIVERT_FILTER_FIELD_UDP_PAYLOADLENGTH: + filter0[i].protocol = WINDIVERT_FILTER_PROTOCOL_UDP; break; default: - goto divert_filter_compile_exit; + goto windivert_filter_compile_exit; } } result = (filter_t)ExAllocatePoolWithTag(NonPagedPool, - i*sizeof(struct filter_s), DIVERT_FILTER_TAG); + i*sizeof(struct filter_s), WINDIVERT_FILTER_TAG); if (result != NULL) { RtlMoveMemory(result, filter0, i*sizeof(struct filter_s)); } -divert_filter_compile_exit: +windivert_filter_compile_exit: if (filter0 != NULL) { - ExFreePoolWithTag(filter0, DIVERT_FILTER_TAG); + ExFreePoolWithTag(filter0, WINDIVERT_FILTER_TAG); } return result; } diff --git a/sys/windivert.inf b/sys/windivert.inf new file mode 100644 index 0000000..a877c20 --- /dev/null +++ b/sys/windivert.inf @@ -0,0 +1,9 @@ +[Version] +Signature="$WINDOWS NT$" + +[windivert.NT.Wdf] +KmdfService = windivert, windivert_WdfSection + +[windivert_WdfSection] +KmdfLibraryVersion = 1.9 + diff --git a/sys/divert.rc b/sys/windivert.rc similarity index 90% rename from sys/divert.rc rename to sys/windivert.rc index 9e92b12..7a32248 100644 --- a/sys/divert.rc +++ b/sys/windivert.rc @@ -1,5 +1,5 @@ /* - * divert.rc + * windivert.rc * (C) 2013, all rights reserved, * * This program is free software: you can redistribute it and/or modify @@ -25,9 +25,9 @@ "WinDivert network packet capture and (re)injection driver" #define VER_INTERNALNAME_STR "WinDivert.sys" #define VER_ORIGINALFILENAME_STR "WinDivert.sys" -#define VER_PRODUCTVERSION 1.0 -#define VER_PRODUCTVERSION_STR "1.0" -#define VER_COMPANYNAME_STR "basil" +#define VER_PRODUCTVERSION 1.1 +#define VER_PRODUCTVERSION_STR "1.1" +#define VER_COMPANYNAME_STR "Basil Projects" #define VER_LEGALCOPYRIGHT_YEARS "2011-2013" #define VER_LEGALCOPYRIGHT_STR \ "Copyright \251 " VER_COMPANYNAME_STR " " VER_LEGALCOPYRIGHT_YEARS diff --git a/wddk-build.bat b/wddk-build.bat index fc97a5a..9277a17 100644 --- a/wddk-build.bat +++ b/wddk-build.bat @@ -1,5 +1,5 @@ :: wddk-build.bat -:: (C) 2012, all rights reserved, +:: (C) 2013, all rights reserved, :: :: This program is free software: you can redistribute it and/or modify :: it under the terms of the GNU Lesser General Public License as published by