63
65
static uint32_t detect_siggroup_matcharray_init_cnt = 0;
64
66
static uint32_t detect_siggroup_matcharray_free_cnt = 0;
66
static SigGroupHeadInitData *SigGroupHeadInitDataAlloc(uint32_t size) {
67
SigGroupHeadInitData *sghid = SCMalloc(sizeof(SigGroupHeadInitData));
71
memset(sghid, 0x00, sizeof(SigGroupHeadInitData));
73
detect_siggroup_head_initdata_init_cnt++;
74
detect_siggroup_head_initdata_memory += sizeof(SigGroupHeadInitData);
78
68
void SigGroupHeadInitDataFree(SigGroupHeadInitData *sghid) {
79
69
if (sghid->content_array != NULL) {
80
70
SCFree(sghid->content_array);
86
76
sghid->uri_content_array = NULL;
87
77
sghid->uri_content_size = 0;
79
if (sghid->sig_array != NULL) {
80
SCFree(sghid->sig_array);
81
sghid->sig_array = NULL;
83
detect_siggroup_sigarray_free_cnt++;
84
detect_siggroup_sigarray_memory -= sghid->sig_size;
91
88
detect_siggroup_head_initdata_free_cnt++;
92
89
detect_siggroup_head_initdata_memory -= sizeof(SigGroupHeadInitData);
92
static SigGroupHeadInitData *SigGroupHeadInitDataAlloc(uint32_t size) {
93
SigGroupHeadInitData *sghid = SCMalloc(sizeof(SigGroupHeadInitData));
97
memset(sghid, 0x00, sizeof(SigGroupHeadInitData));
99
detect_siggroup_head_initdata_init_cnt++;
100
detect_siggroup_head_initdata_memory += sizeof(SigGroupHeadInitData);
102
/* initialize the signature bitarray */
103
sghid->sig_size = size;
104
if ( (sghid->sig_array = SCMalloc(sghid->sig_size)) == NULL)
107
memset(sghid->sig_array, 0, sghid->sig_size);
109
detect_siggroup_sigarray_init_cnt++;
110
detect_siggroup_sigarray_memory += sghid->sig_size;
114
SigGroupHeadInitDataFree(sghid);
118
void SigGroupHeadStore(DetectEngineCtx *de_ctx, SigGroupHead *sgh) {
119
//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);
120
if (de_ctx->sgh_array_cnt < de_ctx->sgh_array_size) {
121
de_ctx->sgh_array[de_ctx->sgh_array_cnt] = sgh;
123
de_ctx->sgh_array = SCRealloc(de_ctx->sgh_array, sizeof(SigGroupHead *) * (16 + de_ctx->sgh_array_size));
124
if (de_ctx->sgh_array == NULL)
126
de_ctx->sgh_array_size += 10;
127
de_ctx->sgh_array[de_ctx->sgh_array_cnt] = sgh;
129
de_ctx->sgh_array_cnt++;
96
133
* \brief Alloc a SigGroupHead and its signature bit_array.
147
175
PatternMatchDestroyGroup(sgh);
149
if (sgh->sig_array != NULL) {
150
SCFree(sgh->sig_array);
151
sgh->sig_array = NULL;
153
detect_siggroup_sigarray_free_cnt++;
154
detect_siggroup_sigarray_memory -= sgh->sig_size;
157
177
if (sgh->match_array != NULL) {
158
178
detect_siggroup_matcharray_free_cnt++;
159
detect_siggroup_matcharray_memory -= (sgh->sig_cnt * sizeof(SigIntId));
179
detect_siggroup_matcharray_memory -= (sgh->sig_cnt * sizeof(Signature *));
160
180
SCFree(sgh->match_array);
161
181
sgh->match_array = NULL;
165
186
if (sgh->init != NULL) {
166
187
SigGroupHeadInitDataFree(sgh->init);
167
188
sgh->init = NULL;
454
* \brief The hash function to be the used by the mpm uri SigGroupHead hash
455
* table - DetectEngineCtx->sgh_mpm_uri_hash_table.
457
* \param ht Pointer to the hash table.
458
* \param data Pointer to the SigGroupHead.
459
* \param datalen Not used in our case.
461
* \retval hash The generated hash value.
463
uint32_t SigGroupHeadMpmStreamHashFunc(HashListTable *ht, void *data, uint16_t datalen)
465
SigGroupHead *sgh = (SigGroupHead *)data;
469
for (b = 0; b < sgh->init->stream_content_size; b++)
470
hash += sgh->init->stream_content_array[b];
472
return hash % ht->array_size;
476
* \brief The Compare function to be used by the mpm uri SigGroupHead hash
477
* table - DetectEngineCtx->sgh_mpm_uri_hash_table.
479
* \param data1 Pointer to the first SigGroupHead.
480
* \param len1 Not used.
481
* \param data2 Pointer to the second SigGroupHead.
482
* \param len2 Not used.
484
* \retval 1 If the 2 SigGroupHeads sent as args match.
485
* \retval 0 If the 2 SigGroupHeads sent as args do not match.
487
char SigGroupHeadMpmStreamCompareFunc(void *data1, uint16_t len1, void *data2,
490
SigGroupHead *sgh1 = (SigGroupHead *)data1;
491
SigGroupHead *sgh2 = (SigGroupHead *)data2;
493
if (sgh1->init->stream_content_size != sgh2->init->stream_content_size)
496
if (memcmp(sgh1->init->stream_content_array, sgh2->init->stream_content_array,
497
sgh1->init->stream_content_size) != 0) {
505
* \brief Initializes the mpm uri hash table to be used by the detection engine
508
* \param de_ctx Pointer to the detection engine context.
510
* \retval 0 On success.
511
* \retval -1 On failure.
513
int SigGroupHeadMpmStreamHashInit(DetectEngineCtx *de_ctx)
515
de_ctx->sgh_mpm_stream_hash_table = HashListTableInit(4096,
516
SigGroupHeadMpmStreamHashFunc, SigGroupHeadMpmStreamCompareFunc, NULL);
517
if (de_ctx->sgh_mpm_stream_hash_table == NULL)
527
* \brief Adds a SigGroupHead to the detection engine context SigGroupHead
528
* mpm uri hash table.
530
* \param de_ctx Pointer to the detection engine context.
531
* \param sgh Pointer to the SigGroupHead.
533
* \retval ret 0 on Successfully adding the argument sgh and -1 on failure.
535
int SigGroupHeadMpmStreamHashAdd(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
537
int ret = HashListTableAdd(de_ctx->sgh_mpm_stream_hash_table, (void *)sgh, 0);
543
* \brief Used to lookup a SigGroupHead from the detection engine context
544
* SigGroupHead mpm uri hash table.
546
* \param de_ctx Pointer to the detection engine context.
547
* \param sgh Pointer to the SigGroupHead.
549
* \retval rsgh On success a pointer to the SigGroupHead if the SigGroupHead is
550
* found in the hash table; NULL on failure.
552
SigGroupHead *SigGroupHeadMpmStreamHashLookup(DetectEngineCtx *de_ctx,
555
SigGroupHead *rsgh = HashListTableLookup(de_ctx->sgh_mpm_stream_hash_table,
562
* \brief Frees the hash table - DetectEngineCtx->sgh_mpm_uri_hash_table,
563
* allocated by SigGroupHeadMpmUriHashInit() function.
565
* \param de_ctx Pointer to the detection engine context.
567
void SigGroupHeadMpmStreamHashFree(DetectEngineCtx *de_ctx)
569
if (de_ctx->sgh_mpm_stream_hash_table == NULL)
572
HashListTableFree(de_ctx->sgh_mpm_stream_hash_table);
573
de_ctx->sgh_mpm_stream_hash_table = NULL;
433
579
* \brief The hash function to be the used by the hash table -
434
580
* DetectEngineCtx->sgh_hash_table.
448
594
SCLogDebug("hashing sgh %p (mpm_content_maxlen %u)", sgh, sgh->mpm_content_maxlen);
450
for (b = 0; b < sgh->sig_size; b++)
451
hash += sgh->sig_array[b];
596
for (b = 0; b < sgh->init->sig_size; b++)
597
hash += sgh->init->sig_array[b];
453
599
hash %= ht->array_size;
454
SCLogDebug("hash %"PRIu32" (sig_size %"PRIu32")", hash, sgh->sig_size);
600
SCLogDebug("hash %"PRIu32" (sig_size %"PRIu32")", hash, sgh->init->sig_size);
739
885
for (htb = HashListTableGetListHead(ht);
741
htb = HashListTableGetListNext(htb)) {
887
htb = HashListTableGetListNext(htb))
742
889
sgh = (SigGroupHead *)HashListTableGetListData(htb);
744
if (sgh->sig_array != NULL) {
891
if (sgh->init->sig_array != NULL) {
745
892
detect_siggroup_sigarray_free_cnt++;
746
detect_siggroup_sigarray_memory -= sgh->sig_size;
893
detect_siggroup_sigarray_memory -= sgh->init->sig_size;
748
SCFree(sgh->sig_array);
749
sgh->sig_array = NULL;
895
SCFree(sgh->init->sig_array);
896
sgh->init->sig_array = NULL;
897
sgh->init->sig_size = 0;
753
900
if (sgh->init != NULL) {
1430
* \brief Loads all the content ids from all the contents belonging to all the
1431
* Signatures in this SigGroupHead, into a bitarray. A fast and an
1432
* efficient way of comparing pattern sets.
1434
* \param de_ctx Pointer to the detection engine context.
1435
* \param sgh Pointer to the SigGroupHead.
1437
* \retval 0 On success, i.e. on either the detection engine context being NULL
1438
* or on succesfully allocating memory and updating it with relevant
1440
* \retval -1 On failure.
1442
int SigGroupHeadLoadStreamContent(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
1444
Signature *s = NULL;
1445
SigMatch *sm = NULL;
1447
DetectContentData *co = NULL;
1452
if (DetectContentMaxId(de_ctx) == 0)
1455
BUG_ON(sgh->init == NULL);
1457
sgh->init->stream_content_size = (DetectContentMaxId(de_ctx) / 8) + 1;
1458
sgh->init->stream_content_array = SCMalloc(sgh->init->stream_content_size);
1459
if (sgh->init->stream_content_array == NULL)
1462
memset(sgh->init->stream_content_array,0, sgh->init->stream_content_size);
1464
for (sig = 0; sig < sgh->sig_cnt; sig++) {
1465
s = sgh->match_array[sig];
1469
if (!(s->flags & SIG_FLAG_MPM))
1472
if (s->flags & SIG_FLAG_DSIZE)
1479
for ( ;sm != NULL; sm = sm->next) {
1480
if (sm->type == DETECT_CONTENT) {
1481
co = (DetectContentData *)sm->ctx;
1483
sgh->init->stream_content_array[co->id / 8] |= 1 << (co->id % 8);
1492
* \brief Clears the memory allocated by SigGroupHeadLoadContent() for the
1493
* bitarray to hold the content ids for a SigGroupHead.
1495
* \param Pointer to the SigGroupHead whose content_array would to be cleared.
1499
int SigGroupHeadClearStreamContent(SigGroupHead *sh)
1504
if (sh->init->stream_content_array != NULL) {
1505
SCFree(sh->init->stream_content_array);
1506
sh->init->stream_content_array = NULL;
1507
sh->init->stream_content_size = 0;
1294
1513
* \brief Create an array with all the internal ids of the sigs that this
1295
1514
* sig group head will check for.
1314
1533
BUG_ON(sgh->match_array != NULL);
1316
sgh->match_array = SCMalloc(sgh->sig_cnt * sizeof(SigIntId));
1535
sgh->match_array = SCMalloc(sgh->sig_cnt * sizeof(Signature *));
1317
1536
if (sgh->match_array == NULL)
1320
memset(sgh->match_array,0, sgh->sig_cnt * sizeof(SigIntId));
1539
memset(sgh->match_array,0, sgh->sig_cnt * sizeof(Signature *));
1322
1541
detect_siggroup_matcharray_init_cnt++;
1323
detect_siggroup_matcharray_memory += (sgh->sig_cnt * sizeof(SigIntId));
1542
detect_siggroup_matcharray_memory += (sgh->sig_cnt * sizeof(Signature *));
1325
1544
for (sig = 0; sig < max_idx + 1; sig++) {
1326
if ( !(sgh->sig_array[(sig / 8)] & (1 << (sig % 8))) )
1545
if (!(sgh->init->sig_array[(sig / 8)] & (1 << (sig % 8))) )
1329
1548
s = de_ctx->sig_array[sig];
1333
sgh->match_array[idx] = s->num;
1552
sgh->match_array[idx] = s;
1559
int SigGroupHeadBuildHeadArray(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
1561
Signature *s = NULL;
1568
BUG_ON(sgh->head_array != NULL);
1570
sgh->head_array = SCMalloc(sgh->sig_cnt * sizeof(SignatureHeader));
1571
if (sgh->head_array == NULL)
1574
memset(sgh->head_array, 0, sgh->sig_cnt * sizeof(SignatureHeader));
1576
detect_siggroup_matcharray_init_cnt++;
1577
detect_siggroup_matcharray_memory += (sgh->sig_cnt * sizeof(SignatureHeader *));
1579
for (sig = 0; sig < sgh->sig_cnt; sig++) {
1580
s = sgh->match_array[sig];
1584
sgh->head_array[idx].flags = s->flags;
1585
sgh->head_array[idx].mpm_pattern_id = s->mpm_pattern_id;
1586
sgh->head_array[idx].alproto = s->alproto;
1587
sgh->head_array[idx].num = s->num;
1588
sgh->head_array[idx].full_sig = s;
1590
BUG_ON(s->flags != sgh->head_array[idx].flags);
1591
BUG_ON(s->alproto != sgh->head_array[idx].alproto);
1592
BUG_ON(s->mpm_pattern_id != sgh->head_array[idx].mpm_pattern_id);
1593
BUG_ON(s->num != sgh->head_array[idx].num);
1594
BUG_ON(s != sgh->head_array[idx].full_sig);
1841
2103
SigGroupHeadSetSigCnt(sh, 4);
1842
2104
SigGroupHeadBuildMatchArray(de_ctx, sh, 4);
1844
result &= (sh->match_array[0] == 0);
1845
result &= (sh->match_array[1] == 2);
1846
result &= (sh->match_array[2] == 4);
2106
result &= (sh->match_array[0] == de_ctx->sig_list);
2107
result &= (sh->match_array[1] == de_ctx->sig_list->next->next);
2108
result &= (sh->match_array[2] == de_ctx->sig_list->next->next->next->next);
1848
2110
SigGroupHeadFree(sh);