Big detection engine update.

remotes/origin/master-1.0.x
Victor Julien 17 years ago
parent ea5bb1c8d5
commit 3f7195454b

@ -129,6 +129,9 @@ int DetectAddressGroupCutIPv4(DetectAddressGroup *a, DetectAddressGroup *b, Dete
DetectPortInsertCopy(&b->port, port);
}
tmp_c->cnt += b->cnt;
b->cnt += a->cnt;
/* we have 3 parts: [bbb[baba]aaa]
* part a: b_ip1 <-> a_ip1 - 1
* part b: a_ip1 <-> b_ip2
@ -182,6 +185,13 @@ int DetectAddressGroupCutIPv4(DetectAddressGroup *a, DetectAddressGroup *b, Dete
DetectPortInsertCopy(&tmp_c->port, port);
}
tmp->cnt += a->cnt;
a->cnt = 0;
tmp_c->cnt += tmp->cnt;
a->cnt += b->cnt;
b->cnt += tmp->cnt;
tmp->cnt = 0;
/* we have 2 or three parts:
*
* 2 part: [[abab]bbb] or [bbb[baba]]
@ -218,6 +228,7 @@ int DetectAddressGroupCutIPv4(DetectAddressGroup *a, DetectAddressGroup *b, Dete
for (port = b->port; port != NULL; port = port->next) {
DetectPortInsertCopy(&a->port, port);
}
a->cnt += b->cnt;
} else if (a_ip2 == b_ip2) {
#ifdef DBG
@ -235,6 +246,7 @@ int DetectAddressGroupCutIPv4(DetectAddressGroup *a, DetectAddressGroup *b, Dete
for (port = a->port; port != NULL; port = port->next) {
DetectPortInsertCopy(&b->port, port);
}
b->cnt += a->cnt;
} else {
#ifdef DBG
printf("3\n");
@ -282,15 +294,12 @@ int DetectAddressGroupCutIPv4(DetectAddressGroup *a, DetectAddressGroup *b, Dete
for (port = tmp->port; port != NULL; port = port->next) {
DetectPortInsertCopy(&b->port, port);
}
#ifdef DBG
SigGroupContainer *sg;
printf("DetectAddressGroupCutIPv4: A "); DetectAddressDataPrint(a->ad); printf(" ");
for(sg = a->sh ? a->sh->head : NULL; sg != NULL; sg = sg->next) printf("%u ", sg->s->id); printf("\n");
printf("DetectAddressGroupCutIPv4: B "); DetectAddressDataPrint(b->ad); printf(" ");
for(sg = b->sh ? b->sh->head : NULL; sg != NULL; sg = sg->next) printf("%u ", sg->s->id); printf("\n");
printf("DetectAddressGroupCutIPv4: C "); DetectAddressDataPrint(tmp_c->ad); printf(" ");
for(sg = tmp_c->sh ? b->sh->head : NULL; sg != NULL; sg = sg->next) printf("%u ", sg->s->id); printf("\n\n");
#endif
tmp->cnt += a->cnt;
a->cnt = 0;
tmp_c->cnt += b->cnt;
a->cnt += b->cnt;
b->cnt += tmp->cnt;
tmp->cnt = 0;
}
/* we have 2 or three parts:
*
@ -338,6 +347,11 @@ for(sg = tmp_c->sh ? b->sh->head : NULL; sg != NULL; sg = sg->next) printf("%u "
for (port = tmp->port; port != NULL; port = port->next) {
DetectPortInsertCopy(&a->port, port);
}
tmp->cnt += b->cnt;
b->cnt = 0;
b->cnt += a->cnt;
a->cnt += tmp->cnt;
tmp->cnt = 0;
} else if (a_ip2 == b_ip2) {
#ifdef DBG
printf("DetectAddressGroupCutIPv4: 2\n");
@ -354,6 +368,8 @@ for(sg = tmp_c->sh ? b->sh->head : NULL; sg != NULL; sg = sg->next) printf("%u "
for (port = a->port; port != NULL; port = port->next) {
DetectPortInsertCopy(&b->port, port);
}
b->cnt += a->cnt;
} else {
#ifdef DBG
printf("DetectAddressGroupCutIPv4: 3\n");
@ -391,6 +407,9 @@ for(sg = tmp_c->sh ? b->sh->head : NULL; sg != NULL; sg = sg->next) printf("%u "
for (port = a->port; port != NULL; port = port->next) {
DetectPortInsertCopy(&tmp_c->port, port);
}
b->cnt += a->cnt;
tmp_c->cnt += a->cnt;
}
}
@ -617,4 +636,13 @@ error:
return -1;
}
int DetectAddressGroupJoinIPv4(DetectAddressGroup *target, DetectAddressGroup *source) {
if (ntohl(source->ad->ip[0]) < ntohl(target->ad->ip[0]))
target->ad->ip[0] = source->ad->ip[0];
if (ntohl(source->ad->ip2[0]) > ntohl(target->ad->ip2[0]))
target->ad->ip2[0] = source->ad->ip2[0];
return 0;
}

@ -12,5 +12,7 @@ int DetectAddressCutNotIPv4(DetectAddressData *, DetectAddressData **);
int DetectAddressGroupCutIPv4(DetectAddressGroup *, DetectAddressGroup *, DetectAddressGroup **);
int DetectAddressGroupJoinIPv4(DetectAddressGroup *target, DetectAddressGroup *source);
#endif /* __DETECT_ADDRESS_IPV4_H__ */

@ -196,6 +196,7 @@ int DetectAddressGroupCutIPv6(DetectAddressGroup *a, DetectAddressGroup *b, Dete
ntohl(b->ad->ip[2]), ntohl(b->ad->ip[3]) };
u_int32_t b_ip2[4] = { ntohl(b->ad->ip2[0]), ntohl(b->ad->ip2[1]),
ntohl(b->ad->ip2[2]), ntohl(b->ad->ip2[3]) };
DetectPort *port = NULL;
/* default to NULL */
*c = NULL;
@ -241,6 +242,16 @@ int DetectAddressGroupCutIPv6(DetectAddressGroup *a, DetectAddressGroup *b, Dete
SigGroupHeadCopySigs(b->sh,&tmp_c->sh); /* copy old b to c */
SigGroupHeadCopySigs(a->sh,&b->sh); /* copy old b to a */
for (port = b->port; port != NULL; port = port->next) {
DetectPortInsertCopy(&tmp_c->port, port);
}
for (port = a->port; port != NULL; port = port->next) {
DetectPortInsertCopy(&b->port, port);
}
tmp_c->cnt += b->cnt;
b->cnt += a->cnt;
/* we have 3 parts: [bbb[baba]aaa]
* part a: b_ip1 <-> a_ip1 - 1
* part b: a_ip1 <-> b_ip2
@ -278,6 +289,26 @@ int DetectAddressGroupCutIPv6(DetectAddressGroup *a, DetectAddressGroup *b, Dete
SigGroupHeadClearSigs(tmp->sh); /* clean tmp list */
for (port = a->port; port != NULL; port = port->next) {
DetectPortInsertCopy(&tmp->port, port);
}
for (port = b->port; port != NULL; port = port->next) {
DetectPortInsertCopy(&a->port, port);
}
for (port = tmp->port; port != NULL; port = port->next) {
DetectPortInsertCopy(&b->port, port);
}
for (port = tmp->port; port != NULL; port = port->next) {
DetectPortInsertCopy(&tmp_c->port, port);
}
tmp->cnt += a->cnt;
a->cnt = 0;
tmp_c->cnt += tmp->cnt;
a->cnt += b->cnt;
b->cnt += tmp->cnt;
tmp->cnt = 0;
/* we have 2 or three parts:
*
* 2 part: [[abab]bbb] or [bbb[baba]]
@ -302,6 +333,12 @@ int DetectAddressGroupCutIPv6(DetectAddressGroup *a, DetectAddressGroup *b, Dete
/* 'b' overlaps 'a' so 'a' needs the 'b' sigs */
SigGroupHeadCopySigs(b->sh,&a->sh);
for (port = b->port; port != NULL; port = port->next) {
DetectPortInsertCopy(&a->port, port);
}
a->cnt += b->cnt;
} else if (AddressIPv6Eq(a_ip2, b_ip2) == 1) {
AddressCutIPv6Copy(b_ip1, a->ad->ip);
AddressCutIPv6CopySubOne(a_ip1, a->ad->ip2);
@ -311,6 +348,11 @@ int DetectAddressGroupCutIPv6(DetectAddressGroup *a, DetectAddressGroup *b, Dete
/* 'a' overlaps 'b' so a needs the 'a' sigs */
SigGroupHeadCopySigs(a->sh,&b->sh);
for (port = a->port; port != NULL; port = port->next) {
DetectPortInsertCopy(&b->port, port);
}
b->cnt += a->cnt;
} else {
AddressCutIPv6Copy(b_ip1, a->ad->ip);
AddressCutIPv6CopySubOne(a_ip1, a->ad->ip2);
@ -342,6 +384,25 @@ int DetectAddressGroupCutIPv6(DetectAddressGroup *a, DetectAddressGroup *b, Dete
SigGroupHeadCopySigs(tmp->sh,&b->sh); /* prepend old a before b */
SigGroupHeadClearSigs(tmp->sh); /* clean tmp list */
for (port = a->port; port != NULL; port = port->next) {
DetectPortInsertCopy(&tmp->port, port);
}
for (port = b->port; port != NULL; port = port->next) {
DetectPortInsertCopy(&tmp_c->port, port);
}
for (port = b->port; port != NULL; port = port->next) {
DetectPortInsertCopy(&a->port, port);
}
for (port = tmp->port; port != NULL; port = port->next) {
DetectPortInsertCopy(&b->port, port);
}
tmp->cnt += a->cnt;
a->cnt = 0;
tmp_c->cnt += b->cnt;
a->cnt += b->cnt;
b->cnt += tmp->cnt;
tmp->cnt = 0;
}
/* we have 2 or three parts:
*
@ -371,6 +432,21 @@ int DetectAddressGroupCutIPv6(DetectAddressGroup *a, DetectAddressGroup *b, Dete
SigGroupHeadCopySigs(a->sh,&b->sh);
SigGroupHeadCopySigs(tmp->sh,&a->sh);
SigGroupHeadClearSigs(tmp->sh);
for (port = b->port; port != NULL; port = port->next) {
DetectPortInsertCopy(&tmp->port, b->port);
}
for (port = a->port; port != NULL; port = port->next) {
DetectPortInsertCopy(&b->port, port);
}
for (port = tmp->port; port != NULL; port = port->next) {
DetectPortInsertCopy(&a->port, port);
}
tmp->cnt += b->cnt;
b->cnt = 0;
b->cnt += a->cnt;
a->cnt += tmp->cnt;
tmp->cnt = 0;
} else if (AddressIPv6Eq(a_ip2, b_ip2) == 1) {
AddressCutIPv6Copy(a_ip1, a->ad->ip);
AddressCutIPv6CopySubOne(b_ip1, a->ad->ip2);
@ -380,6 +456,12 @@ int DetectAddressGroupCutIPv6(DetectAddressGroup *a, DetectAddressGroup *b, Dete
/* 'a' overlaps 'b' so a needs the 'a' sigs */
SigGroupHeadCopySigs(a->sh,&b->sh);
for (port = a->port; port != NULL; port = port->next) {
DetectPortInsertCopy(&b->port, port);
}
b->cnt += a->cnt;
} else {
AddressCutIPv6Copy(a_ip1, a->ad->ip);
AddressCutIPv6CopySubOne(b_ip1, a->ad->ip2);
@ -406,6 +488,16 @@ int DetectAddressGroupCutIPv6(DetectAddressGroup *a, DetectAddressGroup *b, Dete
* 'c' gets 'a' sigs */
SigGroupHeadCopySigs(a->sh,&b->sh);
SigGroupHeadCopySigs(a->sh,&tmp_c->sh);
for (port = a->port; port != NULL; port = port->next) {
DetectPortInsertCopy(&b->port, port);
}
for (port = a->port; port != NULL; port = port->next) {
DetectPortInsertCopy(&tmp_c->port, port);
}
b->cnt += a->cnt;
tmp_c->cnt += a->cnt;
}
}
@ -634,6 +726,24 @@ error:
return -1;
}
int DetectAddressGroupJoinIPv6(DetectAddressGroup *target, DetectAddressGroup *source) {
if (AddressIPv6Lt(source->ad->ip,target->ad->ip)) {
target->ad->ip[0] = source->ad->ip[0];
target->ad->ip[1] = source->ad->ip[1];
target->ad->ip[2] = source->ad->ip[2];
target->ad->ip[3] = source->ad->ip[3];
}
if (AddressIPv6Gt(source->ad->ip,target->ad->ip)) {
target->ad->ip2[0] = source->ad->ip2[0];
target->ad->ip2[1] = source->ad->ip2[1];
target->ad->ip2[2] = source->ad->ip2[2];
target->ad->ip2[3] = source->ad->ip2[3];
}
return 0;
}
/* TESTS */

@ -18,6 +18,8 @@ int DetectAddressCmpIPv6(DetectAddressData *, DetectAddressData *);
int DetectAddressGroupCutIPv6(DetectAddressGroup *, DetectAddressGroup *, DetectAddressGroup **);
int DetectAddressGroupJoinIPv6(DetectAddressGroup *, DetectAddressGroup *);
void DetectAddressIPv6Tests(void);
#endif /* __DETECT_ADDRESS_IPV6_H__ */

@ -81,11 +81,12 @@ void DetectAddressGroupFree(DetectAddressGroup *ag) {
if (ag->dst_gh != NULL) {
DetectAddressGroupsHeadFree(ag->dst_gh);
}
ag->dst_gh = NULL;
if (ag->port != NULL && !(ag->flags & ADDRESS_GROUP_PORTS_COPY)) {
if (ag->port != NULL && !(ag->flags & PORT_GROUP_PORTS_COPY)) {
DetectPortCleanupList(ag->port);
ag->port = NULL;
}
ag->port = NULL;
detect_address_group_memory -= sizeof(DetectAddressGroup);
detect_address_group_free_cnt++;
@ -154,12 +155,9 @@ void DetectAddressGroupCleanupList (DetectAddressGroup *head) {
for (cur = head; cur != NULL; ) {
next = cur->next;
DetectAddressGroupFree(cur);
cur = next;
}
head = NULL;
}
/* do a sorted insert, where the top of the list should be the biggest
@ -278,6 +276,7 @@ int DetectAddressGroupInsert(DetectAddressGroupsHead *gh, DetectAddressGroup *ne
DetectPortInsertCopy(&cur->port,port);
}
SigGroupHeadCopySigs(new->sh,&cur->sh);
cur->cnt += new->cnt;
DetectAddressGroupFree(new);
return 0;
}
@ -397,6 +396,30 @@ error:
return -1;
}
int DetectAddressGroupJoin(DetectAddressGroup *target, DetectAddressGroup *source) {
if (target == NULL || source == NULL)
return -1;
if (target->ad->family != source->ad->family)
return -1;
target->cnt += source->cnt;
SigGroupHeadCopySigs(source->sh,&target->sh);
DetectPort *port = source->port;
for ( ; port != NULL; port = port->next) {
DetectPortInsertCopy(&target->port, port);
}
if (target->ad->family == AF_INET) {
return DetectAddressGroupJoinIPv4(target,source);
} else if (target->ad->family == AF_INET6) {
return DetectAddressGroupJoinIPv6(target,source);
}
return -1;
}
/*
* return codes:
* 1: inserted
@ -781,9 +804,11 @@ DetectAddressGroupsHead *DetectAddressGroupsHeadInit(void) {
void DetectAddressGroupsHeadCleanup(DetectAddressGroupsHead *gh) {
if (gh != NULL) {
DetectAddressGroupCleanupList(gh->any_head);
gh->any_head = NULL;
DetectAddressGroupCleanupList(gh->ipv4_head);
gh->ipv4_head = NULL;
DetectAddressGroupCleanupList(gh->ipv6_head);
gh->any_head = gh->ipv4_head = gh->ipv6_head = NULL;
gh->ipv6_head = NULL;
}
}

@ -18,6 +18,7 @@ enum {
#define ADDRESS_GROUP_SIGGROUPHEAD_COPY 0x01
#define ADDRESS_GROUP_PORTS_COPY 0x02
#define ADDRESS_GROUP_PORTS_NOTUNIQ 0x04
typedef struct DetectAddressData_ {
/* XXX convert to use a Address datatype to replace family, ip,ip2*/
@ -34,6 +35,7 @@ typedef struct DetectAddressGroup_ {
/* XXX ptr to rules, or PortGroup or whatever */
struct DetectAddressGroupsHead_ *dst_gh;
struct DetectPort_ *port;
/* signatures that belong in this group */
struct _SigGroupHead *sh;
u_int8_t flags;
@ -42,6 +44,7 @@ typedef struct DetectAddressGroup_ {
struct DetectAddressGroup_ *prev;
struct DetectAddressGroup_ *next;
u_int32_t cnt;
} DetectAddressGroup;
typedef struct DetectAddressGroupsHead_ {
@ -72,6 +75,7 @@ void DetectAddressGroupFree(DetectAddressGroup *);
int DetectAddressGroupInsert(DetectAddressGroupsHead *, DetectAddressGroup *);
void DetectAddressGroupPrintMemory(void);
void DetectAddressGroupCleanupList (DetectAddressGroup *);
int DetectAddressGroupJoin(DetectAddressGroup *target, DetectAddressGroup *source);
#endif /* __DETECT_ADDRESS_H__ */

@ -75,6 +75,11 @@ void DetectPortFree(DetectPort *dp) {
}
dp->sh = NULL;
if (dp->dst_ph != NULL && !(dp->flags & PORT_GROUP_PORTS_COPY)) {
DetectPortCleanupList(dp->dst_ph);
}
dp->dst_ph = NULL;
detect_port_memory -= sizeof(DetectPort);
detect_port_free_cnt++;
free(dp);
@ -186,6 +191,9 @@ int DetectPortAdd(DetectPort **head, DetectPort *dp) {
int DetectPortInsertCopy(DetectPort **head, DetectPort *new) {
DetectPort *copy = DetectPortCopySingle(new);
//printf("new (%p): ", new); DetectPortPrint(new); printf(" "); DbgPrintSigs2(new->sh);
//printf("copy (%p): ",copy); DetectPortPrint(copy); printf(" "); DbgPrintSigs2(copy->sh);
if (copy != NULL) {
//printf("DetectPortInsertCopy: "); DetectPortPrint(copy); printf("\n");
}
@ -206,7 +214,9 @@ int DetectPortInsert(DetectPort **head, DetectPort *new) {
if (new == NULL)
return 0;
#ifdef DBG
printf("DetectPortInsert: head %p, new %p, new->dp %p\n", head, new, new->dp);
printf("DetectPortInsert: inserting (sig %u) ", new->sh ? new->sh->sig_cnt : 0); DetectPortPrint(new); printf("\n");
//DetectPortPrintList(*head);
#endif
@ -235,6 +245,7 @@ int DetectPortInsert(DetectPort **head, DetectPort *new) {
/* exact overlap/match */
if (cur != new) {
SigGroupHeadCopySigs(new->sh,&cur->sh);
cur->cnt += new->cnt;
DetectPortFree(new);
return 0;
}
@ -563,6 +574,9 @@ int DetectPortCut(DetectPort *a, DetectPort *b, DetectPort **c) {
/* default to NULL */
*c = NULL;
//printf("a (%p): ",a); DetectPortPrint(a); printf(" "); DbgPrintSigs2(a->sh);
//printf("b (%p): ",b); DetectPortPrint(b); printf(" "); DbgPrintSigs2(b->sh);
int r = DetectPortCmp(a,b);
if (r != PORT_ES && r != PORT_EB && r != PORT_LE && r != PORT_GE) {
printf("DetectPortCut: we shouldn't be here\n");
@ -605,6 +619,9 @@ int DetectPortCut(DetectPort *a, DetectPort *b, DetectPort **c) {
SigGroupHeadCopySigs(b->sh,&tmp_c->sh); /* copy old b to c */
SigGroupHeadCopySigs(a->sh,&b->sh); /* copy old b to a */
tmp_c->cnt += b->cnt;
b->cnt += a->cnt;
/* we have 3 parts: [bbb[baba]aaa]
* part a: b_port1 <-> a_port1 - 1
* part b: a_port1 <-> b_port2
@ -640,6 +657,14 @@ int DetectPortCut(DetectPort *a, DetectPort *b, DetectPort **c) {
SigGroupHeadCopySigs(tmp->sh,&b->sh); /* prepend old a before b */
SigGroupHeadClearSigs(tmp->sh); /* clean tmp list */
tmp->cnt += a->cnt;
a->cnt = 0;
tmp_c->cnt += tmp->cnt;
a->cnt += b->cnt;
b->cnt += tmp->cnt;
tmp->cnt = 0;
/* we have 2 or three parts:
*
* 2 part: [[abab]bbb] or [bbb[baba]]
@ -672,6 +697,7 @@ int DetectPortCut(DetectPort *a, DetectPort *b, DetectPort **c) {
/* 'b' overlaps 'a' so 'a' needs the 'b' sigs */
SigGroupHeadCopySigs(b->sh,&a->sh);
a->cnt += b->cnt;
} else if (a_port2 == b_port2) {
#ifdef DBG
@ -685,6 +711,8 @@ int DetectPortCut(DetectPort *a, DetectPort *b, DetectPort **c) {
/* 'a' overlaps 'b' so a needs the 'a' sigs */
SigGroupHeadCopySigs(a->sh,&b->sh);
b->cnt += a->cnt;
} else {
#ifdef DBG
printf("DetectPortCut: 3\n");
@ -715,6 +743,13 @@ int DetectPortCut(DetectPort *a, DetectPort *b, DetectPort **c) {
SigGroupHeadCopySigs(tmp->sh,&b->sh); /* prepend old a before b */
SigGroupHeadClearSigs(tmp->sh); /* clean tmp list */
tmp->cnt += a->cnt;
a->cnt = 0;
tmp_c->cnt += b->cnt;
a->cnt += b->cnt;
b->cnt += tmp->cnt;
tmp->cnt = 0;
}
/* we have 2 or three parts:
*
@ -753,6 +788,15 @@ int DetectPortCut(DetectPort *a, DetectPort *b, DetectPort **c) {
SigGroupHeadCopySigs(tmp->sh,&a->sh);
SigGroupHeadClearSigs(tmp->sh);
tmp->cnt += b->cnt;
b->cnt = 0;
b->cnt += a->cnt;
a->cnt += tmp->cnt;
tmp->cnt = 0;
//printf("2a (%p): ",a); DetectPortPrint(a); printf(" "); DbgPrintSigs2(a->sh);
//printf("2b (%p): ",b); DetectPortPrint(b); printf(" "); DbgPrintSigs2(b->sh);
} else if (a_port2 == b_port2) {
#ifdef DBG
printf("DetectPortCut: 2\n");
@ -765,6 +809,9 @@ int DetectPortCut(DetectPort *a, DetectPort *b, DetectPort **c) {
/* 'a' overlaps 'b' so a needs the 'a' sigs */
SigGroupHeadCopySigs(a->sh,&b->sh);
b->cnt += a->cnt;
} else {
#ifdef DBG
printf("DetectPortCut: 3\n");
@ -787,6 +834,9 @@ int DetectPortCut(DetectPort *a, DetectPort *b, DetectPort **c) {
SigGroupHeadCopySigs(a->sh,&b->sh);
SigGroupHeadCopySigs(a->sh,&tmp_c->sh);
b->cnt += a->cnt;
tmp_c->cnt += a->cnt;
}
}
@ -1028,15 +1078,15 @@ DetectPortLookupGroup(DetectPort *dp, u_int16_t port) {
/* XXX eeewww global! move to DetectionEngineCtx once we have that! */
static DetectPort **port_hash;
static DetectPort *port_list;
#define HASH_SIZE 65536
#define PORT_HASH_SIZE 1024
/* XXX dynamic size based on number of sigs? */
int DetectPortHashInit(void) {
port_hash = (DetectPort **)malloc(sizeof(DetectPort) * HASH_SIZE);
port_hash = (DetectPort **)malloc(sizeof(DetectPort *) * PORT_HASH_SIZE);
if (port_hash == NULL) {
goto error;
}
memset(port_hash,0,sizeof(DetectPort) * HASH_SIZE);
memset(port_hash,0,sizeof(DetectPort *) * PORT_HASH_SIZE);
port_list = NULL;
@ -1052,7 +1102,7 @@ void DetectPortHashFree(void) {
void DetectPortHashReset(void) {
if (port_hash != NULL) {
memset(port_hash,0,sizeof(DetectPort) * HASH_SIZE);
memset(port_hash,0,sizeof(DetectPort *) * PORT_HASH_SIZE);
}
port_list = NULL;
}
@ -1066,13 +1116,13 @@ DetectPort *DetectPortHashGetListPtr(void) {
}
u_int32_t DetectPortHashGetSize(void) {
return HASH_SIZE;
return PORT_HASH_SIZE;
}
static inline u_int32_t DetectPortHash(DetectPort *p) {
u_int32_t hash = p->port * p->port2;
return (hash % HASH_SIZE);
return (hash % PORT_HASH_SIZE);
}
int DetectPortHashAdd(DetectPort *p) {
@ -1151,6 +1201,147 @@ DetectPort *DetectPortHashLookup(DetectPort *p) {
return NULL;
}
/* XXX eeewww global! move to DetectionEngineCtx once we have that! */
static DetectPort **sport_hash;
static DetectPort *sport_list;
#define SPORT_HASH_SIZE 1024
/* XXX dynamic size based on number of sigs? */
int DetectPortSpHashInit(void) {
sport_hash = (DetectPort **)malloc(sizeof(DetectPort *) * SPORT_HASH_SIZE);
if (sport_hash == NULL) {
goto error;
}
memset(sport_hash,0,sizeof(DetectPort *) * SPORT_HASH_SIZE);
sport_list = NULL;
//printf("DetectSPortHashInit: sport_hash %p\n", sport_hash);
return 0;
error:
printf("DetectSPortHashInit: error sport_hash %p\n", sport_hash);
return -1;
}
void DetectPortSpHashFree(void) {
free(sport_hash);
sport_hash = NULL;
}
void DetectPortSpHashReset(void) {
if (sport_hash != NULL) {
memset(sport_hash,0,sizeof(DetectPort *) * SPORT_HASH_SIZE);
}
sport_list = NULL;
}
DetectPort **DetectPortSpHashGetPtr(void) {
return sport_hash;
}
DetectPort *DetectPortSpHashGetListPtr(void) {
return sport_list;
}
u_int32_t DetectPortSpHashGetSize(void) {
return SPORT_HASH_SIZE;
}
static inline u_int32_t DetectPortSpHash(DetectPort *p) {
u_int32_t hash = p->port * p->port2;
return (hash % SPORT_HASH_SIZE);
}
int DetectPortSpHashAdd(DetectPort *p) {
u_int32_t hash = DetectPortSpHash(p);
//printf("DetectSPortHashAdd: hash %u\n", hash);
detect_port_hash_add_cnt++;
/* list */
p->next = sport_list;
sport_list = p;
/* easy: no collision */
if (sport_hash[hash] == NULL) {
sport_hash[hash] = p;
return 0;
}
detect_port_hash_add_coll_cnt++;
/* harder: collision */
DetectPort *h = sport_hash[hash], *ph = NULL;
for ( ; h != NULL; h = h->hnext) {
#if 0
if (DetectPortCmp(p,h) == PORT_EB) {
if (h == port_hash[hash]) {
p->hnext = h;
port_hash[hash] = p;
} else {
p->hnext = ph->hnext;
ph->hnext = p;
}
detect_port_hash_add_insert_cnt++;
return 0;
}
#endif
ph = h;
}
ph->hnext = p;
return 0;
}
DetectPort *DetectPortSpHashLookup(DetectPort *p) {
u_int32_t hash = DetectPortSpHash(p);
//printf("DetectSPortHashLookup: hash %u, sport_hash %p, size %u port %p\n", hash, sport_hash, SPORT_HASH_SIZE, p);
detect_port_hash_lookup_cnt++;
/* easy: no sgh at our hash */
if (sport_hash[hash] == NULL) {
detect_port_hash_lookup_miss_cnt++;
//printf("DetectSPortHashLookup: not found\n");
return NULL;
}
/* see if we have the sgh we're looking for */
DetectPort *h = sport_hash[hash];
for ( ; h != NULL; h = h->hnext) {
detect_port_hash_lookup_loop_cnt++;
if (DetectPortHashCmp(p,h) == 1) {
//printf("DetectSPortHashLookup: found at %p\n", h);
detect_port_hash_lookup_hit_cnt++;
return h;
}
}
//printf("DetectSPortHashLookup: not found\n");
return NULL;
}
int DetectPortJoin(DetectPort *target, DetectPort *source) {
if (target == NULL || source == NULL)
return -1;
target->cnt += source->cnt;
SigGroupHeadCopySigs(source->sh,&target->sh);
//DetectPort *port = source->port;
//for ( ; port != NULL; port = port->next) {
// DetectPortInsertCopy(&target->port, port);
//}
if (source->port < target->port)
target->port = source->port;
if (source->port2 > target->port2)
target->port2 = source->port2;
return -1;
}
/* TESTS */
int PortTestParse01 (void) {

@ -17,6 +17,7 @@ enum {
#define PORT_FLAG_NOT 0x2
#define PORT_SIGGROUPHEAD_COPY 0x04
#define PORT_GROUP_PORTS_COPY 0x08
typedef struct DetectPort_ {
u_int8_t flags;
@ -27,13 +28,16 @@ typedef struct DetectPort_ {
/* signatures that belong in this group */
struct _SigGroupHead *sh;
struct DetectPort_ *dst_ph;
/* double linked list */
union {
struct DetectPort_ *prev;
struct DetectPort_ *hnext;
struct DetectPort_ *hnext; /* hash next */
};
struct DetectPort_ *next;
u_int32_t cnt;
} DetectPort;
/* prototypes */
@ -63,5 +67,16 @@ void DetectPortHashFree(void);
int DetectPortHashAdd(DetectPort *p);
void DetectPortHashReset(void);
DetectPort *DetectPortSpHashLookup(DetectPort *p);
DetectPort **DetectPortSpHashGetPtr(void);
DetectPort *DetectPortSpHashGetListPtr(void);
u_int32_t DetectPortSpHashGetSize(void);
int DetectPortSpHashInit(void);
void DetectPortSpHashFree(void);
int DetectPortSpHashAdd(DetectPort *p);
void DetectPortSpHashReset(void);
int DetectPortJoin(DetectPort *target, DetectPort *source);
#endif /* __DETECT_PORT_H__ */

@ -74,7 +74,7 @@ int DetectProtoSetup (Signature *s, SigMatch *m, char *str)
/* TESTS */
int ProtoTestParse01 (void) {
static int ProtoTestParse01 (void) {
DetectProto dp;
memset(&dp,0,sizeof(DetectProto));
@ -86,8 +86,34 @@ int ProtoTestParse01 (void) {
return 0;
}
static int ProtoTestParse02 (void) {
DetectProto dp;
memset(&dp,0,sizeof(DetectProto));
int r = DetectProtoParse(&dp, "tcp");
if (r == 0 && dp.proto[(IPPROTO_TCP/8)] & (1<<(IPPROTO_TCP%8))) {
return 1;
}
return 0;
}
static int ProtoTestParse03 (void) {
DetectProto dp;
memset(&dp,0,sizeof(DetectProto));
int r = DetectProtoParse(&dp, "ip");
if (r == 0 && dp.flags & DETECT_PROTO_ANY) {
return 1;
}
return 0;
}
void DetectProtoTests(void) {
UtRegisterTest("ProtoTestParse01", ProtoTestParse01, 1);
UtRegisterTest("ProtoTestParse02", ProtoTestParse02, 1);
UtRegisterTest("ProtoTestParse03", ProtoTestParse03, 1);
}

@ -57,12 +57,13 @@ static int SigGroupHeadCmpSigArray(SigGroupHead *a, SigGroupHead *b) {
/* 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;
static SigGroupHead **sgh_port_hash = NULL;
static SigGroupHead **sgh_sport_hash = NULL;
static SigGroupHead **sgh_hash = NULL;
static SigGroupHead **sgh_mpm_hash = NULL;
static SigGroupHead **sgh_mpm_uri_hash = NULL;
#define HASH_SIZE 65536
#define HASH_SIZE 262144
/* mpm sgh hash */
@ -348,6 +349,66 @@ void SigGroupHeadPortHashFree(void) {
sgh_port_hash = NULL;
}
/* XXX dynamic size based on number of sigs? */
int SigGroupHeadSPortHashInit(void) {
sgh_sport_hash = (SigGroupHead **)malloc(sizeof(SigGroupHead *) * HASH_SIZE);
if (sgh_sport_hash == NULL) {
goto error;
}
memset(sgh_sport_hash,0,sizeof(SigGroupHead *) * HASH_SIZE);
return 0;
error:
return -1;
}
int SigGroupHeadSPortHashAdd(SigGroupHead *sgh) {
u_int32_t hash = SigGroupHeadHash(sgh);
//printf("SigGroupHeadHashAdd: hash %u\n", hash);
/* easy: no collision */
if (sgh_sport_hash[hash] == NULL) {
sgh_sport_hash[hash] = sgh;
return 0;
}
/* harder: collision */
SigGroupHead *h = sgh_sport_hash[hash], *ph = NULL;
for ( ; h != NULL; h = h->next) {
ph = h;
}
ph->next = sgh;
return 0;
}
SigGroupHead *SigGroupHeadSPortHashLookup(SigGroupHead *sgh) {
u_int32_t hash = SigGroupHeadHash(sgh);
//printf("SigGroupHeadHashLookup: hash %u\n", hash);
/* easy: no sgh at our hash */
if (sgh_sport_hash[hash] == NULL) {
return NULL;
}
/* see if we have the sgh we're looking for */
SigGroupHead *h = sgh_sport_hash[hash];
for ( ; h != NULL; h = h->next) {
if (SigGroupHeadCmpSigArray(sgh,h) == 1) {
return h;
}
}
return NULL;
}
void SigGroupHeadSPortHashFree(void) {
free(sgh_sport_hash);
sgh_sport_hash = NULL;
}
/* end hashes */
void SigGroupHeadFreeHeads(void) {
@ -379,25 +440,12 @@ printf("SigGroupHeadFreeHeads: want to free %p\n", b);
}
}
/* Free the sigarrays in the sgh's. Those are only
* used during the init stage. */
void SigGroupHeadFreeSigArrays(void) {
static void SigGroupHeadFreeSigArraysHash(SigGroupHead **hashtbl) {
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];
b = hashtbl[hash];
for ( ; b != NULL; b = b->next) {
if (b->sig_array != NULL) {
detect_siggroup_sigarray_free_cnt++;
@ -411,6 +459,14 @@ void SigGroupHeadFreeSigArrays(void) {
}
}
/* Free the sigarrays in the sgh's. Those are only
* used during the init stage. */
void SigGroupHeadFreeSigArrays(void) {
SigGroupHeadFreeSigArraysHash(sgh_hash);
SigGroupHeadFreeSigArraysHash(sgh_port_hash);
SigGroupHeadFreeSigArraysHash(sgh_sport_hash);
}
/* Free the mpm arrays that are only used during the
* init stage */
void SigGroupHeadFreeMpmArrays(void) {
@ -444,6 +500,19 @@ void SigGroupHeadFreeMpmArrays(void) {
b->uri_content_size = 0;
}
}
b = sgh_sport_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;
}
}
}
}
@ -560,16 +629,29 @@ void DetectSigGroupPrintMemory(void) {
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);
u_int32_t i;
for (i = 0; i < DetectContentMaxId(); i++) {
if (sgh->content_array[(i/8)] & (1<<(i%8))) {
printf("%u ", i);
}
}
printf("\n");
}
void SigGroupHeadPrintContentCnt(DetectEngineCtx *de_ctx, SigGroupHead *sgh) {
printf("SigGroupHeadPrintContent: ");
u_int32_t i, cnt = 0;
for (i = 0; i < DetectContentMaxId(); i++) {
if (sgh->content_array[(i/8)] & (1<<(i%8))) {
cnt++;
}
}
printf("cnt %u\n", cnt);
}
/* 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. */

@ -18,22 +18,26 @@ void SigGroupHeadFreeMpmArrays(void);
SigGroupHead *SigGroupHeadHashLookup(SigGroupHead *sgh);
SigGroupHead *SigGroupHeadPortHashLookup(SigGroupHead *sgh);
SigGroupHead *SigGroupHeadSPortHashLookup(SigGroupHead *sgh);
SigGroupHead *SigGroupHeadMpmHashLookup(SigGroupHead *sgh);
SigGroupHead *SigGroupHeadMpmUriHashLookup(SigGroupHead *sgh);
int SigGroupHeadPortHashAdd(SigGroupHead *sgh);
int SigGroupHeadSPortHashAdd(SigGroupHead *sgh);
int SigGroupHeadMpmHashAdd(SigGroupHead *sgh);
int SigGroupHeadMpmUriHashAdd(SigGroupHead *sgh);
int SigGroupHeadHashAdd(SigGroupHead *sgh);
void SigGroupHeadHashFree(void);
void SigGroupHeadPortHashFree(void);
void SigGroupHeadSPortHashFree(void);
void SigGroupHeadMpmHashFree(void);
void SigGroupHeadMpmUriHashFree(void);
int SigGroupHeadMpmHashInit(void);
int SigGroupHeadMpmUriHashInit(void);
int SigGroupHeadPortHashInit(void);
int SigGroupHeadSPortHashInit(void);
int SigGroupHeadHashInit(void);
void SigGroupHeadSetSigCnt(SigGroupHead *sgh, u_int32_t max_idx);

@ -17,6 +17,9 @@ static pcre_extra *option_pcre_extra = NULL;
/* XXX this should be part of the DE */
static u_int32_t signum = 0;
static u_int32_t dbg_srcportany_cnt = 0;
static u_int32_t dbg_dstportany_cnt = 0;
#define CONFIG_PARTS 8
#define CONFIG_ACTION 0
@ -37,6 +40,14 @@ u_int32_t SigGetMaxId(void) {
return signum;
}
u_int32_t DbgGetSrcPortAnyCnt(void) {
return dbg_srcportany_cnt;
}
u_int32_t DbgGetDstPortAnyCnt(void) {
return dbg_dstportany_cnt;
}
void SigResetMaxId(void) {
signum = 0;
}
@ -250,10 +261,16 @@ int SigParseAddress(Signature *s, const char *addrstr, char flag) {
/* pass on to the address(list) parser */
if (flag == 0) {
if (strcasecmp(addrstr,"any") == 0)
s->flags |= SIG_FLAG_SRC_ANY;
if (DetectAddressGroupParse(&s->src,addr) < 0) {
goto error;
}
} else {
if (strcasecmp(addrstr,"any") == 0)
s->flags |= SIG_FLAG_DST_ANY;
if (DetectAddressGroupParse(&s->dst,addr) < 0) {
goto error;
}
@ -299,10 +316,15 @@ int SigParsePort(Signature *s, const char *portstr, char flag) {
}
if (flag == 0) {
if (strcasecmp(port,"any") == 0)
s->flags |= SIG_FLAG_SP_ANY;
r = DetectPortParse(&s->sp,(char *)port);
} else if (flag == 1) {
if (strcasecmp(port,"any") == 0)
s->flags |= SIG_FLAG_DP_ANY;
r = DetectPortParse(&s->dp,(char *)port);
//DetectPortPrintList(s->dp);
}
if (r < 0) {
printf("SigParsePort: DetectPortParse \"%s\" failed\n", portstr);
@ -372,12 +394,15 @@ int SigParseBasics(Signature *s, char *sigstr, char ***result) {
/* Parse Address & Ports */
if (SigParseAddress(s, arr[CONFIG_SRC], 0) < 0)
goto error;
if (SigParsePort(s, arr[CONFIG_SP], 0) < 0)
goto error;
if (strcasecmp(arr[CONFIG_PROTO],"tcp") == 0 ||
strcasecmp(arr[CONFIG_PROTO],"udp") == 0) {
if (SigParsePort(s, arr[CONFIG_SP], 0) < 0)
goto error;
if (SigParsePort(s, arr[CONFIG_DP], 1) < 0)
goto error;
}
if (SigParseAddress(s, arr[CONFIG_DST], 1) < 0)
goto error;
if (SigParsePort(s, arr[CONFIG_DP], 1) < 0)
goto error;
*result = (char **)arr;
DEBUGPRINT("SigParseBasics: %p %p", arr, *result);
@ -479,8 +504,6 @@ int SigParseTest01 (void) {
int result = 1;
Signature *sig = NULL;
//SigParsePrepare();
sig = SigInit("alert tcp 1.2.3.4 any -> !1.2.3.4 any (msg:\"SigParseTest01\"; sid:1;)");
if (sig == NULL) {
result = 0;

File diff suppressed because it is too large Load Diff

@ -9,10 +9,12 @@
#include "detect-uricontent.h"
#define SIG_FLAG_RECURSIVE 0x01
#define SIG_FLAG_SP_ANY 0x02
#define SIG_FLAG_DP_ANY 0x04
#define SIG_FLAG_NOALERT 0x08
#define SIG_FLAG_IPONLY 0x10 /* ip only signature */
#define SIG_FLAG_SRC_ANY 0x02
#define SIG_FLAG_DST_ANY 0x04
#define SIG_FLAG_SP_ANY 0x08
#define SIG_FLAG_DP_ANY 0x10
#define SIG_FLAG_NOALERT 0x20
#define SIG_FLAG_IPONLY 0x40 /* ip only signature */
#define DE_QUIET 0x01
@ -41,12 +43,13 @@ typedef struct _PatternMatcherThread {
} PatternMatcherThread;
typedef struct _Signature {
u_int8_t flags;
u_int32_t num; /* signature number */
u_int32_t id;
u_int8_t rev;
u_int8_t prio;
char *msg;
u_int8_t flags;
u_int8_t action;
DetectAddressGroupsHead src, dst;
@ -99,8 +102,30 @@ typedef struct DetectEngineCtx_ {
mpm_uri_unique, mpm_uri_reuse, mpm_uri_none;
u_int32_t gh_unique, gh_reuse;
u_int32_t mpm_max_patcnt,
mpm_min_patcnt,
mpm_tot_patcnt,
mpm_uri_max_patcnt,
mpm_uri_min_patcnt,
mpm_uri_tot_patcnt;
} DetectEngineCtx;
typedef struct SignatureTuple_ {
DetectAddressGroup *src;
DetectAddressGroup *dst;
DetectPort *sp;
DetectPort *dp;
u_int8_t proto;
struct _SigGroupHead *sgh;
struct SignatureTuple_ *hnext;
struct SignatureTuple_ *next;
u_int32_t cnt;
} SignatureTuple;
/* container for content matches... we use this to compare
* group heads for contents
* XXX name */

@ -25,6 +25,8 @@
#define INIT_HASH_SIZE 65535
#define HASH17_SIZE 131072
#define HASH17(a,b) (((a)<<9) | (b))
#define HASH16_SIZE 65536
#define HASH16(a,b) (((a)<<8) | (b))
#define HASH15_SIZE 32768
@ -49,6 +51,7 @@ u_int32_t WmSearch2Hash12(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, u_int8_
u_int32_t WmSearch2Hash14(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, u_int8_t *buf, u_int16_t buflen);
u_int32_t WmSearch2Hash15(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, u_int8_t *buf, u_int16_t buflen);
u_int32_t WmSearch2Hash16(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, u_int8_t *buf, u_int16_t buflen);
u_int32_t WmSearch2Hash17(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, u_int8_t *buf, u_int16_t buflen);
void WmPrintInfo(MpmCtx *mpm_ctx);
void WmPrintSearchStats(MpmThreadCtx *mpm_thread_ctx);
void WmRegisterTests(void);
@ -139,12 +142,14 @@ void WmPrintInfo(MpmCtx *mpm_ctx) {
if (mpm_ctx->Search == WmSearch1) {
printf("WmSearch1 (allows single byte patterns)\n");
printf("MBSearch funct: ");
if (wm_ctx->MBSearch == WmSearch2Hash16) printf("WmSearch2Hash16\n");
if (wm_ctx->MBSearch == WmSearch2Hash17) printf("WmSearch2Hash17\n");
else if (wm_ctx->MBSearch == WmSearch2Hash16) printf("WmSearch2Hash16\n");
else if (wm_ctx->MBSearch == WmSearch2Hash15) printf("WmSearch2Hash15\n");
else if (wm_ctx->MBSearch == WmSearch2Hash14) printf("WmSearch2Hash14\n");
else if (wm_ctx->MBSearch == WmSearch2Hash12) printf("WmSearch2Hash12\n");
else if (wm_ctx->MBSearch == WmSearch2Hash9) printf("WmSearch2Hash9\n");
}
else if (mpm_ctx->Search == WmSearch2Hash17) printf("WmSearch2Hash17 (only for multibyte patterns)\n");
else if (mpm_ctx->Search == WmSearch2Hash16) printf("WmSearch2Hash16 (only for multibyte patterns)\n");
else if (mpm_ctx->Search == WmSearch2Hash15) printf("WmSearch2Hash15 (only for multibyte patterns)\n");
else if (mpm_ctx->Search == WmSearch2Hash14) printf("WmSearch2Hash14 (only for multibyte patterns)\n");
@ -423,8 +428,10 @@ static void WmPrepareHash(MpmCtx *mpm_ctx) {
idx = HASH14(wm_ctx->parray[i]->ci[patlen-1], wm_ctx->parray[i]->ci[patlen-2]);
else if (wm_ctx->hash_size == HASH15_SIZE)
idx = HASH15(wm_ctx->parray[i]->ci[patlen-1], wm_ctx->parray[i]->ci[patlen-2]);
else
else if (wm_ctx->hash_size == HASH16_SIZE)
idx = HASH16(wm_ctx->parray[i]->ci[patlen-1], wm_ctx->parray[i]->ci[patlen-2]);
else
idx = HASH17(wm_ctx->parray[i]->ci[patlen-1], wm_ctx->parray[i]->ci[patlen-2]);
if (wm_ctx->hash[idx] == NULL) {
WmHashItem *hi = WmAllocHashItem(mpm_ctx);
@ -499,8 +506,11 @@ static void WmPrepareShiftTable(MpmCtx *mpm_ctx)
} else if (wm_ctx->hash_size == HASH15_SIZE) {
idx = HASH15(wm_ctx->parray[i]->ci[k+1], wm_ctx->parray[i]->ci[k]);
//printf("HASH15 idx %u\n", idx);
} else {
} else if (wm_ctx->hash_size == HASH16_SIZE) {
idx = HASH16(wm_ctx->parray[i]->ci[k+1], wm_ctx->parray[i]->ci[k]);
//printf("HASH15 idx %u\n", idx);
} else {
idx = HASH17(wm_ctx->parray[i]->ci[k+1], wm_ctx->parray[i]->ci[k]);
}
//idx = ((wm_ctx->parray[i]->ci[k]) | (wm_ctx->parray[i]->ci[k+1]<<8));
if (shift < wm_ctx->shifttable[idx]) {
@ -543,20 +553,20 @@ int WmPreparePatterns(MpmCtx *mpm_ctx) {
/* TODO VJ these values are chosen pretty much randomly, so
* we should do some performance testing
*
* Right now I've chosen pattern cnt / 5 as max
* */
if (wm_ctx->hash_size == 0) {
if (mpm_ctx->pattern_cnt < 100) {
if (mpm_ctx->pattern_cnt < 50) {
wm_ctx->hash_size = HASH9_SIZE;
} else if(mpm_ctx->pattern_cnt < 800) {
} else if(mpm_ctx->pattern_cnt < 300) {
wm_ctx->hash_size = HASH12_SIZE;
} else if(mpm_ctx->pattern_cnt < 3200) {
} else if(mpm_ctx->pattern_cnt < 1200) {
wm_ctx->hash_size = HASH14_SIZE;
} else if(mpm_ctx->pattern_cnt < 6400) {
} else if(mpm_ctx->pattern_cnt < 2400) {
wm_ctx->hash_size = HASH15_SIZE;
} else {
} else if(mpm_ctx->pattern_cnt < 4000) {
wm_ctx->hash_size = HASH16_SIZE;
} else {
wm_ctx->hash_size = HASH17_SIZE;
}
}
@ -575,9 +585,12 @@ int WmPreparePatterns(MpmCtx *mpm_ctx) {
} else if (wm_ctx->hash_size == HASH15_SIZE) {
wm_ctx->MBSearch = WmSearch2Hash15;
mpm_ctx->Search = WmSearch2Hash15;
} else {
} else if (wm_ctx->hash_size == HASH16_SIZE) {
wm_ctx->MBSearch = WmSearch2Hash16;
mpm_ctx->Search = WmSearch2Hash16;
} else {
wm_ctx->MBSearch = WmSearch2Hash17;
mpm_ctx->Search = WmSearch2Hash17;
}
if (mpm_ctx->minlen == 1) {
@ -1081,6 +1094,98 @@ u_int32_t WmSearch2Hash16(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, u_int8_
return cnt;
}
u_int32_t WmSearch2Hash17(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, u_int8_t *buf, u_int16_t buflen) {
WmCtx *wm_ctx = (WmCtx *)mpm_ctx->ctx;
WmThreadCtx *wm_thread_ctx = (WmThreadCtx *)mpm_thread_ctx->ctx;
u_int32_t cnt = 0;
u_int8_t *bufmin = buf;
u_int8_t *bufend = buf + buflen - 1;
u_int16_t sl = wm_ctx->shiftlen;
u_int16_t h;
u_int8_t shift;
WmHashItem *thi, *hi;
WmPattern *p;
u_int16_t prefixci_buf;
u_int16_t prefixcs_buf;
if (buflen == 0)
return 0;
//printf("BUF(%u) ", buflen); prt(buf,buflen); printf("\n");
buf+=(sl-1);
//buf++;
while (buf <= bufend) {
//h = (wm_tolower(*buf)<<8)+(wm_tolower(*(buf-1)));
h = HASH17(wm_tolower(*buf),(wm_tolower(*(buf-1))));
shift = wm_ctx->shifttable[h];
//printf("search: h %u, shift %u\n", h, shift);
if (shift == 0) {
wm_thread_ctx->stat_shift_null++;
/* get our hash item */
hi = wm_ctx->hash[h];
//printf("search: hi %p\n", hi);
if (hi != NULL) {
prefixci_buf = (u_int16_t)(wm_tolower(*(buf-sl+1)) + wm_tolower(*(buf-sl+2)));
prefixcs_buf = (u_int16_t)(*(buf-sl+1) + *(buf-sl+2));
//printf("WmSearch2: prefixci_buf %u, prefixcs_buf %u\n", prefixci_buf, prefixcs_buf);
for (thi = hi; thi != NULL; thi = thi->nxt) {
p = wm_ctx->parray[thi->idx];
//printf("WmSearch2: p->prefix_ci %u, p->prefix_cs %u\n",
// p->prefix_ci, p->prefix_cs);
if (p->flags & NOCASE) {
if (p->prefix_ci != prefixci_buf || p->len > (bufend-(buf-sl)))
continue;
if (memcmp_lowercase(p->ci, buf-sl+1, p->len) == 0) {
cnt++;
//printf("CI Exact match: "); prt(p->ci, p->len); printf("\n");
wm_thread_ctx->stat_loop_match++;
MpmEndMatch *em;
for (em = p->em; em; em = em->next) {
//printf("em %p id %u\n", em, em->id);
MpmMatchAppend(mpm_thread_ctx, em, &mpm_thread_ctx->match[em->id],(buf-sl+1 - bufmin));
}
} else {
wm_thread_ctx->stat_loop_no_match++;
}
} else {
if (p->prefix_cs != prefixcs_buf || p->len > (bufend-(buf-sl)))
continue;
if (memcmp(p->cs, buf-sl+1, p->len) == 0) {
cnt++;
//printf("CS Exact match: "); prt(p->cs, p->len); printf("\n");
wm_thread_ctx->stat_loop_match++;
MpmEndMatch *em;
for (em = p->em; em; em = em->next) {
//printf("em %p id %u\n", em, em->id);
MpmMatchAppend(mpm_thread_ctx, em, &mpm_thread_ctx->match[em->id],(buf-sl+1 - bufmin));
}
} else {
wm_thread_ctx->stat_loop_no_match++;
}
}
}
}
shift = 1;
} else {
wm_thread_ctx->stat_total_shift += shift;
wm_thread_ctx->stat_num_shift++;
}
buf += shift;
}
return cnt;
}
u_int32_t WmSearch1(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, u_int8_t *buf, u_int16_t buflen) {
WmCtx *wm_ctx = (WmCtx *)mpm_ctx->ctx;
//WmThreadCtx *wm_thread_ctx = (WmThreadCtx *)mpm_thread_ctx->ctx;

@ -23,7 +23,7 @@
#include "util-binsearch.h"
#include "detect-parse.h"
#include "detect-mpm.h"
#include "detect-engine-mpm.h"
#include "tm-queuehandlers.h"
#include "tm-queues.h"

Loading…
Cancel
Save