Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions dll/windivert.c
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,99 @@ static BOOLEAN WinDivertAToX(const char *str, char **endptr, UINT32 *intptr)
return TRUE;
}

/****************************************************************************/
/* WINDIVERT ARP SNIFFER API */
/****************************************************************************/

/*
* Open a WinDivert ARP sniffer handle.
*/
extern HANDLE WinDivertARPSniffOpen(INT16 priority)
{
DWORD err;
HANDLE handle;
SC_HANDLE service;
UINT32 priority32;

// Parameter checking.
priority32 = WINDIVERT_PRIORITY(priority);
if (priority32 < WINDIVERT_PRIORITY_MIN ||
priority32 > WINDIVERT_PRIORITY_MAX)
{
SetLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
}

// 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)
{
err = GetLastError();
if (err != ERROR_FILE_NOT_FOUND && err != ERROR_PATH_NOT_FOUND)
{
return INVALID_HANDLE_VALUE;
}

// Open failed because the device isn't installed; install it now.
SetLastError(0);
service = WinDivertDriverInstall();
if (service == NULL)
{
if (GetLastError() == 0)
{
SetLastError(ERROR_OPEN_FAILED);
}
return INVALID_HANDLE_VALUE;
}
handle = CreateFile(L"\\\\.\\" WINDIVERT_DEVICE_NAME,
GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
INVALID_HANDLE_VALUE);

// Schedule the service to be deleted (once all handles are closed).
DeleteService(service);
CloseServiceHandle(service);

if (handle == INVALID_HANDLE_VALUE)
{
return INVALID_HANDLE_VALUE;
}
}

// Set the priority:
if (priority32 != WINDIVERT_PRIORITY_DEFAULT)
{
if (!WinDivertIoControl(handle, IOCTL_WINDIVERT_SET_PRIORITY, 0,
(UINT64)priority32, NULL, 0, NULL))
{
CloseHandle(handle);
return INVALID_HANDLE_VALUE;
}
}

// Start ASP sniff
if (!WinDivertIoControl(handle, IOCTL_WINDIVERT_START_ARP_SNIFF, 0,
(UINT64)1, NULL, 0, NULL))
{
CloseHandle(handle);
return INVALID_HANDLE_VALUE;
}

// Success!
return handle;
}

/*
* Close a WinDivert handle.
*/
extern BOOL WinDivertARPSniffClose(HANDLE handle)
{
return CloseHandle(handle);
}


/***************************************************************************/
/* DEBUGGING */
/***************************************************************************/
Expand Down
2 changes: 2 additions & 0 deletions dll/windivert.def
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ EXPORTS
WinDivertHelperParseIPv6Address
WinDivertHelperCheckFilter
WinDivertHelperEvalFilter
WinDivertARPSniffOpen
WinDivertARPSniffClose
122 changes: 122 additions & 0 deletions examples/arpdump/arpdump.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/*
* netdump.c
* (C) 2018, all rights reserved,
*
* This file is part of WinDivert.
*
* WinDivert 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 <http://www.gnu.org/licenses/>.
*
* WinDivert is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 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 General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

/*
* DESCRIPTION:
* This is a simple ARP monitor. It uses a WinDivert handle in ARP SNIFF mode.
*
* usage: arpdump.exe interface-name [priority]
*
*/

#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "windivert.h"

#define MAXBUF 0xFFFF

static volatile BOOL g_exit = FALSE;


static BOOL WINAPI console_ctrl_handler(DWORD dwCtrlType)
{
g_exit = TRUE;
return TRUE;
}


/*
* Entry.
*/
int __cdecl main(int argc, char **argv)
{
HANDLE handle, console;
UINT i;
INT16 priority = 0;
unsigned char packet[MAXBUF];
UINT packet_len;
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;
const char *err_str;
LARGE_INTEGER base, freq;
double time_passed;
console = GetStdHandle(STD_OUTPUT_HANDLE);

//SetConsoleCtrlHandler(console_ctrl_handler, TRUE);

// Sniff ARP packets:
handle = WinDivertARPSniffOpen(1000);
if (handle == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "error: failed to open the WinDivert ARP Sniff device (%d)\n",
GetLastError());
exit(EXIT_FAILURE);
}

// Sleep(55000);
while (!g_exit)
{
// Read a matching packet.
if (!WinDivertRecv(handle, packet, sizeof(packet), &addr, &packet_len))
{
fprintf(stderr, "warning: failed to read packet (%d)\n",
GetLastError());
continue;
}

printf("\n");
printf("Received ARP packet with len: %u. direction - %s\n",
packet_len, addr.Direction == WINDIVERT_DIRECTION_OUTBOUND ? "outbound" : "inbound");
for (int i = 0; i < packet_len; i++)
{
if (i % 16 == 0 && i)
{
printf("\n");
}
printf("%02X ", packet[i]);
}
printf("\n");
}

WinDivertARPSniffClose(handle);
}
17 changes: 17 additions & 0 deletions include/windivert.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,23 @@ extern WINDIVERTEXPORT BOOL WinDivertGetParam(
__in WINDIVERT_PARAM param,
__out UINT64 *pValue);


/****************************************************************************/
/* WINDIVERT ARP SNIFFER API */
/****************************************************************************/

/*
* Open a WinDivert ARP sniffer handle.
*/
extern WINDIVERTEXPORT HANDLE WinDivertARPSniffOpen(
__in INT16 priority);

/*
* Close a WinDivert handle.
*/
extern WINDIVERTEXPORT BOOL WinDivertARPSniffClose(
__in HANDLE handle);

#endif /* WINDIVERT_KERNEL */

/****************************************************************************/
Expand Down
2 changes: 2 additions & 0 deletions include/windivert_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,5 +225,7 @@ typedef struct windivert_ioctl_filter_s *windivert_ioctl_filter_t;
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)
#define IOCTL_WINDIVERT_START_ARP_SNIFF \
CTL_CODE(FILE_DEVICE_NETWORK, 0x910, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)

#endif /* __WINDIVERT_DEVICE_H */
47 changes: 47 additions & 0 deletions msvc-build.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
:: msvc-build.bat
:: (C) 2019, all rights reserved,
::
:: This file is part of WinDivert.
::
:: WinDivert 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 <http://www.gnu.org/licenses/>.
::
:: WinDivert is free software; you can redistribute it and/or modify it under
:: the terms of the GNU General Public License as published by the Free
:: Software Foundation; either version 2 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 General Public License
:: for more details.
::
:: You should have received a copy of the GNU General Public License along
:: with this program; if not, write to the Free Software Foundation, Inc., 51
:: Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

@echo off

msbuild sys\windivert.vcxproj ^
/p:Configuration=Release ^
/p:platform=Win32 ^
/p:SignMode=Off ^
/p:OutDir=..\install\MSVC\i386\ ^
/p:AssemblyName=WinDivert32

msbuild sys\windivert.vcxproj ^
/p:Configuration=Release ^
/p:platform=x64 ^
/p:SignMode=Off ^
/p:OutDir=..\install\MSVC\amd64\ ^
/p:AssemblyName=WinDivert64
3 changes: 2 additions & 1 deletion sys/sources
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ TARGETLIBS=\
$(DDK_LIB_PATH)\wdmsec.lib \
$(DDK_LIB_PATH)\ndis.lib \
$(DDK_LIB_PATH)\fwpkclnt.lib \
$(SDK_LIB_PATH)\uuid.lib
$(SDK_LIB_PATH)\uuid.lib \
$(SDK_LIB_PATH)\rtlver.lib
NTTARGETFILES=
KMDF_VERSION_MAJOR=1
C_DEFINES=$(C_DEFINES) -DBINARY_COMPATIBLE=0 -DNT -DUNICODE -D_UNICODE \
Expand Down
Loading