mirror of https://github.com/OISF/suricata
Rename some detection engine related files.
parent
f3a94413db
commit
8b3d06fd92
@ -1,13 +1,14 @@
|
|||||||
#ifndef __DETECT_MPM_H__
|
#ifndef __DETECT_MPM_H__
|
||||||
#define __DETECT_MPM_H__
|
#define __DETECT_MPM_H__
|
||||||
|
|
||||||
MpmCtx mpm_ctx[MPM_INSTANCE_MAX];
|
/* XXX remove once */
|
||||||
|
MpmCtx mpm_ctx[1];
|
||||||
|
|
||||||
u_int32_t PacketPatternMatch(ThreadVars *, PatternMatcherThread *, Packet *);
|
u_int32_t PacketPatternMatch(ThreadVars *, PatternMatcherThread *, Packet *);
|
||||||
int PacketPatternScan(ThreadVars *t, Packet *p, u_int8_t mpm_instance);
|
int PacketPatternScan(ThreadVars *t, Packet *p, u_int8_t mpm_instance);
|
||||||
void PacketPatternCleanup(ThreadVars *, PatternMatcherThread *);
|
void PacketPatternCleanup(ThreadVars *, PatternMatcherThread *);
|
||||||
void PatternMatchPrepare(MpmCtx *);
|
void PatternMatchPrepare(MpmCtx *);
|
||||||
int PatternMatchPrepareGroup(SigGroupHead *);
|
int PatternMatchPrepareGroup(DetectEngineCtx *, SigGroupHead *);
|
||||||
void PatternMatcherThreadInfo(ThreadVars *, PatternMatcherThread *);
|
void PatternMatcherThreadInfo(ThreadVars *, PatternMatcherThread *);
|
||||||
void PatternMatchDestroy(MpmCtx *);
|
void PatternMatchDestroy(MpmCtx *);
|
||||||
void PatternMatchDestroyGroup(SigGroupHead *);
|
void PatternMatchDestroyGroup(SigGroupHead *);
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,67 @@
|
|||||||
|
#ifndef __DETECT_PORT_H__
|
||||||
|
#define __DETECT_PORT_H__
|
||||||
|
|
||||||
|
/* a is ... than b */
|
||||||
|
enum {
|
||||||
|
PORT_ER = -1, /* error e.g. compare ipv4 and ipv6 */
|
||||||
|
PORT_LT, /* smaller [aaa] [bbb] */
|
||||||
|
PORT_LE, /* smaller with overlap [aa[bab]bb] */
|
||||||
|
PORT_EQ, /* exactly equal [abababab] */
|
||||||
|
PORT_ES, /* within [bb[aaa]bb] and [[abab]bbb] and [bbb[abab]] */
|
||||||
|
PORT_EB, /* completely overlaps [aa[bbb]aa] and [[baba]aaa] and [aaa[baba]] */
|
||||||
|
PORT_GE, /* bigger with overlap [bb[aba]aa] */
|
||||||
|
PORT_GT, /* bigger [bbb] [aaa] */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define PORT_FLAG_ANY 0x1
|
||||||
|
#define PORT_FLAG_NOT 0x2
|
||||||
|
|
||||||
|
#define PORT_SIGGROUPHEAD_COPY 0x04
|
||||||
|
|
||||||
|
typedef struct DetectPort_ {
|
||||||
|
u_int8_t flags;
|
||||||
|
|
||||||
|
u_int16_t port;
|
||||||
|
u_int16_t port2;
|
||||||
|
|
||||||
|
/* signatures that belong in this group */
|
||||||
|
struct _SigGroupHead *sh;
|
||||||
|
|
||||||
|
/* double linked list */
|
||||||
|
union {
|
||||||
|
struct DetectPort_ *prev;
|
||||||
|
struct DetectPort_ *hnext;
|
||||||
|
};
|
||||||
|
struct DetectPort_ *next;
|
||||||
|
|
||||||
|
} DetectPort;
|
||||||
|
|
||||||
|
/* prototypes */
|
||||||
|
void DetectPortRegister (void);
|
||||||
|
|
||||||
|
int DetectPortParse(DetectPort **head, char *str);
|
||||||
|
|
||||||
|
DetectPort *DetectPortCopy(DetectPort *);
|
||||||
|
DetectPort *DetectPortCopySingle(DetectPort *);
|
||||||
|
int DetectPortInsertCopy(DetectPort **, DetectPort *);
|
||||||
|
int DetectPortInsert(DetectPort **, DetectPort *);
|
||||||
|
void DetectPortCleanupList (DetectPort *head);
|
||||||
|
|
||||||
|
DetectPort *DetectPortLookup(DetectPort *head, DetectPort *dp);
|
||||||
|
int DetectPortAdd(DetectPort **head, DetectPort *dp);
|
||||||
|
|
||||||
|
DetectPort *DetectPortLookupGroup(DetectPort *dp, u_int16_t port);
|
||||||
|
|
||||||
|
void DetectPortPrintMemory(void);
|
||||||
|
|
||||||
|
DetectPort *DetectPortHashLookup(DetectPort *p);
|
||||||
|
DetectPort **DetectPortHashGetPtr(void);
|
||||||
|
DetectPort *DetectPortHashGetListPtr(void);
|
||||||
|
u_int32_t DetectPortHashGetSize(void);
|
||||||
|
int DetectPortHashInit(void);
|
||||||
|
void DetectPortHashFree(void);
|
||||||
|
int DetectPortHashAdd(DetectPort *p);
|
||||||
|
void DetectPortHashReset(void);
|
||||||
|
|
||||||
|
#endif /* __DETECT_PORT_H__ */
|
||||||
|
|
||||||
@ -0,0 +1,712 @@
|
|||||||
|
|
||||||
|
#include "decode.h"
|
||||||
|
#include "detect.h"
|
||||||
|
#include "flow-var.h"
|
||||||
|
|
||||||
|
#include "util-cidr.h"
|
||||||
|
#include "util-unittest.h"
|
||||||
|
|
||||||
|
#include "detect.h"
|
||||||
|
#include "detect-engine-address.h"
|
||||||
|
#include "detect-mpm.h"
|
||||||
|
|
||||||
|
/* prototypes */
|
||||||
|
int SigGroupHeadClearSigs(SigGroupHead *);
|
||||||
|
|
||||||
|
static u_int32_t detect_siggroup_head_memory = 0;
|
||||||
|
static u_int32_t detect_siggroup_head_init_cnt = 0;
|
||||||
|
static u_int32_t detect_siggroup_head_free_cnt = 0;
|
||||||
|
static u_int32_t detect_siggroup_sigarray_memory = 0;
|
||||||
|
static u_int32_t detect_siggroup_sigarray_init_cnt = 0;
|
||||||
|
static u_int32_t detect_siggroup_sigarray_free_cnt = 0;
|
||||||
|
static u_int32_t detect_siggroup_matcharray_memory = 0;
|
||||||
|
static u_int32_t detect_siggroup_matcharray_init_cnt = 0;
|
||||||
|
static u_int32_t detect_siggroup_matcharray_free_cnt = 0;
|
||||||
|
|
||||||
|
/* Free a sgh */
|
||||||
|
void SigGroupHeadFree(SigGroupHead *sh) {
|
||||||
|
if (sh == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PatternMatchDestroyGroup(sh);
|
||||||
|
SigGroupHeadClearSigs(sh);
|
||||||
|
|
||||||
|
if (sh->sig_array != NULL) {
|
||||||
|
free(sh->sig_array);
|
||||||
|
|
||||||
|
detect_siggroup_sigarray_free_cnt++;
|
||||||
|
detect_siggroup_sigarray_memory -= sh->sig_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(sh);
|
||||||
|
|
||||||
|
detect_siggroup_head_free_cnt++;
|
||||||
|
detect_siggroup_head_memory -= sizeof(SigGroupHead);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int SigGroupHeadCmpSigArray(SigGroupHead *a, SigGroupHead *b) {
|
||||||
|
if (a->sig_size != b->sig_size)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (memcmp(a->sig_array,b->sig_array,a->sig_size) != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* hashes */
|
||||||
|
|
||||||
|
/* XXX eeewww global! move to DetectionEngineCtx once we have that! */
|
||||||
|
static SigGroupHead **sgh_port_hash;
|
||||||
|
static SigGroupHead **sgh_hash;
|
||||||
|
static SigGroupHead **sgh_mpm_hash;
|
||||||
|
static SigGroupHead **sgh_mpm_uri_hash;
|
||||||
|
|
||||||
|
#define HASH_SIZE 65536
|
||||||
|
|
||||||
|
/* mpm sgh hash */
|
||||||
|
|
||||||
|
/* XXX dynamic size based on number of sigs? */
|
||||||
|
int SigGroupHeadMpmHashInit(void) {
|
||||||
|
sgh_mpm_hash = (SigGroupHead **)malloc(sizeof(SigGroupHead *) * HASH_SIZE);
|
||||||
|
if (sgh_mpm_hash == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
memset(sgh_mpm_hash,0,sizeof(SigGroupHead *) * HASH_SIZE);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
u_int32_t SigGroupHeadMpmHash(SigGroupHead *sgh) {
|
||||||
|
u_int32_t hash = sgh->content_size<<8;
|
||||||
|
|
||||||
|
u_int32_t b;
|
||||||
|
for (b = 0; b < sgh->content_size; b+=1) {
|
||||||
|
hash += sgh->content_array[b];
|
||||||
|
}
|
||||||
|
|
||||||
|
return (hash % HASH_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SigGroupHeadMpmHashAdd(SigGroupHead *sgh) {
|
||||||
|
u_int32_t hash = SigGroupHeadMpmHash(sgh);
|
||||||
|
|
||||||
|
//printf("SigGroupHeadMpmHashAdd: hash %u\n", hash);
|
||||||
|
|
||||||
|
/* easy: no collision */
|
||||||
|
if (sgh_mpm_hash[hash] == NULL) {
|
||||||
|
sgh_mpm_hash[hash] = sgh;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* harder: collision */
|
||||||
|
SigGroupHead *h = sgh_mpm_hash[hash], *ph = NULL;
|
||||||
|
for ( ; h != NULL; h = h->mpm_next) {
|
||||||
|
ph = h;
|
||||||
|
}
|
||||||
|
ph->mpm_next = sgh;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SigGroupHead *SigGroupHeadMpmHashLookup(SigGroupHead *sgh) {
|
||||||
|
u_int32_t hash = SigGroupHeadMpmHash(sgh);
|
||||||
|
|
||||||
|
//printf("SigGroupHeadMpmHashLookup: hash %u\n", hash);
|
||||||
|
|
||||||
|
/* easy: no sgh at our hash */
|
||||||
|
if (sgh_mpm_hash[hash] == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* see if we have the sgh we're looking for */
|
||||||
|
SigGroupHead *h = sgh_mpm_hash[hash];
|
||||||
|
for ( ; h != NULL; h = h->mpm_next) {
|
||||||
|
if (sgh->content_size == h->content_size &&
|
||||||
|
memcmp(sgh->content_array,h->content_array,sgh->content_size) == 0) {
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SigGroupHeadMpmHashFree(void) {
|
||||||
|
free(sgh_mpm_hash);
|
||||||
|
sgh_mpm_hash = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mpm uri sgh hash */
|
||||||
|
|
||||||
|
/* XXX dynamic size based on number of sigs? */
|
||||||
|
int SigGroupHeadMpmUriHashInit(void) {
|
||||||
|
sgh_mpm_uri_hash = (SigGroupHead **)malloc(sizeof(SigGroupHead *) * HASH_SIZE);
|
||||||
|
if (sgh_mpm_uri_hash == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
memset(sgh_mpm_uri_hash,0,sizeof(SigGroupHead *) * HASH_SIZE);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
u_int32_t SigGroupHeadMpmUriHash(SigGroupHead *sgh) {
|
||||||
|
u_int32_t hash = sgh->uri_content_size<<8;
|
||||||
|
|
||||||
|
u_int32_t b;
|
||||||
|
for (b = 0; b < sgh->uri_content_size; b+=1) {
|
||||||
|
hash += sgh->uri_content_array[b];
|
||||||
|
}
|
||||||
|
|
||||||
|
return (hash % HASH_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SigGroupHeadMpmUriHashAdd(SigGroupHead *sgh) {
|
||||||
|
u_int32_t hash = SigGroupHeadMpmUriHash(sgh);
|
||||||
|
|
||||||
|
//printf("SigGroupHeadHashAdd: hash %u\n", hash);
|
||||||
|
|
||||||
|
/* easy: no collision */
|
||||||
|
if (sgh_mpm_uri_hash[hash] == NULL) {
|
||||||
|
sgh_mpm_uri_hash[hash] = sgh;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* harder: collision */
|
||||||
|
SigGroupHead *h = sgh_mpm_uri_hash[hash], *ph = NULL;
|
||||||
|
for ( ; h != NULL; h = h->mpm_uri_next) {
|
||||||
|
ph = h;
|
||||||
|
}
|
||||||
|
ph->mpm_uri_next = sgh;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SigGroupHead *SigGroupHeadMpmUriHashLookup(SigGroupHead *sgh) {
|
||||||
|
u_int32_t hash = SigGroupHeadMpmUriHash(sgh);
|
||||||
|
|
||||||
|
//printf("SigGroupHeadHashLookup: hash %u\n", hash);
|
||||||
|
|
||||||
|
/* easy: no sgh at our hash */
|
||||||
|
if (sgh_mpm_uri_hash[hash] == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* see if we have the sgh we're looking for */
|
||||||
|
SigGroupHead *h = sgh_mpm_uri_hash[hash];
|
||||||
|
for ( ; h != NULL; h = h->mpm_uri_next) {
|
||||||
|
if (sgh->uri_content_size == h->uri_content_size &&
|
||||||
|
memcmp(sgh->uri_content_array,h->uri_content_array,sgh->uri_content_size) == 0) {
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SigGroupHeadMpmUriHashFree(void) {
|
||||||
|
free(sgh_mpm_uri_hash);
|
||||||
|
sgh_mpm_uri_hash = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* non-port sgh hash */
|
||||||
|
|
||||||
|
/* XXX dynamic size based on number of sigs? */
|
||||||
|
int SigGroupHeadHashInit(void) {
|
||||||
|
sgh_hash = (SigGroupHead **)malloc(sizeof(SigGroupHead *) * HASH_SIZE);
|
||||||
|
if (sgh_hash == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
memset(sgh_hash,0,sizeof(SigGroupHead *) * HASH_SIZE);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
u_int32_t SigGroupHeadHash(SigGroupHead *sgh) {
|
||||||
|
u_int32_t hash = 0;
|
||||||
|
|
||||||
|
u_int32_t b;
|
||||||
|
for (b = 0; b < sgh->content_size; b+=1) {
|
||||||
|
hash += sgh->content_array[b];
|
||||||
|
}
|
||||||
|
|
||||||
|
return (hash % HASH_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SigGroupHeadHashAdd(SigGroupHead *sgh) {
|
||||||
|
u_int32_t hash = SigGroupHeadHash(sgh);
|
||||||
|
|
||||||
|
//printf("SigGroupHeadHashAdd: hash %u\n", hash);
|
||||||
|
|
||||||
|
/* easy: no collision */
|
||||||
|
if (sgh_hash[hash] == NULL) {
|
||||||
|
sgh_hash[hash] = sgh;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* harder: collision */
|
||||||
|
SigGroupHead *h = sgh_hash[hash], *ph = NULL;
|
||||||
|
for ( ; h != NULL; h = h->next) {
|
||||||
|
ph = h;
|
||||||
|
}
|
||||||
|
ph->next = sgh;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SigGroupHead *SigGroupHeadHashLookup(SigGroupHead *sgh) {
|
||||||
|
u_int32_t hash = SigGroupHeadHash(sgh);
|
||||||
|
|
||||||
|
//printf("SigGroupHeadHashLookup: hash %u\n", hash);
|
||||||
|
|
||||||
|
/* easy: no sgh at our hash */
|
||||||
|
if (sgh_hash[hash] == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* see if we have the sgh we're looking for */
|
||||||
|
SigGroupHead *h = sgh_hash[hash];
|
||||||
|
for ( ; h != NULL; h = h->next) {
|
||||||
|
if (SigGroupHeadCmpSigArray(sgh,h) == 1) {
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SigGroupHeadHashFree(void) {
|
||||||
|
free(sgh_hash);
|
||||||
|
sgh_hash = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* port based sgh hash */
|
||||||
|
|
||||||
|
/* XXX dynamic size based on number of sigs? */
|
||||||
|
int SigGroupHeadPortHashInit(void) {
|
||||||
|
sgh_port_hash = (SigGroupHead **)malloc(sizeof(SigGroupHead *) * HASH_SIZE);
|
||||||
|
if (sgh_port_hash == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
memset(sgh_port_hash,0,sizeof(SigGroupHead *) * HASH_SIZE);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SigGroupHeadPortHashAdd(SigGroupHead *sgh) {
|
||||||
|
u_int32_t hash = SigGroupHeadHash(sgh);
|
||||||
|
|
||||||
|
//printf("SigGroupHeadHashAdd: hash %u\n", hash);
|
||||||
|
|
||||||
|
/* easy: no collision */
|
||||||
|
if (sgh_port_hash[hash] == NULL) {
|
||||||
|
sgh_port_hash[hash] = sgh;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* harder: collision */
|
||||||
|
SigGroupHead *h = sgh_port_hash[hash], *ph = NULL;
|
||||||
|
for ( ; h != NULL; h = h->next) {
|
||||||
|
ph = h;
|
||||||
|
}
|
||||||
|
ph->next = sgh;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SigGroupHead *SigGroupHeadPortHashLookup(SigGroupHead *sgh) {
|
||||||
|
u_int32_t hash = SigGroupHeadHash(sgh);
|
||||||
|
|
||||||
|
//printf("SigGroupHeadHashLookup: hash %u\n", hash);
|
||||||
|
|
||||||
|
/* easy: no sgh at our hash */
|
||||||
|
if (sgh_port_hash[hash] == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* see if we have the sgh we're looking for */
|
||||||
|
SigGroupHead *h = sgh_port_hash[hash];
|
||||||
|
for ( ; h != NULL; h = h->next) {
|
||||||
|
if (SigGroupHeadCmpSigArray(sgh,h) == 1) {
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SigGroupHeadPortHashFree(void) {
|
||||||
|
free(sgh_port_hash);
|
||||||
|
sgh_port_hash = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end hashes */
|
||||||
|
|
||||||
|
void SigGroupHeadFreeHeads(void) {
|
||||||
|
SigGroupHead *b, *nb, *pb;
|
||||||
|
|
||||||
|
u_int32_t hash = 0;
|
||||||
|
for ( ; hash < HASH_SIZE; hash++) {
|
||||||
|
b = sgh_hash[hash];
|
||||||
|
for ( ; b != NULL; ) {
|
||||||
|
nb = b->next;
|
||||||
|
|
||||||
|
if (b->flags & SIG_GROUP_HEAD_FREE) {
|
||||||
|
printf("SigGroupHeadFreeHeads: want to free %p\n", b);
|
||||||
|
//#if 0
|
||||||
|
SigGroupHeadFree(b);
|
||||||
|
|
||||||
|
/* remove from the hash as well */
|
||||||
|
if (b == sgh_hash[hash]) {
|
||||||
|
sgh_hash[hash] = nb;
|
||||||
|
} else {
|
||||||
|
pb->next = nb;
|
||||||
|
}
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
pb = b;
|
||||||
|
b = nb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the sigarrays in the sgh's. Those are only
|
||||||
|
* used during the init stage. */
|
||||||
|
void SigGroupHeadFreeSigArrays(void) {
|
||||||
|
SigGroupHead *b;
|
||||||
|
|
||||||
|
u_int32_t hash = 0;
|
||||||
|
for ( ; hash < HASH_SIZE; hash++) {
|
||||||
|
b = sgh_hash[hash];
|
||||||
|
for ( ; b != NULL; b = b->next) {
|
||||||
|
if (b->sig_array != NULL) {
|
||||||
|
detect_siggroup_sigarray_free_cnt++;
|
||||||
|
detect_siggroup_sigarray_memory -= b->sig_size;
|
||||||
|
|
||||||
|
free(b->sig_array);
|
||||||
|
b->sig_array = NULL;
|
||||||
|
b->sig_size = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b = sgh_port_hash[hash];
|
||||||
|
for ( ; b != NULL; b = b->next) {
|
||||||
|
if (b->sig_array != NULL) {
|
||||||
|
detect_siggroup_sigarray_free_cnt++;
|
||||||
|
detect_siggroup_sigarray_memory -= b->sig_size;
|
||||||
|
|
||||||
|
free(b->sig_array);
|
||||||
|
b->sig_array = NULL;
|
||||||
|
b->sig_size = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the mpm arrays that are only used during the
|
||||||
|
* init stage */
|
||||||
|
void SigGroupHeadFreeMpmArrays(void) {
|
||||||
|
SigGroupHead *b;
|
||||||
|
|
||||||
|
u_int32_t hash = 0;
|
||||||
|
for ( ; hash < HASH_SIZE; hash++) {
|
||||||
|
b = sgh_hash[hash];
|
||||||
|
for ( ; b != NULL; b = b->next) {
|
||||||
|
if (b->content_array != NULL) {
|
||||||
|
free(b->content_array);
|
||||||
|
b->content_array = NULL;
|
||||||
|
b->content_size = 0;
|
||||||
|
}
|
||||||
|
if (b->uri_content_array != NULL) {
|
||||||
|
free(b->uri_content_array);
|
||||||
|
b->uri_content_array = NULL;
|
||||||
|
b->uri_content_size = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b = sgh_port_hash[hash];
|
||||||
|
for ( ; b != NULL; b = b->next) {
|
||||||
|
if (b->content_array != NULL) {
|
||||||
|
free(b->content_array);
|
||||||
|
b->content_array = NULL;
|
||||||
|
b->content_size = 0;
|
||||||
|
}
|
||||||
|
if (b->uri_content_array != NULL) {
|
||||||
|
free(b->uri_content_array);
|
||||||
|
b->uri_content_array = NULL;
|
||||||
|
b->uri_content_size = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int SigGroupHeadAppendSig(SigGroupHead **sh, Signature *s) {
|
||||||
|
/* see if we have a head already */
|
||||||
|
if (*sh == NULL) {
|
||||||
|
*sh = malloc(sizeof(SigGroupHead));
|
||||||
|
if (*sh == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
memset(*sh, 0, sizeof(SigGroupHead));
|
||||||
|
|
||||||
|
detect_siggroup_head_init_cnt++;
|
||||||
|
detect_siggroup_head_memory += sizeof(SigGroupHead);
|
||||||
|
|
||||||
|
/* initialize the signature bitarray */
|
||||||
|
(*sh)->sig_size = SigGetMaxId() / 8 + 1;
|
||||||
|
(*sh)->sig_array = malloc((*sh)->sig_size);
|
||||||
|
if ((*sh)->sig_array == NULL)
|
||||||
|
goto error;
|
||||||
|
memset((*sh)->sig_array,0,(*sh)->sig_size);
|
||||||
|
|
||||||
|
detect_siggroup_sigarray_init_cnt++;
|
||||||
|
detect_siggroup_sigarray_memory += (*sh)->sig_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* enable the sig in the bitarray */
|
||||||
|
(*sh)->sig_array[(s->num/8)] |= 1<<(s->num%8);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SigGroupHeadClearSigs(SigGroupHead *sh) {
|
||||||
|
if (sh == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (sh->sig_array != NULL) {
|
||||||
|
memset(sh->sig_array,0,sh->sig_size);
|
||||||
|
sh->sig_cnt = 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SigGroupHeadCopySigs(SigGroupHead *src, SigGroupHead **dst) {
|
||||||
|
if (src == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (*dst == NULL) {
|
||||||
|
*dst = malloc(sizeof(SigGroupHead));
|
||||||
|
if (*dst == NULL) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
memset(*dst, 0, sizeof(SigGroupHead));
|
||||||
|
|
||||||
|
detect_siggroup_head_init_cnt++;
|
||||||
|
detect_siggroup_head_memory += sizeof(SigGroupHead);
|
||||||
|
|
||||||
|
(*dst)->sig_size = SigGetMaxId() / 8 + 1;
|
||||||
|
(*dst)->sig_array = malloc((*dst)->sig_size);
|
||||||
|
if ((*dst)->sig_array == NULL)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
memset((*dst)->sig_array,0,(*dst)->sig_size);
|
||||||
|
|
||||||
|
detect_siggroup_sigarray_init_cnt++;
|
||||||
|
detect_siggroup_sigarray_memory += (*dst)->sig_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do the copy */
|
||||||
|
u_int32_t idx;
|
||||||
|
for (idx = 0; idx < src->sig_size; idx++) {
|
||||||
|
(*dst)->sig_array[idx] = (*dst)->sig_array[idx] | src->sig_array[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SigGroupHeadSetSigCnt(SigGroupHead *sgh, u_int32_t max_idx) {
|
||||||
|
u_int32_t sig;
|
||||||
|
|
||||||
|
for (sig = 0; sig < max_idx+1; sig++) {
|
||||||
|
if (sgh->sig_array[(sig/8)] & (1<<(sig%8))) {
|
||||||
|
sgh->sig_cnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DetectSigGroupPrintMemory(void) {
|
||||||
|
printf(" * Sig group head memory stats (SigGroupHead %u):\n", sizeof(SigGroupHead));
|
||||||
|
printf(" - detect_siggroup_head_memory %u\n", detect_siggroup_head_memory);
|
||||||
|
printf(" - detect_siggroup_head_init_cnt %u\n", detect_siggroup_head_init_cnt);
|
||||||
|
printf(" - detect_siggroup_head_free_cnt %u\n", detect_siggroup_head_free_cnt);
|
||||||
|
printf(" - outstanding sig group heads %u\n", detect_siggroup_head_init_cnt - detect_siggroup_head_free_cnt);
|
||||||
|
printf(" * Sig group head memory stats done\n");
|
||||||
|
printf(" * Sig group sigarray memory stats:\n");
|
||||||
|
printf(" - detect_siggroup_sigarray_memory %u\n", detect_siggroup_sigarray_memory);
|
||||||
|
printf(" - detect_siggroup_sigarray_init_cnt %u\n", detect_siggroup_sigarray_init_cnt);
|
||||||
|
printf(" - detect_siggroup_sigarray_free_cnt %u\n", detect_siggroup_sigarray_free_cnt);
|
||||||
|
printf(" - outstanding sig group sigarrays %u\n", detect_siggroup_sigarray_init_cnt - detect_siggroup_sigarray_free_cnt);
|
||||||
|
printf(" * Sig group sigarray memory stats done\n");
|
||||||
|
printf(" * Sig group matcharray memory stats:\n");
|
||||||
|
printf(" - detect_siggroup_matcharray_memory %u\n", detect_siggroup_matcharray_memory);
|
||||||
|
printf(" - detect_siggroup_matcharray_init_cnt %u\n", detect_siggroup_matcharray_init_cnt);
|
||||||
|
printf(" - detect_siggroup_matcharray_free_cnt %u\n", detect_siggroup_matcharray_free_cnt);
|
||||||
|
printf(" - outstanding sig group matcharrays %u\n", detect_siggroup_matcharray_init_cnt - detect_siggroup_matcharray_free_cnt);
|
||||||
|
printf(" * Sig group sigarray memory stats done\n");
|
||||||
|
printf(" X Total %u\n", detect_siggroup_head_memory + detect_siggroup_sigarray_memory + detect_siggroup_matcharray_memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SigGroupHeadPrintContent(DetectEngineCtx *de_ctx, SigGroupHead *sgh) {
|
||||||
|
printf("SigGroupHeadPrintContent: ");
|
||||||
|
|
||||||
|
u_int32_t sig;
|
||||||
|
for (sig = 0; sig < sgh->sig_cnt; sig++) {
|
||||||
|
u_int32_t num = sgh->match_array[sig];
|
||||||
|
|
||||||
|
Signature *s = de_ctx->sig_array[num];
|
||||||
|
printf("%u ", s->id);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* load all pattern id's into a single bitarray that we can memcmp
|
||||||
|
* with other bitarrays. A fast and efficient way of comparing pattern
|
||||||
|
* sets. */
|
||||||
|
int SigGroupHeadLoadContent(DetectEngineCtx *de_ctx, SigGroupHead *sgh) {
|
||||||
|
if (sgh == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
Signature *s;
|
||||||
|
SigMatch *sm;
|
||||||
|
|
||||||
|
if (DetectContentMaxId() == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
sgh->content_size = (DetectContentMaxId() / 8) + 1;
|
||||||
|
sgh->content_array = malloc(sgh->content_size * sizeof(u_int32_t));
|
||||||
|
if (sgh->content_array == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
memset(sgh->content_array,0, sgh->content_size * sizeof(u_int32_t));
|
||||||
|
|
||||||
|
u_int32_t sig;
|
||||||
|
for (sig = 0; sig < sgh->sig_cnt; sig++) {
|
||||||
|
u_int32_t num = sgh->match_array[sig];
|
||||||
|
|
||||||
|
s = de_ctx->sig_array[num];
|
||||||
|
if (s == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sm = s->match;
|
||||||
|
if (sm == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for ( ; sm != NULL; sm = sm->next) {
|
||||||
|
if (sm->type == DETECT_CONTENT) {
|
||||||
|
DetectContentData *co = (DetectContentData *)sm->ctx;
|
||||||
|
|
||||||
|
sgh->content_array[(co->id/8)] |= 1<<(co->id%8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SigGroupHeadClearContent(SigGroupHead *sh) {
|
||||||
|
if (sh == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (sh->content_array != NULL) {
|
||||||
|
free(sh->content_array);
|
||||||
|
sh->content_array = NULL;
|
||||||
|
sh->content_size = 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SigGroupHeadLoadUricontent(DetectEngineCtx *de_ctx, SigGroupHead *sgh) {
|
||||||
|
if (sgh == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
Signature *s;
|
||||||
|
SigMatch *sm;
|
||||||
|
|
||||||
|
if (DetectUricontentMaxId() == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
sgh->uri_content_size = (DetectUricontentMaxId() / 8) + 1;
|
||||||
|
sgh->uri_content_array = malloc(sgh->uri_content_size * sizeof(u_int32_t));
|
||||||
|
if (sgh->uri_content_array == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
memset(sgh->uri_content_array,0, sgh->uri_content_size * sizeof(u_int32_t));
|
||||||
|
|
||||||
|
u_int32_t sig;
|
||||||
|
for (sig = 0; sig < sgh->sig_cnt; sig++) {
|
||||||
|
u_int32_t num = sgh->match_array[sig];
|
||||||
|
|
||||||
|
s = de_ctx->sig_array[num];
|
||||||
|
if (s == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sm = s->match;
|
||||||
|
if (sm == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for ( ; sm != NULL; sm = sm->next) {
|
||||||
|
if (sm->type == DETECT_URICONTENT) {
|
||||||
|
DetectUricontentData *co = (DetectUricontentData *)sm->ctx;
|
||||||
|
|
||||||
|
sgh->uri_content_array[(co->id/8)] |= 1<<(co->id%8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SigGroupHeadClearUricontent(SigGroupHead *sh) {
|
||||||
|
if (sh == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (sh->uri_content_array != NULL) {
|
||||||
|
free(sh->uri_content_array);
|
||||||
|
sh->uri_content_array = NULL;
|
||||||
|
sh->uri_content_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SigGroupHeadBuildMatchArray (DetectEngineCtx *de_ctx, SigGroupHead *sgh, u_int32_t max_idx) {
|
||||||
|
u_int32_t idx = 0;
|
||||||
|
u_int32_t sig = 0;
|
||||||
|
|
||||||
|
if (sgh == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
sgh->match_array = malloc(sgh->sig_cnt * sizeof(u_int32_t));
|
||||||
|
if (sgh->match_array == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
memset(sgh->match_array,0, sgh->sig_cnt * sizeof(u_int32_t));
|
||||||
|
|
||||||
|
detect_siggroup_matcharray_init_cnt++;
|
||||||
|
detect_siggroup_matcharray_memory += (sgh->sig_cnt * sizeof(u_int32_t));
|
||||||
|
|
||||||
|
for (sig = 0; sig < max_idx+1; sig++) {
|
||||||
|
if (!(sgh->sig_array[(sig/8)] & (1<<(sig%8))))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Signature *s = de_ctx->sig_array[sig];
|
||||||
|
if (s == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sgh->match_array[idx] = s->num;
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
#ifndef __DETECT_SIGGROUP_H__
|
||||||
|
#define __DETECT_SIGGROUP_H__
|
||||||
|
|
||||||
|
/* XXX cleanup */
|
||||||
|
|
||||||
|
int SigGroupHeadAppendSig(SigGroupHead **, Signature *);
|
||||||
|
int SigGroupHeadClearSigs(SigGroupHead *);
|
||||||
|
int SigGroupHeadCopySigs(SigGroupHead *, SigGroupHead **);
|
||||||
|
|
||||||
|
int SigGroupHeadLoadContent(DetectEngineCtx *, SigGroupHead *);
|
||||||
|
int SigGroupHeadLoadUricontent(DetectEngineCtx *, SigGroupHead *);
|
||||||
|
int SigGroupHeadClearContent(SigGroupHead *);
|
||||||
|
int SigGroupHeadClearUricontent(SigGroupHead *);
|
||||||
|
|
||||||
|
void SigGroupHeadFree(SigGroupHead *);
|
||||||
|
|
||||||
|
void SigGroupHeadFreeMpmArrays(void);
|
||||||
|
|
||||||
|
SigGroupHead *SigGroupHeadHashLookup(SigGroupHead *sgh);
|
||||||
|
SigGroupHead *SigGroupHeadPortHashLookup(SigGroupHead *sgh);
|
||||||
|
SigGroupHead *SigGroupHeadMpmHashLookup(SigGroupHead *sgh);
|
||||||
|
SigGroupHead *SigGroupHeadMpmUriHashLookup(SigGroupHead *sgh);
|
||||||
|
|
||||||
|
int SigGroupHeadPortHashAdd(SigGroupHead *sgh);
|
||||||
|
int SigGroupHeadMpmHashAdd(SigGroupHead *sgh);
|
||||||
|
int SigGroupHeadMpmUriHashAdd(SigGroupHead *sgh);
|
||||||
|
int SigGroupHeadHashAdd(SigGroupHead *sgh);
|
||||||
|
|
||||||
|
void SigGroupHeadHashFree(void);
|
||||||
|
void SigGroupHeadPortHashFree(void);
|
||||||
|
void SigGroupHeadMpmHashFree(void);
|
||||||
|
void SigGroupHeadMpmUriHashFree(void);
|
||||||
|
|
||||||
|
int SigGroupHeadMpmHashInit(void);
|
||||||
|
int SigGroupHeadMpmUriHashInit(void);
|
||||||
|
int SigGroupHeadPortHashInit(void);
|
||||||
|
int SigGroupHeadHashInit(void);
|
||||||
|
|
||||||
|
void SigGroupHeadSetSigCnt(SigGroupHead *sgh, u_int32_t max_idx);
|
||||||
|
int SigGroupHeadBuildMatchArray (DetectEngineCtx *de_ctx, SigGroupHead *sgh, u_int32_t max_idx);
|
||||||
|
void SigGroupHeadFreeSigArrays(void);
|
||||||
|
|
||||||
|
#endif /* __DETECT_SIGGROUP_H__ */
|
||||||
|
|
||||||
@ -1,432 +0,0 @@
|
|||||||
|
|
||||||
#include "decode.h"
|
|
||||||
#include "detect.h"
|
|
||||||
#include "flow-var.h"
|
|
||||||
|
|
||||||
#include "util-cidr.h"
|
|
||||||
#include "util-unittest.h"
|
|
||||||
|
|
||||||
#include "detect.h"
|
|
||||||
#include "detect-address.h"
|
|
||||||
#include "detect-mpm.h"
|
|
||||||
|
|
||||||
int SigGroupHeadCmp(SigGroupHead *, SigGroupHead *);
|
|
||||||
|
|
||||||
static u_int32_t detect_siggroup_memory = 0;
|
|
||||||
static u_int32_t detect_siggroup_append_cnt = 0;
|
|
||||||
static u_int32_t detect_siggroup_free_cnt = 0;
|
|
||||||
|
|
||||||
static u_int32_t detect_siggroup_head_memory = 0;
|
|
||||||
static u_int32_t detect_siggroup_head_init_cnt = 0;
|
|
||||||
static u_int32_t detect_siggroup_head_free_cnt = 0;
|
|
||||||
|
|
||||||
/* XXX eeewww global! move to DetectionEngineCtx once we have that! */
|
|
||||||
static SigGroupHead *sgh_list = NULL;
|
|
||||||
|
|
||||||
/* return the first SigGroupHead that matches
|
|
||||||
* the lookup one. */
|
|
||||||
SigGroupHead* SigGroupHeadListGet(SigGroupHead *a) {
|
|
||||||
SigGroupHead *b = sgh_list;
|
|
||||||
|
|
||||||
for ( ; b != NULL; b = b->next) {
|
|
||||||
if (SigGroupHeadCmp(a,b) == 1 && a != b) {
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SigGroupHeadFreeMpmArrays(void) {
|
|
||||||
SigGroupHead *b = sgh_list;
|
|
||||||
|
|
||||||
for ( ; b != NULL; b = b->next) {
|
|
||||||
if (b->content_array != NULL) {
|
|
||||||
free(b->content_array);
|
|
||||||
b->content_array = NULL;
|
|
||||||
b->content_size = 0;
|
|
||||||
}
|
|
||||||
if (b->uri_content_array != NULL) {
|
|
||||||
free(b->uri_content_array);
|
|
||||||
b->uri_content_array = NULL;
|
|
||||||
b->uri_content_size = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int SigGroupContentCmp(SigGroupContent *a, SigGroupContent *b);
|
|
||||||
|
|
||||||
/* return the first SigGroupHead that matches
|
|
||||||
* the lookup one. */
|
|
||||||
SigGroupHead* SigGroupHeadListGetMpm(SigGroupHead *a) {
|
|
||||||
SigGroupHead *b = sgh_list;
|
|
||||||
|
|
||||||
for ( ; b != NULL; b = b->next) {
|
|
||||||
if (a->content_size != b->content_size)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (memcmp(a->content_array,b->content_array,a->content_size) == 0)
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* return the first SigGroupHead that matches
|
|
||||||
* the lookup one. */
|
|
||||||
SigGroupHead* SigGroupHeadListGetMpmUri(SigGroupHead *a) {
|
|
||||||
SigGroupHead *b = sgh_list;
|
|
||||||
|
|
||||||
for ( ; b != NULL; b = b->next) {
|
|
||||||
if (a->uri_content_size != b->uri_content_size)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (memcmp(a->uri_content_array,b->uri_content_array,a->uri_content_size) == 0)
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* basically just reset the prt as the list items
|
|
||||||
* themselves are removed elsewhere */
|
|
||||||
void SigGroupHeadListClean(void) {
|
|
||||||
sgh_list = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SigGroupHeadList(void) {
|
|
||||||
SigGroupHead *sh;
|
|
||||||
|
|
||||||
printf("SigGroupHeadList: start\n");
|
|
||||||
for (sh = sgh_list; sh != NULL; sh = sh->next) {
|
|
||||||
printf("%p sig_cnt %u\n", sh, sh->sig_cnt);
|
|
||||||
}
|
|
||||||
printf("SigGroupHeadList: end\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* put this head in the list */
|
|
||||||
void SigGroupHeadAppend(SigGroupHead *sh) {
|
|
||||||
if (sgh_list == NULL) {
|
|
||||||
sgh_list = sh;
|
|
||||||
} else {
|
|
||||||
SigGroupHead *list = sgh_list;
|
|
||||||
|
|
||||||
while (list->next != NULL)
|
|
||||||
list = list->next;
|
|
||||||
|
|
||||||
list->next = sh;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int SigGroupAppend(DetectAddressGroup *ag, Signature *s) {
|
|
||||||
SigGroupContainer *sg = NULL, *tmp_sg = NULL;
|
|
||||||
|
|
||||||
sg = malloc(sizeof(SigGroupContainer));
|
|
||||||
if (sg == NULL) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
memset(sg,0,sizeof(SigGroupContainer));
|
|
||||||
|
|
||||||
detect_siggroup_append_cnt++;
|
|
||||||
detect_siggroup_memory += sizeof(SigGroupContainer);
|
|
||||||
|
|
||||||
/* connect the signature to the container */
|
|
||||||
sg->s = s;
|
|
||||||
|
|
||||||
/* see if we have a head already */
|
|
||||||
if (ag->sh == NULL) {
|
|
||||||
ag->sh = malloc(sizeof(SigGroupHead));
|
|
||||||
if (ag->sh == NULL) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
memset(ag->sh, 0, sizeof(SigGroupHead));
|
|
||||||
|
|
||||||
detect_siggroup_head_init_cnt++;
|
|
||||||
detect_siggroup_head_memory += sizeof(SigGroupHead);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ag->sh->head == NULL) {
|
|
||||||
/* put it as first in the list */
|
|
||||||
ag->sh->head = sg;
|
|
||||||
ag->sh->tail = sg;
|
|
||||||
} else {
|
|
||||||
/* append to the list */
|
|
||||||
tmp_sg = ag->sh->tail;
|
|
||||||
ag->sh->tail = tmp_sg->next = sg;
|
|
||||||
}
|
|
||||||
ag->sh->sig_cnt++;
|
|
||||||
return 0;
|
|
||||||
error:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SigGroupListClean(SigGroupHead *sh) {
|
|
||||||
SigGroupContainer *sg = NULL, *next_sg = NULL;
|
|
||||||
|
|
||||||
if (sh == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
sg = sh->head;
|
|
||||||
|
|
||||||
while (sg != NULL) {
|
|
||||||
detect_siggroup_free_cnt++;
|
|
||||||
detect_siggroup_memory -= sizeof(SigGroupContainer);
|
|
||||||
|
|
||||||
next_sg = sg->next;
|
|
||||||
|
|
||||||
sg->s->rulegroup_refcnt--;
|
|
||||||
sg->s = NULL;
|
|
||||||
free(sg);
|
|
||||||
|
|
||||||
sh->sig_cnt--;
|
|
||||||
|
|
||||||
sg = next_sg;
|
|
||||||
}
|
|
||||||
sh->head = NULL;
|
|
||||||
sh->tail = NULL;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int SigGroupListCopyPrepend(DetectAddressGroup *src, DetectAddressGroup *dst) {
|
|
||||||
SigGroupContainer *sg = NULL;
|
|
||||||
|
|
||||||
if (src->sh == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (dst->sh == NULL) {
|
|
||||||
dst->sh = malloc(sizeof(SigGroupHead));
|
|
||||||
if (dst->sh == NULL) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
memset(dst->sh, 0, sizeof(SigGroupHead));
|
|
||||||
|
|
||||||
detect_siggroup_head_init_cnt++;
|
|
||||||
detect_siggroup_head_memory += sizeof(SigGroupHead);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* save the head & tail */
|
|
||||||
SigGroupContainer *dsthead = dst->sh->head;
|
|
||||||
SigGroupContainer *dsttail = dst->sh->tail;
|
|
||||||
/* reset dst head */
|
|
||||||
dst->sh->head = NULL;
|
|
||||||
dst->sh->tail = NULL;
|
|
||||||
/* append the sigs into the now cleared dst */
|
|
||||||
for (sg = src->sh->head; sg != NULL; sg = sg->next) {
|
|
||||||
SigGroupAppend(dst,sg->s);
|
|
||||||
}
|
|
||||||
|
|
||||||
dst->sh->tail->next = dsthead;
|
|
||||||
dst->sh->tail = dsttail;
|
|
||||||
return 0;
|
|
||||||
error:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SigGroupListCopyAppend(DetectAddressGroup *src, DetectAddressGroup *dst) {
|
|
||||||
SigGroupContainer *sg = NULL;
|
|
||||||
|
|
||||||
if (src->sh == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (dst->sh == NULL) {
|
|
||||||
dst->sh = malloc(sizeof(SigGroupHead));
|
|
||||||
if (dst->sh == NULL) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
memset(dst->sh, 0, sizeof(SigGroupHead));
|
|
||||||
|
|
||||||
detect_siggroup_head_init_cnt++;
|
|
||||||
detect_siggroup_head_memory += sizeof(SigGroupHead);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (sg = src->sh->head; sg != NULL; sg = sg->next) {
|
|
||||||
SigGroupAppend(dst,sg->s);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
error:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SigGroupHeadCmp(SigGroupHead *a, SigGroupHead *b) {
|
|
||||||
SigGroupContainer *sg_a = NULL, *sg_b = NULL;
|
|
||||||
|
|
||||||
if (a->sig_cnt != b->sig_cnt)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (sg_a = a->head, sg_b = b->head;
|
|
||||||
sg_a != NULL && sg_b != NULL;
|
|
||||||
sg_a = sg_a->next, sg_b = sg_b->next) {
|
|
||||||
if (sg_a->s != sg_b->s)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SigGroupHeadFree(SigGroupHead *sh) {
|
|
||||||
if (sh == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
PatternMatchDestroyGroup(sh);
|
|
||||||
|
|
||||||
SigGroupListClean(sh);
|
|
||||||
|
|
||||||
free(sh);
|
|
||||||
|
|
||||||
detect_siggroup_head_free_cnt++;
|
|
||||||
detect_siggroup_head_memory -= sizeof(SigGroupHead);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DetectSigGroupPrintMemory(void) {
|
|
||||||
printf(" * Sig group memory stats (SigGroupContainer %u):\n", sizeof(SigGroupContainer));
|
|
||||||
printf(" - detect_siggroup_memory %u\n", detect_siggroup_memory);
|
|
||||||
printf(" - detect_siggroup_append_cnt %u\n", detect_siggroup_append_cnt);
|
|
||||||
printf(" - detect_siggroup_free_cnt %u\n", detect_siggroup_free_cnt);
|
|
||||||
printf(" - outstanding sig containers %u\n", detect_siggroup_append_cnt - detect_siggroup_free_cnt);
|
|
||||||
printf(" * Sig group memory stats done\n");
|
|
||||||
printf(" * Sig group head memory stats (SigGroupHead %u):\n", sizeof(SigGroupHead));
|
|
||||||
printf(" - detect_siggroup_head_memory %u\n", detect_siggroup_head_memory);
|
|
||||||
printf(" - detect_siggroup_head_init_cnt %u\n", detect_siggroup_head_init_cnt);
|
|
||||||
printf(" - detect_siggroup_head_free_cnt %u\n", detect_siggroup_head_free_cnt);
|
|
||||||
printf(" - outstanding sig containers %u\n", detect_siggroup_head_init_cnt - detect_siggroup_head_free_cnt);
|
|
||||||
printf(" * Sig group head memory stats done\n");
|
|
||||||
printf(" X Total %u\n", detect_siggroup_memory + detect_siggroup_head_memory);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* -1: a is smaller
|
|
||||||
* 0: equal
|
|
||||||
* 1: a is bigger
|
|
||||||
*/
|
|
||||||
int SigGroupContentCmp(SigGroupContent *a, SigGroupContent *b) {
|
|
||||||
|
|
||||||
//printf("a->content->id %u, b->content->id %u\n", a->content->id, b->content->id);
|
|
||||||
if (a->content->id < b->content->id)
|
|
||||||
return -1;
|
|
||||||
else if (a->content->id > b->content->id)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* implied equal */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* load all pattern id's into a single bitarray that we can memcmp
|
|
||||||
* with other bitarrays. A fast and efficient way of comparing pattern
|
|
||||||
* sets. */
|
|
||||||
int SigGroupContentLoad(SigGroupHead *sgh) {
|
|
||||||
SigGroupContainer *sgc = sgh->head;
|
|
||||||
Signature *s;
|
|
||||||
SigMatch *sm;
|
|
||||||
u_int16_t min_depth = 65535;
|
|
||||||
u_int16_t min_offset = 65535;
|
|
||||||
|
|
||||||
if (DetectContentMaxId() == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
sgh->content_size = (DetectContentMaxId() / 8) + 1;
|
|
||||||
sgh->content_array = malloc(sgh->content_size * sizeof(u_int32_t));
|
|
||||||
if (sgh->content_array == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
memset(sgh->content_array,0, sgh->content_size * sizeof(u_int32_t));
|
|
||||||
|
|
||||||
for ( ; sgc != NULL; sgc = sgc->next) {
|
|
||||||
s = sgc->s;
|
|
||||||
if (s == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
sm = s->match;
|
|
||||||
if (sm == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for ( ; sm != NULL; sm = sm->next) {
|
|
||||||
if (sm->type == DETECT_CONTENT) {
|
|
||||||
DetectContentData *co = (DetectContentData *)sm->ctx;
|
|
||||||
|
|
||||||
sgh->content_array[(co->id/8)] |= 1<<(co->id%8);
|
|
||||||
|
|
||||||
if (co->depth < min_depth) min_depth = co->depth;
|
|
||||||
if (co->offset < min_offset) min_offset = co->offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//printf(" * min_depth %u, min_offset %u\n", min_depth, min_offset);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SigGroupListContentClean(SigGroupHead *sh) {
|
|
||||||
if (sh == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (sh->content_array != NULL) {
|
|
||||||
free(sh->content_array);
|
|
||||||
sh->content_array = NULL;
|
|
||||||
sh->content_size = 0;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -1: a is smaller
|
|
||||||
* 0: equal
|
|
||||||
* 1: a is bigger
|
|
||||||
*/
|
|
||||||
int SigGroupUricontentCmp(SigGroupUricontent *a, SigGroupUricontent *b) {
|
|
||||||
//printf("a->content->id %u, b->content->id %u\n", a->content->id, b->content->id);
|
|
||||||
|
|
||||||
if (a->content->id < b->content->id)
|
|
||||||
return -1;
|
|
||||||
else if (a->content->id > b->content->id)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* implied equal */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SigGroupUricontentLoad(SigGroupHead *sgh) {
|
|
||||||
SigGroupContainer *sgc = sgh->head;
|
|
||||||
Signature *s;
|
|
||||||
SigMatch *sm;
|
|
||||||
|
|
||||||
if (DetectUricontentMaxId() == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
sgh->uri_content_size = (DetectUricontentMaxId() / 8) + 1;
|
|
||||||
sgh->uri_content_array = malloc(sgh->uri_content_size * sizeof(u_int32_t));
|
|
||||||
if (sgh->uri_content_array == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
memset(sgh->uri_content_array,0, sgh->uri_content_size * sizeof(u_int32_t));
|
|
||||||
|
|
||||||
for ( ; sgc != NULL; sgc = sgc->next) {
|
|
||||||
s = sgc->s;
|
|
||||||
if (s == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
sm = s->match;
|
|
||||||
if (sm == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for ( ; sm != NULL; sm = sm->next) {
|
|
||||||
if (sm->type == DETECT_URICONTENT) {
|
|
||||||
DetectUricontentData *co = (DetectUricontentData *)sm->ctx;
|
|
||||||
|
|
||||||
sgh->uri_content_array[(co->id/8)] |= 1<<(co->id%8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SigGroupListUricontentClean(SigGroupHead *sh) {
|
|
||||||
if (sh == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (sh->uri_content_array != NULL) {
|
|
||||||
free(sh->uri_content_array);
|
|
||||||
sh->uri_content_array = NULL;
|
|
||||||
sh->uri_content_size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
#ifndef __DETECT_SIGGROUP_H__
|
|
||||||
#define __DETECT_SIGGROUP_H__
|
|
||||||
|
|
||||||
int SigGroupAppend(DetectAddressGroup *, Signature *);
|
|
||||||
int SigGroupClean(DetectAddressGroup *ag);
|
|
||||||
SigGroupHead* SigGroupHeadListGet(SigGroupHead *a);
|
|
||||||
SigGroupHead* SigGroupHeadListGetMpm(SigGroupHead *a);
|
|
||||||
SigGroupHead* SigGroupHeadListGetMpmUri(SigGroupHead *a);
|
|
||||||
void SigGroupHeadListClean(void);
|
|
||||||
void SigGroupHeadAppend(SigGroupHead *);
|
|
||||||
void SigGroupHeadFree(SigGroupHead *);
|
|
||||||
int SigGroupListCopyPrepend(DetectAddressGroup *src, DetectAddressGroup *dst);
|
|
||||||
int SigGroupListCopyAppend(DetectAddressGroup *src, DetectAddressGroup *dst);
|
|
||||||
void SigGroupHeadListClean(void);
|
|
||||||
int SigGroupListClean(SigGroupHead *sh);
|
|
||||||
void DetectSigGroupPrintMemory(void);
|
|
||||||
|
|
||||||
int SigGroupContentLoad(SigGroupHead *sgh);
|
|
||||||
int SigGroupUricontentLoad(SigGroupHead *sgh);
|
|
||||||
|
|
||||||
int SigGroupListContentClean(SigGroupHead *sh);
|
|
||||||
int SigGroupListUricontentClean(SigGroupHead *sh);
|
|
||||||
|
|
||||||
int SigGroupContentCmp(SigGroupContent *, SigGroupContent *);
|
|
||||||
int SigGroupUricontentCmp(SigGroupUricontent *, SigGroupUricontent *);
|
|
||||||
|
|
||||||
void SigGroupHeadFreeMpmArrays(void);
|
|
||||||
|
|
||||||
#endif /* __DETECT_SIGGROUP_H__ */
|
|
||||||
|
|
||||||
Loading…
Reference in New Issue