reject: allow configuration of the reject interface

Using the '--reject-dev <dev>' commandline option. This is a global option
that applies to all 'reject' actions.

If the interface specified is using ethernet, libnet will use the faster
L2 (link) layer. Suricata sets up the ethernet header based on the packet.

When the interface is specified, cache libnet_t ctx for (much) better
performance.
pull/5110/head
Victor Julien 5 years ago
parent 604aa65c80
commit c594d0c1ad

@ -57,13 +57,17 @@
#define LIBNET_INIT_CAST
#endif
/* Globally configured device to use for sending resets in IDS mode. */
const char *g_reject_dev = NULL;
/** set to true in main if we're setting caps. We need it here if we're using
* reject rules as libnet 1.1 is not compatible with caps. */
extern int sc_set_caps;
#include <libnet.h>
extern uint8_t host_mode;
thread_local libnet_t *t_c = NULL;
thread_local int t_inject_mode = -1;
typedef struct Libnet11Packet_ {
uint32_t ack, seq;
@ -76,38 +80,59 @@ typedef struct Libnet11Packet_ {
uint32_t src4, dst4;
uint16_t sp, dp;
size_t len;
uint8_t *smac, *dmac;
} Libnet11Packet;
int RejectSendLibnet11L3IPv4TCP(ThreadVars *tv, Packet *p, void *data, int dir)
static inline libnet_t *GetCtx(const Packet *p, int injection_type)
{
Libnet11Packet lpacket;
libnet_t *c; /* libnet context */
char ebuf[LIBNET_ERRBUF_SIZE];
int result;
const char *devname = NULL;
/* fill in struct defaults */
lpacket.ttl = 0;
lpacket.id = 0;
lpacket.flow = 0;
lpacket.class = 0;
/* fast path: use cache ctx */
if (t_c)
return t_c;
if (IS_SURI_HOST_MODE_SNIFFER_ONLY(host_mode) && (p->livedev)) {
devname = p->livedev->dev;
SCLogDebug("Will emit reject packet on dev %s", devname);
/* slow path: setup a new ctx */
bool store_ctx = false;
const char *devname = NULL;
extern uint8_t host_mode;
if (IS_SURI_HOST_MODE_SNIFFER_ONLY(host_mode)) {
if (g_reject_dev != NULL) {
if (p->datalink == LINKTYPE_ETHERNET)
injection_type = t_inject_mode = LIBNET_LINK;
devname = g_reject_dev;
store_ctx = true;
} else {
devname = p->livedev ? p->livedev->dev : NULL;
}
}
if (p->tcph == NULL)
return 1;
if ((c = libnet_init(LIBNET_RAW4, LIBNET_INIT_CAST devname, ebuf)) == NULL) {
char ebuf[LIBNET_ERRBUF_SIZE];
libnet_t *c = libnet_init(injection_type, LIBNET_INIT_CAST devname, ebuf);
if (c == NULL) {
SCLogError(SC_ERR_LIBNET_INIT,"libnet_init failed: %s", ebuf);
return 1;
}
if (store_ctx) {
t_c = c;
}
return c;
}
/* save payload len */
lpacket.dsize = p->payload_len;
static inline void ClearCtx(libnet_t *c)
{
if (t_c == c)
libnet_clear_packet(c);
else
libnet_destroy(c);
}
void FreeCachedCtx(void)
{
if (t_c) {
libnet_destroy(t_c);
t_c = NULL;
}
}
static inline void SetupTCP(Packet *p, Libnet11Packet *lpacket, int dir)
{
switch (dir) {
case REJECT_DIR_SRC:
SCLogDebug("sending a tcp reset to src");
@ -117,50 +142,41 @@ int RejectSendLibnet11L3IPv4TCP(ThreadVars *tv, Packet *p, void *data, int dir)
* is equal to the ACK of incoming packet and the ACK is build
* using packet sequence number and size of the data. */
if (TCP_GET_ACK(p) == 0) {
lpacket.seq = 0;
lpacket.ack = TCP_GET_SEQ(p) + lpacket.dsize + 1;
lpacket->seq = 0;
lpacket->ack = TCP_GET_SEQ(p) + lpacket->dsize + 1;
} else {
lpacket.seq = TCP_GET_ACK(p);
lpacket.ack = TCP_GET_SEQ(p) + lpacket.dsize;
lpacket->seq = TCP_GET_ACK(p);
lpacket->ack = TCP_GET_SEQ(p) + lpacket->dsize;
}
lpacket.sp = TCP_GET_DST_PORT(p);
lpacket.dp = TCP_GET_SRC_PORT(p);
lpacket.src4 = GET_IPV4_DST_ADDR_U32(p);
lpacket.dst4 = GET_IPV4_SRC_ADDR_U32(p);
lpacket->sp = TCP_GET_DST_PORT(p);
lpacket->dp = TCP_GET_SRC_PORT(p);
break;
case REJECT_DIR_DST:
SCLogDebug("sending a tcp reset to dst");
lpacket.seq = TCP_GET_SEQ(p);
lpacket.ack = TCP_GET_ACK(p);
lpacket.sp = TCP_GET_SRC_PORT(p);
lpacket.dp = TCP_GET_DST_PORT(p);
lpacket->seq = TCP_GET_SEQ(p);
lpacket->ack = TCP_GET_ACK(p);
lpacket.src4 = GET_IPV4_SRC_ADDR_U32(p);
lpacket.dst4 = GET_IPV4_DST_ADDR_U32(p);
lpacket->sp = TCP_GET_SRC_PORT(p);
lpacket->dp = TCP_GET_DST_PORT(p);
break;
default:
SCLogError(SC_ERR_LIBNET_INVALID_DIR,
"reset not src or dst returning");
return 1;
abort();
}
lpacket.window = TCP_GET_WINDOW(p);
lpacket->window = TCP_GET_WINDOW(p);
//lpacket.seq += lpacket.dsize;
}
/* TODO come up with ttl calc function */
lpacket.ttl = 64;
static inline int BuildTCP(libnet_t *c, Libnet11Packet *lpacket)
{
/* build the package */
if ((libnet_build_tcp(
lpacket.sp, /* source port */
lpacket.dp, /* dst port */
lpacket.seq, /* seq number */
lpacket.ack, /* ack number */
lpacket->sp, /* source port */
lpacket->dp, /* dst port */
lpacket->seq, /* seq number */
lpacket->ack, /* ack number */
TH_RST|TH_ACK, /* flags */
lpacket.window, /* window size */
lpacket->window, /* window size */
0, /* checksum */
0, /* urgent flag */
LIBNET_TCP_H, /* header length */
@ -170,26 +186,129 @@ int RejectSendLibnet11L3IPv4TCP(ThreadVars *tv, Packet *p, void *data, int dir)
0)) < 0) /* libnet ptag */
{
SCLogError(SC_ERR_LIBNET_BUILD_FAILED,"libnet_build_tcp %s", libnet_geterror(c));
goto cleanup;
return -1;
}
return 0;
}
static inline int BuildIPv4(libnet_t *c, Libnet11Packet *lpacket, const uint8_t proto)
{
const int len = LIBNET_IPV4_H + lpacket->len +
((proto == IPPROTO_TCP) ? LIBNET_TCP_H : LIBNET_ICMPV4_H);
if ((libnet_build_ipv4(
LIBNET_TCP_H + LIBNET_IPV4_H, /* entire packet length */
len, /* entire packet length */
0, /* tos */
lpacket.id, /* ID */
lpacket->id, /* ID */
0, /* fragmentation flags and offset */
lpacket.ttl, /* TTL */
IPPROTO_TCP, /* protocol */
lpacket->ttl, /* TTL */
proto, /* protocol */
0, /* checksum */
lpacket.src4, /* source address */
lpacket.dst4, /* destination address */
lpacket->src4, /* source address */
lpacket->dst4, /* destination address */
NULL, /* pointer to packet data (or NULL) */
0, /* payload length */
c, /* libnet context pointer */
0)) < 0) /* packet id */
{
SCLogError(SC_ERR_LIBNET_BUILD_FAILED,"libnet_build_ipv4 %s", libnet_geterror(c));
return -1;
}
return 0;
}
static inline int BuildIPv6(libnet_t *c, Libnet11Packet *lpacket, const uint8_t proto)
{
const int len = lpacket->len +
((proto == IPPROTO_TCP) ? LIBNET_TCP_H : LIBNET_ICMPV6_H);
if ((libnet_build_ipv6(
lpacket->class, /* traffic class */
lpacket->flow, /* Flow label */
len, /* payload length */
proto, /* next header */
lpacket->ttl, /* TTL */
lpacket->src6, /* source address */
lpacket->dst6, /* destination address */
NULL, /* pointer to packet data (or NULL) */
0, /* payload length */
c, /* libnet context pointer */
0)) < 0) /* packet id */
{
SCLogError(SC_ERR_LIBNET_BUILD_FAILED,"libnet_build_ipv6 %s", libnet_geterror(c));
return -1;
}
return 0;
}
static inline void SetupEthernet(Packet *p, Libnet11Packet *lpacket, int dir)
{
switch (dir) {
case REJECT_DIR_SRC:
lpacket->smac = p->ethh->eth_dst;
lpacket->dmac = p->ethh->eth_src;
break;
case REJECT_DIR_DST:
lpacket->smac = p->ethh->eth_src;
lpacket->dmac = p->ethh->eth_dst;
break;
default:
abort();
}
}
static inline int BuildEthernet(libnet_t *c, Libnet11Packet *lpacket, uint16_t proto)
{
if ((libnet_build_ethernet(lpacket->dmac,lpacket->smac, proto , NULL, 0, c, 0)) < 0) {
SCLogError(SC_ERR_LIBNET_BUILD_FAILED,"libnet_build_ethernet %s", libnet_geterror(c));
return -1;
}
return 0;
}
int RejectSendLibnet11L3IPv4TCP(ThreadVars *tv, Packet *p, void *data, int dir)
{
Libnet11Packet lpacket;
int result;
/* fill in struct defaults */
lpacket.ttl = 0;
lpacket.id = 0;
lpacket.flow = 0;
lpacket.class = 0;
if (p->tcph == NULL)
return 1;
libnet_t *c = GetCtx(p, LIBNET_RAW4);
if (c == NULL)
return 1;
/* save payload len */
lpacket.dsize = p->payload_len;
switch (dir) {
case REJECT_DIR_SRC:
lpacket.src4 = GET_IPV4_DST_ADDR_U32(p);
lpacket.dst4 = GET_IPV4_SRC_ADDR_U32(p);
break;
case REJECT_DIR_DST:
lpacket.src4 = GET_IPV4_SRC_ADDR_U32(p);
lpacket.dst4 = GET_IPV4_DST_ADDR_U32(p);
break;
}
/* TODO come up with ttl calc function */
lpacket.ttl = 64;
SetupTCP(p, &lpacket, dir);
if (BuildTCP(c, &lpacket) < 0)
goto cleanup;
if (BuildIPv4(c, &lpacket, IPPROTO_TCP) < 0)
goto cleanup;
if (t_inject_mode == LIBNET_LINK) {
SetupEthernet(p, &lpacket, dir);
if (BuildEthernet(c, &lpacket, ETHERNET_TYPE_IP) < 0)
goto cleanup;
}
result = libnet_write(c);
@ -199,17 +318,14 @@ int RejectSendLibnet11L3IPv4TCP(ThreadVars *tv, Packet *p, void *data, int dir)
}
cleanup:
libnet_destroy (c);
ClearCtx(c);
return 0;
}
int RejectSendLibnet11L3IPv4ICMP(ThreadVars *tv, Packet *p, void *data, int dir)
{
Libnet11Packet lpacket;
libnet_t *c; /* libnet context */
char ebuf[LIBNET_ERRBUF_SIZE];
int result;
const char *devname = NULL;
/* fill in struct defaults */
lpacket.ttl = 0;
@ -218,13 +334,9 @@ int RejectSendLibnet11L3IPv4ICMP(ThreadVars *tv, Packet *p, void *data, int dir)
lpacket.class = 0;
lpacket.len = (IPV4_GET_HLEN(p) + p->payload_len);
if (IS_SURI_HOST_MODE_SNIFFER_ONLY(host_mode) && (p->livedev)) {
devname = p->livedev->dev;
}
if ((c = libnet_init(LIBNET_RAW4, LIBNET_INIT_CAST devname, ebuf)) == NULL) {
SCLogError(SC_ERR_LIBNET_INIT,"libnet_inint failed: %s", ebuf);
libnet_t *c = GetCtx(p, LIBNET_RAW4);
if (c == NULL)
return 1;
}
switch (dir) {
case REJECT_DIR_SRC:
@ -258,24 +370,13 @@ int RejectSendLibnet11L3IPv4ICMP(ThreadVars *tv, Packet *p, void *data, int dir)
goto cleanup;
}
if ((libnet_build_ipv4(
LIBNET_ICMPV4_H + LIBNET_IPV4_H +
lpacket.len, /* entire packet length */
0, /* tos */
lpacket.id, /* ID */
0, /* fragmentation flags and offset */
lpacket.ttl, /* TTL */
IPPROTO_ICMP, /* protocol */
0, /* checksum */
lpacket.src4, /* source address */
lpacket.dst4, /* destination address */
NULL, /* pointer to packet data (or NULL) */
0, /* payload length */
c, /* libnet context pointer */
0)) < 0) /* packet id */
{
SCLogError(SC_ERR_LIBNET_BUILD_FAILED,"libnet_build_ipv4 %s", libnet_geterror(c));
if (BuildIPv4(c, &lpacket, IPPROTO_ICMP) < 0)
goto cleanup;
if (t_inject_mode == LIBNET_LINK) {
SetupEthernet(p, &lpacket, dir);
if (BuildEthernet(c, &lpacket, ETHERNET_TYPE_IP) < 0)
goto cleanup;
}
result = libnet_write(c);
@ -285,17 +386,14 @@ int RejectSendLibnet11L3IPv4ICMP(ThreadVars *tv, Packet *p, void *data, int dir)
}
cleanup:
libnet_destroy (c);
ClearCtx(c);
return 0;
}
int RejectSendLibnet11L3IPv6TCP(ThreadVars *tv, Packet *p, void *data, int dir)
{
Libnet11Packet lpacket;
libnet_t *c; /* libnet context */
char ebuf[LIBNET_ERRBUF_SIZE];
int result;
const char *devname = NULL;
/* fill in struct defaults */
lpacket.ttl = 0;
@ -303,102 +401,40 @@ int RejectSendLibnet11L3IPv6TCP(ThreadVars *tv, Packet *p, void *data, int dir)
lpacket.flow = 0;
lpacket.class = 0;
if (IS_SURI_HOST_MODE_SNIFFER_ONLY(host_mode) && (p->livedev)) {
devname = p->livedev->dev;
}
if (p->tcph == NULL)
return 1;
if ((c = libnet_init(LIBNET_RAW6, LIBNET_INIT_CAST devname, ebuf)) == NULL) {
SCLogError(SC_ERR_LIBNET_INIT,"libnet_init failed: %s", ebuf);
libnet_t *c = GetCtx(p, LIBNET_RAW6);
if (c == NULL)
return 1;
}
/* save payload len */
lpacket.dsize = p->payload_len;
switch (dir) {
case REJECT_DIR_SRC:
SCLogDebug("sending a tcp reset to src");
/* We follow http://tools.ietf.org/html/rfc793#section-3.4 :
* If packet has no ACK, the seq number is 0 and the ACK is built
* the normal way. If packet has a ACK, the seq of the RST packet
* is equal to the ACK of incoming packet and the ACK is build
* using packet sequence number and size of the data. */
if (TCP_GET_ACK(p) == 0) {
lpacket.seq = 0;
lpacket.ack = TCP_GET_SEQ(p) + lpacket.dsize + 1;
} else {
lpacket.seq = TCP_GET_ACK(p);
lpacket.ack = TCP_GET_SEQ(p) + lpacket.dsize;
}
lpacket.sp = TCP_GET_DST_PORT(p);
lpacket.dp = TCP_GET_SRC_PORT(p);
memcpy(lpacket.src6.libnet_s6_addr, GET_IPV6_DST_ADDR(p), 16);
memcpy(lpacket.dst6.libnet_s6_addr, GET_IPV6_SRC_ADDR(p), 16);
break;
case REJECT_DIR_DST:
SCLogDebug("sending a tcp reset to dst");
lpacket.seq = TCP_GET_SEQ(p);
lpacket.ack = TCP_GET_ACK(p);
lpacket.sp = TCP_GET_SRC_PORT(p);
lpacket.dp = TCP_GET_DST_PORT(p);
memcpy(lpacket.src6.libnet_s6_addr, GET_IPV6_SRC_ADDR(p), 16);
memcpy(lpacket.dst6.libnet_s6_addr, GET_IPV6_DST_ADDR(p), 16);
break;
default:
SCLogError(SC_ERR_LIBNET_INVALID_DIR,
"reset not src or dst returning");
return 1;
}
lpacket.window = TCP_GET_WINDOW(p);
//lpacket.seq += lpacket.dsize;
/* TODO come up with ttl calc function */
lpacket.ttl = 64;
/* build the package */
if ((libnet_build_tcp(
lpacket.sp, /* source port */
lpacket.dp, /* dst port */
lpacket.seq, /* seq number */
lpacket.ack, /* ack number */
TH_RST|TH_ACK, /* flags */
lpacket.window, /* window size */
0, /* checksum */
0, /* urgent flag */
LIBNET_TCP_H, /* header length */
NULL, /* payload */
0, /* payload length */
c, /* libnet context */
0)) < 0) /* libnet ptag */
{
SCLogError(SC_ERR_LIBNET_BUILD_FAILED,"libnet_build_tcp %s", libnet_geterror(c));
goto cleanup;
}
SetupTCP(p, &lpacket, dir);
if ((libnet_build_ipv6(
lpacket.class, /* traffic class */
lpacket.flow, /* Flow label */
LIBNET_TCP_H, /* payload length */
IPPROTO_TCP, /* next header */
lpacket.ttl, /* TTL */
lpacket.src6, /* source address */
lpacket.dst6, /* destination address */
NULL, /* pointer to packet data (or NULL) */
0, /* payload length */
c, /* libnet context pointer */
0)) < 0) /* packet id */
{
SCLogError(SC_ERR_LIBNET_BUILD_FAILED,"libnet_build_ipv6 %s", libnet_geterror(c));
BuildTCP(c, &lpacket);
if (BuildIPv6(c, &lpacket, IPPROTO_ICMP) < 0)
goto cleanup;
if (t_inject_mode == LIBNET_LINK) {
SetupEthernet(p, &lpacket, dir);
if (BuildEthernet(c, &lpacket, ETHERNET_TYPE_IPV6) < 0)
goto cleanup;
}
result = libnet_write(c);
@ -408,7 +444,7 @@ int RejectSendLibnet11L3IPv6TCP(ThreadVars *tv, Packet *p, void *data, int dir)
}
cleanup:
libnet_destroy (c);
ClearCtx(c);
return 0;
}
@ -416,10 +452,7 @@ cleanup:
int RejectSendLibnet11L3IPv6ICMP(ThreadVars *tv, Packet *p, void *data, int dir)
{
Libnet11Packet lpacket;
libnet_t *c; /* libnet context */
char ebuf[LIBNET_ERRBUF_SIZE];
int result;
const char *devname = NULL;
/* fill in struct defaults */
lpacket.ttl = 0;
@ -428,13 +461,9 @@ int RejectSendLibnet11L3IPv6ICMP(ThreadVars *tv, Packet *p, void *data, int dir)
lpacket.class = 0;
lpacket.len = IPV6_GET_PLEN(p) + IPV6_HEADER_LEN;
if (IS_SURI_HOST_MODE_SNIFFER_ONLY(host_mode) && (p->livedev)) {
devname = p->livedev->dev;
}
if ((c = libnet_init(LIBNET_RAW6, LIBNET_INIT_CAST devname, ebuf)) == NULL) {
SCLogError(SC_ERR_LIBNET_INIT,"libnet_inint failed: %s", ebuf);
libnet_t *c = GetCtx(p, LIBNET_RAW6);
if (c == NULL)
return 1;
}
switch (dir) {
case REJECT_DIR_SRC:
@ -468,21 +497,13 @@ int RejectSendLibnet11L3IPv6ICMP(ThreadVars *tv, Packet *p, void *data, int dir)
goto cleanup;
}
if ((libnet_build_ipv6(
lpacket.class, /* traffic class */
lpacket.flow, /* Flow label */
LIBNET_ICMPV6_H + lpacket.len, /* IPv6 payload length */
IPPROTO_ICMPV6, /* next header */
lpacket.ttl, /* TTL */
lpacket.src6, /* source address */
lpacket.dst6, /* destination address */
NULL, /* pointer to packet data (or NULL) */
0, /* payload length */
c, /* libnet context pointer */
0)) < 0) /* packet id */
{
SCLogError(SC_ERR_LIBNET_BUILD_FAILED,"libnet_build_ipv6 %s", libnet_geterror(c));
if (BuildIPv6(c, &lpacket, IPPROTO_ICMP) < 0)
goto cleanup;
if (t_inject_mode == LIBNET_LINK) {
SetupEthernet(p, &lpacket, dir);
if (BuildEthernet(c, &lpacket, ETHERNET_TYPE_IPV6) < 0)
goto cleanup;
}
result = libnet_write(c);
@ -492,9 +513,10 @@ int RejectSendLibnet11L3IPv6ICMP(ThreadVars *tv, Packet *p, void *data, int dir)
}
cleanup:
libnet_destroy (c);
ClearCtx(c);
return 0;
}
#else /* HAVE_LIBNET_ICMPV6_UNREACH */
int RejectSendLibnet11L3IPv6ICMP(ThreadVars *tv, Packet *p, void *data, int dir)
@ -541,4 +563,9 @@ int RejectSendLibnet11L3IPv6ICMP(ThreadVars *tv, Packet *p, void *data, int dir)
return 0;
}
void FreeCachedCtx(void)
{
SCLogDebug("no libhnet support");
}
#endif /* HAVE_LIBNET11 */

@ -31,4 +31,6 @@ int RejectSendLibnet11L3IPv4ICMP(ThreadVars *, Packet *, void *,int);
int RejectSendLibnet11L3IPv6TCP(ThreadVars *, Packet *, void *,int);
int RejectSendLibnet11L3IPv6ICMP(ThreadVars *, Packet *, void *,int);
void FreeCachedCtx(void);
#endif /* __RESPOND_REJECT_LIBNET11_H__ */

@ -44,17 +44,24 @@ int RejectSendIPv4ICMP(ThreadVars *, Packet *, void *);
int RejectSendIPv6TCP(ThreadVars *, Packet *, void *);
int RejectSendIPv6ICMP(ThreadVars *, Packet *, void *);
static TmEcode RespondRejectFunc(ThreadVars *tv, Packet *p, void *data);
static TmEcode RespondRejectThreadDeinit(ThreadVars *tv, void *data);
void TmModuleRespondRejectRegister (void)
{
tmm_modules[TMM_RESPONDREJECT].name = "RespondReject";
tmm_modules[TMM_RESPONDREJECT].ThreadInit = NULL;
tmm_modules[TMM_RESPONDREJECT].Func = RespondRejectFunc;
tmm_modules[TMM_RESPONDREJECT].ThreadDeinit = NULL;
tmm_modules[TMM_RESPONDREJECT].ThreadDeinit = RespondRejectThreadDeinit;
tmm_modules[TMM_RESPONDREJECT].RegisterTests = NULL;
tmm_modules[TMM_RESPONDREJECT].cap_flags = 0; /* libnet is not compat with caps */
}
static TmEcode RespondRejectThreadDeinit(ThreadVars *tv, void *data)
{
FreeCachedCtx();
return TM_ECODE_OK;
}
static TmEcode RespondRejectFunc(ThreadVars *tv, Packet *p, void *data)
{
/* ACTION_REJECT defaults to rejecting the SRC */

@ -1,4 +1,4 @@
/* Copyright (C) 2011-2016 Open Information Security Foundation
/* Copyright (C) 2011-2020 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

@ -221,7 +221,6 @@ static void *ParsePcapConfig(const char *iface)
aconf->snaplen = snaplen;
}
return aconf;
}

@ -633,6 +633,9 @@ static void PrintUsage(const char *progname)
#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
#ifdef HAVE_LIBNET11
printf("\t--reject-dev <dev> : send reject packets from this interface\n");
#endif
printf("\t--set name=value : set a configuration value\n");
printf("\n");
@ -1229,6 +1232,9 @@ static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri)
#ifdef WINDIVERT
{"windivert", required_argument, 0, 0},
{"windivert-forward", required_argument, 0, 0},
#endif
#ifdef HAVE_LIBNET11
{"reject-dev", required_argument, 0, 0},
#endif
{"set", required_argument, 0, 0},
#ifdef HAVE_NFLOG
@ -1524,6 +1530,15 @@ static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri)
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, "reject-dev") == 0) {
#ifdef HAVE_LIBNET11
extern char *g_reject_dev;
g_reject_dev = optarg;
#else
SCLogError(SC_ERR_LIBNET_NOT_ENABLED,
"Libnet 1.1 support not enabled. Compile Suricata with libnet support.");
return TM_ECODE_FAILED;
#endif
}
else if (strcmp((long_opts[option_index]).name, "set") == 0) {
if (optarg != NULL) {

Loading…
Cancel
Save