Adds WinDivert support to Windows builds

Enables IPS functionality on Windows using the open-source
(LGPLv3/GPLv2) WinDivert driver and API.

From https://www.reqrypt.org/windivert-doc.html : "WinDivert is a
user-mode capture/sniffing/modification/blocking/re-injection package
for Windows Vista, Windows Server 2008, Windows 7, and Windows 8.
WinDivert can be used to implement user-mode packet filters, packet
sniffers, firewalls, NAT, VPNs, tunneling applications, etc., without
the need to write kernel-mode code."

- adds `--windivert [filter string]` and `--windivert-forward [filter
    string]` command-line options to enable WinDivert IPS mode.
    `--windivert[-forward] true` will open a filter for all traffic. See
    https://www.reqrypt.org/windivert-doc.html#filter_language for more
    information.

Limitation: currently limited to `autofp` runmode.

Additionally:
- `tmm_modules` now zeroed during `RegisterAllModules`
- fixed Windows Vista+ `inet_ntop` call in `PrintInet`
- fixed `GetRandom` bug (nonexistent keys) on fresh Windows installs
- fixed `RandomGetClock` building on Windows builds
- Added WMI queries for MTU
pull/3402/head
Jacob Masen-Smith 8 years ago
parent 55ad4e4ece
commit ec77632e84

@ -233,7 +233,7 @@
;;
*-*-mingw32*)
CFLAGS="${CFLAGS} -DOS_WIN32"
LDFLAGS="${LDFLAGS} -lws2_32"
LDFLAGS="${LDFLAGS} -lws2_32 -liphlpapi -lwbemuuid -lOle32 -lOleAut32 -lUuid"
WINDOWS_PATH="yes"
PCAP_LIB_NAME="wpcap"
AC_DEFINE([HAVE_NON_POSIX_MKDIR], [1], [mkdir is not POSIX compliant: single arg])
@ -1051,6 +1051,50 @@
fi
fi
# WinDivert support
AC_ARG_ENABLE(windivert,
AS_HELP_STRING([--enable-windivert],[Enable WinDivert support [default=no]]),,
[enable_windivert="no"])
# WinDivert can only be enabled on Windows builds
AC_CHECK_DECL([OS_WIN32],,[enable_windivert="no"])
if test "x$enable_windivert" = "xyes"; then
# WinDivert requires Vista at a minimum. If the user has selected their own NTDDI_VERSION
# then don't override it.
AC_CHECK_DECL([NTDDI_VERSION],,
[CFLAGS="${CFLAGS} -DNTDDI_VERSION=NTDDI_VISTA -D_WIN32_WINNT=_WIN32_WINNT_VISTA"])
AC_DEFINE_UNQUOTED([WINDIVERT],[1],[Enable Windows WinDivert support for inline IDP])
AC_ARG_WITH(windivert_include,
[ --with-windivert-include=DIR WinDivert include path],
[with_windivert_include="$withval"],[with_windivert_include="no"])
AC_ARG_WITH(windivert_libraries,
[ --with-windivert-libraries=DIR WinDivert library path],
[with_windivert_libraries="$withval"],[with_windivert_libraries="no"])
if test "$with_windivert_include" != "no"; then
CPPFLAGS="${CPPFLAGS} -I${with_windivert_include}"
fi
if test "$with_windivert_libraries" != "no"; then
LDFLAGS="${LDFLAGS} -L${with_windivert_libraries}"
fi
AC_CHECK_HEADER(windivert.h,,WINDIVERT_INC="no")
AC_CHECK_LIB(WinDivert, WinDivertOpen,, WINDIVERT_LIB="no")
if test "$WINDIVERT_LIB" = "no" || test "$WINDIVERT_INC" = "no"; then
echo
echo " ERROR! WinDivert not found, go get it from"
echo " https://www.reqrypt.org/windivert.html"
echo
exit 1
fi
fi
# /WinDivert
# prelude
AC_ARG_ENABLE(prelude,
AS_HELP_STRING([--enable-prelude], [Enable Prelude support for alerts]),,[enable_prelude=no])
@ -2309,6 +2353,7 @@ SURICATA_BUILD_CONF="Suricata Configuration:
Netmap support: ${enable_netmap}
DAG enabled: ${enable_dag}
Napatech enabled: ${enable_napatech}
WinDivert enabled: ${enable_windivert}
Unix socket enabled: ${enable_unixsocket}
Detection enabled: ${enable_detection}

@ -0,0 +1,64 @@
Setting up IPS/inline for Windows
=================================
This guide explains how to work with Suricata in layer 4 inline mode using
WinDivert on Windows.
First start by compiling Suricata with WinDivert support. For instructions, see
`Windows Installation
<https://redmine.openinfosecfoundation.org/attachments/download/1175/SuricataWinInstallationGuide_v1.4.3.pdf>`_.
This documentation has not yet been updated with WinDivert information, so make
sure to add the following flags to `configure`:
::
--enable-windivert=yes --with-windivert-include=<include-dir> --with-windivert-libraries=<libraries-dir>
WinDivert.dll and WinDivert.sys must be in the same directory as the Suricata
executable. WinDivert automatically installs the driver when it is run. For more
information about WinDivert, see https://www.reqrypt.org/windivert-doc.html.
To check if you have WinDivert enabled in your Suricata, enter the following
command in an elevated command prompt or terminal:
::
suricata -c suricata.yaml --windivert [filter string]
For information on the WinDivert filter language, see
https://www.reqrypt.org/windivert-doc.html#filter_language
If Suricata is running on a gateway and is meant to protect the network behind
that gateway, you need to run WinDivert at the NETWORK_FORWARD layer. This can
be achieved using the following command:
::
suricata -c suricata.yaml --windivert-forward [filter string]
The filter is automatically stopped and normal traffic resumes when Suricata is
stopped.
A quick start is to examine all traffic, in which case you can use the following
command:
::
suricata -c suricata.yaml --windivert[-forward] true
A few additional examples:
Only TCP traffic:
::
suricata -c suricata.yaml --windivert tcp
Only TCP traffic on port 80:
::
suricata -c suricata.yaml --windivert "tcp.DstPort == 80"
TCP and ICMP traffic:
::
suricata -c suricata.yaml --windivert "tcp or icmp"

@ -2,6 +2,7 @@ noinst_HEADERS = action-globals.h \
app-layer-nbss.h app-layer-dcerpc-common.h \
debug.h \
flow-private.h queue.h source-nfq-prototypes.h \
source-windivert-prototypes.h \
suricata-common.h threadvars.h util-binsearch.h \
util-validate.h
bin_PROGRAMS = suricata
@ -357,6 +358,7 @@ runmode-pfring.c runmode-pfring.h \
runmode-unittests.c runmode-unittests.h \
runmode-unix-socket.c runmode-unix-socket.h \
runmode-tile.c runmode-tile.h \
runmode-windivert.c runmode-windivert.h \
runmodes.c runmodes.h \
rust.h \
source-af-packet.c source-af-packet.h \
@ -373,6 +375,7 @@ source-pcap-file.c source-pcap-file.h \
source-pcap-file-directory-helper.c source-pcap-file-directory-helper.h \
source-pcap-file-helper.c source-pcap-file-helper.h \
source-pfring.c source-pfring.h \
source-windivert.c source-windivert.h \
stream.c stream.h \
stream-tcp.c stream-tcp.h stream-tcp-private.h \
stream-tcp-inline.c stream-tcp-inline.h \
@ -502,6 +505,7 @@ util-validate.h util-affinity.h util-affinity.c \
util-var.c util-var.h \
util-var-name.c util-var-name.h \
util-vector.h \
win32-syscall.c win32-syscall.h \
win32-misc.c win32-misc.h \
win32-service.c win32-service.h \
win32-syslog.h

@ -64,6 +64,7 @@ enum PktSrcEnum {
#include "source-af-packet.h"
#include "source-mpipe.h"
#include "source-netmap.h"
#include "source-windivert.h"
#ifdef HAVE_PF_RING_FLOW_OFFLOAD
#include "source-pfring.h"
#endif
@ -474,6 +475,9 @@ typedef struct Packet_
PfringPacketVars pfring_v;
#endif
#endif
#ifdef WINDIVERT
WinDivertPacketVars windivert_v;
#endif /* WINDIVERT */
/** libpcap vars: shared by Pcap Live mode and Pcap File mode */
PcapPacketVars pcap_v;

@ -122,6 +122,14 @@
#include "util-streaming-buffer.h"
#include "util-lua.h"
#ifdef OS_WIN32
#include "win32-syscall.h"
#endif
#ifdef WINDIVERT
#include "source-windivert.h"
#endif
#ifdef HAVE_NSS
#include <prinit.h>
#include <nss.h>
@ -218,6 +226,12 @@ static void RegisterUnittests(void)
AppLayerUnittestsRegister();
MimeDecRegisterTests();
StreamingBufferRegisterTests();
#ifdef OS_WIN32
Win32SyscallRegisterTests();
#endif
#ifdef WINDIVERT
SourceWinDivertRegisterTests();
#endif
}
#endif

@ -0,0 +1,71 @@
/* Copyright (C) 2018 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/**
* \file
*
* \author Jacob Masen-Smith <jacob@evengx.com>
*
* Handling of WinDivert runmodes.
*/
#include "suricata-common.h"
#include "tm-threads.h"
#include "conf.h"
#include "runmodes.h"
#include "runmode-windivert.h"
#include "output.h"
#include "util-affinity.h"
#include "util-cpu.h"
#include "util-debug.h"
#include "util-device.h"
#include "util-runmodes.h"
#include "util-time.h"
static const char *default_mode;
const char *RunModeIpsWinDivertGetDefaultMode(void) { return default_mode; }
void RunModeIpsWinDivertRegister(void)
{
default_mode = "autofp";
RunModeRegisterNewRunMode(
RUNMODE_WINDIVERT, "autofp",
"Multi-threaded WinDivert IPS mode load-balanced by flow",
RunModeIpsWinDivertAutoFp);
}
int RunModeIpsWinDivertAutoFp(void)
{
SCEnter();
int ret = 0;
#ifdef WINDIVERT
RunModeInitialize();
TimeModeSetLive();
LiveDeviceHasNoStats();
ret = RunModeSetIPSAutoFp(WinDivertGetThread, "ReceiveWinDivert",
"VerdictWinDivert", "DecodeWinDivert");
#endif /* WINDIVERT */
return ret;
}

@ -0,0 +1,32 @@
/* Copyright (C) 2018 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/**
* \file
*
* \author Jacob Masen-Smith <jacob@evengx.com>
*
*/
#ifndef __RUNMODE_WINDIVERT_H__
#define __RUNMODE_WINDIVERT_H__
int RunModeIpsWinDivertAutoFp(void);
void RunModeIpsWinDivertRegister(void);
const char *RunModeIpsWinDivertGetDefaultMode(void);
#endif /* __RUNMODE_WINDIVERT_H__ */

@ -147,6 +147,12 @@ static const char *RunModeTranslateModeToName(int runmode)
#endif
case RUNMODE_UNIX_SOCKET:
return "UNIX_SOCKET";
case RUNMODE_WINDIVERT:
#ifdef WINDIVERT
return "WINDIVERT";
#else
return "WINDIVERT(DISABLED)";
#endif
default:
SCLogError(SC_ERR_UNKNOWN_RUN_MODE, "Unknown runtime mode. Aborting");
exit(EXIT_FAILURE);
@ -220,6 +226,7 @@ void RunModeRegisterRunModes(void)
RunModeIdsNflogRegister();
RunModeTileMpipeRegister();
RunModeUnixSocketRegister();
RunModeIpsWinDivertRegister();
#ifdef UNITTESTS
UtRunModeRegister();
#endif
@ -328,6 +335,11 @@ void RunModeDispatch(int runmode, const char *custom_mode)
case RUNMODE_NFLOG:
custom_mode = RunModeIdsNflogGetDefaultMode();
break;
#ifdef WINDIVERT
case RUNMODE_WINDIVERT:
custom_mode = RunModeIpsWinDivertGetDefaultMode();
break;
#endif
default:
SCLogError(SC_ERR_UNKNOWN_RUN_MODE, "Unknown runtime mode. Aborting");
exit(EXIT_FAILURE);

@ -40,6 +40,7 @@ enum RunModes {
RUNMODE_UNITTEST,
RUNMODE_NAPATECH,
RUNMODE_UNIX_SOCKET,
RUNMODE_WINDIVERT,
RUNMODE_USER_MAX, /* Last standard running mode */
RUNMODE_LIST_KEYWORDS,
RUNMODE_LIST_APP_LAYERS,
@ -106,6 +107,7 @@ int RunModeNeedsBypassManager(void);
#include "runmode-nflog.h"
#include "runmode-unix-socket.h"
#include "runmode-netmap.h"
#include "runmode-windivert.h"
int threading_set_cpu_affinity;
extern float threading_detect_ratio;

@ -0,0 +1,31 @@
/* Copyright (C) 2018 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/**
* \file
*
* \author Jacob Masen-Smith <jacob@evengx.com>
*/
#ifndef __SOURCE_WINDIVERT_PROTOTYPES_H__
#define __SOURCE_WINDIVERT_PROTOTYPES_H__
void TmModuleReceiveWinDivertRegister(void);
void TmModuleVerdictWinDivertRegister(void);
void TmModuleDecodeWinDivertRegister(void);
#endif /* __SOURCE_WINDIVERT_PROTOTYPES_H__ */

File diff suppressed because it is too large Load Diff

@ -0,0 +1,82 @@
/* Copyright (C) 2018 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/**
*
* \file
*
* \author Jacob Masen-Smith <jacob@evengx.com>
*
*/
#ifndef __SOURCE_WINDIVERT_H__
#define __SOURCE_WINDIVERT_H__
#ifdef WINDIVERT
#include "windivert.h"
#define WINDIVERT_FILTER_MAXLEN 128 /* from windivert_device.h */
typedef void *WinDivertHandle;
/**
* \brief WinDivertQueueVars is the queue configuration and other miscellaneous
* information about the specific queue/filter.
*
* see https://reqrypt.org/windivert-doc.html#divert_open for more info
*/
typedef struct WinDivertQueueVars_
{
int queue_num;
/* see https://reqrypt.org/windivert-doc.html#filter_language */
char filter_str[WINDIVERT_FILTER_MAXLEN + 1];
WINDIVERT_LAYER layer;
int16_t priority;
uint64_t flags;
WinDivertHandle filter_handle;
/* only needed for setup/teardown; Recv/Send are internally synchronized */
SCMutex filter_init_mutex;
/* counters */
uint32_t pkts;
uint64_t bytes;
uint32_t errs;
uint32_t accepted;
uint32_t dropped;
uint32_t replaced;
SCMutex counters_mutex;
} WinDivertQueueVars;
typedef struct WinDivertPacketVars_
{
int thread_num;
WINDIVERT_ADDRESS addr;
bool verdicted;
} WinDivertPacketVars;
int WinDivertRegisterQueue(bool forward, char *filter_str);
void *WinDivertGetThread(int thread);
void *WinDivertGetQueue(int queue);
void SourceWinDivertRegisterTests(void);
#endif /* WINDIVERT */
#endif /* __SOURCE_WINDIVERT_H__ */

@ -95,6 +95,9 @@
#include "source-netmap.h"
#include "source-mpipe.h"
#include "source-windivert.h"
#include "source-windivert-prototypes.h"
#include "respond-reject.h"
#include "flow.h"
@ -651,6 +654,10 @@ static void PrintUsage(const char *progname)
#endif
#ifdef HAVE_MPIPE
printf("\t--mpipe : run with tilegx mpipe interface(s)\n");
#endif
#ifdef WINDIVERT
printf("\t--windivert <filter> : run in inline WinDivert mode\n");
printf("\t--windivert-forward <filter> : run in inline WinDivert mode, as a gateway\n");
#endif
printf("\t--set name=value : set a configuration value\n");
printf("\n");
@ -855,6 +862,9 @@ int g_ut_covered;
void RegisterAllModules(void)
{
// zero all module storage
memset(tmm_modules, 0, TMM_SIZE * sizeof(TmModule));
/* commanders */
TmModuleUnixManagerRegister();
/* managers */
@ -912,6 +922,11 @@ void RegisterAllModules(void)
/* nflog */
TmModuleReceiveNFLOGRegister();
TmModuleDecodeNFLOGRegister();
/* windivert */
TmModuleReceiveWinDivertRegister();
TmModuleVerdictWinDivertRegister();
TmModuleDecodeWinDivertRegister();
}
static TmEcode LoadYamlConfig(SCInstance *suri)
@ -1533,6 +1548,10 @@ static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri)
{"build-info", 0, &build_info, 1},
#ifdef HAVE_MPIPE
{"mpipe", optional_argument, 0, 0},
#endif
#ifdef WINDIVERT
{"windivert", required_argument, 0, 0},
{"windivert-forward", required_argument, 0, 0},
#endif
{"set", required_argument, 0, 0},
#ifdef HAVE_NFLOG
@ -1812,6 +1831,45 @@ static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri)
}
}
#endif
else if(strcmp((long_opts[option_index]).name, "windivert-forward") == 0) {
#ifdef WINDIVERT
if (suri->run_mode == RUNMODE_UNKNOWN) {
suri->run_mode = RUNMODE_WINDIVERT;
if (WinDivertRegisterQueue(true, optarg) == -1) {
exit(EXIT_FAILURE);
}
} else if (suri->run_mode == RUNMODE_WINDIVERT) {
if (WinDivertRegisterQueue(true, optarg) == -1) {
exit(EXIT_FAILURE);
}
} else {
SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
"has been specified");
PrintUsage(argv[0]);
exit(EXIT_FAILURE);
}
}
else if(strcmp((long_opts[option_index]).name, "windivert") == 0) {
if (suri->run_mode == RUNMODE_UNKNOWN) {
suri->run_mode = RUNMODE_WINDIVERT;
if (WinDivertRegisterQueue(false, optarg) == -1) {
exit(EXIT_FAILURE);
}
} else if (suri->run_mode == RUNMODE_WINDIVERT) {
if (WinDivertRegisterQueue(false, optarg) == -1) {
exit(EXIT_FAILURE);
}
} else {
SCLogError(SC_ERR_MULTIPLE_RUN_MODE, "more than one run mode "
"has been specified");
PrintUsage(argv[0]);
exit(EXIT_FAILURE);
}
#else
SCLogError(SC_ERR_WINDIVERT_NOSUPPORT,"WinDivert not enabled. Make sure to pass --enable-windivert to configure when building.");
return TM_ECODE_FAILED;
#endif /* WINDIVERT */
}
else if (strcmp((long_opts[option_index]).name, "set") == 0) {
if (optarg != NULL) {
/* Quick validation. */
@ -2405,10 +2463,27 @@ static int ConfigGetCaptureValue(SCInstance *suri)
* back on a sane default. */
const char *temp_default_packet_size;
if ((ConfGet("default-packet-size", &temp_default_packet_size)) != 1) {
int mtu = 0;
int lthread;
int nlive;
int strip_trailing_plus = 0;
switch (suri->run_mode) {
#ifdef WINDIVERT
case RUNMODE_WINDIVERT:
/* by default, WinDivert collects from all devices */
mtu = GetGlobalMTUWin32();
if (mtu > 0) {
g_default_mtu = mtu;
/* SLL_HEADER_LEN is the longest header + 8 for VLAN */
default_packet_size = mtu + SLL_HEADER_LEN + 8;
break;
}
g_default_mtu = DEFAULT_MTU;
default_packet_size = DEFAULT_PACKET_SIZE;
break;
#endif /* WINDIVERT */
case RUNMODE_PCAP_DEV:
case RUNMODE_AFP_DEV:
case RUNMODE_NETMAP:
@ -2420,7 +2495,7 @@ static int ConfigGetCaptureValue(SCInstance *suri)
nlive = LiveGetDeviceCount();
for (lthread = 0; lthread < nlive; lthread++) {
const char *live_dev = LiveGetDeviceName(lthread);
char dev[32];
char dev[128]; /* need to be able to support GUID names on Windows */
(void)strlcpy(dev, live_dev, sizeof(dev));
if (strip_trailing_plus) {
@ -2429,7 +2504,7 @@ static int ConfigGetCaptureValue(SCInstance *suri)
dev[len-1] = '\0';
}
}
int mtu = GetIfaceMTU(dev);
mtu = GetIfaceMTU(dev);
g_default_mtu = MAX(mtu, g_default_mtu);
unsigned int iface_max_packet_size = GetIfaceMaxPacketSize(dev);

@ -234,6 +234,9 @@ const char * TmModuleTmmIdToString(TmmId id)
CASE_CODE (TMM_DETECTLOADER);
CASE_CODE (TMM_RECEIVENETMAP);
CASE_CODE (TMM_DECODENETMAP);
CASE_CODE (TMM_RECEIVEWINDIVERT);
CASE_CODE (TMM_VERDICTWINDIVERT);
CASE_CODE (TMM_DECODEWINDIVERT);
CASE_CODE (TMM_SIZE);
}

@ -61,6 +61,9 @@ typedef enum {
TMM_STATSLOGGER,
TMM_RECEIVENFLOG,
TMM_DECODENFLOG,
TMM_RECEIVEWINDIVERT,
TMM_VERDICTWINDIVERT,
TMM_DECODEWINDIVERT,
TMM_FLOWMANAGER,
TMM_FLOWRECYCLER,

@ -352,6 +352,10 @@ const char * SCErrorToString(SCError err)
CASE_CODE (SC_WARN_JA3_DISABLED);
CASE_CODE (SC_ERR_PCAP_LOG_COMPRESS);
CASE_CODE (SC_ERR_FSEEK);
CASE_CODE (SC_ERR_WINDIVERT_GENERIC);
CASE_CODE (SC_ERR_WINDIVERT_NOSUPPORT);
CASE_CODE (SC_ERR_WINDIVERT_INVALID_FILTER);
CASE_CODE (SC_ERR_WINDIVERT_TOOLONG_FILTER);
CASE_CODE (SC_ERR_MAX);
}

@ -342,6 +342,10 @@ typedef enum {
SC_WARN_JA3_DISABLED,
SC_ERR_PCAP_LOG_COMPRESS,
SC_ERR_FSEEK,
SC_ERR_WINDIVERT_GENERIC,
SC_ERR_WINDIVERT_NOSUPPORT,
SC_ERR_WINDIVERT_INVALID_FILTER,
SC_ERR_WINDIVERT_TOOLONG_FILTER,
SC_ERR_MAX,
} SCError;

@ -44,6 +44,10 @@
#include <net/if.h>
#endif
#ifdef OS_WIN32
#include "win32-syscall.h"
#endif
#include "util-ioctl.h"
/**
@ -77,6 +81,7 @@ static int GetIfaceMaxHWHeaderLength(const char *pcap_dev)
return 8 + SLL_HEADER_LEN;
}
/**
* \brief output the link MTU
*
@ -85,7 +90,7 @@ static int GetIfaceMaxHWHeaderLength(const char *pcap_dev)
*/
int GetIfaceMTU(const char *pcap_dev)
{
#ifdef SIOCGIFMTU
#if defined SIOCGIFMTU
struct ifreq ifr;
int fd;
@ -106,6 +111,8 @@ int GetIfaceMTU(const char *pcap_dev)
SCLogInfo("Found an MTU of %d for '%s'", ifr.ifr_mtu,
pcap_dev);
return ifr.ifr_mtu;
#elif defined OS_WIN32
return GetIfaceMTUWin32(pcap_dev);
#else
/* ioctl is not defined, let's pretend returning 0 is ok */
return 0;
@ -675,6 +682,8 @@ int GetIfaceOffloading(const char *dev, int csum, int other)
return GetIfaceOffloadingLinux(dev, csum, other);
#elif defined SIOCGIFCAP
return GetIfaceOffloadingBSD(dev);
#elif defined OS_WIN32
return GetIfaceOffloadingWin32(dev, csum, other);
#else
return 0;
#endif
@ -686,6 +695,8 @@ int DisableIfaceOffloading(LiveDevice *dev, int csum, int other)
return DisableIfaceOffloadingLinux(dev, csum, other);
#elif defined SIOCSIFCAP
return DisableIfaceOffloadingBSD(dev);
#elif defined OS_WIN32
return DisableIfaceOffloadingWin32(dev, csum, other);
#else
return 0;
#endif
@ -699,6 +710,8 @@ void RestoreIfaceOffloading(LiveDevice *dev)
RestoreIfaceOffloadingLinux(dev);
#elif defined SIOCSIFCAP
RestoreIfaceOffloadingBSD(dev);
#elif defined OS_WIN32
RestoreIfaceOffloadingWin32(dev);
#endif
}
}

@ -24,6 +24,10 @@
#include "suricata-common.h"
#include "util-device.h"
#ifdef OS_WIN32
#include "win32-syscall.h"
#endif
int GetIfaceMTU(const char *pcap_dev);
int GetIfaceMaxPacketSize(const char *pcap_dev);
int GetIfaceOffloading(const char *dev, int csum, int other);

@ -268,7 +268,17 @@ const char *PrintInet(int af, const void *src, char *dst, socklen_t size)
{
switch (af) {
case AF_INET:
#if defined(OS_WIN32) && NTDDI_VERSION >= NTDDI_VISTA
{
// because Windows has to provide a non-conformant inet_ntop, of
// course!
struct in_addr _src;
memcpy(&_src, src, sizeof(struct in_addr));
return inet_ntop(af, &_src, dst, size);
}
#else
return inet_ntop(af, src, dst, size);
#endif
case AF_INET6:
/* Format IPv6 without deleting zeroes */
return PrintInetIPv6(src, dst, size);

@ -27,6 +27,8 @@
#include "suricata-common.h"
#include "util-random.h"
#if !(defined(HAVE_WINCRYPT_H) && defined(OS_WIN32))
#if defined(HAVE_CLOCK_GETTIME)
static long int RandomGetClock(void)
@ -39,7 +41,7 @@ static long int RandomGetClock(void)
return value;
}
#elif !(defined(HAVE_WINCRYPT_H) && defined(OS_WIN32))
#else
static long int RandomGetPosix(void)
{
@ -53,6 +55,7 @@ static long int RandomGetPosix(void)
}
#endif
#endif /* !(defined(HAVE_WINCRYPT_H) && defined(OS_WIN32)) */
#if defined(HAVE_WINCRYPT_H) && defined(OS_WIN32)
#include <wincrypt.h>
@ -63,9 +66,21 @@ long int RandomGet(void)
return 0;
HCRYPTPROV p;
if (!(CryptAcquireContext(&p, NULL, NULL,
PROV_RSA_FULL, 0))) {
return -1;
if (!CryptAcquireContext(&p, NULL, NULL, PROV_RSA_FULL, 0)) {
DWORD err = GetLastError();
SCLogDebug("CryptAcquireContext error: %" PRIu32, (uint32_t)err);
if (err == (DWORD)NTE_BAD_KEYSET) {
/* The key doesn't exist yet, create it */
if (!CryptAcquireContext(&p, NULL, NULL, PROV_RSA_FULL,
CRYPT_NEWKEYSET)) {
SCLogDebug("CryptAcquireContext error: %" PRIu32,
(uint32_t)err);
return -1;
}
} else {
return -1;
}
}
long int value = 0;

@ -291,7 +291,7 @@ recurse:
sse *= 10;
sse += *bp++ - '0';
rulim /= 10;
} while ((sse * 10 <= TIME_MAX) &&
} while (((uint64_t)sse * 10 <= TIME_MAX) &&
rulim && *bp >= '0' && *bp <= '9');
if (sse < 0 || (uint64_t)sse > TIME_MAX) {

@ -52,6 +52,8 @@ void unsetenv(const char *name)
SCFree(str);
}
/* these functions have been defined on Vista and later */
#if NTDDI_VERSION < NTDDI_VISTA
const char* inet_ntop(int af, const void *src, char *dst, uint32_t cnt)
{
if (af == AF_INET)
@ -116,5 +118,6 @@ int inet_pton(int af, const char *src, void *dst)
return -1;
}
#endif
#endif /* OS_WIN32 */

@ -24,6 +24,8 @@
#ifndef __WIN32_MISC_H__
#define __WIN32_MISC_H__
#include <sdkddkver.h>
#define index strchr
#define rindex strrchr
@ -36,8 +38,10 @@
void setenv(const char *name, const char *value, int overwrite);
void unsetenv(const char *name);
#if NTDDI_VERSION < NTDDI_VISTA
const char* inet_ntop(int af, const void *src, char *dst, uint32_t cnt);
int inet_pton(int af, const char *src, void *dst);
#endif
#define geteuid() (0)

File diff suppressed because it is too large Load Diff

@ -0,0 +1,53 @@
/* Copyright (C) 2018 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/**
* \file
*
* \author Jacob Masen-Smith <jacob@evengx.com>
*
* Isolation for WMI/COM functionality
*/
#ifndef __WIN32_SYSCALL_H__
#define __WIN32_SYSCALL_H__
#ifdef OS_WIN32
#include <inttypes.h>
#include <iptypes.h>
#include "util-device.h"
const char *Win32GetErrorString(DWORD error_code, HMODULE ext_module);
uint32_t Win32GetAdaptersAddresses(IP_ADAPTER_ADDRESSES **pif_info_list);
uint32_t Win32FindAdapterAddresses(IP_ADAPTER_ADDRESSES *if_info_list,
const char *adapter_name,
IP_ADAPTER_ADDRESSES **pif_info);
int GetIfaceMTUWin32(const char *pcap_dev);
int GetGlobalMTUWin32(void);
int GetIfaceOffloadingWin32(const char *ifname, int csum, int other);
int DisableIfaceOffloadingWin32(LiveDevice *ldev, int csum, int other);
int RestoreIfaceOffloadingWin32(LiveDevice *ldev);
void Win32SyscallRegisterTests(void);
#endif /* OS_WIN32 */
#endif /* __WIN32_SYSCALL_H__ */
Loading…
Cancel
Save