From 19d701ddf07d855128ded0cf2b573ce468e3bdd6 Mon Sep 17 00:00:00 2001 From: Ashlee Young Date: Wed, 20 Jan 2016 01:10:01 +0000 Subject: Removing Suricata and Audit from source repo, and updated build.sh to avoid building suricata. Will re-address this in C release via tar balls. Change-Id: I3710076f8b7f3313cb3cb5260c4eb0a6834d4f6e Signed-off-by: Ashlee Young --- framework/src/suricata/src/detect-modbus.c | 897 ----------------------------- 1 file changed, 897 deletions(-) delete mode 100644 framework/src/suricata/src/detect-modbus.c (limited to 'framework/src/suricata/src/detect-modbus.c') diff --git a/framework/src/suricata/src/detect-modbus.c b/framework/src/suricata/src/detect-modbus.c deleted file mode 100644 index d1e4ec50..00000000 --- a/framework/src/suricata/src/detect-modbus.c +++ /dev/null @@ -1,897 +0,0 @@ -/* - * Copyright (C) 2014 ANSSI - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * \file - * - * \author David DIALLO - * - * Implements the Modbus function and access keywords - * You can specify a: - * - concrete function like Modbus: - * function 8, subfunction 4 (diagnostic: Force Listen Only Mode) - * - data (in primary table) register access (r/w) like Modbus: - * access read coils, address 1000 (.i.e Read coils: at address 1000) - * - write data value at specific address Modbus: - * access write, address 1500<>2000, value >2000 (Write multiple coils/register: - * at address between 1500 and 2000 value greater than 2000) - */ - -#include "suricata-common.h" - -#include "detect.h" -#include "detect-parse.h" - -#include "detect-modbus.h" - -#include "util-debug.h" - -#include "app-layer-modbus.h" - -#include "stream-tcp.h" - -/** - * \brief Regex for parsing the Modbus function string - */ -#define PARSE_REGEX_FUNCTION "^\\s*\"?\\s*function\\s*(!?[A-z0-9]+)(,\\s*subfunction\\s+(\\d+))?\\s*\"?\\s*$" -static pcre *function_parse_regex; -static pcre_extra *function_parse_regex_study; - -/** - * \brief Regex for parsing the Modbus access string - */ -#define PARSE_REGEX_ACCESS "^\\s*\"?\\s*access\\s*(read|write)\\s*(discretes|coils|input|holding)?(,\\s*address\\s+([<>]?\\d+)(<>\\d+)?(,\\s*value\\s+([<>]?\\d+)(<>\\d+)?)?)?\\s*\"?\\s*$" -static pcre *access_parse_regex; -static pcre_extra *access_parse_regex_study; - -#define MAX_SUBSTRINGS 30 - -void DetectModbusRegisterTests(void); - -/** \internal - * - * \brief this function will free memory associated with DetectModbus - * - * \param ptr pointer to DetectModbus - */ -static void DetectModbusFree(void *ptr) { - SCEnter(); - DetectModbus *modbus = (DetectModbus *) ptr; - - if(modbus) { - if (modbus->subfunction) - SCFree(modbus->subfunction); - - if (modbus->address) - SCFree(modbus->address); - - if (modbus->data) - SCFree(modbus->data); - - SCFree(modbus); - } -} - -/** \internal - * - * \brief This function is used to parse Modbus parameters in access mode - * - * \param str Pointer to the user provided id option - * - * \retval Pointer to DetectModbusData on success or NULL on failure - */ -static DetectModbus *DetectModbusAccessParse(char *str) -{ - SCEnter(); - DetectModbus *modbus = NULL; - - char arg[MAX_SUBSTRINGS]; - int ov[MAX_SUBSTRINGS], ret, res; - - ret = pcre_exec(access_parse_regex, access_parse_regex_study, str, strlen(str), 0, 0, ov, MAX_SUBSTRINGS); - - if (ret < 1) - goto error; - - res = pcre_copy_substring(str, ov, MAX_SUBSTRINGS, 1, arg, MAX_SUBSTRINGS); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - /* We have a correct Modbus option */ - modbus = (DetectModbus *) SCCalloc(1, sizeof(DetectModbus)); - if (unlikely(modbus == NULL)) - goto error; - - if (strcmp(arg, "read") == 0) - modbus->type = MODBUS_TYP_READ; - else if (strcmp(arg, "write") == 0) - modbus->type = MODBUS_TYP_WRITE; - else - goto error; - - if (ret > 2) { - res = pcre_copy_substring(str, ov, MAX_SUBSTRINGS, 2, arg, MAX_SUBSTRINGS); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - if (*arg != '\0') { - if (strcmp(arg, "discretes") == 0) { - if (modbus->type == MODBUS_TYP_WRITE) - /* Discrete access is only read access. */ - goto error; - - modbus->type |= MODBUS_TYP_DISCRETES; - } - else if (strcmp(arg, "coils") == 0) { - modbus->type |= MODBUS_TYP_COILS; - } - else if (strcmp(arg, "input") == 0) { - if (modbus->type == MODBUS_TYP_WRITE) { - /* Input access is only read access. */ - goto error; - } - - modbus->type |= MODBUS_TYP_INPUT; - } - else if (strcmp(arg, "holding") == 0) { - modbus->type |= MODBUS_TYP_HOLDING; - } - else - goto error; - } - - if (ret > 4) { - res = pcre_copy_substring(str, ov, MAX_SUBSTRINGS, 4, arg, MAX_SUBSTRINGS); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - /* We have a correct address option */ - modbus->address = (DetectModbusValue *) SCCalloc(1, sizeof(DetectModbusValue)); - if (unlikely(modbus->address == NULL)) - goto error; - - if (arg[0] == '>') { - modbus->address->min = atoi((const char*) (arg+1)); - modbus->address->mode = DETECT_MODBUS_GT; - } else if (arg[0] == '<') { - modbus->address->min = atoi((const char*) (arg+1)); - modbus->address->mode = DETECT_MODBUS_LT; - } else { - modbus->address->min = atoi((const char*) arg); - } - SCLogDebug("and min/equal address %d", modbus->address->min); - - if (ret > 5) { - res = pcre_copy_substring(str, ov, MAX_SUBSTRINGS, 5, arg, MAX_SUBSTRINGS); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - if (*arg != '\0') { - modbus->address->max = atoi((const char*) (arg+2)); - modbus->address->mode = DETECT_MODBUS_RA; - SCLogDebug("and max address %d", modbus->address->max); - } - - if (ret > 7) { - res = pcre_copy_substring(str, ov, MAX_SUBSTRINGS, 7, arg, MAX_SUBSTRINGS); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - if (modbus->address->mode != DETECT_MODBUS_EQ) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords (address range and value)."); - goto error; - } - - /* We have a correct address option */ - modbus->data = (DetectModbusValue *) SCCalloc(1, sizeof(DetectModbusValue)); - if (unlikely(modbus->data == NULL)) - goto error; - - if (arg[0] == '>') { - modbus->data->min = atoi((const char*) (arg+1)); - modbus->data->mode = DETECT_MODBUS_GT; - } else if (arg[0] == '<') { - modbus->data->min = atoi((const char*) (arg+1)); - modbus->data->mode = DETECT_MODBUS_LT; - } else { - modbus->data->min = atoi((const char*) arg); - } - SCLogDebug("and min/equal value %d", modbus->data->min); - - if (ret > 8) { - res = pcre_copy_substring(str, ov, MAX_SUBSTRINGS, 8, arg, MAX_SUBSTRINGS); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - if (*arg != '\0') { - modbus->data->max = atoi((const char*) (arg+2)); - modbus->data->mode = DETECT_MODBUS_RA; - SCLogDebug("and max value %d", modbus->data->max); - } - } - } - } - } - } - - SCReturnPtr(modbus, "DetectModbusAccess"); - -error: - if (modbus != NULL) - DetectModbusFree(modbus); - - SCReturnPtr(NULL, "DetectModbus"); -} - -/** \internal - * - * \brief This function is used to parse Modbus parameters in function mode - * - * \param str Pointer to the user provided id option - * - * \retval id_d pointer to DetectModbusData on success - * \retval NULL on failure - */ -static DetectModbus *DetectModbusFunctionParse(char *str) -{ - SCEnter(); - DetectModbus *modbus = NULL; - - char arg[MAX_SUBSTRINGS], *ptr = arg; - int ov[MAX_SUBSTRINGS], res, ret; - - ret = pcre_exec(function_parse_regex, function_parse_regex_study, str, strlen(str), 0, 0, ov, MAX_SUBSTRINGS); - - if (ret < 1) - goto error; - - res = pcre_copy_substring(str, ov, MAX_SUBSTRINGS, 1, arg, MAX_SUBSTRINGS); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - /* We have a correct Modbus function option */ - modbus = (DetectModbus *) SCCalloc(1, sizeof(DetectModbus)); - if (unlikely(modbus == NULL)) - goto error; - - if (isdigit((unsigned char)ptr[0])) { - modbus->function = atoi((const char*) ptr); - SCLogDebug("will look for modbus function %d", modbus->function); - - if (ret > 2) { - res = pcre_copy_substring(str, ov, MAX_SUBSTRINGS, 3, arg, MAX_SUBSTRINGS); - if (res < 0) { - SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed"); - goto error; - } - - /* We have a correct address option */ - modbus->subfunction =(uint16_t *) SCCalloc(1, sizeof(uint16_t)); - if (modbus->subfunction == NULL) - goto error; - - *(modbus->subfunction) = atoi((const char*) arg); - SCLogDebug("and subfunction %d", *(modbus->subfunction)); - } - } else { - uint8_t neg = 0; - - if (ptr[0] == '!') { - neg = 1; - ptr++; - } - - if (strcmp("assigned", ptr) == 0) - modbus->category = MODBUS_CAT_PUBLIC_ASSIGNED; - else if (strcmp("unassigned", ptr) == 0) - modbus->category = MODBUS_CAT_PUBLIC_UNASSIGNED; - else if (strcmp("public", ptr) == 0) - modbus->category = MODBUS_CAT_PUBLIC_ASSIGNED | MODBUS_CAT_PUBLIC_UNASSIGNED; - else if (strcmp("user", ptr) == 0) - modbus->category = MODBUS_CAT_USER_DEFINED; - else if (strcmp("reserved", ptr) == 0) - modbus->category = MODBUS_CAT_RESERVED; - else if (strcmp("all", ptr) == 0) - modbus->category = MODBUS_CAT_ALL; - - if (neg) - modbus->category = ~modbus->category; - SCLogDebug("will look for modbus category function %d", modbus->category); - } - - SCReturnPtr(modbus, "DetectModbusFunction"); - -error: - if (modbus != NULL) - DetectModbusFree(modbus); - - SCReturnPtr(NULL, "DetectModbus"); -} - -/** \internal - * - * \brief this function is used to add the parsed "id" option into the current signature - * - * \param de_ctx Pointer to the Detection Engine Context - * \param s Pointer to the Current Signature - * \param str Pointer to the user provided "id" option - * - * \retval 0 on Success or -1 on Failure - */ -static int DetectModbusSetup(DetectEngineCtx *de_ctx, Signature *s, char *str) -{ - SCEnter(); - DetectModbus *modbus = NULL; - SigMatch *sm = NULL; - - if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_MODBUS) { - SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords."); - goto error; - } - - if ((modbus = DetectModbusFunctionParse(str)) == NULL) { - if ((modbus = DetectModbusAccessParse(str)) == NULL) { - SCLogError(SC_ERR_PCRE_MATCH, "invalid modbus option"); - goto error; - } - } - - /* Okay so far so good, lets get this into a SigMatch and put it in the Signature. */ - sm = SigMatchAlloc(); - if (sm == NULL) - goto error; - - sm->type = DETECT_AL_MODBUS; - sm->ctx = (void *) modbus; - - SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MODBUS_MATCH); - s->alproto = ALPROTO_MODBUS; - - SCReturnInt(0); - -error: - if (modbus != NULL) - DetectModbusFree(modbus); - if (sm != NULL) - SCFree(sm); - SCReturnInt(-1); -} - -/** - * \brief Registration function for Modbus keyword - */ -void DetectModbusRegister(void) -{ - SCEnter(); - sigmatch_table[DETECT_AL_MODBUS].name = "modbus"; - sigmatch_table[DETECT_AL_MODBUS].Match = NULL; - sigmatch_table[DETECT_AL_MODBUS].AppLayerMatch = NULL; - sigmatch_table[DETECT_AL_MODBUS].alproto = ALPROTO_MODBUS; - sigmatch_table[DETECT_AL_MODBUS].Setup = DetectModbusSetup; - sigmatch_table[DETECT_AL_MODBUS].Free = DetectModbusFree; - sigmatch_table[DETECT_AL_MODBUS].RegisterTests = DetectModbusRegisterTests; - - const char *eb; - int eo, opts = 0; - - SCLogDebug("registering modbus rule option"); - - /* Function PARSE_REGEX */ - function_parse_regex = pcre_compile(PARSE_REGEX_FUNCTION, opts, &eb, &eo, NULL); - if (function_parse_regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s", - PARSE_REGEX_FUNCTION, eo, eb); - goto error; - } - - function_parse_regex_study = pcre_study(function_parse_regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - - /* Access PARSE_REGEX */ - access_parse_regex = pcre_compile(PARSE_REGEX_ACCESS, opts, &eb, &eo, NULL); - if (access_parse_regex == NULL) { - SCLogError(SC_ERR_PCRE_COMPILE, "Compile of \"%s\" failed at offset %" PRId32 ": %s", - PARSE_REGEX_ACCESS, eo, eb); - goto error; - } - - access_parse_regex_study = pcre_study(access_parse_regex, 0, &eb); - if (eb != NULL) { - SCLogError(SC_ERR_PCRE_STUDY, "pcre study failed: %s", eb); - goto error; - } - -error: - SCReturn; -} - -#ifdef UNITTESTS /* UNITTESTS */ -#include "detect-engine.h" - -#include "util-unittest.h" - -/** \test Signature containing a function. */ -static int DetectModbusTest01(void) -{ - DetectEngineCtx *de_ctx = NULL; - DetectModbus *modbus = NULL; - - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus function\"; " - "modbus: function 1; sid:1;)"); - - if (de_ctx->sig_list == NULL) - goto end; - - if ((de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH] == NULL) || - (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx == NULL)) { - printf("de_ctx->pmatch_tail == NULL && de_ctx->pmatch_tail->ctx == NULL: "); - goto end; - } - - modbus = (DetectModbus *) de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx; - - if (modbus->function != 1) { - printf("expected function %" PRIu8 ", got %" PRIu8 ": ", 1, modbus->function); - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** \test Signature containing a function and a subfunction. */ -static int DetectModbusTest02(void) -{ - DetectEngineCtx *de_ctx = NULL; - DetectModbus *modbus = NULL; - - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus function and subfunction\"; " - "modbus: function 8, subfunction 4; sid:1;)"); - - if (de_ctx->sig_list == NULL) - goto end; - - if ((de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH] == NULL) || - (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx == NULL)) { - printf("de_ctx->pmatch_tail == NULL && de_ctx->pmatch_tail->ctx == NULL: "); - goto end; - } - - modbus = (DetectModbus *) de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx; - - if ((modbus->function != 8) || (*modbus->subfunction != 4)) { - printf("expected function %" PRIu8 ", got %" PRIu8 ": ", 1, modbus->function); - printf("expected subfunction %" PRIu8 ", got %" PRIu16 ": ", 4, *modbus->subfunction); - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** \test Signature containing a function category. */ -static int DetectModbusTest03(void) -{ - DetectEngineCtx *de_ctx = NULL; - DetectModbus *modbus = NULL; - - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus.function\"; " - "modbus: function reserved; sid:1;)"); - - if (de_ctx->sig_list == NULL) - goto end; - - if ((de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH] == NULL) || - (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx == NULL)) { - printf("de_ctx->pmatch_tail == NULL && de_ctx->pmatch_tail->ctx == NULL: "); - goto end; - } - - modbus = (DetectModbus *) de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx; - - if (modbus->category != MODBUS_CAT_RESERVED) { - printf("expected function %" PRIu8 ", got %" PRIu8 ": ", MODBUS_CAT_RESERVED, modbus->category); - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** \test Signature containing a negative function category. */ -static int DetectModbusTest04(void) -{ - DetectEngineCtx *de_ctx = NULL; - DetectModbus *modbus = NULL; - - uint8_t category = ~MODBUS_CAT_PUBLIC_ASSIGNED; - - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus function\"; " - "modbus: function !assigned; sid:1;)"); - - if (de_ctx->sig_list == NULL) - goto end; - - if ((de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH] == NULL) || - (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx == NULL)) { - printf("de_ctx->pmatch_tail == NULL && de_ctx->pmatch_tail->ctx == NULL: "); - goto end; - } - - modbus = (DetectModbus *) de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx; - - if (modbus->category != category) { - printf("expected function %" PRIu8 ", got %" PRIu8 ": ", ~MODBUS_CAT_PUBLIC_ASSIGNED, modbus->category); - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** \test Signature containing a access type. */ -static int DetectModbusTest05(void) -{ - DetectEngineCtx *de_ctx = NULL; - DetectModbus *modbus = NULL; - - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus.access\"; " - "modbus: access read; sid:1;)"); - - if (de_ctx->sig_list == NULL) - goto end; - - if ((de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH] == NULL) || - (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx == NULL)) { - printf("de_ctx->pmatch_tail == NULL && de_ctx->pmatch_tail->ctx == NULL: "); - goto end; - } - - modbus = (DetectModbus *) de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx; - - if (modbus->type != MODBUS_TYP_READ) { - printf("expected function %" PRIu8 ", got %" PRIu8 ": ", MODBUS_TYP_READ, modbus->type); - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** \test Signature containing a access function. */ -static int DetectModbusTest06(void) -{ - DetectEngineCtx *de_ctx = NULL; - DetectModbus *modbus = NULL; - - uint8_t type = (MODBUS_TYP_READ | MODBUS_TYP_DISCRETES); - - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus.access\"; " - "modbus: access read discretes; sid:1;)"); - - if (de_ctx->sig_list == NULL) - goto end; - - if ((de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH] == NULL) || - (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx == NULL)) { - printf("de_ctx->pmatch_tail == NULL && de_ctx->pmatch_tail->ctx == NULL: "); - goto end; - } - - modbus = (DetectModbus *) de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx; - - if (modbus->type != type) { - printf("expected function %" PRIu8 ", got %" PRIu8 ": ", type, modbus->type); - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** \test Signature containing a read access at an address. */ -static int DetectModbusTest07(void) -{ - DetectEngineCtx *de_ctx = NULL; - DetectModbus *modbus = NULL; - DetectModbusMode mode = DETECT_MODBUS_EQ; - - uint8_t type = MODBUS_TYP_READ; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus.access\"; " - "modbus: access read, address 1000; sid:1;)"); - - if (de_ctx->sig_list == NULL) - goto end; - - if ((de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH] == NULL) || - (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx == NULL)) { - printf("de_ctx->pmatch_tail == NULL && de_ctx->pmatch_tail->ctx == NULL: "); - goto end; - } - - modbus = (DetectModbus *) de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx; - - if ((modbus->type != type) || - ((*modbus->address).mode != mode) || - ((*modbus->address).min != 1000)) { - printf("expected function %" PRIu8 ", got %" PRIu8 ": ", type, modbus->type); - printf("expected mode %" PRIu8 ", got %" PRIu16 ": ", mode, (*modbus->address).mode); - printf("expected address %" PRIu8 ", got %" PRIu16 ": ", 1000, (*modbus->address).min); - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** \test Signature containing a write access at a range of address. */ -static int DetectModbusTest08(void) -{ - DetectEngineCtx *de_ctx = NULL; - DetectModbus *modbus = NULL; - DetectModbusMode mode = DETECT_MODBUS_GT; - - uint8_t type = (MODBUS_TYP_WRITE | MODBUS_TYP_COILS); - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus.access\"; " - "modbus: access write coils, address >500; sid:1;)"); - - if (de_ctx->sig_list == NULL) - goto end; - - if ((de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH] == NULL) || - (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx == NULL)) { - printf("de_ctx->pmatch_tail == NULL && de_ctx->pmatch_tail->ctx == NULL: "); - goto end; - } - - modbus = (DetectModbus *) de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx; - - if ((modbus->type != type) || - ((*modbus->address).mode != mode) || - ((*modbus->address).min != 500)) { - printf("expected function %" PRIu8 ", got %" PRIu8 ": ", type, modbus->type); - printf("expected mode %" PRIu8 ", got %" PRIu16 ": ", mode, (*modbus->address).mode); - printf("expected address %" PRIu8 ", got %" PRIu16 ": ", 500, (*modbus->address).min); - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** \test Signature containing a write access at a address a range of value. */ -static int DetectModbusTest09(void) -{ - DetectEngineCtx *de_ctx = NULL; - DetectModbus *modbus = NULL; - DetectModbusMode addressMode = DETECT_MODBUS_EQ; - DetectModbusMode valueMode = DETECT_MODBUS_RA; - - uint8_t type = (MODBUS_TYP_WRITE | MODBUS_TYP_HOLDING); - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert modbus any any -> any any " - "(msg:\"Testing modbus.access\"; " - "modbus: access write holding, address 100, value 500<>1000; sid:1;)"); - - if (de_ctx->sig_list == NULL) - goto end; - - if ((de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH] == NULL) || - (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx == NULL)) { - printf("de_ctx->pmatch_tail == NULL && de_ctx->pmatch_tail->ctx == NULL: "); - goto end; - } - - modbus = (DetectModbus *) de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_MODBUS_MATCH]->ctx; - - if ((modbus->type != type) || - ((*modbus->address).mode != addressMode) || - ((*modbus->address).min != 100) || - ((*modbus->data).mode != valueMode) || - ((*modbus->data).min != 500) || - ((*modbus->data).max != 1000)) { - printf("expected function %" PRIu8 ", got %" PRIu8 ": ", type, modbus->type); - printf("expected address mode %" PRIu8 ", got %" PRIu16 ": ", addressMode, (*modbus->address).mode); - printf("expected address %" PRIu8 ", got %" PRIu16 ": ", 500, (*modbus->address).min); - printf("expected value mode %" PRIu8 ", got %" PRIu16 ": ", valueMode, (*modbus->data).mode); - printf("expected min value %" PRIu8 ", got %" PRIu16 ": ", 500, (*modbus->data).min); - printf("expected max value %" PRIu8 ", got %" PRIu16 ": ", 1000, (*modbus->data).max); - goto end; - } - - result = 1; - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} -#endif /* UNITTESTS */ - -/** - * \brief this function registers unit tests for DetectModbus - */ -void DetectModbusRegisterTests(void) -{ -#ifdef UNITTESTS /* UNITTESTS */ - UtRegisterTest("DetectModbusTest01 - Testing function", DetectModbusTest01, 1); - UtRegisterTest("DetectModbusTest02 - Testing function and subfunction", DetectModbusTest02, 1); - UtRegisterTest("DetectModbusTest03 - Testing category function", DetectModbusTest03, 1); - UtRegisterTest("DetectModbusTest04 - Testing category function in negative", DetectModbusTest04, 1); - UtRegisterTest("DetectModbusTest05 - Testing access type", DetectModbusTest05, 1); - UtRegisterTest("DetectModbusTest06 - Testing access function", DetectModbusTest06, 1); - UtRegisterTest("DetectModbusTest07 - Testing access at address", DetectModbusTest07, 1); - UtRegisterTest("DetectModbusTest08 - Testing a range of address", DetectModbusTest08, 1); - UtRegisterTest("DetectModbusTest09 - Testing write a range of value", DetectModbusTest09, 1); -#endif /* UNITTESTS */ -} -- cgit 1.2.3-korg