-/* Copyright (C) 2007-2014 Open Information Security Foundation
+/* Copyright (C) 2007-2019 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
*
* Netfilter's netfilter_queue support for reading packets from the
* kernel and setting verdicts back to it (inline mode).
- * Supported on Linux and Windows.
- *
- * \todo test if Receive and Verdict if both are present
*/
#include "suricata-common.h"
#include "source-nfq.h"
+/* Handle the case where no NFQ support is compiled in. */
#ifndef NFQ
-/** Handle the case where no NFQ support is compiled in.
- *
- */
-
-TmEcode NoNFQSupportExit(ThreadVars *, const void *, void **);
+static TmEcode NoNFQSupportExit(ThreadVars *, const void *, void **);
void TmModuleReceiveNFQRegister (void)
{
tmm_modules[TMM_RECEIVENFQ].name = "ReceiveNFQ";
tmm_modules[TMM_RECEIVENFQ].ThreadInit = NoNFQSupportExit;
- tmm_modules[TMM_RECEIVENFQ].Func = NULL;
tmm_modules[TMM_RECEIVENFQ].ThreadExitPrintStats = NULL;
tmm_modules[TMM_RECEIVENFQ].ThreadDeinit = NULL;
tmm_modules[TMM_RECEIVENFQ].RegisterTests = NULL;
{
tmm_modules[TMM_VERDICTNFQ].name = "VerdictNFQ";
tmm_modules[TMM_VERDICTNFQ].ThreadInit = NoNFQSupportExit;
- tmm_modules[TMM_VERDICTNFQ].Func = NULL;
tmm_modules[TMM_VERDICTNFQ].ThreadExitPrintStats = NULL;
tmm_modules[TMM_VERDICTNFQ].ThreadDeinit = NULL;
tmm_modules[TMM_VERDICTNFQ].RegisterTests = NULL;
{
tmm_modules[TMM_DECODENFQ].name = "DecodeNFQ";
tmm_modules[TMM_DECODENFQ].ThreadInit = NoNFQSupportExit;
- tmm_modules[TMM_DECODENFQ].Func = NULL;
tmm_modules[TMM_DECODENFQ].ThreadExitPrintStats = NULL;
tmm_modules[TMM_DECODENFQ].ThreadDeinit = NULL;
tmm_modules[TMM_DECODENFQ].RegisterTests = NULL;
tmm_modules[TMM_DECODENFQ].flags = TM_FLAG_DECODE_TM;
}
-TmEcode NoNFQSupportExit(ThreadVars *tv, const void *initdata, void **data)
+static TmEcode NoNFQSupportExit(ThreadVars *tv, const void *initdata, void **data)
{
- SCLogError(SC_ERR_NFQ_NOSUPPORT,"Error creating thread %s: you do not have support for nfqueue "
- "enabled please recompile with --enable-nfqueue", tv->name);
- exit(EXIT_FAILURE);
+ FatalError(SC_ERR_NFQ_NOSUPPORT,"Error creating thread %s: you do not "
+ "have support for nfqueue enabled please recompile with "
+ "--enable-nfqueue", tv->name);
}
-#else /* implied we do have NFQ support */
+#else /* we do have NFQ support */
extern int max_pending_packets;
#define SOL_NETLINK 270
#endif
-//#define NFQ_DFT_QUEUE_LEN NFQ_BURST_FACTOR * MAX_PENDING
-//#define NFQ_NF_BUFSIZE 1500 * NFQ_DFT_QUEUE_LEN
-
typedef struct NFQThreadVars_
{
uint16_t nfq_index;
tmm_modules[TMM_RECEIVENFQ].name = "ReceiveNFQ";
tmm_modules[TMM_RECEIVENFQ].ThreadInit = ReceiveNFQThreadInit;
- tmm_modules[TMM_RECEIVENFQ].Func = NULL;
tmm_modules[TMM_RECEIVENFQ].PktAcqLoop = ReceiveNFQLoop;
tmm_modules[TMM_RECEIVENFQ].PktAcqBreakLoop = NULL;
tmm_modules[TMM_RECEIVENFQ].ThreadExitPrintStats = ReceiveNFQThreadExitStats;
tmm_modules[TMM_RECEIVENFQ].ThreadDeinit = ReceiveNFQThreadDeinit;
- tmm_modules[TMM_RECEIVENFQ].RegisterTests = NULL;
tmm_modules[TMM_RECEIVENFQ].flags = TM_FLAG_RECEIVE_TM;
}
tmm_modules[TMM_VERDICTNFQ].name = "VerdictNFQ";
tmm_modules[TMM_VERDICTNFQ].ThreadInit = VerdictNFQThreadInit;
tmm_modules[TMM_VERDICTNFQ].Func = VerdictNFQ;
- tmm_modules[TMM_VERDICTNFQ].ThreadExitPrintStats = NULL;
tmm_modules[TMM_VERDICTNFQ].ThreadDeinit = VerdictNFQThreadDeinit;
tmm_modules[TMM_VERDICTNFQ].RegisterTests = NULL;
}
tmm_modules[TMM_DECODENFQ].name = "DecodeNFQ";
tmm_modules[TMM_DECODENFQ].ThreadInit = DecodeNFQThreadInit;
tmm_modules[TMM_DECODENFQ].Func = DecodeNFQ;
- tmm_modules[TMM_DECODENFQ].ThreadExitPrintStats = NULL;
tmm_modules[TMM_DECODENFQ].ThreadDeinit = DecodeNFQThreadDeinit;
- tmm_modules[TMM_DECODENFQ].RegisterTests = NULL;
tmm_modules[TMM_DECODENFQ].flags = TM_FLAG_DECODE_TM;
}
ph = nfq_get_msg_packet_hdr(tb);
if (ph != NULL) {
p->nfq_v.id = SCNtohl(ph->packet_id);
- //p->nfq_v.hw_protocol = SCNtohs(p->nfq_v.ph->hw_protocol);
p->nfq_v.hw_protocol = ph->hw_protocol;
}
/* coverity[missing_lock] */
*/
static void NFQRecvPkt(NFQQueueVars *t, NFQThreadVars *tv)
{
- int rv, ret;
+ int ret;
int flag = NFQVerdictCacheLen(t) ? MSG_DONTWAIT : 0;
- /* XXX what happens on rv == 0? */
- rv = recv(t->fd, tv->data, tv->datalen, flag);
-
+ int rv = recv(t->fd, tv->data, tv->datalen, flag);
if (rv < 0) {
if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) {
/* no error on timeout */
t->dbg_maxreadsize = rv;
#endif /* DBG_PERF */
- //printf("NFQRecvPkt: t %p, rv = %" PRId32 "\n", t, rv);
-
NFQMutexLock(t);
if (t->qh != NULL) {
ret = nfq_handle_packet(t->h, tv->data, rv);
TmEcode NFQSetVerdict(Packet *p)
{
int iter = 0;
- int ret = 0;
/* we could also have a direct pointer but we need to have a ref counf in this case */
NFQQueueVars *t = g_nfq_q + p->nfq_v.nfq_index;
- /** \todo add a test on validity of the entry NFQQueueVars could have been
- * wipeout
- */
-
p->nfq_v.verdicted = 1;
/* can't verdict a "fake" packet */
UpdateCounters(t, p);
#endif /* COUNTERS */
- ret = NFQVerdictCacheAdd(t, p, verdict);
+ int ret = NFQVerdictCacheAdd(t, p, verdict);
if (ret == 0) {
NFQMutexUnlock(t);
return TM_ECODE_OK;
/* update counters */
CaptureStatsUpdate(tv, &ntv->stats, p);
- int ret;
/* if this is a tunnel packet we check if we are ready to verdict
* already. */
if (IS_TUNNEL_PKT(p)) {
bool verdict = VerdictTunnelPacket(p);
/* don't verdict if we are not ready */
if (verdict == true) {
- ret = NFQSetVerdict(p->root ? p->root : p);
+ int ret = NFQSetVerdict(p->root ? p->root : p);
if (ret != TM_ECODE_OK) {
return ret;
}
}
} else {
/* no tunnel, verdict normally */
- ret = NFQSetVerdict(p);
+ int ret = NFQSetVerdict(p);
if (ret != TM_ECODE_OK) {
return ret;
}
}
SCLogDebug("IPv4 packet");
DecodeIPV4(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
- } else if(IPV6_GET_RAW_VER(ip6h) == 6) {
+ } else if (IPV6_GET_RAW_VER(ip6h) == 6) {
if (unlikely(GET_PKT_LEN(p) > USHRT_MAX)) {
return TM_ECODE_FAILED;
}
*/
TmEcode DecodeNFQThreadInit(ThreadVars *tv, const void *initdata, void **data)
{
- DecodeThreadVars *dtv = NULL;
- dtv = DecodeThreadVarsAlloc(tv);
-
+ DecodeThreadVars *dtv = DecodeThreadVarsAlloc(tv);
if (dtv == NULL)
SCReturnInt(TM_ECODE_FAILED);
DecodeRegisterPerfCounters(dtv, tv);
*data = (void *)dtv;
-
return TM_ECODE_OK;
}
g_nfq_t = NULL;
}
}
-
#endif /* NFQ */