static int g_modbus_buffer_id = 0;
-#ifdef UNITTESTS
-static void DetectModbusRegisterTests(void);
-#endif
-
/** \internal
*
* \brief this function will free memory associated with DetectModbus
sigmatch_table[DETECT_AL_MODBUS].Setup = DetectModbusSetup;
sigmatch_table[DETECT_AL_MODBUS].Free = DetectModbusFree;
sigmatch_table[DETECT_AL_MODBUS].AppLayerTxMatch = DetectModbusMatch;
-#ifdef UNITTESTS
- sigmatch_table[DETECT_AL_MODBUS].RegisterTests = DetectModbusRegisterTests;
-#endif
DetectAppLayerInspectEngineRegister2(
"modbus", ALPROTO_MODBUS, SIG_FLAG_TOSERVER, 0, DetectEngineInspectModbus, NULL);
g_modbus_buffer_id = DetectBufferTypeGetByName("modbus");
}
-
-#ifdef UNITTESTS /* UNITTESTS */
-#include "app-layer-parser.h"
-
-#include "flow-util.h"
-
-#include "util-unittest.h"
-#include "util-unittest-helper.h"
-
-/**
- * Sample data for tests derived from
- * https://github.com/bro/bro/blob/master/testing/btest/Traces/modbus/modbus.trace
- */
-static uint8_t writeSingleCoil[] = {
- /* Transaction ID */ 0x00, 0x01,
- /* Protocol ID */ 0x00, 0x00,
- /* Length */ 0x00, 0x06,
- /* Unit ID */ 0x0a,
- /* Function code */ 0x05,
- /* Read Starting Address */ 0x00, 0x02,
- /* Data */ 0x00, 0x00
-};
-
-static uint8_t restartCommOption[] = {
- /* Transaction ID */ 0x00, 0x00,
- /* Protocol ID */ 0x00, 0x00,
- /* Length */ 0x00, 0x06,
- /* Unit ID */ 0x0a,
- /* Function code */ 0x08,
- /* Diagnostic Code */ 0x00, 0x01,
- /* Data */ 0x00, 0x00
-};
-
-/** \test Signature containing an access type. */
-static int DetectModbusTestAccess(void)
-{
- AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
- DetectEngineThreadCtx *det_ctx = NULL;
- DetectEngineCtx *de_ctx = NULL;
- Flow f;
- Packet *p = NULL;
- Signature *s = NULL;
- TcpSession ssn;
- ThreadVars tv;
-
- FAIL_IF_NULL(alp_tctx);
-
- memset(&tv, 0, sizeof(ThreadVars));
- memset(&f, 0, sizeof(Flow));
- memset(&ssn, 0, sizeof(TcpSession));
-
- p = UTHBuildPacket(restartCommOption, sizeof(restartCommOption), IPPROTO_TCP);
-
- FLOW_INITIALIZE(&f);
- f.alproto = ALPROTO_MODBUS;
- f.protoctx = (void *)&ssn;
- f.proto = IPPROTO_TCP;
- f.flags |= FLOW_IPV4;
-
- p->flow = &f;
- p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST;
- p->flowflags |= FLOW_PKT_TOSERVER | FLOW_PKT_ESTABLISHED;
-
- StreamTcpInitConfig(TRUE);
-
- de_ctx = DetectEngineCtxInit();
- FAIL_IF_NULL(de_ctx);
-
- de_ctx->flags |= DE_QUIET;
- s = de_ctx->sig_list = SigInit(de_ctx, "alert modbus any any -> any any "
- "(msg:\"Testing modbus code function\"; "
- "modbus: access write; sid:1;)");
- FAIL_IF_NULL(s);
-
- SigGroupBuild(de_ctx);
- DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
-
- FLOWLOCK_WRLOCK(&f);
- int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOSERVER,
- writeSingleCoil, sizeof(writeSingleCoil));
- FAIL_IF_NOT(r == 0);
- FLOWLOCK_UNLOCK(&f);
-
- FAIL_IF_NULL(f.alstate);
-
- /* do detect */
- SigMatchSignatures(&tv, de_ctx, det_ctx, p);
-
- FAIL_IF_NOT(PacketAlertCheck(p, 1));
-
- AppLayerParserThreadCtxFree(alp_tctx);
- DetectEngineThreadCtxDeinit(&tv, det_ctx);
- SigGroupCleanup(de_ctx);
- DetectEngineCtxFree(de_ctx);
-
- StreamTcpFreeConfig(TRUE);
- FLOW_DESTROY(&f);
- UTHFreePacket(p);
- PASS;
-}
-
-/** \test Signature containing a function. */
-static int DetectModbusTestFunction(void)
-{
- AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
- DetectEngineThreadCtx *det_ctx = NULL;
- DetectEngineCtx *de_ctx = NULL;
- Flow f;
- Packet *p = NULL;
- Signature *s = NULL;
- TcpSession ssn;
- ThreadVars tv;
-
- FAIL_IF_NULL(alp_tctx);
-
- memset(&tv, 0, sizeof(ThreadVars));
- memset(&f, 0, sizeof(Flow));
- memset(&ssn, 0, sizeof(TcpSession));
-
- p = UTHBuildPacket(writeSingleCoil, sizeof(writeSingleCoil), IPPROTO_TCP);
-
- FLOW_INITIALIZE(&f);
- f.alproto = ALPROTO_MODBUS;
- f.protoctx = (void *)&ssn;
- f.proto = IPPROTO_TCP;
- f.flags |= FLOW_IPV4;
-
- p->flow = &f;
- p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST;
- p->flowflags |= FLOW_PKT_TOSERVER | FLOW_PKT_ESTABLISHED;
-
- StreamTcpInitConfig(TRUE);
-
- de_ctx = DetectEngineCtxInit();
- FAIL_IF_NULL(de_ctx);
-
- de_ctx->flags |= DE_QUIET;
- s = de_ctx->sig_list = SigInit(de_ctx, "alert modbus any any -> any any "
- "(msg:\"Testing modbus code function\"; "
- "modbus: function 8; sid:1;)");
- FAIL_IF_NULL(s);
-
- SigGroupBuild(de_ctx);
- DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
-
- FLOWLOCK_WRLOCK(&f);
- int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_MODBUS, STREAM_TOSERVER,
- restartCommOption, sizeof(restartCommOption));
- FAIL_IF_NOT(r == 0);
- FLOWLOCK_UNLOCK(&f);
-
- FAIL_IF_NULL(f.alstate);
-
- /* do detect */
- SigMatchSignatures(&tv, de_ctx, det_ctx, p);
-
- FAIL_IF_NOT(PacketAlertCheck(p, 1));
-
- AppLayerParserThreadCtxFree(alp_tctx);
- DetectEngineThreadCtxDeinit(&tv, det_ctx);
- SigGroupCleanup(de_ctx);
- DetectEngineCtxFree(de_ctx);
-
- StreamTcpFreeConfig(TRUE);
- FLOW_DESTROY(&f);
- UTHFreePacket(p);
- PASS;
-}
-
-/**
- * \brief this function registers unit tests for DetectModbus
- */
-void DetectModbusRegisterTests(void)
-{
- UtRegisterTest("DetectModbusTestAccess", DetectModbusTestAccess);
- UtRegisterTest("DetectModbusTestFunction", DetectModbusTestFunction);
-}
-#endif /* UNITTESTS */