From c594d0c1ad4ea738ca66a0d27ea1cfc5b966e155 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Thu, 11 Jun 2020 11:27:29 +0200 Subject: [PATCH] reject: allow configuration of the reject interface Using the '--reject-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. --- src/respond-reject-libnet11.c | 403 ++++++++++++++++++---------------- src/respond-reject-libnet11.h | 2 + src/respond-reject.c | 9 +- src/runmode-af-packet.c | 2 +- src/runmode-pcap.c | 1 - src/suricata.c | 15 ++ 6 files changed, 241 insertions(+), 191 deletions(-) diff --git a/src/respond-reject-libnet11.c b/src/respond-reject-libnet11.c index 0e15fe47fe..a4f3ab1ab7 100644 --- a/src/respond-reject-libnet11.c +++ b/src/respond-reject-libnet11.c @@ -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 -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 */ diff --git a/src/respond-reject-libnet11.h b/src/respond-reject-libnet11.h index 06fdde45f4..f7ffab98b7 100644 --- a/src/respond-reject-libnet11.h +++ b/src/respond-reject-libnet11.h @@ -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__ */ diff --git a/src/respond-reject.c b/src/respond-reject.c index 6f054fc8ae..b454f61060 100644 --- a/src/respond-reject.c +++ b/src/respond-reject.c @@ -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 */ diff --git a/src/runmode-af-packet.c b/src/runmode-af-packet.c index f7b2647b80..8143b43b00 100644 --- a/src/runmode-af-packet.c +++ b/src/runmode-af-packet.c @@ -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 diff --git a/src/runmode-pcap.c b/src/runmode-pcap.c index 53b49f74da..7cb35790f5 100644 --- a/src/runmode-pcap.c +++ b/src/runmode-pcap.c @@ -221,7 +221,6 @@ static void *ParsePcapConfig(const char *iface) aconf->snaplen = snaplen; } - return aconf; } diff --git a/src/suricata.c b/src/suricata.c index 675747dca7..dba6ba67d9 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -633,6 +633,9 @@ static void PrintUsage(const char *progname) #ifdef WINDIVERT printf("\t--windivert : run in inline WinDivert mode\n"); printf("\t--windivert-forward : run in inline WinDivert mode, as a gateway\n"); +#endif +#ifdef HAVE_LIBNET11 + printf("\t--reject-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) {