detect/dnp3: add dnp3.data with v2 api support

Adds MPM support as well. Add TxDetectFlags support to the parser
to avoid duplicate matches.
pull/3826/head
Victor Julien 8 years ago
parent 09a21627d5
commit 752bb1c410

@ -1568,6 +1568,27 @@ int DNP3PrefixIsSize(uint8_t prefix_code)
} }
} }
static uint64_t DNP3GetTxDetectFlags(void *vtx, uint8_t dir)
{
DNP3Transaction *tx = (DNP3Transaction *)vtx;
if (dir & STREAM_TOSERVER) {
return tx->detect_flags_ts;
} else {
return tx->detect_flags_tc;
}
}
static void DNP3SetTxDetectFlags(void *vtx, uint8_t dir, uint64_t detect_flags)
{
DNP3Transaction *tx = (DNP3Transaction *)vtx;
if (dir & STREAM_TOSERVER) {
tx->detect_flags_ts = detect_flags;
} else {
tx->detect_flags_tc = detect_flags;
}
return;
}
/** /**
* \brief Register the DNP3 application protocol parser. * \brief Register the DNP3 application protocol parser.
*/ */
@ -1618,6 +1639,8 @@ void RegisterDNP3Parsers(void)
DNP3GetEvents); DNP3GetEvents);
AppLayerParserRegisterDetectStateFuncs(IPPROTO_TCP, ALPROTO_DNP3, AppLayerParserRegisterDetectStateFuncs(IPPROTO_TCP, ALPROTO_DNP3,
DNP3GetTxDetectState, DNP3SetTxDetectState); DNP3GetTxDetectState, DNP3SetTxDetectState);
AppLayerParserRegisterDetectFlagsFuncs(IPPROTO_TCP, ALPROTO_DNP3,
DNP3GetTxDetectFlags, DNP3SetTxDetectFlags);
AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_DNP3, DNP3GetTx); AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_DNP3, DNP3GetTx);
AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_DNP3, DNP3GetTxCnt); AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_DNP3, DNP3GetTxCnt);

@ -207,6 +207,10 @@ typedef TAILQ_HEAD(DNP3ObjectList_, DNP3Object_) DNP3ObjectList;
* \brief DNP3 transaction. * \brief DNP3 transaction.
*/ */
typedef struct DNP3Transaction_ { typedef struct DNP3Transaction_ {
/** detection engine flags */
uint64_t detect_flags_ts;
uint64_t detect_flags_tc;
uint64_t tx_num; /**< Internal transaction ID. */ uint64_t tx_num; /**< Internal transaction ID. */
uint32_t logged; /**< Flags indicating which loggers have logged this tx. */ uint32_t logged; /**< Flags indicating which loggers have logged this tx. */

@ -23,6 +23,8 @@
#include "detect-parse.h" #include "detect-parse.h"
#include "detect-dnp3.h" #include "detect-dnp3.h"
#include "detect-engine.h" #include "detect-engine.h"
#include "detect-engine-mpm.h"
#include "detect-engine-prefilter.h"
#include "detect-engine-content-inspection.h" #include "detect-engine-content-inspection.h"
#include "app-layer-dnp3.h" #include "app-layer-dnp3.h"
@ -141,30 +143,35 @@ static char *TrimString(char *str)
return str; return str;
} }
static int DetectEngineInspectDNP3Data(ThreadVars *tv, DetectEngineCtx *de_ctx, static InspectionBuffer *GetDNP3Data(DetectEngineThreadCtx *det_ctx,
DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, const DetectEngineTransforms *transforms,
Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id) Flow *_f, const uint8_t flow_flags,
void *txv, const int list_id)
{ {
SCEnter(); SCLogDebug("list_id %d", list_id);
DNP3Transaction *tx = (DNP3Transaction *)txv; InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
if (buffer->inspect == NULL) {
int r = 0; DNP3Transaction *tx = (DNP3Transaction *)txv;
SCLogDebug("tx %p", tx);
const uint8_t *data = NULL;
uint32_t data_len = 0;
if (flow_flags & STREAM_TOSERVER) {
data = tx->request_buffer;
data_len = tx->request_buffer_len;
} else if (flow_flags & STREAM_TOCLIENT) {
data = tx->response_buffer;
data_len = tx->response_buffer_len;
}
if (data == NULL || data_len == 0)
return NULL;
/* Content match - should probably be put into its own file. */ SCLogDebug("tx %p data %p data_len %u", tx, data, data_len);
if (flags & STREAM_TOSERVER && tx->request_buffer != NULL) { InspectionBufferSetup(buffer, data, data_len);
r = DetectEngineContentInspection(de_ctx, det_ctx, s, InspectionBufferApplyTransforms(buffer, transforms);
smd, NULL, f, tx->request_buffer,
tx->request_buffer_len, 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE);
} }
else if (flags & STREAM_TOCLIENT && tx->response_buffer != NULL) { return buffer;
r = DetectEngineContentInspection(de_ctx, det_ctx, s,
smd, NULL, f, tx->response_buffer,
tx->response_buffer_len, 0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE);
}
SCReturnInt(r);
} }
static int DetectEngineInspectDNP3(ThreadVars *tv, DetectEngineCtx *de_ctx, static int DetectEngineInspectDNP3(ThreadVars *tv, DetectEngineCtx *de_ctx,
@ -533,7 +540,9 @@ static int DetectDNP3DataSetup(DetectEngineCtx *de_ctx, Signature *s, const char
if (DetectSignatureSetAppProto(s, ALPROTO_DNP3) != 0) if (DetectSignatureSetAppProto(s, ALPROTO_DNP3) != 0)
return -1; return -1;
DetectBufferSetActiveList(s, g_dnp3_data_buffer_id); if (DetectBufferSetActiveList(s, g_dnp3_data_buffer_id) != 0)
return -1;
SCReturnInt(0); SCReturnInt(0);
} }
@ -541,21 +550,29 @@ static void DetectDNP3DataRegister(void)
{ {
SCEnter(); SCEnter();
sigmatch_table[DETECT_AL_DNP3DATA].name = "dnp3_data"; sigmatch_table[DETECT_AL_DNP3DATA].name = "dnp3.data";
sigmatch_table[DETECT_AL_DNP3DATA].Match = NULL; sigmatch_table[DETECT_AL_DNP3DATA].alias = "dnp3_data";
sigmatch_table[DETECT_AL_DNP3DATA].Setup = DetectDNP3DataSetup; sigmatch_table[DETECT_AL_DNP3DATA].Setup = DetectDNP3DataSetup;
sigmatch_table[DETECT_AL_DNP3DATA].Free = NULL;
sigmatch_table[DETECT_AL_DNP3DATA].RegisterTests = sigmatch_table[DETECT_AL_DNP3DATA].RegisterTests =
DetectDNP3DataRegisterTests; DetectDNP3DataRegisterTests;
sigmatch_table[DETECT_AL_DNP3DATA].flags |= SIGMATCH_NOOPT; sigmatch_table[DETECT_AL_DNP3DATA].flags |= SIGMATCH_NOOPT|SIGMATCH_INFO_STICKY_BUFFER;
DetectAppLayerInspectEngineRegister("dnp3_data", DetectAppLayerInspectEngineRegister2("dnp3_data",
ALPROTO_DNP3, SIG_FLAG_TOSERVER, 0, ALPROTO_DNP3, SIG_FLAG_TOSERVER, 0,
DetectEngineInspectDNP3Data); DetectEngineInspectBufferGeneric,
DetectAppLayerInspectEngineRegister("dnp3_data", GetDNP3Data);
DetectAppLayerMpmRegister2("dnp3_data", SIG_FLAG_TOSERVER, 2,
PrefilterGenericMpmRegister, GetDNP3Data,
ALPROTO_DNP3, 0);
DetectAppLayerInspectEngineRegister2("dnp3_data",
ALPROTO_DNP3, SIG_FLAG_TOCLIENT, 0, ALPROTO_DNP3, SIG_FLAG_TOCLIENT, 0,
DetectEngineInspectDNP3Data); DetectEngineInspectBufferGeneric,
GetDNP3Data);
DetectAppLayerMpmRegister2("dnp3_data", SIG_FLAG_TOCLIENT, 2,
PrefilterGenericMpmRegister, GetDNP3Data,
ALPROTO_DNP3, 0);
g_dnp3_data_buffer_id = DetectBufferTypeGetByName("dnp3_data"); g_dnp3_data_buffer_id = DetectBufferTypeGetByName("dnp3_data");
SCReturn; SCReturn;

Loading…
Cancel
Save