diff options
Diffstat (limited to 'framework/src/suricata/src/detect-engine-siggroup.c')
-rw-r--r-- | framework/src/suricata/src/detect-engine-siggroup.c | 2420 |
1 files changed, 0 insertions, 2420 deletions
diff --git a/framework/src/suricata/src/detect-engine-siggroup.c b/framework/src/suricata/src/detect-engine-siggroup.c deleted file mode 100644 index 89e0eb79..00000000 --- a/framework/src/suricata/src/detect-engine-siggroup.c +++ /dev/null @@ -1,2420 +0,0 @@ -/* Copyright (C) 2007-2013 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 - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Victor Julien <victor@inliniac.net> - * - * Signature grouping part of the detection engine. - */ - -#include "suricata-common.h" -#include "decode.h" - -#include "flow-var.h" - -#include "app-layer-protos.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-address.h" -#include "detect-engine-mpm.h" -#include "detect-engine-siggroup.h" - -#include "detect-content.h" -#include "detect-uricontent.h" - -#include "util-hash.h" -#include "util-hashlist.h" - -#include "util-error.h" -#include "util-debug.h" -#include "util-cidr.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-memcmp.h" - -/* prototypes */ -int SigGroupHeadClearSigs(SigGroupHead *); - -static uint32_t detect_siggroup_head_memory = 0; -static uint32_t detect_siggroup_head_init_cnt = 0; -static uint32_t detect_siggroup_head_free_cnt = 0; -static uint32_t detect_siggroup_head_initdata_memory = 0; -static uint32_t detect_siggroup_head_initdata_init_cnt = 0; -static uint32_t detect_siggroup_head_initdata_free_cnt = 0; -static uint32_t detect_siggroup_sigarray_memory = 0; -static uint32_t detect_siggroup_sigarray_init_cnt = 0; -static uint32_t detect_siggroup_sigarray_free_cnt = 0; -static uint32_t detect_siggroup_matcharray_memory = 0; -static uint32_t detect_siggroup_matcharray_init_cnt = 0; -static uint32_t detect_siggroup_matcharray_free_cnt = 0; - -void SigGroupHeadInitDataFree(SigGroupHeadInitData *sghid) -{ - if (sghid->content_array != NULL) { - SCFree(sghid->content_array); - sghid->content_array = NULL; - sghid->content_size = 0; - } - if (sghid->uri_content_array != NULL) { - SCFree(sghid->uri_content_array); - sghid->uri_content_array = NULL; - sghid->uri_content_size = 0; - } - if (sghid->sig_array != NULL) { - SCFree(sghid->sig_array); - sghid->sig_array = NULL; - - detect_siggroup_sigarray_free_cnt++; - detect_siggroup_sigarray_memory -= sghid->sig_size; - } - SCFree(sghid); - - detect_siggroup_head_initdata_free_cnt++; - detect_siggroup_head_initdata_memory -= sizeof(SigGroupHeadInitData); -} - -static SigGroupHeadInitData *SigGroupHeadInitDataAlloc(uint32_t size) -{ - SigGroupHeadInitData *sghid = SCMalloc(sizeof(SigGroupHeadInitData)); - if (unlikely(sghid == NULL)) - return NULL; - - memset(sghid, 0x00, sizeof(SigGroupHeadInitData)); - - detect_siggroup_head_initdata_init_cnt++; - detect_siggroup_head_initdata_memory += sizeof(SigGroupHeadInitData); - - /* initialize the signature bitarray */ - sghid->sig_size = size; - if ( (sghid->sig_array = SCMalloc(sghid->sig_size)) == NULL) - goto error; - - memset(sghid->sig_array, 0, sghid->sig_size); - - detect_siggroup_sigarray_init_cnt++; - detect_siggroup_sigarray_memory += sghid->sig_size; - - return sghid; -error: - SigGroupHeadInitDataFree(sghid); - return NULL; -} - -void SigGroupHeadStore(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - void *ptmp; - //printf("de_ctx->sgh_array_cnt %u, de_ctx->sgh_array_size %u, de_ctx->sgh_array %p\n", de_ctx->sgh_array_cnt, de_ctx->sgh_array_size, de_ctx->sgh_array); - if (de_ctx->sgh_array_cnt < de_ctx->sgh_array_size) { - de_ctx->sgh_array[de_ctx->sgh_array_cnt] = sgh; - } else { - int increase = 16; - ptmp = SCRealloc(de_ctx->sgh_array, - sizeof(SigGroupHead *) * (increase + de_ctx->sgh_array_size)); - if (ptmp == NULL) { - SCFree(de_ctx->sgh_array); - de_ctx->sgh_array = NULL; - return; - } - de_ctx->sgh_array = ptmp; - - de_ctx->sgh_array_size += increase; - de_ctx->sgh_array[de_ctx->sgh_array_cnt] = sgh; - } - de_ctx->sgh_array_cnt++; -} - -/** - * \brief Alloc a SigGroupHead and its signature bit_array. - * - * \param size Size of the sig_array that has to be created for this - * SigGroupHead. - * - * \retval sgh Pointer to the newly init SigGroupHead on success; or NULL in - * case of error. - */ -static SigGroupHead *SigGroupHeadAlloc(DetectEngineCtx *de_ctx, uint32_t size) -{ - SigGroupHead *sgh = SCMalloc(sizeof(SigGroupHead)); - if (unlikely(sgh == NULL)) - return NULL; - memset(sgh, 0, sizeof(SigGroupHead)); - - sgh->init = SigGroupHeadInitDataAlloc(size); - if (sgh->init == NULL) - goto error; - - detect_siggroup_head_init_cnt++; - detect_siggroup_head_memory += sizeof(SigGroupHead); - - return sgh; - -error: - SigGroupHeadFree(sgh); - return NULL; -} - -/** - * \brief Free a SigGroupHead and its members. - * - * \param sgh Pointer to the SigGroupHead that has to be freed. - */ -void SigGroupHeadFree(SigGroupHead *sgh) -{ - if (sgh == NULL) - return; - - SCLogDebug("sgh %p", sgh); - - PatternMatchDestroyGroup(sgh); - - if (sgh->match_array != NULL) { - detect_siggroup_matcharray_free_cnt++; - detect_siggroup_matcharray_memory -= (sgh->sig_cnt * sizeof(Signature *)); - SCFree(sgh->match_array); - sgh->match_array = NULL; - } - - if (sgh->non_mpm_store_array != NULL) { - SCFree(sgh->non_mpm_store_array); - sgh->non_mpm_store_array = NULL; - sgh->non_mpm_store_cnt = 0; - } - - sgh->sig_cnt = 0; - - if (sgh->init != NULL) { - SigGroupHeadInitDataFree(sgh->init); - sgh->init = NULL; - } - - SCFree(sgh); - - detect_siggroup_head_free_cnt++; - detect_siggroup_head_memory -= sizeof(SigGroupHead); - - return; -} - -/** - * \brief The hash function to be the used by the mpm SigGroupHead hash table - - * DetectEngineCtx->sgh_mpm_hash_table. - * - * \param ht Pointer to the hash table. - * \param data Pointer to the SigGroupHead. - * \param datalen Not used in our case. - * - * \retval hash The generated hash value. - */ -uint32_t SigGroupHeadMpmHashFunc(HashListTable *ht, void *data, uint16_t datalen) -{ - SigGroupHead *sgh = (SigGroupHead *)data; - uint32_t hash = 0; - uint32_t b = 0; - - for (b = 0; b < sgh->init->content_size; b++) - hash += sgh->init->content_array[b]; - - return hash % ht->array_size; -} - -/** - * \brief The Compare function to be used by the mpm SigGroupHead hash table - - * DetectEngineCtx->sgh_mpm_hash_table. - * - * \param data1 Pointer to the first SigGroupHead. - * \param len1 Not used. - * \param data2 Pointer to the second SigGroupHead. - * \param len2 Not used. - * - * \retval 1 If the 2 SigGroupHeads sent as args match. - * \retval 0 If the 2 SigGroupHeads sent as args do not match. - */ -char SigGroupHeadMpmCompareFunc(void *data1, uint16_t len1, void *data2, - uint16_t len2) -{ - SigGroupHead *sgh1 = (SigGroupHead *)data1; - SigGroupHead *sgh2 = (SigGroupHead *)data2; - - if (sgh1->init->content_size != sgh2->init->content_size) - return 0; - - if (SCMemcmp(sgh1->init->content_array, sgh2->init->content_array, - sgh1->init->content_size) != 0) { - return 0; - } - - return 1; -} - -/** - * \brief Initializes the SigGroupHead mpm hash table to be used by the detection - * engine context. - * - * \param de_ctx Pointer to the detection engine context. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SigGroupHeadMpmHashInit(DetectEngineCtx *de_ctx) -{ - de_ctx->sgh_mpm_hash_table = HashListTableInit(4096, SigGroupHeadMpmHashFunc, - SigGroupHeadMpmCompareFunc, - NULL); - - if (de_ctx->sgh_mpm_hash_table == NULL) - goto error; - - return 0; - -error: - return -1; -} - -/** - * \brief Adds a SigGroupHead to the detection engine context SigGroupHead - * mpm hash table. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval ret 0 on Successfully adding the argument sgh; -1 on failure. - */ -int SigGroupHeadMpmHashAdd(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - int ret = HashListTableAdd(de_ctx->sgh_mpm_hash_table, (void *)sgh, 0); - - return ret; -} - -/** - * \brief Used to lookup a SigGroupHead from the detection engine context - * SigGroupHead mpm hash table. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval rsgh On success a pointer to the SigGroupHead if the SigGroupHead is - * found in the hash table; NULL on failure. - */ -SigGroupHead *SigGroupHeadMpmHashLookup(DetectEngineCtx *de_ctx, - SigGroupHead *sgh) -{ - SigGroupHead *rsgh = HashListTableLookup(de_ctx->sgh_mpm_hash_table, - (void *)sgh, 0); - - return rsgh; -} - -/** - * \brief Frees the hash table - DetectEngineCtx->sgh_mpm_hash_table, allocated by - * SigGroupHeadMpmHashInit() function. - * - * \param de_ctx Pointer to the detection engine context. - */ -void SigGroupHeadMpmHashFree(DetectEngineCtx *de_ctx) -{ - if (de_ctx->sgh_mpm_hash_table == NULL) - return; - - HashListTableFree(de_ctx->sgh_mpm_hash_table); - de_ctx->sgh_mpm_hash_table = NULL; - - return; -} - -/** - * \brief The hash function to be the used by the mpm uri SigGroupHead hash - * table - DetectEngineCtx->sgh_mpm_uri_hash_table. - * - * \param ht Pointer to the hash table. - * \param data Pointer to the SigGroupHead. - * \param datalen Not used in our case. - * - * \retval hash The generated hash value. - */ -uint32_t SigGroupHeadMpmUriHashFunc(HashListTable *ht, void *data, uint16_t datalen) -{ - SigGroupHead *sgh = (SigGroupHead *)data; - uint32_t hash = 0; - uint32_t b = 0; - - for (b = 0; b < sgh->init->uri_content_size; b++) - hash += sgh->init->uri_content_array[b]; - - return hash % ht->array_size; -} - -/** - * \brief The Compare function to be used by the mpm uri SigGroupHead hash - * table - DetectEngineCtx->sgh_mpm_uri_hash_table. - * - * \param data1 Pointer to the first SigGroupHead. - * \param len1 Not used. - * \param data2 Pointer to the second SigGroupHead. - * \param len2 Not used. - * - * \retval 1 If the 2 SigGroupHeads sent as args match. - * \retval 0 If the 2 SigGroupHeads sent as args do not match. - */ -char SigGroupHeadMpmUriCompareFunc(void *data1, uint16_t len1, void *data2, - uint16_t len2) -{ - SigGroupHead *sgh1 = (SigGroupHead *)data1; - SigGroupHead *sgh2 = (SigGroupHead *)data2; - - if (sgh1->init->uri_content_size != sgh2->init->uri_content_size) - return 0; - - if (SCMemcmp(sgh1->init->uri_content_array, sgh2->init->uri_content_array, - sgh1->init->uri_content_size) != 0) { - return 0; - } - - return 1; -} - -/** - * \brief Initializes the mpm uri hash table to be used by the detection engine - * context. - * - * \param de_ctx Pointer to the detection engine context. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SigGroupHeadMpmUriHashInit(DetectEngineCtx *de_ctx) -{ - de_ctx->sgh_mpm_uri_hash_table = HashListTableInit(4096, - SigGroupHeadMpmUriHashFunc, - SigGroupHeadMpmUriCompareFunc, - NULL); - if (de_ctx->sgh_mpm_uri_hash_table == NULL) - goto error; - - return 0; - -error: - return -1; -} - -/** - * \brief Adds a SigGroupHead to the detection engine context SigGroupHead - * mpm uri hash table. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval ret 0 on Successfully adding the argument sgh and -1 on failure. - */ -int SigGroupHeadMpmUriHashAdd(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - int ret = HashListTableAdd(de_ctx->sgh_mpm_uri_hash_table, (void *)sgh, 0); - - return ret; -} - -/** - * \brief Used to lookup a SigGroupHead from the detection engine context - * SigGroupHead mpm uri hash table. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval rsgh On success a pointer to the SigGroupHead if the SigGroupHead is - * found in the hash table; NULL on failure. - */ -SigGroupHead *SigGroupHeadMpmUriHashLookup(DetectEngineCtx *de_ctx, - SigGroupHead *sgh) -{ - SigGroupHead *rsgh = HashListTableLookup(de_ctx->sgh_mpm_uri_hash_table, - (void *)sgh, 0); - - return rsgh; -} - -/** - * \brief Frees the hash table - DetectEngineCtx->sgh_mpm_uri_hash_table, - * allocated by SigGroupHeadMpmUriHashInit() function. - * - * \param de_ctx Pointer to the detection engine context. - */ -void SigGroupHeadMpmUriHashFree(DetectEngineCtx *de_ctx) -{ - if (de_ctx->sgh_mpm_uri_hash_table == NULL) - return; - - HashListTableFree(de_ctx->sgh_mpm_uri_hash_table); - de_ctx->sgh_mpm_uri_hash_table = NULL; - - return; -} - -/** - * \brief The hash function to be the used by the mpm uri SigGroupHead hash - * table - DetectEngineCtx->sgh_mpm_uri_hash_table. - * - * \param ht Pointer to the hash table. - * \param data Pointer to the SigGroupHead. - * \param datalen Not used in our case. - * - * \retval hash The generated hash value. - */ -uint32_t SigGroupHeadMpmStreamHashFunc(HashListTable *ht, void *data, uint16_t datalen) -{ - SigGroupHead *sgh = (SigGroupHead *)data; - uint32_t hash = 0; - uint32_t b = 0; - - for (b = 0; b < sgh->init->stream_content_size; b++) - hash += sgh->init->stream_content_array[b]; - - return hash % ht->array_size; -} - -/** - * \brief The Compare function to be used by the mpm uri SigGroupHead hash - * table - DetectEngineCtx->sgh_mpm_uri_hash_table. - * - * \param data1 Pointer to the first SigGroupHead. - * \param len1 Not used. - * \param data2 Pointer to the second SigGroupHead. - * \param len2 Not used. - * - * \retval 1 If the 2 SigGroupHeads sent as args match. - * \retval 0 If the 2 SigGroupHeads sent as args do not match. - */ -char SigGroupHeadMpmStreamCompareFunc(void *data1, uint16_t len1, void *data2, - uint16_t len2) -{ - SigGroupHead *sgh1 = (SigGroupHead *)data1; - SigGroupHead *sgh2 = (SigGroupHead *)data2; - - if (sgh1->init->stream_content_size != sgh2->init->stream_content_size) - return 0; - - if (SCMemcmp(sgh1->init->stream_content_array, sgh2->init->stream_content_array, - sgh1->init->stream_content_size) != 0) { - return 0; - } - - return 1; -} - -/** - * \brief Initializes the mpm uri hash table to be used by the detection engine - * context. - * - * \param de_ctx Pointer to the detection engine context. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SigGroupHeadMpmStreamHashInit(DetectEngineCtx *de_ctx) -{ - de_ctx->sgh_mpm_stream_hash_table = HashListTableInit(4096, - SigGroupHeadMpmStreamHashFunc, SigGroupHeadMpmStreamCompareFunc, NULL); - if (de_ctx->sgh_mpm_stream_hash_table == NULL) - goto error; - - return 0; - -error: - return -1; -} - -/** - * \brief Adds a SigGroupHead to the detection engine context SigGroupHead - * mpm uri hash table. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval ret 0 on Successfully adding the argument sgh and -1 on failure. - */ -int SigGroupHeadMpmStreamHashAdd(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - int ret = HashListTableAdd(de_ctx->sgh_mpm_stream_hash_table, (void *)sgh, 0); - - return ret; -} - -/** - * \brief Used to lookup a SigGroupHead from the detection engine context - * SigGroupHead mpm uri hash table. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval rsgh On success a pointer to the SigGroupHead if the SigGroupHead is - * found in the hash table; NULL on failure. - */ -SigGroupHead *SigGroupHeadMpmStreamHashLookup(DetectEngineCtx *de_ctx, - SigGroupHead *sgh) -{ - SigGroupHead *rsgh = HashListTableLookup(de_ctx->sgh_mpm_stream_hash_table, - (void *)sgh, 0); - - return rsgh; -} - -/** - * \brief Frees the hash table - DetectEngineCtx->sgh_mpm_uri_hash_table, - * allocated by SigGroupHeadMpmUriHashInit() function. - * - * \param de_ctx Pointer to the detection engine context. - */ -void SigGroupHeadMpmStreamHashFree(DetectEngineCtx *de_ctx) -{ - if (de_ctx->sgh_mpm_stream_hash_table == NULL) - return; - - HashListTableFree(de_ctx->sgh_mpm_stream_hash_table); - de_ctx->sgh_mpm_stream_hash_table = NULL; - - return; -} - -/** - * \brief The hash function to be the used by the hash table - - * DetectEngineCtx->sgh_hash_table. - * - * \param ht Pointer to the hash table. - * \param data Pointer to the SigGroupHead. - * \param datalen Not used in our case. - * - * \retval hash The generated hash value. - */ -uint32_t SigGroupHeadHashFunc(HashListTable *ht, void *data, uint16_t datalen) -{ - SigGroupHead *sgh = (SigGroupHead *)data; - uint32_t hash = 0; - uint32_t b = 0; - - SCLogDebug("hashing sgh %p (mpm_content_minlen %u)", sgh, sgh->mpm_content_minlen); - - for (b = 0; b < sgh->init->sig_size; b++) - hash += sgh->init->sig_array[b]; - - hash %= ht->array_size; - SCLogDebug("hash %"PRIu32" (sig_size %"PRIu32")", hash, sgh->init->sig_size); - return hash; -} - -/** - * \brief The Compare function to be used by the SigGroupHead hash table - - * DetectEngineCtx->sgh_hash_table. - * - * \param data1 Pointer to the first SigGroupHead. - * \param len1 Not used. - * \param data2 Pointer to the second SigGroupHead. - * \param len2 Not used. - * - * \retval 1 If the 2 SigGroupHeads sent as args match. - * \retval 0 If the 2 SigGroupHeads sent as args do not match. - */ -char SigGroupHeadCompareFunc(void *data1, uint16_t len1, void *data2, - uint16_t len2) -{ - SigGroupHead *sgh1 = (SigGroupHead *)data1; - SigGroupHead *sgh2 = (SigGroupHead *)data2; - - if (data1 == NULL || data2 == NULL) - return 0; - - if (sgh1->init->sig_size != sgh2->init->sig_size) - return 0; - - if (SCMemcmp(sgh1->init->sig_array, sgh2->init->sig_array, sgh1->init->sig_size) != 0) - return 0; - - return 1; -} - -/** - * \brief Initializes the hash table in the detection engine context to hold the - * SigGroupHeads. - * - * \param de_ctx Pointer to the detection engine context. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SigGroupHeadHashInit(DetectEngineCtx *de_ctx) -{ - de_ctx->sgh_hash_table = HashListTableInit(4096, SigGroupHeadHashFunc, - SigGroupHeadCompareFunc, NULL); - if (de_ctx->sgh_hash_table == NULL) - goto error; - - return 0; - -error: - return -1; -} - -/** - * \brief Adds a SigGroupHead to the detection engine context SigGroupHead - * hash table. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval ret 0 on Successfully adding the SigGroupHead; -1 on failure. - */ -int SigGroupHeadHashAdd(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - int ret = HashListTableAdd(de_ctx->sgh_hash_table, (void *)sgh, 0); - - return ret; -} - -int SigGroupHeadHashRemove(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - return HashListTableRemove(de_ctx->sgh_hash_table, (void *)sgh, 0); -} - -/** - * \brief Used to lookup a SigGroupHead hash from the detection engine context - * SigGroupHead hash table. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval rsgh On success a pointer to the SigGroupHead if the SigGroupHead is - * found in the hash table; NULL on failure. - */ -SigGroupHead *SigGroupHeadHashLookup(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - SCEnter(); - - SigGroupHead *rsgh = HashListTableLookup(de_ctx->sgh_hash_table, - (void *)sgh, 0); - - SCReturnPtr(rsgh, "SigGroupHead"); -} - -/** - * \brief Frees the hash table - DetectEngineCtx->sgh_hash_table, allocated by - * SigGroupHeadHashInit() function. - * - * \param de_ctx Pointer to the detection engine context. - */ -void SigGroupHeadHashFree(DetectEngineCtx *de_ctx) -{ - if (de_ctx->sgh_hash_table == NULL) - return; - - HashListTableFree(de_ctx->sgh_hash_table); - de_ctx->sgh_hash_table = NULL; - - return; -} - -/** - * \brief Initializes the dport based SigGroupHead hash table to hold the - * SigGroupHeads. The hash table that would be initialized is - * DetectEngineCtx->sgh_dport_hash_table. - * - * \param de_ctx Pointer to the detection engine context. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SigGroupHeadDPortHashInit(DetectEngineCtx *de_ctx) -{ - de_ctx->sgh_dport_hash_table = HashListTableInit(4096, SigGroupHeadHashFunc, - SigGroupHeadCompareFunc, - NULL); - if (de_ctx->sgh_dport_hash_table == NULL) - goto error; - - return 0; - -error: - return -1; -} - -/** - * \brief Adds a SigGroupHead to the detection engine context dport based - * SigGroupHead hash table(DetectEngineCtx->sgh_dport_hash_table). - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval ret 0 on Successfully adding the argument sgh and -1 on failure. - */ -int SigGroupHeadDPortHashAdd(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - int ret = HashListTableAdd(de_ctx->sgh_dport_hash_table, (void *)sgh, 0); - - return ret; -} - -/** - * \brief Used to lookup a SigGroupHead hash from the detection engine ctx dport - * based SigGroupHead hash table(DetectEngineCtx->sgh_dport_hash_table). - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval rsgh On success a pointer to the SigGroupHead if the SigGroupHead is - * found in the hash table; NULL on failure. - */ -SigGroupHead *SigGroupHeadDPortHashLookup(DetectEngineCtx *de_ctx, - SigGroupHead *sgh) -{ - SCEnter(); - - SigGroupHead *rsgh = HashListTableLookup(de_ctx->sgh_dport_hash_table, - (void *)sgh, 0); - - SCReturnPtr(rsgh,"SigGroupHead"); -} - -/** - * \brief Frees the hash table - DetectEngineCtx->sgh_dport_hash_table, - * allocated by the SigGroupHeadDPortHashInit() function. - * - * \param de_ctx Pointer to the detection engine context. - */ -void SigGroupHeadDPortHashFree(DetectEngineCtx *de_ctx) -{ - if (de_ctx->sgh_dport_hash_table == NULL) - return; - - HashListTableFree(de_ctx->sgh_dport_hash_table); - de_ctx->sgh_dport_hash_table = NULL; - - return; -} - -/** - * \brief Initializes the sport based SigGroupHead hash table to hold the - * SigGroupHeads. The hash table that would be initialized is - * DetectEngineCtx->sgh_sport_hash_table. - * - * \param de_ctx Pointer to the detection engine context. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SigGroupHeadSPortHashInit(DetectEngineCtx *de_ctx) -{ - de_ctx->sgh_sport_hash_table = HashListTableInit(4096, - SigGroupHeadHashFunc, - SigGroupHeadCompareFunc, - NULL); - if (de_ctx->sgh_sport_hash_table == NULL) - goto error; - - return 0; - -error: - return -1; -} - -/** - * \brief Adds a SigGroupHead to the detection engine context dport based - * SigGroupHead hash table(DetectEngineCtx->sgh_sport_hash_table). - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval ret 0 on Successfully adding the argument sgh and -1 on failure. - */ -int SigGroupHeadSPortHashAdd(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - int ret = HashListTableAdd(de_ctx->sgh_sport_hash_table, (void *)sgh, 0); - - return ret; -} - -int SigGroupHeadSPortHashRemove(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - return HashListTableRemove(de_ctx->sgh_sport_hash_table, (void *)sgh, 0); -} - -/** - * \brief Used to lookup a SigGroupHead hash from the detection engine ctx sport - * based SigGroupHead hash table(DetectEngineCtx->sgh_dport_hash_table). - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval rsgh On success a pointer to the SigGroupHead if the SigGroupHead is - * found in the hash table; NULL on failure. - */ -SigGroupHead *SigGroupHeadSPortHashLookup(DetectEngineCtx *de_ctx, - SigGroupHead *sgh) -{ - SigGroupHead *rsgh = HashListTableLookup(de_ctx->sgh_sport_hash_table, - (void *)sgh, 0); - - return rsgh; -} - -/** - * \brief Frees the hash table - DetectEngineCtx->sgh_sport_hash_table, - * allocated by the SigGroupHeadSPortHashInit() function. - * - * \param de_ctx Pointer to the detection engine context. - */ -void SigGroupHeadSPortHashFree(DetectEngineCtx *de_ctx) -{ - if (de_ctx->sgh_sport_hash_table == NULL) - return; - - HashListTableFree(de_ctx->sgh_sport_hash_table); - de_ctx->sgh_sport_hash_table = NULL; - - return; -} - -/** - * \brief Used to free the signature array, content_array and uri_content_array - * members from the SigGroupHeads in the HashListTable. - * - * \param de_ctx Pointer to the detection engine context. - * \param ht Pointer to the HashListTable - */ -static void SigGroupHeadFreeSigArraysHash2(DetectEngineCtx *de_ctx, - HashListTable *ht) -{ - HashListTableBucket *htb = NULL; - SigGroupHead *sgh = NULL; - - for (htb = HashListTableGetListHead(ht); - htb != NULL; - htb = HashListTableGetListNext(htb)) - { - sgh = (SigGroupHead *)HashListTableGetListData(htb); - if (sgh == NULL) { - continue; - } - - if (sgh->init->sig_array != NULL) { - detect_siggroup_sigarray_free_cnt++; - detect_siggroup_sigarray_memory -= sgh->init->sig_size; - - SCFree(sgh->init->sig_array); - sgh->init->sig_array = NULL; - sgh->init->sig_size = 0; - } - - SigGroupHeadInitDataFree(sgh->init); - sgh->init = NULL; - } - - return; -} - -/** - * \brief Used to free the sig_array member of the SigGroupHeads present - * in the HashListTable. - * - * \param de_ctx Pointer to the detection engine context. - * \param ht Pointer to the HashListTable - */ -static void SigGroupHeadFreeSigArraysHash(DetectEngineCtx *de_ctx, - HashListTable *ht) -{ - HashListTableBucket *htb = NULL; - SigGroupHead *sgh = NULL; - - for (htb = HashListTableGetListHead(ht); - htb != NULL; - htb = HashListTableGetListNext(htb)) { - sgh = (SigGroupHead *)HashListTableGetListData(htb); - - if (sgh->init != NULL) { - SigGroupHeadInitDataFree(sgh->init); - sgh->init = NULL; - } - } - - return; -} - -/** - * \brief Free the sigarrays in the sgh's. Those are only used during the init - * stage. - * - * \param de_ctx Pointer to the detection engine context whose sigarrays have to - * be freed. - */ -void SigGroupHeadFreeSigArrays(DetectEngineCtx *de_ctx) -{ - SigGroupHeadFreeSigArraysHash2(de_ctx, de_ctx->sgh_hash_table); - SigGroupHeadFreeSigArraysHash(de_ctx, de_ctx->sgh_dport_hash_table); - SigGroupHeadFreeSigArraysHash(de_ctx, de_ctx->sgh_sport_hash_table); - - return; -} - -/** - * \brief Free the mpm arrays that are only used during the init stage. - * - * \param de_ctx Pointer to the detection engine context. - */ -void SigGroupHeadFreeMpmArrays(DetectEngineCtx *de_ctx) -{ - HashListTableBucket *htb = NULL; - SigGroupHead *sgh = NULL; - - for (htb = HashListTableGetListHead(de_ctx->sgh_dport_hash_table); htb != NULL; htb = HashListTableGetListNext(htb)) { - sgh = (SigGroupHead *)HashListTableGetListData(htb); - if (sgh->init != NULL) { - SigGroupHeadInitDataFree(sgh->init); - sgh->init = NULL; - } - } - - for (htb = HashListTableGetListHead(de_ctx->sgh_sport_hash_table); htb != NULL; htb = HashListTableGetListNext(htb)) { - sgh = (SigGroupHead *)HashListTableGetListData(htb); - if (sgh->init != NULL) { - SigGroupHeadInitDataFree(sgh->init); - sgh->init = NULL; - } - } - - return; -} - -static uint16_t SignatureGetMpmPatternLen(Signature *s, int list) -{ - if (s->sm_lists[list] != NULL && s->mpm_sm != NULL && - SigMatchListSMBelongsTo(s, s->mpm_sm) == list) - { - DetectContentData *cd = (DetectContentData *)s->mpm_sm->ctx; - return cd->content_len; - } - return 0; -} - -/** - * \brief Add a Signature to a SigGroupHead. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to a SigGroupHead. Can be NULL also. - * \param s Pointer to the Signature that has to be added to the - * SigGroupHead. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SigGroupHeadAppendSig(DetectEngineCtx *de_ctx, SigGroupHead **sgh, - Signature *s) -{ - if (de_ctx == NULL) - return 0; - - /* see if we have a head already */ - if (*sgh == NULL) { - *sgh = SigGroupHeadAlloc(de_ctx, DetectEngineGetMaxSigId(de_ctx) / 8 + 1); - if (*sgh == NULL) - goto error; - } - - /* enable the sig in the bitarray */ - (*sgh)->init->sig_array[s->num / 8] |= 1 << (s->num % 8); - - /* update minlen for mpm */ - if (s->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - /* check with the precalculated values from the sig */ - uint16_t mpm_content_minlen = SignatureGetMpmPatternLen(s, DETECT_SM_LIST_PMATCH); - if (mpm_content_minlen > 0) { - if ((*sgh)->mpm_content_minlen == 0) - (*sgh)->mpm_content_minlen = mpm_content_minlen; - - if ((*sgh)->mpm_content_minlen > mpm_content_minlen) - (*sgh)->mpm_content_minlen = mpm_content_minlen; - - SCLogDebug("(%p)->mpm_content_minlen %u", *sgh, (*sgh)->mpm_content_minlen); - } - } - return 0; - -error: - return -1; -} - -/** - * \brief Clears the bitarray holding the sids for this SigGroupHead. - * - * \param sgh Pointer to the SigGroupHead. - * - * \retval 0 Always. - */ -int SigGroupHeadClearSigs(SigGroupHead *sgh) -{ - if (sgh == NULL) - return 0; - - if (sgh->init->sig_array != NULL) - memset(sgh->init->sig_array, 0, sgh->init->sig_size); - - sgh->sig_cnt = 0; - - return 0; -} - -/** - * \brief Copies the bitarray holding the sids from the source SigGroupHead to - * the destination SigGroupHead. - * - * \param de_ctx Pointer to the detection engine context. - * \param src Pointer to the source SigGroupHead. - * \param dst Pointer to the destination SigGroupHead. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SigGroupHeadCopySigs(DetectEngineCtx *de_ctx, SigGroupHead *src, SigGroupHead **dst) -{ - uint32_t idx = 0; - - if (src == NULL || de_ctx == NULL) - return 0; - - if (*dst == NULL) { - *dst = SigGroupHeadAlloc(de_ctx, DetectEngineGetMaxSigId(de_ctx) / 8 + 1); - if (*dst == NULL) - goto error; - } - - /* do the copy */ - for (idx = 0; idx < src->init->sig_size; idx++) - (*dst)->init->sig_array[idx] = (*dst)->init->sig_array[idx] | src->init->sig_array[idx]; - - if (src->mpm_content_minlen != 0) { - if ((*dst)->mpm_content_minlen == 0) - (*dst)->mpm_content_minlen = src->mpm_content_minlen; - - if ((*dst)->mpm_content_minlen > src->mpm_content_minlen) - (*dst)->mpm_content_minlen = src->mpm_content_minlen; - - SCLogDebug("src (%p)->mpm_content_minlen %u", src, src->mpm_content_minlen); - SCLogDebug("dst (%p)->mpm_content_minlen %u", (*dst), (*dst)->mpm_content_minlen); - BUG_ON((*dst)->mpm_content_minlen == 0); - } - return 0; - -error: - return -1; -} - -/** - * \brief Updates the SigGroupHead->sig_cnt with the total count of all the - * Signatures present in this SigGroupHead. - * - * \param sgh Pointer to the SigGroupHead. - * \param max_idx Maximum sid of the all the Signatures present in this - * SigGroupHead. - */ -void SigGroupHeadSetSigCnt(SigGroupHead *sgh, uint32_t max_idx) -{ - uint32_t sig; - - sgh->sig_cnt = 0; - for (sig = 0; sig < max_idx + 1; sig++) { - if (sgh->init->sig_array[sig / 8] & (1 << (sig % 8))) - sgh->sig_cnt++; - } - - return; -} - -/** - * \brief Prints the memory statistics for the detect-engine-siggroup.[ch] module. - */ -void DetectSigGroupPrintMemory(void) -{ - SCLogDebug(" * Sig group head memory stats (SigGroupHead %" PRIuMAX "):", - (uintmax_t)sizeof(SigGroupHead)); - SCLogDebug(" - detect_siggroup_head_memory %" PRIu32, - detect_siggroup_head_memory); - SCLogDebug(" - detect_siggroup_head_init_cnt %" PRIu32, - detect_siggroup_head_init_cnt); - SCLogDebug(" - detect_siggroup_head_free_cnt %" PRIu32, - detect_siggroup_head_free_cnt); - SCLogDebug(" - outstanding sig group heads %" PRIu32, - detect_siggroup_head_init_cnt - detect_siggroup_head_free_cnt); - SCLogDebug(" * Sig group head memory stats done"); - SCLogDebug(" * Sig group head initdata memory stats (SigGroupHeadInitData %" PRIuMAX "):", - (uintmax_t)sizeof(SigGroupHeadInitData)); - SCLogDebug(" - detect_siggroup_head_initdata_memory %" PRIu32, - detect_siggroup_head_initdata_memory); - SCLogDebug(" - detect_siggroup_head_initdata_init_cnt %" PRIu32, - detect_siggroup_head_initdata_init_cnt); - SCLogDebug(" - detect_siggroup_head_initdata_free_cnt %" PRIu32, - detect_siggroup_head_initdata_free_cnt); - SCLogDebug(" - outstanding sig group head initdatas %" PRIu32, - detect_siggroup_head_initdata_init_cnt - detect_siggroup_head_initdata_free_cnt); - SCLogDebug(" * Sig group head memory initdata stats done"); - SCLogDebug(" * Sig group sigarray memory stats:"); - SCLogDebug(" - detect_siggroup_sigarray_memory %" PRIu32, - detect_siggroup_sigarray_memory); - SCLogDebug(" - detect_siggroup_sigarray_init_cnt %" PRIu32, - detect_siggroup_sigarray_init_cnt); - SCLogDebug(" - detect_siggroup_sigarray_free_cnt %" PRIu32, - detect_siggroup_sigarray_free_cnt); - SCLogDebug(" - outstanding sig group sigarrays %" PRIu32, - (detect_siggroup_sigarray_init_cnt - - detect_siggroup_sigarray_free_cnt)); - SCLogDebug(" * Sig group sigarray memory stats done"); - SCLogDebug(" * Sig group matcharray memory stats:"); - SCLogDebug(" - detect_siggroup_matcharray_memory %" PRIu32, - detect_siggroup_matcharray_memory); - SCLogDebug(" - detect_siggroup_matcharray_init_cnt %" PRIu32, - detect_siggroup_matcharray_init_cnt); - SCLogDebug(" - detect_siggroup_matcharray_free_cnt %" PRIu32, - detect_siggroup_matcharray_free_cnt); - SCLogDebug(" - outstanding sig group matcharrays %" PRIu32, - (detect_siggroup_matcharray_init_cnt - - detect_siggroup_matcharray_free_cnt)); - SCLogDebug(" * Sig group sigarray memory stats done"); - SCLogDebug(" X Total %" PRIu32, - (detect_siggroup_head_memory + detect_siggroup_sigarray_memory + - detect_siggroup_matcharray_memory)); - - return; -} - -/** - * \brief Helper function used to print the list of sids for the Signatures - * present in this SigGroupHead. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - */ -void SigGroupHeadPrintSigs(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - SCEnter(); - - if (sgh == NULL) { - SCReturn; - } - - uint32_t u; - - SCLogDebug("The Signatures present in this SigGroupHead are: "); - for (u = 0; u < (sgh->init->sig_size * 8); u++) { - if (sgh->init->sig_array[u / 8] & (1 << (u % 8))) { - SCLogDebug("%" PRIu32, u); - printf("s->num %"PRIu32" ", u); - } - } - - SCReturn; -} - -/** - * \brief Helper function used to print the content ids of all the contents that - * have been added to the bitarray of this SigGroupHead. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - */ -void SigGroupHeadPrintContent(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - SCEnter(); - - uint32_t i = 0; - - SCLogDebug("Contents with the following content ids are present in this " - "SigGroupHead - "); - for (i = 0; i < DetectContentMaxId(de_ctx); i++) { - if (sgh->init->content_array[i / 8] & (1 << (i % 8))) - SCLogDebug("%" PRIu32, i); - } - - SCReturn; -} - -/** - * \brief Helper function used to print the total no of contents that have - * been added to the bitarray for this SigGroupHead. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - */ -void SigGroupHeadPrintContentCnt(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - SCEnter(); - - uint32_t i = 0; - uint32_t cnt = 0; - - for (i = 0; i < DetectContentMaxId(de_ctx); i++) { - if (sgh->init->content_array[i / 8] & (1 << (i % 8))) - cnt++; - } - - SCLogDebug("Total contents added to the SigGroupHead content bitarray: " - "%" PRIu32, cnt); - - SCReturn; -} - -/** - * \brief Loads all the content ids from all the contents belonging to all the - * Signatures in this SigGroupHead, into a bitarray. A fast and an - * efficient way of comparing pattern sets. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval 0 On success, i.e. on either the detection engine context being NULL - * or on successfully allocating memory and updating it with relevant - * data. - * \retval -1 On failure. - */ -int SigGroupHeadLoadContent(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - Signature *s = NULL; - SigMatch *sm = NULL; - uint32_t sig = 0; - DetectContentData *co = NULL; - - if (sgh == NULL) - return 0; - - if (DetectContentMaxId(de_ctx) == 0) - return 0; - - BUG_ON(sgh->init == NULL); - - sgh->init->content_size = (DetectContentMaxId(de_ctx) / 8) + 1; - sgh->init->content_array = SCMalloc(sgh->init->content_size); - if (sgh->init->content_array == NULL) - return -1; - - memset(sgh->init->content_array,0, sgh->init->content_size); - - for (sig = 0; sig < sgh->sig_cnt; sig++) { - s = sgh->match_array[sig]; - if (s == NULL) - continue; - - if (s->alproto != ALPROTO_UNKNOWN) - continue; - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm == NULL) - continue; - - for ( ;sm != NULL; sm = sm->next) { - if (sm->type == DETECT_CONTENT) { - co = (DetectContentData *)sm->ctx; - - sgh->init->content_array[co->id / 8] |= 1 << (co->id % 8); - } - } - } - - return 0; -} - -/** - * \brief Clears the memory allocated by SigGroupHeadLoadContent() for the - * bitarray to hold the content ids for a SigGroupHead. - * - * \param Pointer to the SigGroupHead whose content_array would to be cleared. - * - * \ret 0 Always. - */ -int SigGroupHeadClearContent(SigGroupHead *sh) -{ - if (sh == NULL) - return 0; - - if (sh->init->content_array != NULL) { - SCFree(sh->init->content_array); - sh->init->content_array = NULL; - sh->init->content_size = 0; - } - return 0; -} - -/** - * \brief Loads all the uri content ids from all the uri contents belonging to - * all the Signatures in this SigGroupHead, into a bitarray. A fast and - * an efficient way of comparing pattern sets. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval 0 On success, i.e. on either the detection engine context being NULL - * or on successfully allocating memory and updating it with relevant - * data. - * \retval -1 On failure. - */ -int SigGroupHeadLoadUricontent(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - Signature *s = NULL; - SigMatch *sm = NULL; - uint32_t sig = 0; - DetectContentData *co = NULL; - - if (sgh == NULL) - return 0; - - if (DetectUricontentMaxId(de_ctx) == 0) - return 0; - - BUG_ON(sgh->init == NULL); - - sgh->init->uri_content_size = (DetectUricontentMaxId(de_ctx) / 8) + 1; - sgh->init->uri_content_array = SCMalloc(sgh->init->uri_content_size); - if (sgh->init->uri_content_array == NULL) - return -1; - - memset(sgh->init->uri_content_array, 0, sgh->init->uri_content_size); - - for (sig = 0; sig < sgh->sig_cnt; sig++) { - s = sgh->match_array[sig]; - - if (s == NULL) - continue; - - sm = s->sm_lists[DETECT_SM_LIST_UMATCH]; - if (sm == NULL) - continue; - - for ( ;sm != NULL; sm = sm->next) { - if (sm->type == DETECT_CONTENT) { - co = (DetectContentData *)sm->ctx; - - sgh->init->uri_content_array[co->id / 8] |= 1 << (co->id % 8); - } - } - } - - return 0; -} - -/** - * \brief Clears the memory allocated by SigGroupHeadLoadUriContent() for the - * bitarray to hold the uri content ids for a SigGroupHead. - * - * \param Pointer to the SigGroupHead whose uri_content_array would to be - * cleared. - * - * \retval 0 Always. - */ -int SigGroupHeadClearUricontent(SigGroupHead *sh) -{ - if (sh == NULL) - return 0; - - if (sh->init->uri_content_array != NULL) { - SCFree(sh->init->uri_content_array); - sh->init->uri_content_array = NULL; - sh->init->uri_content_size = 0; - } - - return 0; -} - -/** - * \brief Loads all the content ids from all the contents belonging to all the - * Signatures in this SigGroupHead, into a bitarray. A fast and an - * efficient way of comparing pattern sets. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * - * \retval 0 On success, i.e. on either the detection engine context being NULL - * or on successfully allocating memory and updating it with relevant - * data. - * \retval -1 On failure. - */ -int SigGroupHeadLoadStreamContent(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - SCEnter(); - - Signature *s = NULL; - SigMatch *sm = NULL; - uint32_t sig = 0; - DetectContentData *co = NULL; - - if (sgh == NULL) { - SCReturnInt(0); - } - - if (DetectContentMaxId(de_ctx) == 0) { - SCReturnInt(0); - } - - BUG_ON(sgh->init == NULL); - - sgh->init->stream_content_size = (DetectContentMaxId(de_ctx) / 8) + 1; - sgh->init->stream_content_array = SCMalloc(sgh->init->stream_content_size); - if (sgh->init->stream_content_array == NULL) { - SCReturnInt(-1); - } - - memset(sgh->init->stream_content_array,0, sgh->init->stream_content_size); - - for (sig = 0; sig < sgh->sig_cnt; sig++) { - s = sgh->match_array[sig]; - - SCLogDebug("s %"PRIu32, s->id); - - if (s == NULL) - continue; - - if (SignatureHasPacketContent(s)) { - SCLogDebug("Sig has packet content"); - continue; - } - - sm = s->sm_lists[DETECT_SM_LIST_PMATCH]; - if (sm == NULL) - continue; - - for ( ;sm != NULL; sm = sm->next) { - if (sm->type == DETECT_CONTENT) { - co = (DetectContentData *)sm->ctx; - - sgh->init->stream_content_array[co->id / 8] |= 1 << (co->id % 8); - } - } - } - - SCReturnInt(0); -} - -/** - * \brief Clears the memory allocated by SigGroupHeadLoadContent() for the - * bitarray to hold the content ids for a SigGroupHead. - * - * \param Pointer to the SigGroupHead whose content_array would to be cleared. - * - * \ret 0 Always. - */ -int SigGroupHeadClearStreamContent(SigGroupHead *sh) -{ - if (sh == NULL) - return 0; - - if (sh->init->stream_content_array != NULL) { - SCFree(sh->init->stream_content_array); - sh->init->stream_content_array = NULL; - sh->init->stream_content_size = 0; - } - return 0; -} - -/** - * \brief Create an array with all the internal ids of the sigs that this - * sig group head will check for. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead. - * \param max_idx The maximum value of the sid in the SigGroupHead arg. - * - * \retval 0 success - * \retval -1 error - */ -int SigGroupHeadBuildMatchArray(DetectEngineCtx *de_ctx, SigGroupHead *sgh, - uint32_t max_idx) -{ - Signature *s = NULL; - uint32_t idx = 0; - uint32_t sig = 0; - - if (sgh == NULL) - return 0; - - BUG_ON(sgh->match_array != NULL); - - sgh->match_array = SCMalloc(sgh->sig_cnt * sizeof(Signature *)); - if (sgh->match_array == NULL) - return -1; - - memset(sgh->match_array,0, sgh->sig_cnt * sizeof(Signature *)); - - detect_siggroup_matcharray_init_cnt++; - detect_siggroup_matcharray_memory += (sgh->sig_cnt * sizeof(Signature *)); - - for (sig = 0; sig < max_idx + 1; sig++) { - if (!(sgh->init->sig_array[(sig / 8)] & (1 << (sig % 8))) ) - continue; - - s = de_ctx->sig_array[sig]; - if (s == NULL) - continue; - - sgh->match_array[idx] = s; - idx++; - } - - return 0; -} - -/** - * \brief Set the need md5 flag in the sgh. - * - * \param de_ctx detection engine ctx for the signatures - * \param sgh sig group head to set the flag in - */ -void SigGroupHeadSetFilemagicFlag(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - Signature *s = NULL; - uint32_t sig = 0; - - if (sgh == NULL) - return; - - for (sig = 0; sig < sgh->sig_cnt; sig++) { - s = sgh->match_array[sig]; - if (s == NULL) - continue; - - if (SignatureIsFilemagicInspecting(s)) { - sgh->flags |= SIG_GROUP_HEAD_HAVEFILEMAGIC; - break; - } - } - - return; -} - -/** - * \brief Get size of the shortest mpm pattern. - * - * \param de_ctx detection engine ctx for the signatures - * \param sgh sig group head to set the flag in - * \param list sm_list to consider - */ -uint16_t SigGroupHeadGetMinMpmSize(DetectEngineCtx *de_ctx, - SigGroupHead *sgh, int list) -{ - Signature *s = NULL; - uint32_t sig = 0; - uint16_t min = USHRT_MAX; - - if (sgh == NULL) - return 0; - - for (sig = 0; sig < sgh->sig_cnt; sig++) { - s = sgh->match_array[sig]; - if (s == NULL) - continue; - - uint16_t mpm_content_minlen = SignatureGetMpmPatternLen(s, DETECT_SM_LIST_PMATCH); - if (mpm_content_minlen > 0) { - if (mpm_content_minlen < min) - min = mpm_content_minlen; - SCLogDebug("mpm_content_minlen %u", mpm_content_minlen); - } - } - - if (min == USHRT_MAX) - min = 0; - SCLogDebug("min mpm size %u", min); - return min; -} - -/** - * \brief Set the need size flag in the sgh. - * - * \param de_ctx detection engine ctx for the signatures - * \param sgh sig group head to set the flag in - */ -void SigGroupHeadSetFilesizeFlag(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - Signature *s = NULL; - uint32_t sig = 0; - - if (sgh == NULL) - return; - - for (sig = 0; sig < sgh->sig_cnt; sig++) { - s = sgh->match_array[sig]; - if (s == NULL) - continue; - - if (SignatureIsFilesizeInspecting(s)) { - sgh->flags |= SIG_GROUP_HEAD_HAVEFILESIZE; - break; - } - } - - return; -} - -/** - * \brief Set the need magic flag in the sgh. - * - * \param de_ctx detection engine ctx for the signatures - * \param sgh sig group head to set the flag in - */ -void SigGroupHeadSetFileMd5Flag(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - Signature *s = NULL; - uint32_t sig = 0; - - if (sgh == NULL) - return; - - for (sig = 0; sig < sgh->sig_cnt; sig++) { - s = sgh->match_array[sig]; - if (s == NULL) - continue; - - if (SignatureIsFileMd5Inspecting(s)) { - sgh->flags |= SIG_GROUP_HEAD_HAVEFILEMD5; - SCLogDebug("sgh %p has filemd5", sgh); - break; - } - } - - return; -} - -/** - * \brief Set the filestore_cnt in the sgh. - * - * \param de_ctx detection engine ctx for the signatures - * \param sgh sig group head to set the counter in - */ -void SigGroupHeadSetFilestoreCount(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - Signature *s = NULL; - uint32_t sig = 0; - - if (sgh == NULL) - return; - - for (sig = 0; sig < sgh->sig_cnt; sig++) { - s = sgh->match_array[sig]; - if (s == NULL) - continue; - - if (SignatureIsFilestoring(s)) { - sgh->filestore_cnt++; - } - } - - return; -} - -/** \brief build an array of rule id's for sigs with no mpm - * Also updated de_ctx::non_mpm_store_cnt_max to track the highest cnt - */ -int SigGroupHeadBuildNonMpmArray(DetectEngineCtx *de_ctx, SigGroupHead *sgh) -{ - Signature *s = NULL; - uint32_t sig = 0; - uint32_t non_mpm = 0; - - if (sgh == NULL) - return 0; - - BUG_ON(sgh->non_mpm_store_array != NULL); - - for (sig = 0; sig < sgh->sig_cnt; sig++) { - s = sgh->match_array[sig]; - if (s == NULL) - continue; - - if (s->mpm_sm == NULL) - non_mpm++; - else if (s->flags & (SIG_FLAG_MPM_PACKET_NEG|SIG_FLAG_MPM_STREAM_NEG|SIG_FLAG_MPM_APPLAYER_NEG)) - non_mpm++; - } - - if (non_mpm == 0) { - sgh->non_mpm_store_array = NULL; - return 0; - } - - sgh->non_mpm_store_array = SCMalloc(non_mpm * sizeof(SignatureNonMpmStore)); - BUG_ON(sgh->non_mpm_store_array == NULL); - memset(sgh->non_mpm_store_array, 0, non_mpm * sizeof(SignatureNonMpmStore)); - - for (sig = 0; sig < sgh->sig_cnt; sig++) { - s = sgh->match_array[sig]; - if (s == NULL) - continue; - - if (s->mpm_sm == NULL) { - BUG_ON(sgh->non_mpm_store_cnt >= non_mpm); - sgh->non_mpm_store_array[sgh->non_mpm_store_cnt].id = s->num; - sgh->non_mpm_store_array[sgh->non_mpm_store_cnt].mask = s->mask; - sgh->non_mpm_store_cnt++; - } else if (s->flags & (SIG_FLAG_MPM_PACKET_NEG|SIG_FLAG_MPM_STREAM_NEG|SIG_FLAG_MPM_APPLAYER_NEG)) { - BUG_ON(sgh->non_mpm_store_cnt >= non_mpm); - sgh->non_mpm_store_array[sgh->non_mpm_store_cnt].id = s->num; - sgh->non_mpm_store_array[sgh->non_mpm_store_cnt].mask = s->mask; - sgh->non_mpm_store_cnt++; - } - } - - /* track highest cnt for any sgh in our de_ctx */ - if (sgh->non_mpm_store_cnt > de_ctx->non_mpm_store_cnt_max) - de_ctx->non_mpm_store_cnt_max = sgh->non_mpm_store_cnt; - - return 0; -} - -/** - * \brief Check if a SigGroupHead contains a Signature, whose sid is sent as an - * argument. - * - * \param de_ctx Pointer to the detection engine context. - * \param sgh Pointer to the SigGroupHead that has to be checked for the - * presence of a Signature. - * \param sid The Signature id(sid) that has to be checked in the SigGroupHead. - * - * \retval 1 On successfully finding the sid in the SigGroupHead. - * \retval 0 If the sid is not found in the SigGroupHead - */ -int SigGroupHeadContainsSigId(DetectEngineCtx *de_ctx, SigGroupHead *sgh, - uint32_t sid) -{ - SCEnter(); - - uint32_t sig = 0; - Signature *s = NULL; - uint32_t max_sid = DetectEngineGetMaxSigId(de_ctx); - - if (sgh == NULL) { - SCReturnInt(0); - } - - for (sig = 0; sig < max_sid; sig++) { - if (sgh->init->sig_array == NULL) { - SCReturnInt(0); - } - - /* Check if the SigGroupHead has an entry for the sid */ - if ( !(sgh->init->sig_array[sig / 8] & (1 << (sig % 8))) ) - continue; - - /* If we have reached here, we have an entry for sid in the SigGrouHead. - * Retrieve the Signature from the detection engine context */ - s = de_ctx->sig_array[sig]; - if (s == NULL) - continue; - - /* If the retrieved Signature matches the sid arg, we have a match */ - if (s->id == sid) { - SCReturnInt(1); - } - } - - SCReturnInt(0); -} - -/*----------------------------------Unittests---------------------------------*/ - -#ifdef UNITTESTS - -int SigAddressPrepareStage1(DetectEngineCtx *); - -/** - * \test Check if a SigGroupHead mpm hash table is properly allocated and - * deallocated when calling SigGroupHeadMpmHashInit() and - * SigGroupHeadMpmHashFree() respectively. - */ -static int SigGroupHeadTest01(void) -{ - int result = 1; - - DetectEngineCtx de_ctx; - - SigGroupHeadMpmHashInit(&de_ctx); - - result &= (de_ctx.sgh_mpm_hash_table != NULL); - - SigGroupHeadMpmHashFree(&de_ctx); - - result &= (de_ctx.sgh_mpm_hash_table == NULL); - - return result; -} - -/** - * \test Check if a SigGroupHead mpm uri hash table is properly allocated and - * deallocated when calling SigGroupHeadMpmUriHashInit() and - * SigGroupHeadMpmUriHashFree() respectively. - */ -static int SigGroupHeadTest02(void) -{ - int result = 1; - - DetectEngineCtx de_ctx; - - SigGroupHeadMpmUriHashInit(&de_ctx); - - result &= (de_ctx.sgh_mpm_uri_hash_table != NULL); - - SigGroupHeadMpmUriHashFree(&de_ctx); - - result &= (de_ctx.sgh_mpm_uri_hash_table == NULL); - - return result; -} - -/** - * \test Check if a SigGroupHead hash table is properly allocated and - * deallocated when calling SigGroupHeadHashInit() and - * SigGroupHeadHashFree() respectively. - */ -static int SigGroupHeadTest03(void) -{ - int result = 1; - - DetectEngineCtx de_ctx; - - SigGroupHeadHashInit(&de_ctx); - - result &= (de_ctx.sgh_hash_table != NULL); - - SigGroupHeadHashFree(&de_ctx); - - result &= (de_ctx.sgh_hash_table == NULL); - - return result; -} - -/** - * \test Check if a SigGroupHead dport hash table is properly allocated and - * deallocated when calling SigGroupHeadDPortHashInit() and - * SigGroupHeadDportHashFree() respectively. - */ -static int SigGroupHeadTest04(void) -{ - int result = 1; - - DetectEngineCtx de_ctx; - - SigGroupHeadDPortHashInit(&de_ctx); - - result &= (de_ctx.sgh_dport_hash_table != NULL); - - SigGroupHeadDPortHashFree(&de_ctx); - - result &= (de_ctx.sgh_dport_hash_table == NULL); - - return result; -} - -/** - * \test Check if a SigGroupHead dport hash table is properly allocated and - * deallocated when calling SigGroupHeadSPortHashInit() and - * SigGroupHeadSportHashFree() respectively. - */ -static int SigGroupHeadTest05(void) -{ - int result = 1; - - DetectEngineCtx de_ctx; - - SigGroupHeadSPortHashInit(&de_ctx); - - result &= (de_ctx.sgh_sport_hash_table != NULL); - - SigGroupHeadSPortHashFree(&de_ctx); - - result &= (de_ctx.sgh_sport_hash_table == NULL); - - return result; -} - -/** - * \test Check if a SigGroupHeadAppendSig() correctly appends a sid to a - * SigGroupHead() and SigGroupHeadContainsSigId() correctly indicates - * the presence of a sid. - */ -static int SigGroupHeadTest06(void) -{ - int result = 1; - SigGroupHead *sh = NULL; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - Signature *prev_sig = NULL; - - if (de_ctx == NULL) - return 0; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:0;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - prev_sig = de_ctx->sig_list; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:1;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:2;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:3;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:4;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - SigAddressPrepareStage1(de_ctx); - - SigGroupHeadAppendSig(de_ctx, &sh, de_ctx->sig_list); - SigGroupHeadAppendSig(de_ctx, &sh, de_ctx->sig_list->next->next); - SigGroupHeadAppendSig(de_ctx, &sh, de_ctx->sig_list->next->next->next->next); - - SigGroupHeadSetSigCnt(sh, 4); - - result &= (sh->sig_cnt == 3); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 0) == 1); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 1) == 0); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 2) == 1); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 3) == 0); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 4) == 1); - - SigGroupHeadFree(sh); - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Check if a SigGroupHeadAppendSig(), correctly appends a sid to a - * SigGroupHead() and SigGroupHeadContainsSigId(), correctly indicates - * the presence of a sid and SigGroupHeadClearSigs(), correctly clears - * the SigGroupHead->sig_array and SigGroupHead->sig_cnt. - */ -static int SigGroupHeadTest07(void) -{ - int result = 1; - SigGroupHead *sh = NULL; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - Signature *prev_sig = NULL; - - if (de_ctx == NULL) - return 0; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:0;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - prev_sig = de_ctx->sig_list; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:1;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:2;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:3;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:4;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - SigAddressPrepareStage1(de_ctx); - - SigGroupHeadAppendSig(de_ctx, &sh, de_ctx->sig_list); - SigGroupHeadAppendSig(de_ctx, &sh, de_ctx->sig_list->next->next); - SigGroupHeadAppendSig(de_ctx, &sh, de_ctx->sig_list->next->next->next->next); - - SigGroupHeadSetSigCnt(sh, 4); - - result &= (sh->sig_cnt == 3); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 0) == 1); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 1) == 0); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 2) == 1); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 3) == 0); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 4) == 1); - - SigGroupHeadClearSigs(sh); - - result &= (sh->sig_cnt == 0); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 0) == 0); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 1) == 0); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 2) == 0); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 3) == 0); - result &= (SigGroupHeadContainsSigId(de_ctx, sh, 4) == 0); - - SigGroupHeadFree(sh); - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Check if SigGroupHeadCopySigs(), correctly copies the sig_array from - * the source to the destination SigGroupHead. - */ -static int SigGroupHeadTest08(void) -{ - int result = 1; - SigGroupHead *src_sh = NULL; - SigGroupHead *dst_sh = NULL; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - Signature *prev_sig = NULL; - - if (de_ctx == NULL) - return 0; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:0;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - prev_sig = de_ctx->sig_list; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:1;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:2;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:3;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:4;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - SigAddressPrepareStage1(de_ctx); - - SigGroupHeadAppendSig(de_ctx, &src_sh, de_ctx->sig_list); - SigGroupHeadAppendSig(de_ctx, &src_sh, de_ctx->sig_list->next->next); - SigGroupHeadAppendSig(de_ctx, &src_sh, de_ctx->sig_list->next->next->next->next); - - SigGroupHeadSetSigCnt(src_sh, 4); - - result &= (src_sh->sig_cnt == 3); - result &= (SigGroupHeadContainsSigId(de_ctx, src_sh, 0) == 1); - result &= (SigGroupHeadContainsSigId(de_ctx, src_sh, 1) == 0); - result &= (SigGroupHeadContainsSigId(de_ctx, src_sh, 2) == 1); - result &= (SigGroupHeadContainsSigId(de_ctx, src_sh, 3) == 0); - result &= (SigGroupHeadContainsSigId(de_ctx, src_sh, 4) == 1); - - SigGroupHeadCopySigs(de_ctx, src_sh, &dst_sh); - - SigGroupHeadSetSigCnt(dst_sh, 4); - - result &= (dst_sh->sig_cnt == 3); - result &= (SigGroupHeadContainsSigId(de_ctx, dst_sh, 0) == 1); - result &= (SigGroupHeadContainsSigId(de_ctx, dst_sh, 1) == 0); - result &= (SigGroupHeadContainsSigId(de_ctx, dst_sh, 2) == 1); - result &= (SigGroupHeadContainsSigId(de_ctx, dst_sh, 3) == 0); - result &= (SigGroupHeadContainsSigId(de_ctx, dst_sh, 4) == 1); - - SigGroupHeadFree(src_sh); - SigGroupHeadFree(dst_sh); - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Check if SigGroupHeadBuildMatchArray(), correctly updates the - * match array with the sids. - */ -static int SigGroupHeadTest09(void) -{ - int result = 1; - SigGroupHead *sh = NULL; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - Signature *prev_sig = NULL; - - if (de_ctx == NULL) - return 0; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:0;)"); - if (de_ctx->sig_list == NULL) { - result = 0; - goto end; - } - prev_sig = de_ctx->sig_list; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:1;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:2;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:3;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - prev_sig->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"SigGroupHead tests\"; content:\"test1\"; " - "content:\"test2\"; content:\"test3\"; sid:4;)"); - if (prev_sig->next == NULL) { - result = 0; - goto end; - } - prev_sig = prev_sig->next; - - SigAddressPrepareStage1(de_ctx); - - SigGroupHeadAppendSig(de_ctx, &sh, de_ctx->sig_list); - SigGroupHeadAppendSig(de_ctx, &sh, de_ctx->sig_list->next->next); - SigGroupHeadAppendSig(de_ctx, &sh, de_ctx->sig_list->next->next->next->next); - - SigGroupHeadSetSigCnt(sh, 4); - SigGroupHeadBuildMatchArray(de_ctx, sh, 4); - - result &= (sh->match_array[0] == de_ctx->sig_list); - result &= (sh->match_array[1] == de_ctx->sig_list->next->next); - result &= (sh->match_array[2] == de_ctx->sig_list->next->next->next->next); - - SigGroupHeadFree(sh); - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test ICMP(?) sig grouping bug. - */ -static int SigGroupHeadTest10(void) -{ - int result = 0; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - Signature *s = NULL; - Packet *p = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - ThreadVars th_v; - - memset(&th_v, 0, sizeof(ThreadVars)); - - p = UTHBuildPacketSrcDst(NULL, 0, IPPROTO_ICMP, "192.168.1.1", "1.2.3.4"); - p->icmpv4h->type = 5; - p->icmpv4h->code = 1; - - /* originally ip's were - p.src.addr_data32[0] = 0xe08102d3; - p.dst.addr_data32[0] = 0x3001a8c0; - */ - - if (de_ctx == NULL) - return 0; - - s = DetectEngineAppendSig(de_ctx, "alert icmp 192.168.0.0/16 any -> any any (icode:>1; itype:11; sid:1; rev:1;)"); - if (s == NULL) { - goto end; - } - s = DetectEngineAppendSig(de_ctx, "alert icmp any any -> 192.168.0.0/16 any (icode:1; itype:5; sid:2; rev:1;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - AddressDebugPrint(&p->dst); - - SigGroupHead *sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (sgh == NULL) { - goto end; - } - - result = 1; -end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - UTHFreePackets(&p, 1); - return result; -} - -/** - * \test sig grouping bug. - */ -static int SigGroupHeadTest11(void) -{ - int result = 0; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - Signature *s = NULL; - Packet *p = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - ThreadVars th_v; - - memset(&th_v, 0, sizeof(ThreadVars)); - - p = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "192.168.1.1", "1.2.3.4", 60000, 80); - - if (de_ctx == NULL || p == NULL) - return 0; - - s = DetectEngineAppendSig(de_ctx, "alert tcp any 1024: -> any 1024: (content:\"abc\"; sid:1;)"); - if (s == NULL) { - goto end; - } - s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (content:\"def\"; http_client_body; sid:2;)"); - if (s == NULL) { - goto end; - } - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - AddressDebugPrint(&p->dst); - - SigGroupHead *sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); - if (sgh == NULL) { - goto end; - } - - /* check if hcbd flag is set in sgh */ - if (!(sgh->flags & SIG_GROUP_HEAD_MPM_HCBD)) { - printf("sgh has not SIG_GROUP_HEAD_MPM_HCBD flag set: "); - goto end; - } - - /* check if sig 2 is part of the sgh */ - - result = 1; -end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - UTHFreePackets(&p, 1); - return result; -} -#endif - -void SigGroupHeadRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("SigGroupHeadTest01", SigGroupHeadTest01, 1); - UtRegisterTest("SigGroupHeadTest02", SigGroupHeadTest02, 1); - UtRegisterTest("SigGroupHeadTest03", SigGroupHeadTest03, 1); - UtRegisterTest("SigGroupHeadTest04", SigGroupHeadTest04, 1); - UtRegisterTest("SigGroupHeadTest05", SigGroupHeadTest05, 1); - UtRegisterTest("SigGroupHeadTest06", SigGroupHeadTest06, 1); - UtRegisterTest("SigGroupHeadTest07", SigGroupHeadTest07, 1); - UtRegisterTest("SigGroupHeadTest08", SigGroupHeadTest08, 1); - UtRegisterTest("SigGroupHeadTest09", SigGroupHeadTest09, 1); - UtRegisterTest("SigGroupHeadTest10", SigGroupHeadTest10, 1); - UtRegisterTest("SigGroupHeadTest11", SigGroupHeadTest11, 1); -#endif -} |