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 7 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.
*/
@ -1618,6 +1639,8 @@ void RegisterDNP3Parsers(void)
DNP3GetEvents);
AppLayerParserRegisterDetectStateFuncs(IPPROTO_TCP, ALPROTO_DNP3,
DNP3GetTxDetectState, DNP3SetTxDetectState);
AppLayerParserRegisterDetectFlagsFuncs(IPPROTO_TCP, ALPROTO_DNP3,
DNP3GetTxDetectFlags, DNP3SetTxDetectFlags);
AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_DNP3, DNP3GetTx);
AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_DNP3, DNP3GetTxCnt);

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

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

Loading…
Cancel
Save