Big detection engine update: scan improvements, b2g/b3g updates, bloom fixes, iponly detection implementation, dsize/flow grouping.

remotes/origin/master-1.0.x
Victor Julien 17 years ago
parent e877d69a2d
commit 657be002d1

@ -27,6 +27,7 @@ detect-engine-proto.c detect-engine-proto.h \
detect-engine-port.c detect-engine-port.h \
detect-engine-siggroup.c detect-engine-siggroup.h \
detect-engine-mpm.c detect-engine-mpm.h \
detect-engine-iponly.c detect-engine-iponly.h \
detect-parse.c detect-parse.h \
detect-content.c detect-content.h \
detect-uricontent.c detect-uricontent.h \

@ -126,8 +126,8 @@ static int DecodeTCPPacket(ThreadVars *t, Packet *p, u_int8_t *pkt, u_int16_t le
DecodeTCPOptions(t, p, pkt + TCP_HEADER_LEN, p->tcpvars.tcp_opt_len);
}
p->tcp_payload = pkt + p->tcpvars.hlen;
p->tcp_payload_len = len - p->tcpvars.hlen;
p->payload = pkt + p->tcpvars.hlen;
p->payload_len = len - p->tcpvars.hlen;
p->proto = IPPROTO_TCP;

@ -28,8 +28,8 @@ static int DecodeUDPPacket(ThreadVars *t, Packet *p, u_int8_t *pkt, u_int16_t le
SET_UDP_SRC_PORT(p,&p->sp);
SET_UDP_DST_PORT(p,&p->dp);
p->tcp_payload = pkt + UDP_HEADER_LEN;
p->tcp_payload_len = len - UDP_HEADER_LEN;
p->payload = pkt + UDP_HEADER_LEN;
p->payload_len = len - UDP_HEADER_LEN;
p->proto = IPPROTO_UDP;

@ -189,16 +189,12 @@ typedef struct _Packet
Port sp;
Port dp;
u_int8_t proto;
/* make sure we can't be attacked on when the tunneled packet
* has the exact same tuple as the lower levels */
u_int8_t recursion_level;
/* XXX make sure we can't be attacked on when the tunneled packet
* has the exact same tuple as the lower levels */
struct timeval ts;
/* program flow */
int pickup_q_id;
int verdict_q_id;
/* ready to set verdict counter, only set in root */
u_int8_t rtv_cnt;
/* tunnel packet ref count */
@ -243,13 +239,14 @@ typedef struct _Packet
TCPHdr *tcph;
TCPVars tcpvars;
u_int8_t *tcp_payload;
u_int16_t tcp_payload_len;
UDPHdr *udph;
UDPVars udpvars;
u_int8_t *udp_payload;
u_int16_t udp_payload_len;
/* ptr to the payload of the packet
* with it's length. */
u_int8_t *payload;
u_int16_t payload_len;
/* decoder events: review how many events we have */
u_int8_t events[65535/8];
@ -313,6 +310,7 @@ typedef struct _PacketQueue {
(p)->http_uri.cnt = 0; \
PktVarFree((p)->pktvar); \
(p)->pktvar = NULL; \
(p)->recursion_level = 0; \
}

@ -179,7 +179,7 @@ DoDetectContent(ThreadVars *t, PatternMatcherThread *pmt, Packet *p, Signature *
ret = TestWithinDistanceOffsetDepth(t, pmt, m, sm->next, pmt->pkt_off);
if (ret == 1) {
//printf("DoDetectContent: TestWithinDistanceOffsetDepth returned 1\n");
pmt->pkt_ptr = p->tcp_payload + m->offset;
pmt->pkt_ptr = p->payload + m->offset;
pmt->pkt_off = m->offset;
match = 1;
break;
@ -214,7 +214,7 @@ DoDetectContent(ThreadVars *t, PatternMatcherThread *pmt, Packet *p, Signature *
if (m->offset >= pmt->pkt_off) {
/* update pkt ptrs, content doesn't use this,
* but pcre does */
pmt->pkt_ptr = p->tcp_payload + m->offset;
pmt->pkt_ptr = p->payload + m->offset;
pmt->pkt_off = m->offset;
match = 1;
break;
@ -227,7 +227,7 @@ DoDetectContent(ThreadVars *t, PatternMatcherThread *pmt, Packet *p, Signature *
if (ret == 1) {
/* update pkt ptrs, this content run doesn't
* use this, but pcre does */
pmt->pkt_ptr = p->tcp_payload + m->offset;
pmt->pkt_ptr = p->payload + m->offset;
pmt->pkt_off = m->offset;
match = 1;
break;
@ -249,7 +249,7 @@ int DetectContentMatch (ThreadVars *t, PatternMatcherThread *pmt, Packet *p, Sig
{
u_int32_t len = 0;
if (p->tcp_payload_len == 0)
if (p->payload_len == 0)
return 0;
DetectContentData *co = (DetectContentData *)m->ctx;
@ -384,6 +384,8 @@ int DetectContentSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char
cd->id = de_ctx->content_max_id;
de_ctx->content_max_id++;
s->flags |= SIG_FLAG_MPM;
if (dubbed) free(str);
return 0;

@ -4,6 +4,8 @@
#include "detect.h"
#include "flow-var.h"
#include "detect-dsize.h"
#include "util-unittest.h"
#include <pcre.h>
@ -12,17 +14,6 @@
static pcre *parse_regex;
static pcre_extra *parse_regex_study;
#define LT 0
#define EQ 1
#define GT 2
#define RA 3
typedef struct _DetectDsizeData {
u_int16_t dsize;
u_int16_t dsize2;
u_int8_t mode;
} DetectDsizeData;
int DetectDsizeMatch (ThreadVars *, PatternMatcherThread *, Packet *, Signature *, SigMatch *);
int DetectDsizeSetup (DetectEngineCtx *, Signature *s, SigMatch *m, char *str);
void DsizeRegisterTests(void);
@ -70,13 +61,13 @@ int DetectDsizeMatch (ThreadVars *t, PatternMatcherThread *pmt, Packet *p, Signa
DetectDsizeData *dd = (DetectDsizeData *)m->ctx;
if (dd->mode == EQ && dd->dsize == p->tcp_payload_len)
if (dd->mode == DETECTDSIZE_EQ && dd->dsize == p->payload_len)
ret = 1;
else if (dd->mode == LT && p->tcp_payload_len < dd->dsize)
else if (dd->mode == DETECTDSIZE_LT && p->payload_len < dd->dsize)
ret = 1;
else if (dd->mode == GT && p->tcp_payload_len > dd->dsize)
else if (dd->mode == DETECTDSIZE_GT && p->payload_len > dd->dsize)
ret = 1;
else if (dd->mode == RA && p->tcp_payload_len > dd->dsize && p->tcp_payload_len < dd->dsize2)
else if (dd->mode == DETECTDSIZE_RA && p->payload_len > dd->dsize && p->payload_len < dd->dsize2)
ret = 1;
return ret;
@ -139,21 +130,21 @@ DetectDsizeData *DetectDsizeParse (char *rawstr)
dd->dsize = 0;
dd->dsize2 = 0;
if (mode[0] == '<') dd->mode = LT;
else if (mode[0] == '>') dd->mode = GT;
else dd->mode = EQ;
if (mode[0] == '<') dd->mode = DETECTDSIZE_LT;
else if (mode[0] == '>') dd->mode = DETECTDSIZE_GT;
else dd->mode = DETECTDSIZE_EQ;
if (strcmp("<>", range) == 0) {
if (strlen(mode) != 0)
goto error;
dd->mode = RA;
dd->mode = DETECTDSIZE_RA;
}
/* set the value */
dd->dsize = (u_int16_t)atoi(value1);
if (strlen(value2) > 0) {
if (dd->mode != RA)
if (dd->mode != DETECTDSIZE_RA)
goto error;
dd->dsize2 = (u_int16_t)atoi(value2);
@ -276,7 +267,7 @@ int DsizeTestParse06 (void) {
DetectDsizeData *dd = NULL;
dd = DetectDsizeParse(">10");
if (dd) {
if (dd->dsize == 10 && dd->mode == GT)
if (dd->dsize == 10 && dd->mode == DETECTDSIZE_GT)
result = 1;
DetectDsizeFree(dd);
@ -290,7 +281,7 @@ int DsizeTestParse07 (void) {
DetectDsizeData *dd = NULL;
dd = DetectDsizeParse("<100");
if (dd) {
if (dd->dsize == 100 && dd->mode == LT)
if (dd->dsize == 100 && dd->mode == DETECTDSIZE_LT)
result = 1;
DetectDsizeFree(dd);
@ -304,7 +295,7 @@ int DsizeTestParse08 (void) {
DetectDsizeData *dd = NULL;
dd = DetectDsizeParse("1<>2");
if (dd) {
if (dd->dsize == 1 && dd->dsize2 == 2 && dd->mode == RA)
if (dd->dsize == 1 && dd->dsize2 == 2 && dd->mode == DETECTDSIZE_RA)
result = 1;
DetectDsizeFree(dd);

@ -1,6 +1,17 @@
#ifndef __DETECT_DSIZE_H__
#define __DETECT_DSIZE_H__
#define DETECTDSIZE_LT 0
#define DETECTDSIZE_EQ 1
#define DETECTDSIZE_GT 2
#define DETECTDSIZE_RA 3
typedef struct _DetectDsizeData {
u_int16_t dsize;
u_int16_t dsize2;
u_int8_t mode;
} DetectDsizeData;
/* prototypes */
void DetectDsizeRegister (void);

@ -79,15 +79,17 @@ void DetectAddressGroupFree(DetectAddressGroup *ag) {
}
ag->sh = NULL;
if (ag->dst_gh != NULL) {
DetectAddressGroupsHeadFree(ag->dst_gh);
}
ag->dst_gh = NULL;
if (ag->port != NULL && !(ag->flags & PORT_GROUP_PORTS_COPY)) {
DetectPortCleanupList(ag->port);
if (!(ag->flags & ADDRESS_GROUP_HAVEPORT)) {
if (ag->dst_gh != NULL) {
DetectAddressGroupsHeadFree(ag->dst_gh);
}
ag->dst_gh = NULL;
} else {
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++;

@ -0,0 +1,463 @@
/* ip only part of the detection engine */
/* TODO: needs a lot of work
*
*/
#include "vips.h"
#include "debug.h"
#include "detect.h"
#include "flow.h"
#include "detect-parse.h"
#include "detect-engine.h"
#include "detect-engine-siggroup.h"
#include "detect-engine-address.h"
#include "detect-engine-proto.h"
#include "detect-engine-port.h"
#include "detect-engine-mpm.h"
/* build a lookup tree for src, if we have one: save
* build a lookup tree for dst, if we have one: save
* compare tree's: if they have one (or more) matching
* sig, we have a match. */
#define IPONLY_EXTRACT_16(a) ((a)->ip[0] & 0x0000ffff)
//#define IPONLY_EXTRACT_24(a) ((a)->ip[0] & 0x00ffffff)
/* No need to calc a constant every lookup: htonl(65535) */
#define IPONLY_HTONL_65535 4294901760UL
static u_int32_t IPOnlyHashFunc16(HashListTable *ht, void *data, u_int16_t len) {
DetectAddressGroup *gr = (DetectAddressGroup *) data;
u_int32_t hash = IPONLY_EXTRACT_16(gr->ad) % ht->array_size;
return hash;
}
/*
static u_int32_t IPOnlyHashFunc24(HashListTable *ht, void *data, u_int16_t len) {
DetectAddressGroup *gr = (DetectAddressGroup *) data;
u_int32_t hash = IPONLY_EXTRACT_24(gr->ad) % ht->array_size;
return hash;
}
*/
static void IPOnlyAddSlash16(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ctx, HashListTable *ht, DetectAddressGroup *gr, char direction, Signature *s) {
u_int32_t high = ntohl(gr->ad->ip2[0]);
u_int32_t low = ntohl(gr->ad->ip[0]);
if ((ntohl(gr->ad->ip2[0]) - ntohl(gr->ad->ip[0])) > 65536) {
//printf("Bigger than a class/16:\n"); DetectAddressDataPrint(gr->ad);
u_int32_t s16_cnt = 0;
while (high > low) {
s16_cnt++;
DetectAddressGroup *grtmp = DetectAddressGroupInit();
if (grtmp == NULL) {
goto error;
}
DetectAddressData *adtmp = DetectAddressDataCopy(gr->ad);
if (adtmp == NULL) {
goto error;
}
adtmp->ip[0] = htonl(high - 65535);
adtmp->ip2[0] = htonl(high);
grtmp->ad = adtmp;
grtmp->cnt = 1;
SigGroupHeadAppendSig(de_ctx, &grtmp->sh, s);
//printf(" -=- "); DetectAddressDataPrint(na);
DetectAddressGroup *rgr = HashListTableLookup(ht,grtmp,0);
if (rgr == NULL) {
SigGroupHeadAppendSig(de_ctx, &grtmp->sh, s);
HashListTableAdd(ht,grtmp,0);
direction ? io_ctx->a_dst_uniq16++ : io_ctx->a_src_uniq16++;
//printf(" uniq\n");
} else {
SigGroupHeadAppendSig(de_ctx, &rgr->sh, s);
DetectAddressGroupFree(grtmp);
direction ? io_ctx->a_dst_total16++ : io_ctx->a_src_total16++;
//printf(" dup\n");
}
if (high >= 65536)
high -= 65536;
else
high = 0;
}
//printf(" contains %u /16's\n", s16_cnt);
} else {
DetectAddressGroup *grtmp = DetectAddressGroupInit();
if (grtmp == NULL) {
goto error;
}
DetectAddressData *adtmp = DetectAddressDataCopy(gr->ad);
if (adtmp == NULL) {
goto error;
}
adtmp->ip[0] = IPONLY_EXTRACT_16(gr->ad);
adtmp->ip2[0] = IPONLY_EXTRACT_16(gr->ad) | IPONLY_HTONL_65535;
grtmp->ad = adtmp;
grtmp->cnt = 1;
//SigGroupHeadAppendSig(de_ctx, &grtmp->sh, s);
DetectAddressGroup *rgr = HashListTableLookup(ht,grtmp,0);
if (rgr == NULL) {
SigGroupHeadAppendSig(de_ctx, &grtmp->sh, s);
HashListTableAdd(ht,grtmp,0);
direction ? io_ctx->a_dst_uniq16++ : io_ctx->a_src_uniq16++;
} else {
SigGroupHeadAppendSig(de_ctx, &rgr->sh, s);
DetectAddressGroupFree(grtmp);
direction ? io_ctx->a_dst_total16++ : io_ctx->a_src_total16++;
}
}
error:
return;
}
/*
static void IPOnlyAddSlash24(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ctx, HashListTable *ht, DetectAddressGroup *gr, char direction, Signature *s) {
if ((ntohl(gr->ad->ip2[0]) - ntohl(gr->ad->ip[0])) > 256) {
//printf("Bigger than a class/24:\n"); DetectAddressDataPrint(a);
u_int32_t high = ntohl(gr->ad->ip2[0]);
u_int32_t low = ntohl(gr->ad->ip[0]);
u_int32_t s24_cnt = 0;
while (high > low) {
s24_cnt++;
DetectAddressGroup *grtmp = DetectAddressGroupInit();
if (grtmp == NULL) {
goto error;
}
DetectAddressData *adtmp = DetectAddressDataCopy(gr->ad);
if (adtmp == NULL) {
goto error;
}
adtmp->ip[0] = htonl(high - 255);
adtmp->ip2[0] = htonl(high);
grtmp->ad = adtmp;
grtmp->cnt = 1;
//printf(" -=- "); DetectAddressDataPrint(na);
DetectAddressGroup *rgr = HashListTableLookup(ht,grtmp,0);
if (rgr == NULL) {
HashListTableAdd(ht,grtmp,0);
direction ? io_ctx->a_dst_uniq24++ : io_ctx->a_src_uniq24++;
//printf(" uniq\n");
} else {
DetectAddressGroupFree(grtmp);
direction ? io_ctx->a_dst_total24++ : io_ctx->a_src_total24++;
//printf(" dup\n");
}
if (high >= 256)
high -= 256;
else
high = 0;
}
//printf(" contains %u /24's\n", s24_cnt);
} else {
DetectAddressGroup *rgr = HashListTableLookup(ht,gr,0);
if (rgr == NULL) {
HashListTableAdd(ht,gr,0);
direction ? io_ctx->a_dst_uniq24++ : io_ctx->a_src_uniq24++;
} else {
direction ? io_ctx->a_dst_total24++ : io_ctx->a_src_total24++;
}
}
error:
return;
}
*/
static char IPOnlyCompareFunc(void *data1, u_int16_t len1, void *data2, u_int16_t len2) {
DetectAddressGroup *a1 = (DetectAddressGroup *)data1;
DetectAddressGroup *a2 = (DetectAddressGroup *)data2;
//printf("IPOnlyCompareFunc: "); DetectAddressDataPrint(a1->ad);
//printf(" "); DetectAddressDataPrint(a2->ad); printf("\n");
if (DetectAddressCmp(a1->ad,a2->ad) != ADDRESS_EQ)
return 0;
return 1;
}
/* XXX error checking */
void IPOnlyInit(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ctx) {
io_ctx->ht16_src = HashListTableInit(65536, IPOnlyHashFunc16, IPOnlyCompareFunc, NULL);
io_ctx->ht16_dst = HashListTableInit(65536, IPOnlyHashFunc16, IPOnlyCompareFunc, NULL);
/*
io_ctx->ht24_src = HashListTableInit(65536, IPOnlyHashFunc24, IPOnlyCompareFunc, NULL);
io_ctx->ht24_dst = HashListTableInit(65536, IPOnlyHashFunc24, IPOnlyCompareFunc, NULL);
*/
io_ctx->sig_init_size = DetectEngineGetMaxSigId(de_ctx) / 8 + 1;
io_ctx->sig_init_array = malloc(io_ctx->sig_init_size);
memset(io_ctx->sig_init_array, 0, io_ctx->sig_init_size);
}
/* XXX error checking */
void DetectEngineIPOnlyThreadInit(DetectEngineCtx *de_ctx, DetectEngineIPOnlyThreadCtx *io_tctx) {
DetectAddressData *sad = DetectAddressDataInit();
sad->family = AF_INET;
DetectAddressData *dad = DetectAddressDataInit();
dad->family = AF_INET;
io_tctx->src = DetectAddressGroupInit();
io_tctx->src->ad = sad;
io_tctx->dst = DetectAddressGroupInit();
io_tctx->dst->ad = dad;
/* initialize the signature bitarray */
io_tctx->sig_match_size = de_ctx->io_ctx.max_idx / 8 + 1;
io_tctx->sig_match_array = malloc(io_tctx->sig_match_size);
memset(io_tctx->sig_match_array, 0, io_tctx->sig_match_size);
}
void IPOnlyPrint(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ctx) {
if (!(de_ctx->flags & DE_QUIET)) {
printf(" * IP ONLY (SRC): %u /16's in our hash, %u total address ranges in them\n",
io_ctx->a_src_uniq16, io_ctx->a_src_uniq16 + io_ctx->a_src_total16);
printf(" * IP ONLY (DST): %u /16's in our hash, %u total address ranges in them\n",
io_ctx->a_dst_uniq16, io_ctx->a_dst_uniq16 + io_ctx->a_dst_total16);
/*
printf(" * IP ONLY (SRC): %u /24's in our hash, %u total address ranges in them\n",
io_ctx->a_src_uniq24, io_ctx->a_src_uniq24 + io_ctx->a_src_total24);
printf(" * IP ONLY (DST): %u /24's in our hash, %u total address ranges in them\n",
io_ctx->a_dst_uniq24, io_ctx->a_dst_uniq24 + io_ctx->a_dst_total24);
*/
}
}
void IPOnlyDeinit(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ctx) {
HashListTableFree(io_ctx->ht16_src);
io_ctx->ht16_src = NULL;
HashListTableFree(io_ctx->ht16_dst);
io_ctx->ht16_dst = NULL;
/*
HashListTableFree(io_ctx->ht24_src);
io_ctx->ht24_src = NULL;
HashListTableFree(io_ctx->ht24_dst);
io_ctx->ht24_dst = NULL;
*/
free(io_ctx->sig_init_array);
io_ctx->sig_init_array = NULL;
}
DetectAddressGroup *IPOnlyLookupSrc16(DetectEngineCtx *de_ctx, DetectEngineIPOnlyThreadCtx *io_tctx, Packet *p) {
io_tctx->src->ad->ip[0] = GET_IPV4_SRC_ADDR_U32(p) & 0x0000ffff;
io_tctx->src->ad->ip2[0] = (GET_IPV4_SRC_ADDR_U32(p) & 0x0000ffff) | IPONLY_HTONL_65535;
//printf("IPOnlyLookupSrc16: "); DetectAddressDataPrint(io_tctx->src->ad); printf("\n");
DetectAddressGroup *rgr = HashListTableLookup(de_ctx->io_ctx.ht16_src, io_tctx->src, 0);
return rgr;
}
DetectAddressGroup *IPOnlyLookupDst16(DetectEngineCtx *de_ctx, DetectEngineIPOnlyThreadCtx *io_tctx, Packet *p) {
io_tctx->dst->ad->ip[0] = GET_IPV4_DST_ADDR_U32(p) & 0x0000ffff;
io_tctx->dst->ad->ip2[0] = (GET_IPV4_DST_ADDR_U32(p) & 0x0000ffff) | IPONLY_HTONL_65535;
//printf("IPOnlyLookupDst16: "); DetectAddressDataPrint(io_tctx->dst->ad); printf("\n");
DetectAddressGroup *rgr = HashListTableLookup(de_ctx->io_ctx.ht16_dst, io_tctx->dst, 0);
return rgr;
}
/* XXX handle any case: preinit a array with the any's set to 1 for both
* src and dst, and use that if src/dst is NULL and AND that with the other
* array. */
void IPOnlyMatchPacket(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ctx,
DetectEngineIPOnlyThreadCtx *io_tctx, Packet *p) {
DetectAddressGroup *src = NULL, *dst = NULL;
#if 0
/* debug print */
char s[16], d[16];
inet_ntop(AF_INET, (const void *)(p->src.addr_data32), s, sizeof(s));
inet_ntop(AF_INET, (const void *)(p->dst.addr_data32), d, sizeof(d));
printf("IPV4 %s->%s\n",s,d);
printf("IPOnlyMatchPacket starting...\n");
#endif
if (io_tctx->src == NULL)
return;
//printf("IPOnlyMatchPacket looking up src...\n");
/* lookup source address group */
src = IPOnlyLookupSrc16(de_ctx, io_tctx, p);
if (src == NULL || src->sh == NULL)
return;
//printf("IPOnlyMatchPacket looking up dst...\n");
/* lookup source address group */
dst = IPOnlyLookupDst16(de_ctx, io_tctx, p);
if (dst == NULL || dst->sh == NULL)
return;
//printf("IPOnlyMatchPacket processing arrays...\n");
/* copy the match array from source... */
u_int32_t u;
for (u = 0; u < io_tctx->sig_match_size; u++) {
io_tctx->sig_match_array[u] = src->sh->sig_array[u];
}
/* ...then bitwise AND it with the dst... */
for (u = 0; u < io_tctx->sig_match_size; u++) {
io_tctx->sig_match_array[u] &= dst->sh->sig_array[u];
}
//printf("Let's inspect the sigs\n");
u_int32_t sig_cnt;
if (src->sh->sig_cnt > dst->sh->sig_cnt) sig_cnt = dst->sh->sig_cnt;
else sig_cnt = src->sh->sig_cnt;
/* ...the result is that only the sigs with both
* enable match */
u_int32_t idx;
for (idx = 0; idx < sig_cnt; idx++) {
u_int32_t sig = io_ctx->match_array[idx];
//printf("sig internal id %u\n", sig);
/* sig doesn't match */
if (!(io_tctx->sig_match_array[(sig / 8)] & (1<<(sig % 8))))
continue;
Signature *s = de_ctx->sig_array[sig];
if (s == NULL)
continue;
/* check the source address */
if (!(s->flags & SIG_FLAG_SRC_ANY)) {
DetectAddressGroup *saddr = DetectAddressLookupGroup(&s->src,&p->src);
if (saddr == NULL)
continue;
}
/* check the destination address */
if (!(s->flags & SIG_FLAG_DST_ANY)) {
DetectAddressGroup *daddr = DetectAddressLookupGroup(&s->dst,&p->dst);
if (daddr == NULL)
continue;
}
if (!(s->flags & SIG_FLAG_NOALERT)) {
PacketAlertAppend(p, 1, s->id, s->rev, s->prio, s->msg);
/* set verdict on packet */
p->action = s->action;
}
}
}
int IPOnlyBuildMatchArray(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ctx) {
u_int32_t idx = 0;
u_int32_t sig = 0;
for (sig = 0; sig < io_ctx->max_idx + 1; sig++) {
if (!(io_ctx->sig_init_array[(sig/8)] & (1<<(sig%8))))
continue;
Signature *s = de_ctx->sig_array[sig];
if (s == NULL)
continue;
io_ctx->sig_cnt++;
}
io_ctx->match_array = malloc(io_ctx->sig_cnt * sizeof(u_int32_t));
if (io_ctx->match_array == NULL)
return -1;
memset(io_ctx->match_array,0, io_ctx->sig_cnt * sizeof(u_int32_t));
for (sig = 0; sig < io_ctx->max_idx + 1; sig++) {
if (!(io_ctx->sig_init_array[(sig/8)] & (1<<(sig%8))))
continue;
Signature *s = de_ctx->sig_array[sig];
if (s == NULL)
continue;
io_ctx->match_array[idx] = s->num;
idx++;
}
return 0;
}
void IPOnlyPrepare(DetectEngineCtx *de_ctx) {
IPOnlyBuildMatchArray(de_ctx, &de_ctx->io_ctx);
/* source: set sig_cnt */
HashListTableBucket *hb = HashListTableGetListHead(de_ctx->io_ctx.ht16_src);
if (hb == NULL)
return;
for ( ; hb != NULL; hb = HashListTableGetListNext(hb)) {
DetectAddressGroup *gr = (DetectAddressGroup *)HashListTableGetListData(hb);
if (gr == NULL)
continue;
SigGroupHeadSetSigCnt(gr->sh, de_ctx->io_ctx.max_idx);
}
/* destination: set sig_cnt */
hb = HashListTableGetListHead(de_ctx->io_ctx.ht16_dst);
if (hb == NULL)
return;
for ( ; hb != NULL; hb = HashListTableGetListNext(hb)) {
DetectAddressGroup *gr = (DetectAddressGroup *)HashListTableGetListData(hb);
if (gr == NULL)
continue;
SigGroupHeadSetSigCnt(gr->sh, de_ctx->io_ctx.max_idx);
}
}
void IPOnlyAddSignature(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ctx, Signature *s) {
if (!(s->flags & SIG_FLAG_IPONLY))
return;
DetectAddressGroup *src = s->src.ipv4_head;
DetectAddressGroup *dst = s->dst.ipv4_head;
for ( ; src != NULL; src = src->next) {
IPOnlyAddSlash16(de_ctx, io_ctx, io_ctx->ht16_src, src, 0, s);
// IPOnlyAddSlash24(de_ctx, io_ctx, io_ctx->ht24_src, src, 0, s);
}
for ( ; dst != NULL; dst = dst->next) {
IPOnlyAddSlash16(de_ctx, io_ctx, io_ctx->ht16_dst, dst, 1, s);
// IPOnlyAddSlash24(de_ctx, io_ctx, io_ctx->ht24_dst, dst, 1, s);
}
if (s->num > io_ctx->max_idx)
io_ctx->max_idx = s->num;
/* enable the sig in the bitarray */
io_ctx->sig_init_array[(s->num/8)] |= 1<<(s->num%8);
}

@ -0,0 +1,13 @@
#ifndef __DETECT_ENGINE_IPONLY_H__
#define __DETECT_ENGINE_IPONLY_H__
void IPOnlyMatchPacket(DetectEngineCtx *, DetectEngineIPOnlyCtx *, DetectEngineIPOnlyThreadCtx *, Packet *);
void IPOnlyInit(DetectEngineCtx *, DetectEngineIPOnlyCtx *);
void IPOnlyPrint(DetectEngineCtx *, DetectEngineIPOnlyCtx *);
void IPOnlyDeinit(DetectEngineCtx *, DetectEngineIPOnlyCtx *);
void IPOnlyPrepare(DetectEngineCtx *);
void DetectEngineIPOnlyThreadInit(DetectEngineCtx *, DetectEngineIPOnlyThreadCtx *);
void IPOnlyAddSignature(DetectEngineCtx *, DetectEngineIPOnlyCtx *, Signature *);
#endif /* __DETECT_ENGINE_IPONLY_H__ */

@ -27,7 +27,7 @@ u_int32_t PacketPatternScan(ThreadVars *t, PatternMatcherThread *pmt, Packet *p)
u_int32_t ret;
pmt->pmq.mode = PMQ_MODE_SCAN;
ret = pmt->sgh->mpm_ctx->Scan(pmt->sgh->mpm_ctx, &pmt->mtc, &pmt->pmq, p->tcp_payload, p->tcp_payload_len);
ret = pmt->sgh->mpm_ctx->Scan(pmt->sgh->mpm_ctx, &pmt->mtc, &pmt->pmq, p->payload, p->payload_len);
//printf("PacketPatternScan: ret %u\n", ret);
return ret;
@ -37,7 +37,7 @@ u_int32_t PacketPatternMatch(ThreadVars *t, PatternMatcherThread *pmt, Packet *p
u_int32_t ret;
pmt->pmq.mode = PMQ_MODE_SEARCH;
ret = pmt->sgh->mpm_ctx->Search(pmt->sgh->mpm_ctx, &pmt->mtc, &pmt->pmq, p->tcp_payload, p->tcp_payload_len);
ret = pmt->sgh->mpm_ctx->Search(pmt->sgh->mpm_ctx, &pmt->mtc, &pmt->pmq, p->payload, p->payload_len);
//printf("PacketPatternMatch: ret %u\n", ret);
return ret;
@ -101,14 +101,21 @@ void PatternMatchDestroyGroup(SigGroupHead *sh) {
}
}
static int g_content_scan = 0;
static int g_uricontent_scan = 0;
static int g_content_search = 0;
static int g_uricontent_search = 0;
static int g_content_maxdepth = 0;
static int g_content_minoffset = 0;
static int g_content_total = 0;
static int g_content_maxlen = 0;
static int g_content_sigcnt = 0;
static int g_content_sigcnt1 = 0;
static int g_content_sigcnt2 = 0;
static int g_content_sigcnt3 = 0;
static int g_content_sigcnt4 = 0;
static int g_content_sigcnt5 = 0;
static int g_content_sigcnt10= 0;
void DbgPrintScanSearchStats() {
#if 0
printf(" - MPM: scan %d, search %d (%02.1f%%) :\n", g_content_scan, g_content_search,
@ -117,9 +124,335 @@ void DbgPrintScanSearchStats() {
(float)(g_content_maxdepth/(float)(g_content_total))*100);
printf(" - MPM: minoffset %d, total %d (%02.1f%%) :\n", g_content_minoffset, g_content_total,
(float)(g_content_minoffset/(float)(g_content_total))*100);
printf(" - MPM: avg maxlen %02.1f (%u/%u)\n", (float)((float)g_content_maxlen/(float)(g_content_sigcnt)), g_content_maxlen, g_content_sigcnt);
printf(" - MPM: 1 len %u (%02.1f%%)\n", g_content_sigcnt1, (float)(g_content_sigcnt1/(float)(g_content_sigcnt))*100);
printf(" - MPM: 2 len %u (%02.1f%%)\n", g_content_sigcnt2, (float)(g_content_sigcnt2/(float)(g_content_sigcnt))*100);
printf(" - MPM: 3 len %u (%02.1f%%)\n", g_content_sigcnt3, (float)(g_content_sigcnt3/(float)(g_content_sigcnt))*100);
printf(" - MPM: 4 len %u (%02.1f%%)\n", g_content_sigcnt4, (float)(g_content_sigcnt4/(float)(g_content_sigcnt))*100);
printf(" - MPM: 5+len %u (%02.1f%%)\n", g_content_sigcnt5, (float)(g_content_sigcnt5/(float)(g_content_sigcnt))*100);
printf(" - MPM: 10+ln %u (%02.1f%%)\n", g_content_sigcnt10,(float)(g_content_sigcnt10/(float)(g_content_sigcnt))*100);
#endif
}
/* set the mpm_content_maxlen and mpm_uricontent_maxlen variables in
* a sig group head */
void SigGroupHeadSetMpmMaxlen(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
{
SigMatch *sm;
u_int32_t sig;
sgh->mpm_content_maxlen = 0;
sgh->mpm_uricontent_maxlen = 0;
/* for each signature in this group do */
for (sig = 0; sig < DetectEngineGetMaxSigId(de_ctx); sig++) {
if (!(sgh->sig_array[(sig/8)] & (1<<(sig%8))))
continue;
Signature *s = de_ctx->sig_array[sig];
if (s == NULL)
continue;
if (!(s->flags & SIG_FLAG_MPM))
continue;
u_int16_t content_maxlen = 0, uricontent_maxlen = 0;
/* determine the length of the longest pattern */
for (sm = s->match; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_CONTENT && !(sgh->flags & SIG_GROUP_HEAD_MPM_COPY)) {
DetectContentData *cd = (DetectContentData *)sm->ctx;
if (cd->content_len > content_maxlen)
content_maxlen = cd->content_len;
} else if (sm->type == DETECT_URICONTENT && !(sgh->flags & SIG_GROUP_HEAD_MPM_URI_COPY)) {
DetectUricontentData *ud = (DetectUricontentData *)sm->ctx;
if (ud->uricontent_len > uricontent_maxlen)
uricontent_maxlen = ud->uricontent_len;
}
}
if (sgh->mpm_content_maxlen == 0) sgh->mpm_content_maxlen = content_maxlen;
if (sgh->mpm_content_maxlen > content_maxlen)
sgh->mpm_content_maxlen = content_maxlen;
if (sgh->mpm_uricontent_maxlen == 0) sgh->mpm_uricontent_maxlen = uricontent_maxlen;
if (sgh->mpm_uricontent_maxlen > uricontent_maxlen)
sgh->mpm_uricontent_maxlen = uricontent_maxlen;
}
}
typedef struct _ContentHash {
DetectContentData *ptr;
u_int16_t cnt;
u_int8_t use; /* use no matter what */
u_int8_t nosearch; /* single match, no search after
* scan match (for this pattern) */
} ContentHash;
u_int32_t ContentHashFunc(HashTable *ht, void *data, u_int16_t datalen) {
ContentHash *ch = (ContentHash *)data;
DetectContentData *co = ch->ptr;
u_int32_t hash = 0;
int i;
for (i = 0; i < co->content_len; i++) {
hash += co->content[i];
}
hash = hash % ht->array_size;
//printf("hash %u\n", hash);
return hash;
}
char ContentHashCompareFunc(void *data1, u_int16_t len1, void *data2, u_int16_t len2) {
ContentHash *ch1 = (ContentHash *)data1;
ContentHash *ch2 = (ContentHash *)data2;
DetectContentData *co1 = ch1->ptr;
DetectContentData *co2 = ch2->ptr;
if (co1->content_len == co2->content_len &&
memcmp(co1->content, co2->content, co1->content_len) == 0)
return 1;
return 0;
}
ContentHash *ContentHashAlloc(DetectContentData *ptr) {
ContentHash *ch = malloc(sizeof(ContentHash));
if (ch == NULL)
return NULL;
ch->ptr = ptr;
ch->cnt = 1;
ch->use = 0;
ch->nosearch = 0;
return ch;
}
void ContentHashFree(void *ch) {
free(ch);
}
/* Predict a strength value for patterns
*
*/
u_int32_t PatternStrength(u_int8_t *pat, u_int16_t patlen, u_int16_t len) {
u_int8_t a[256];
memset(&a,0,sizeof(a));
u_int32_t s = 0;
u_int16_t u = 0;
for (u = 0; u < patlen; u++) {
if (a[pat[u]] == 0) {
if (isalpha(pat[u]))
s+=3;
else if (isprint(pat[u]) || pat[u] == 0x00 || pat[u] == 0x01 || pat[u] == 0xFF)
s+=4;
else
s+=6;//5
a[pat[u]] = 1;
} else {
s++;
}
}
return s;
}
int PatternMatchPreprarePopulateMpm(DetectEngineCtx *de_ctx, SigGroupHead *sgh) {
u_int32_t sig;
HashTable *ht = HashTableInit(4096, ContentHashFunc, ContentHashCompareFunc, ContentHashFree);
if (ht == NULL)
return -1;
/* add all the contents to a counting hash */
for (sig = 0; sig < sgh->sig_cnt; sig++) {
u_int32_t num = sgh->match_array[sig];
Signature *s = de_ctx->sig_array[num];
if (s == NULL)
continue;
int cnt = 0;
SigMatch *sm;
for (sm = s->match; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_CONTENT) {
DetectContentData *co = (DetectContentData *)sm->ctx;
if (co == NULL)
continue;
cnt++;
}
}
for (sm = s->match; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_CONTENT) {
DetectContentData *co = (DetectContentData *)sm->ctx;
if (co == NULL)
continue;
if (co->content_len < sgh->mpm_content_maxlen)
continue;
ContentHash *ch = ContentHashAlloc(co);
if (ch == NULL)
goto error;
if (cnt == 1) {
ch->nosearch = 1;
ch->use = 1;
}
ContentHash *lookup_ch = (ContentHash *)HashTableLookup(ht, ch, 0);
if (lookup_ch == NULL) {
int r = HashTableAdd(ht, ch, 0);
if (r < 0) printf("Add hash failed\n");
} else {
/* at least one sig relies soly on this content
* so flag that we will use this content no matter
* what. */
if (cnt == 1) {
lookup_ch->use = 1;
}
/* only set the nosearch flag if all sigs have it
* as their sole pattern */
if (ch->nosearch == 0)
lookup_ch->nosearch = 0;
lookup_ch->cnt++;
ContentHashFree(ch);
}
}
}
}
/* now determine which one to add to the scan phase */
for (sig = 0; sig < sgh->sig_cnt; sig++) {
u_int32_t num = sgh->match_array[sig];
Signature *s = de_ctx->sig_array[num];
if (s == NULL)
continue;
ContentHash *scan_ch = NULL;
SigMatch *sm = s->match;
for ( ; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_CONTENT) {
DetectContentData *co = (DetectContentData *)sm->ctx;
if (co == NULL)
continue;
if (co->content_len < sgh->mpm_content_maxlen)
continue;
ContentHash *ch = ContentHashAlloc(co);
if (ch == NULL)
goto error;
//if (s->id == 2002102) {
//printf("%p %u Content: ", sgh, s->id); PrintRawUriFp(stdout,co->content,co->content_len);printf(" (strength %u, maxlen %u)\n", PatternStrength(co->content,co->content_len,sgh->mpm_content_maxlen), sgh->mpm_content_maxlen);
//}
ContentHash *lookup_ch = (ContentHash *)HashTableLookup(ht, ch, 0);
if (lookup_ch == NULL) {
continue;
}
if (scan_ch == NULL) {
scan_ch = lookup_ch;
} else {
if (lookup_ch->use == 0) {
u_int32_t ls = PatternStrength(lookup_ch->ptr->content,lookup_ch->ptr->content_len,sgh->mpm_content_maxlen);
u_int32_t ss = PatternStrength(scan_ch->ptr->content,scan_ch->ptr->content_len,sgh->mpm_content_maxlen);
if (ls > ss)
scan_ch = lookup_ch;
else if (ls == ss) {
if (lookup_ch->ptr->content_len > scan_ch->ptr->content_len)
scan_ch = lookup_ch;
}
// if (lookup_ch->cnt > scan_ch->cnt) {
// scan_ch = lookup_ch;
// } else if (lookup_ch->cnt == scan_ch->cnt) {
// if (lookup_ch->ptr->content_len < scan_ch->ptr->content_len)
// scan_ch = lookup_ch;
// }
} else {
if (scan_ch->use == 0)
scan_ch = lookup_ch;
else {
u_int32_t ls = PatternStrength(lookup_ch->ptr->content,lookup_ch->ptr->content_len,sgh->mpm_content_maxlen);
u_int32_t ss = PatternStrength(scan_ch->ptr->content,scan_ch->ptr->content_len,sgh->mpm_content_maxlen);
if (ls > ss)
scan_ch = lookup_ch;
else if (ls == ss) {
if (lookup_ch->ptr->content_len > scan_ch->ptr->content_len)
scan_ch = lookup_ch;
}
/*
if (lookup_ch->cnt > scan_ch->cnt) {
scan_ch = lookup_ch;
} else if (lookup_ch->cnt == scan_ch->cnt) {
if (lookup_ch->ptr->content_len < scan_ch->ptr->content_len)
scan_ch = lookup_ch;
}
*/
}
}
}
ContentHashFree(ch);
}
}
/* now add the scan_ch to the mpm ctx */
if (scan_ch != NULL) {
DetectContentData *co = scan_ch->ptr;
//if (s->id == 2002102) {
//if (sgh->mpm_content_maxlen == 1) {
//printf("%p %u SCAN: ", sgh, s->id); PrintRawUriFp(stdout,co->content,co->content_len);printf("\n");
//}
//if (scan_ch->nosearch == 1) { printf("%3u (%u) Content: ", scan_ch->cnt, scan_ch->use); PrintRawUriFp(stdout,co->content,co->content_len);printf("\n"); }
u_int16_t offset = s->flags & SIG_FLAG_RECURSIVE ? 0 : co->offset;
u_int16_t depth = s->flags & SIG_FLAG_RECURSIVE ? 0 : co->depth;
offset = scan_ch->cnt ? 0 : offset;
depth = scan_ch->cnt ? 0 : depth;
if (co->flags & DETECT_CONTENT_NOCASE) {
sgh->mpm_ctx->AddScanPatternNocase(sgh->mpm_ctx, co->content, co->content_len, offset, depth, co->id, s->num, scan_ch->nosearch);
} else {
sgh->mpm_ctx->AddScanPattern(sgh->mpm_ctx, co->content, co->content_len, offset, depth, co->id, s->num, scan_ch->nosearch);
}
}
/* add the rest of the patterns to the search ctx */
for (sm = s->match ; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_CONTENT) {
DetectContentData *co = (DetectContentData *)sm->ctx;
if (co == NULL)
continue;
/* skip the one we already added */
if (scan_ch != NULL && co == scan_ch->ptr)
continue;
u_int16_t offset = s->flags & SIG_FLAG_RECURSIVE ? 0 : co->offset;
u_int16_t depth = s->flags & SIG_FLAG_RECURSIVE ? 0 : co->depth;
if (co->flags & DETECT_CONTENT_NOCASE) {
sgh->mpm_ctx->AddPatternNocase(sgh->mpm_ctx, co->content, co->content_len, offset, depth, co->id, s->num);
} else {
sgh->mpm_ctx->AddPattern(sgh->mpm_ctx, co->content, co->content_len, offset, depth, co->id, s->num);
}
}
}
}
HashTableFree(ht);
return 0;
error:
if (ht != NULL)
HashTableFree(ht);
return -1;
}
/*
*
* TODO
@ -132,11 +465,20 @@ void DbgPrintScanSearchStats() {
int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
{
Signature *s;
SigMatch *sm;
u_int32_t co_cnt = 0;
u_int32_t ur_cnt = 0;
u_int32_t cnt = 0;
u_int32_t sig;
g_content_sigcnt++;
if (!(sh->flags & SIG_GROUP_HEAD_MPM_COPY))
sh->mpm_content_maxlen = 0;
if (!(sh->flags & SIG_GROUP_HEAD_MPM_URI_COPY))
sh->mpm_uricontent_maxlen = 0;
/* see if this head has content and/or uricontent */
for (sig = 0; sig < sh->sig_cnt; sig++) {
u_int32_t num = sh->match_array[sig];
@ -146,8 +488,6 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
continue;
/* find flow setting of this rule */
SigMatch *sm;
for (sm = s->match; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_CONTENT) {
co_cnt++;
@ -200,6 +540,7 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
cnt++;
char content_added = 0;
u_int16_t content_maxlen = 0, uricontent_maxlen = 0;
u_int16_t content_minlen = 0, uricontent_minlen = 0;
u_int16_t content_cnt = 0, uricontent_cnt = 0;
@ -213,6 +554,7 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
for (sm = s->match; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_CONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_COPY)) {
DetectContentData *cd = (DetectContentData *)sm->ctx;
if (cd->content_len > content_maxlen)
content_maxlen = cd->content_len;
@ -222,6 +564,10 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
mpm_content_cnt++;
content_cnt++;
if (!content_added) {
content_added = 1;
}
} else if (sm->type == DETECT_URICONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_URI_COPY)) {
DetectUricontentData *ud = (DetectUricontentData *)sm->ctx;
if (ud->uricontent_len > uricontent_maxlen)
@ -240,6 +586,9 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
for (sm = s->match; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_CONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_COPY)) {
DetectContentData *cd = (DetectContentData *)sm->ctx;
//if (content_maxlen < 4) {
//printf("\""); PrintRawUriFp(stdout,cd->content,cd->content_len); printf("\" ");
//}
if (cd->content_len == content_maxlen) {
if (content_maxdepth > cd->depth)
content_maxdepth = cd->depth;
@ -253,6 +602,7 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
}
}
}
//if (content_maxlen < 4 && content_cnt) printf(" (%u, min %u, max %u)\n", content_cnt, content_minlen, content_maxlen);
int content_depth_atleastone = 0;
int content_offset_atleastone = 0;
@ -320,37 +670,68 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
if (sh->mpm_uricontent_maxlen > uricontent_maxlen)
sh->mpm_uricontent_maxlen = uricontent_maxlen;
}
}
char content_scanadded = 0, uricontent_scanadded = 0;
g_content_maxlen += sh->mpm_content_maxlen;
if (sh->mpm_content_maxlen == 1) g_content_sigcnt1++;
if (sh->mpm_content_maxlen == 2) g_content_sigcnt2++;
if (sh->mpm_content_maxlen == 3) g_content_sigcnt3++;
if (sh->mpm_content_maxlen == 4) g_content_sigcnt4++;
if (sh->mpm_content_maxlen >= 5) g_content_sigcnt5++;
if (sh->mpm_content_maxlen >= 10) g_content_sigcnt10++;
/* see if we will use the scanning phase */
// if (sh->mpm_content_maxlen == 1) {
// sh->flags |= SIG_GROUP_HEAD_MPM_NOSCAN;
// printf("(%p) noscan set (%s)\n", sh, sh->flags & SIG_GROUP_HEAD_MPM_NOSCAN ? "TRUE":"FALSE");
// }
// if (sh->mpm_uricontent_maxlen < 4) sh->flags |= SIG_GROUP_HEAD_MPM_URI_NOSCAN;
/* add the signatures */
for (sig = 0; sig < sh->sig_cnt; sig++) {
u_int32_t num = sh->match_array[sig];
s = de_ctx->sig_array[num];
if (s == NULL)
continue;
u_int16_t content_maxlen = 0, uricontent_maxlen = 0;
u_int16_t content_minlen = 0, uricontent_minlen = 0;
/* determine the length of the longest pattern */
for (sm = s->match; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_CONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_COPY)) {
DetectContentData *cd = (DetectContentData *)sm->ctx;
u_int16_t offset = s->flags & SIG_FLAG_RECURSIVE ? 0 : cd->offset;
u_int16_t depth = s->flags & SIG_FLAG_RECURSIVE ? 0 : cd->depth;
if (cd->content_len > content_maxlen)
content_maxlen = cd->content_len;
if (!content_scanadded && content_maxlen == cd->content_len) {
if (cd->flags & DETECT_CONTENT_NOCASE) {
sh->mpm_ctx->AddScanPatternNocase(sh->mpm_ctx, cd->content, cd->content_len, offset, depth, cd->id, s->num);
} else {
sh->mpm_ctx->AddScanPattern(sh->mpm_ctx, cd->content, cd->content_len, offset, depth, cd->id, s->num);
}
content_scanadded = 1;
} else {
if (cd->flags & DETECT_CONTENT_NOCASE) {
sh->mpm_ctx->AddPatternNocase(sh->mpm_ctx, cd->content, cd->content_len, offset, depth, cd->id, s->num);
} else {
sh->mpm_ctx->AddPattern(sh->mpm_ctx, cd->content, cd->content_len, offset, depth, cd->id, s->num);
}
}
if (content_minlen == 0) content_minlen = cd->content_len;
else if (cd->content_len < content_minlen)
content_minlen = cd->content_len;
} else if (sm->type == DETECT_URICONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_URI_COPY)) {
DetectUricontentData *ud = (DetectUricontentData *)sm->ctx;
if (ud->uricontent_len > uricontent_maxlen)
uricontent_maxlen = ud->uricontent_len;
if (!uricontent_scanadded && uricontent_maxlen == ud->uricontent_len) {
if (uricontent_minlen == 0) uricontent_minlen = ud->uricontent_len;
else if (ud->uricontent_len < uricontent_minlen)
uricontent_minlen = ud->uricontent_len;
}
}
char content_scanadded = 0, uricontent_scanadded = 0;
for (sm = s->match; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_URICONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_URI_COPY)) {
DetectUricontentData *ud = (DetectUricontentData *)sm->ctx;
/* only add the pattern if:
* noscan is not set, we didn't add a pattern already, length
* is the same as maxlen (ie we only add the longest pattern) */
if (!(sh->flags & SIG_GROUP_HEAD_MPM_URI_NOSCAN) && !uricontent_scanadded && uricontent_maxlen == ud->uricontent_len) {
if (ud->flags & DETECT_URICONTENT_NOCASE) {
sh->mpm_uri_ctx->AddScanPatternNocase(sh->mpm_uri_ctx, ud->uricontent, ud->uricontent_len, 0, 0, ud->id, s->num);
sh->mpm_uri_ctx->AddScanPatternNocase(sh->mpm_uri_ctx, ud->uricontent, ud->uricontent_len, 0, 0, ud->id, s->num, 0);
} else {
sh->mpm_uri_ctx->AddScanPattern(sh->mpm_uri_ctx, ud->uricontent, ud->uricontent_len, 0, 0, ud->id, s->num);
sh->mpm_uri_ctx->AddScanPattern(sh->mpm_uri_ctx, ud->uricontent, ud->uricontent_len, 0, 0, ud->id, s->num, 0);
}
uricontent_scanadded = 1;
} else {
@ -369,19 +750,12 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
/* content */
if (sh->flags & SIG_GROUP_HAVECONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_COPY)) {
/* search ctx */
PatternMatchPreprarePopulateMpm(de_ctx, sh);
if (sh->mpm_ctx->Prepare != NULL) {
sh->mpm_ctx->Prepare(sh->mpm_ctx);
}
if (mpm_content_cnt && sh->mpm_content_maxlen > 1) {
//printf("mpm_content_cnt %u, mpm_content_maxlen %d\n", mpm_content_cnt, mpm_content_maxlen);
g_content_scan++;
} else {
g_content_search++;
}
//printf("(sh %p) mpm_content_cnt %u, mpm_content_maxlen %u, mpm_content_scan_maxlen %u\n", sh, mpm_content_cnt, sh->mpm_content_maxlen, mpm_content_scan_maxlen);
if (mpm_content_maxdepth) {
// printf("mpm_content_maxdepth %u\n", mpm_content_maxdepth);
g_content_maxdepth++;
@ -392,8 +766,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
}
g_content_total++;
// if (mpm_content_depth_present) printf("(sh %p) at least one depth: %d, depth %u\n", sh, mpm_content_depth_present, mpm_content_maxdepth_one);
// if (mpm_content_offset_present) printf("(sh %p) at least one offset: %d, offset %u\n", sh, mpm_content_offset_present, mpm_content_minoffset_one);
//if (mpm_content_depth_present) printf("(sh %p) at least one depth: %d, depth %u\n", sh, mpm_content_depth_present, mpm_content_maxdepth_one);
//if (mpm_content_offset_present) printf("(sh %p) at least one offset: %d, offset %u\n", sh, mpm_content_offset_present, mpm_content_minoffset_one);
//sh->mpm_ctx->PrintCtx(sh->mpm_ctx);
}

@ -17,5 +17,7 @@ void PatternMatchDestroyGroup(SigGroupHead *);
int PatternMatcherThreadInit(ThreadVars *, void *, void **);
int PatternMatcherThreadDeinit(ThreadVars *, void *);
void SigGroupHeadSetMpmMaxlen(DetectEngineCtx *, SigGroupHead *);
#endif /* __DETECT_MPM_H__ */

@ -655,6 +655,8 @@ int SigGroupHeadClearUricontent(SigGroupHead *sh) {
return 0;
}
/* Create an array with all the internal id's of the sigs
* that this sig group head will check for. */
int SigGroupHeadBuildMatchArray (DetectEngineCtx *de_ctx, SigGroupHead *sgh, u_int32_t max_idx) {
u_int32_t idx = 0;
u_int32_t sig = 0;
@ -662,6 +664,10 @@ int SigGroupHeadBuildMatchArray (DetectEngineCtx *de_ctx, SigGroupHead *sgh, u_i
if (sgh == NULL)
return 0;
/* XXX ugly */
if (sgh->match_array == NULL)
free(sgh->match_array);
sgh->match_array = malloc(sgh->sig_cnt * sizeof(u_int32_t));
if (sgh->match_array == NULL)
return -1;
@ -686,3 +692,23 @@ int SigGroupHeadBuildMatchArray (DetectEngineCtx *de_ctx, SigGroupHead *sgh, u_i
return 0;
}
int SigGroupHeadContainsSigId (DetectEngineCtx *de_ctx, SigGroupHead *sgh, u_int32_t sid) {
u_int32_t sig = 0;
if (sgh == NULL)
return 0;
for (sig = 0; sig < sgh->sig_cnt; sig++) {
if (!(sgh->sig_array[(sig/8)] & (1<<(sig%8))))
continue;
Signature *s = de_ctx->sig_array[sig];
if (s == NULL)
continue;
if (s->id == sid)
return 1;
}
return 0;
}

@ -236,6 +236,7 @@ int SigParseAddress(Signature *s, const char *addrstr, char flag) {
if (strcmp(addrstr,"$HOME_NET") == 0) {
addr = "[192.168.0.0/16,10.8.0.0/16,127.0.0.1,2001:888:13c5:5AFE::/64,2001:888:13c5:CAFE::/64]";
// addr = "[192.168.0.0/16,10.8.0.0/16,2001:888:13c5:5AFE::/64,2001:888:13c5:CAFE::/64]";
} else if (strcmp(addrstr,"$EXTERNAL_NET") == 0) {
addr = "[!192.168.0.0/16,2000::/3]";
} else if (strcmp(addrstr,"$HTTP_SERVERS") == 0) {

@ -84,21 +84,21 @@ int DetectPcreMatch (ThreadVars *t, PatternMatcherThread *pmt, Packet *p, Signat
u_int8_t *ptr = NULL;
u_int16_t len = 0;
if (p->tcp_payload_len == 0)
if (p->payload_len == 0)
return 0;
DetectPcreData *pe = (DetectPcreData *)m->ctx;
if (s->flags & SIG_FLAG_RECURSIVE) {
ptr = pmt->pkt_ptr ? pmt->pkt_ptr : p->tcp_payload;
len = p->tcp_payload_len - pmt->pkt_off;
ptr = pmt->pkt_ptr ? pmt->pkt_ptr : p->payload;
len = p->payload_len - pmt->pkt_off;
} else if (pe->flags & DETECT_PCRE_RELATIVE) {
ptr = pmt->pkt_ptr;
len = p->tcp_payload_len - pmt->pkt_off;
len = p->payload_len - pmt->pkt_off;
if (ptr == NULL || len == 0)
return 0;
} else {
ptr = p->tcp_payload;
len = p->tcp_payload_len;
ptr = p->payload;
len = p->payload_len;
}
//printf("DetectPcre: ptr %p, len %u\n", ptr, len);
@ -161,7 +161,7 @@ int DetectPcreMatch (ThreadVars *t, PatternMatcherThread *pmt, Packet *p, Signat
/* update ptrs for pcre RELATIVE */
pmt->pkt_ptr = ptr+ov[1];
pmt->pkt_off = (ptr+ov[1]) - p->tcp_payload;
pmt->pkt_off = (ptr+ov[1]) - p->payload;
//printf("DetectPcre: post match: t->pkt_ptr %p t->pkt_off %u\n", t->pkt_ptr, t->pkt_off);
ret = 1;

@ -175,7 +175,7 @@ DoDetectUricontent(ThreadVars *t, PatternMatcherThread *pmt, Packet *p, SigMatch
if (ret == 1) {
/* update pkt ptrs, content doesn't use this,
* but pcre does */
pmt->pkt_ptr = p->tcp_payload + m->offset;
pmt->pkt_ptr = p->payload + m->offset;
pmt->pkt_off = m->offset;
match = 1;
break;
@ -206,7 +206,7 @@ DoDetectUricontent(ThreadVars *t, PatternMatcherThread *pmt, Packet *p, SigMatch
if (ret == 1) {
/* update pkt ptrs, content doesn't use this,
* but pcre does */
pmt->pkt_ptr = p->tcp_payload + m->offset;
pmt->pkt_ptr = p->payload + m->offset;
pmt->pkt_off = m->offset;
match = 1;
break;
@ -367,6 +367,8 @@ int DetectUricontentSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, c
cd->id = de_ctx->uricontent_max_id;
de_ctx->uricontent_max_id++;
s->flags |= SIG_FLAG_MPM;
if (dubbed) free(str);
return 0;

File diff suppressed because it is too large Load Diff

@ -28,6 +28,7 @@ enum {
#define ADDRESS_GROUP_SIGGROUPHEAD_COPY 0x01
#define ADDRESS_GROUP_PORTS_COPY 0x02
#define ADDRESS_GROUP_PORTS_NOTUNIQ 0x04
#define ADDRESS_GROUP_HAVEPORT 0x08
typedef struct DetectAddressData_ {
/* XXX convert to use a Address datatype to replace family, ip,ip2*/
@ -42,9 +43,10 @@ typedef struct DetectAddressGroup_ {
DetectAddressData *ad;
/* XXX ptr to rules, or PortGroup or whatever */
union {
struct DetectAddressGroupsHead_ *dst_gh;
struct DetectPort_ *port;
};
/* signatures that belong in this group */
struct _SigGroupHead *sh;
u_int8_t flags;
@ -105,8 +107,6 @@ typedef struct DetectPort_ {
u_int32_t cnt;
} DetectPort;
/* Signature flags */
#define SIG_FLAG_RECURSIVE 0x0001 /* recurive capturing enabled */
#define SIG_FLAG_SRC_ANY 0x0002 /* source is any */
@ -120,6 +120,12 @@ typedef struct DetectPort_ {
/* Detection Engine flags */
#define DE_QUIET 0x01 /* DE is quiet (esp for unittests) */
typedef struct DetectEngineIPOnlyThreadCtx_ {
DetectAddressGroup *src, *dst;
u_int8_t *sig_match_array; /* bit array of sig nums */
u_int32_t sig_match_size; /* size in bytes of the array */
} DetectEngineIPOnlyThreadCtx;
typedef struct _PatternMatcherThread {
/* detection engine variables */
u_int8_t *pkt_ptr; /* ptr to the current position in the pkt */
@ -164,6 +170,8 @@ typedef struct _PatternMatcherThread {
u_int32_t pkts_uri_scanned4;
u_int32_t pkts_uri_searched4;
DetectEngineIPOnlyThreadCtx io_ctx;
} PatternMatcherThread;
typedef struct _Signature {
@ -184,6 +192,48 @@ typedef struct _Signature {
struct _Signature *next;
} Signature;
typedef struct DetectEngineIPOnlyCtx_ {
/* lookup hashes */
HashListTable *ht16_src, *ht16_dst;
HashListTable *ht24_src, *ht24_dst;
/* counters */
u_int32_t a_src_uniq16, a_src_total16;
u_int32_t a_dst_uniq16, a_dst_total16;
u_int32_t a_src_uniq24, a_src_total24;
u_int32_t a_dst_uniq24, a_dst_total24;
u_int32_t max_idx;
u_int8_t *sig_init_array; /* bit array of sig nums */
u_int32_t sig_init_size; /* size in bytes of the array */
/* number of sigs in this head */
u_int32_t sig_cnt;
u_int32_t *match_array;
} DetectEngineIPOnlyCtx;
typedef struct DetectEngineLookupFlow_ {
DetectAddressGroupsHead *src_gh[256]; /* a head for each protocol */
DetectAddressGroupsHead *tmp_gh[256];
} DetectEngineLookupFlow;
/* Flow status
*
* to server
* to client
*/
#define FLOW_STATES 2
typedef struct DetectEngineLookupDsize_ {
DetectEngineLookupFlow flow_gh[FLOW_STATES];
} DetectEngineLookupDsize;
/* Dsize states
* <= 100
* >100
*/
#define DSIZE_STATES 2
typedef struct DetectEngineCtx_ {
u_int8_t flags;
@ -196,15 +246,10 @@ typedef struct DetectEngineCtx_ {
u_int32_t signum;
/* ip only sigs: we only add 'alert ip' without
* an ip_proto setting here, so no need to look
* at the proto */
DetectAddressGroupsHead *io_src_gh;
DetectAddressGroupsHead *io_tmp_gh;
/* main sigs */
DetectAddressGroupsHead *src_gh[256]; /* a head for each protocol */
DetectAddressGroupsHead *tmp_gh[256];
// DetectAddressGroupsHead *src_gh[256]; /* a head for each protocol */
// DetectAddressGroupsHead *tmp_gh[256];
DetectEngineLookupDsize dsize_gh[DSIZE_STATES];
u_int32_t mpm_unique, mpm_reuse, mpm_none,
mpm_uri_unique, mpm_uri_reuse, mpm_uri_none;
@ -231,30 +276,34 @@ typedef struct DetectEngineCtx_ {
/* memory counters */
u_int32_t mpm_memory_size;
DetectEngineIPOnlyCtx io_ctx;
} DetectEngineCtx;
typedef struct _SigMatch {
u_int8_t type;
void *ctx;
struct _SigMatch *prev;
struct _SigMatch *next;
struct _SigMatch *prev;
} SigMatch;
typedef struct SigTableElmt {
char *name;
u_int8_t cost; /* 0 hardly any, 255 very expensive */
int (*Match)(ThreadVars *, PatternMatcherThread *, Packet *, Signature *, SigMatch *);
int (*Setup)(DetectEngineCtx *, Signature *, SigMatch *, char *);
int (*Free)(SigMatch *);
void (*RegisterTests)(void);
u_int8_t flags;
char *name;
} SigTableElmt;
#define SIG_GROUP_HAVECONTENT 0x1
#define SIG_GROUP_HAVEURICONTENT 0x2
#define SIG_GROUP_HEAD_MPM_COPY 0x4
#define SIG_GROUP_HEAD_MPM_URI_COPY 0x8
#define SIG_GROUP_HEAD_FREE 0x10
#define SIG_GROUP_HAVECONTENT 0x1
#define SIG_GROUP_HAVEURICONTENT 0x2
#define SIG_GROUP_HEAD_MPM_COPY 0x4
#define SIG_GROUP_HEAD_MPM_URI_COPY 0x8
#define SIG_GROUP_HEAD_FREE 0x10
#define SIG_GROUP_HEAD_MPM_NOSCAN 0x20
#define SIG_GROUP_HEAD_MPM_URI_NOSCAN 0x40
/* head of the list of containers. */
typedef struct _SigGroupHead {
@ -288,9 +337,10 @@ typedef struct _SigGroupHead {
/* port ptr */
struct DetectPort_ *port;
struct _SigGroupHead *mpm_next; /* mpm and mpm_uri hash */
struct _SigGroupHead *mpm_uri_next; /* mpm and mpm_uri hash */
struct _SigGroupHead *next;
u_int16_t mpm_len1;
u_int16_t mpm_len2;
u_int16_t mpm_len3;
u_int16_t mpm_len4; /* 4+ */
} SigGroupHead;
#define SIGMATCH_NOOPT 0x01
@ -346,6 +396,7 @@ void TmModuleDetectRegister (void);
int SigGroupBuild(DetectEngineCtx *);
int SigGroupCleanup();
int PacketAlertAppend(Packet *, u_int8_t, u_int32_t, u_int8_t, u_int8_t, char *);
/*
* XXX globals, remove
*/

@ -7,10 +7,12 @@
#include "flow-queue.h"
/* per flow flags */
#define FLOW_TO_SRC_SEEN 0x01
#define FLOW_TO_DST_SEEN 0x02
#define FLOW_NEW_LIST 0x04
#define FLOW_EST_LIST 0x08
#define FLOW_TO_SRC_SEEN 0x01
#define FLOW_TO_DST_SEEN 0x02
#define FLOW_NEW_LIST 0x04
#define FLOW_EST_LIST 0x08
#define FLOW_TOSERVER_IPONLY_SET 0x10
#define FLOW_TOCLIENT_IPONLY_SET 0x20
/* global flow flags */
#define FLOW_EMERGENCY 0x01

@ -172,6 +172,14 @@ static int FlowUpdateSpareFlows(void) {
return 1;
}
/* Set the IPOnly scanned flag for 'direction'. This function
* handles the locking too. */
void FlowSetIPOnlyFlag(Flow *f, char direction) {
mutex_lock(&f->m);
direction ? (f->flags |= FLOW_TOSERVER_IPONLY_SET) : (f->flags |= FLOW_TOCLIENT_IPONLY_SET);
mutex_unlock(&f->m);
}
/* FlowHandlePacket
*
* This is called for every packet.
@ -205,6 +213,12 @@ void FlowHandlePacket (ThreadVars *th_v, Packet *p)
/* update queue positions */
FlowUpdateQueue(f);
/* set the iponly stuff */
if (f->flags & FLOW_TOCLIENT_IPONLY_SET)
p->flowflags |= FLOW_PKT_TOCLIENT_IPONLY_SET;
if (f->flags & FLOW_TOSERVER_IPONLY_SET)
p->flowflags |= FLOW_PKT_TOSERVER_IPONLY_SET;
/* set the flow in the packet */
p->flow = f;

@ -6,10 +6,12 @@
#include "decode.h"
/* pkt flow flags */
#define FLOW_PKT_TOSERVER 0x01
#define FLOW_PKT_TOCLIENT 0x02
#define FLOW_PKT_ESTABLISHED 0x04
#define FLOW_PKT_STATELESS 0x08
#define FLOW_PKT_TOSERVER 0x01
#define FLOW_PKT_TOCLIENT 0x02
#define FLOW_PKT_ESTABLISHED 0x04
#define FLOW_PKT_STATELESS 0x08
#define FLOW_PKT_TOSERVER_IPONLY_SET 0x10
#define FLOW_PKT_TOCLIENT_IPONLY_SET 0x20
/* global flow config */
typedef struct _FlowCnf
@ -70,10 +72,11 @@ typedef struct _Flow
struct _FlowBucket *fb;
} Flow;
void FlowHandlePacket (ThreadVars *th_v, Packet *p);
void FlowHandlePacket (ThreadVars *, Packet *);
void FlowInitConfig (void);
void FlowPrintFlows (void);
void FlowShutdown(void);
void FlowSetIPOnlyFlag(Flow *, char);
void *FlowManagerThread(void *td);

@ -71,7 +71,7 @@ int RejectSendLibnet11L3IPv4TCP(ThreadVars *tv, Packet *p, void *data, int dir)
return 1;
/* save payload len */
lpacket.dsize = p->tcp_payload_len;
lpacket.dsize = p->payload_len;
if (dir == REJECT_DIR_SRC) {
printf ("sending a tcp reset to src\n");
@ -170,7 +170,7 @@ int RejectSendLibnet11L3IPv4ICMP(ThreadVars *tv, Packet *p, void *data, int dir)
lpacket.flow = 0;
lpacket.class = 0;
lpacket.len = (IPV4_GET_HLEN(p) + p->tcp_payload_len);
lpacket.len = (IPV4_GET_HLEN(p) + p->payload_len);
if ((c = libnet_init (LIBNET_RAW4, NULL, ebuf)) == NULL){
printf("RejectSendLibnet11L3IPv4ICMP libnet_init %s\n", ebuf);
return 1;

@ -119,9 +119,6 @@ static int cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
Packet *p = tv->tmqh_in(tv);
NFQSetupPkt(p, (void *)nfa);
p->pickup_q_id = tv->pickup_q_id;
p->verdict_q_id = tv->verdict_q_id;
#ifdef COUNTERS
nfq_t->pkts++;
nfq_t->bytes += p->pktlen;
@ -200,7 +197,7 @@ int NFQInitThread(NFQThreadVars *nfq_t, u_int16_t queue_num, u_int32_t queue_max
return -1;
}
/* XXX detect this at configure time & make it an option */
/* XXX detect this at configure time & make it an option */
#define HAVE_NFQ_MAXLEN
#ifdef HAVE_NFQ_MAXLEN
if (queue_maxlen > 0) {
@ -209,7 +206,7 @@ int NFQInitThread(NFQThreadVars *nfq_t, u_int16_t queue_num, u_int32_t queue_max
/* non-fatal if it fails */
if (nfq_set_queue_maxlen(nfq_t->qh, queue_maxlen) < 0) {
printf("NFQInitThread: can't set queue maxlen: your kernel probably "
"doesn't support setting the queue length\n");
"doesn't support setting the queue length\n");
}
}
#endif
@ -226,8 +223,7 @@ int NFQInitThread(NFQThreadVars *nfq_t, u_int16_t queue_num, u_int32_t queue_max
printf("NFQInitThread: can't set socket timeout: %s\n", strerror(errno));
}
printf("NFQInitThread: nfq_t->h %p, nfq_t->nh %p, nfq_t->qh %p, nfq_t->fd %d\n", nfq_t->h, nfq_t->nh, nfq_t->qh, nfq_t->fd);
//printf("NFQInitThread: nfq_t->h %p, nfq_t->nh %p, nfq_t->qh %p, nfq_t->fd %d\n", nfq_t->h, nfq_t->nh, nfq_t->qh, nfq_t->fd);
return 0;
}
@ -235,6 +231,10 @@ int ReceiveNFQThreadInit(ThreadVars *tv, void *initdata, void **data) {
mutex_lock(&nfq_init_lock);
printf("ReceiveNFQThreadInit: starting... will bind to queuenum %u\n", receive_queue_num);
sigset_t sigs;
sigfillset(&sigs);
pthread_sigmask(SIG_BLOCK, &sigs, NULL);
NFQThreadVars *ntv = &nfq_t[receive_queue_num];
/* store the ThreadVars pointer in our NFQ thread context
@ -265,7 +265,6 @@ int VerdictNFQThreadInit(ThreadVars *tv, void *initdata, void **data) {
*data = (void *)ntv;
verdict_queue_num++;
printf("VerdictNFQThreadInit: ntv %p\n", ntv);
mutex_unlock(&nfq_init_lock);
return 0;
}
@ -273,9 +272,7 @@ int VerdictNFQThreadInit(ThreadVars *tv, void *initdata, void **data) {
int VerdictNFQThreadDeinit(ThreadVars *tv, void *data) {
NFQThreadVars *ntv = (NFQThreadVars *)data;
printf("VerdictNFQThreadDeinit: ntv %p\n", ntv);
printf("VerdictNFQThreadDeinit: starting... will close queuenum %u\n", ntv->queue_num);
nfq_destroy_queue(ntv->qh);
return 0;
@ -303,6 +300,8 @@ void NFQRecvPkt(NFQThreadVars *t) {
t->dbg_maxreadsize = rv;
#endif /* DBG_PERF */
//printf("NFQRecvPkt: t %p, rv = %d\n", t, rv);
mutex_lock(&t->mutex_qh);
ret = nfq_handle_packet(t->h, buf, rv);
mutex_unlock(&t->mutex_qh);
@ -317,11 +316,6 @@ int ReceiveNFQ(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) {
//printf("%p receiving on queue %u\n", ntv, ntv->queue_num);
/* XXX can we move this to initialization? */
sigset_t sigs;
sigfillset(&sigs);
pthread_sigmask(SIG_BLOCK, &sigs, NULL);
/* do our nfq magic */
NFQRecvPkt(ntv);

@ -12,6 +12,7 @@ ThreadVars *TmThreadCreate(char *name, char *inq_name, char *inqh_name, char *ou
int TmThreadSpawn(ThreadVars *);
void TmThreadKillThreads(void);
void TmThreadAppend(ThreadVars *);
int TmThreadSetCPUAffinity(ThreadVars *, int);
#endif /* __TM_THREADS_H__ */

@ -18,11 +18,14 @@ void TmqhNfqRegister (void) {
void TmqhOutputVerdictNfq(ThreadVars *t, Packet *p)
{
/* XXX not scaling */
#if 0
PacketQueue *q = &trans_q[p->verdict_q_id];
mutex_lock(&q->mutex_q);
PacketEnqueue(q, p);
pthread_cond_signal(&q->cond_q);
mutex_unlock(&q->mutex_q);
#endif
}

@ -82,7 +82,7 @@ int BloomFilterAdd(BloomFilter *bf, void *data, u_int16_t datalen) {
return 0;
}
int BloomFilterTest(BloomFilter *bf, void *data, u_int16_t datalen) {
inline int BloomFilterTest(BloomFilter *bf, void *data, u_int16_t datalen) {
u_int8_t iter = 0;
u_int32_t hash = 0;
int hit = 1;

@ -16,7 +16,7 @@ BloomFilter *BloomFilterInit(u_int32_t, u_int8_t, u_int32_t (*Hash)(void *, u_in
void BloomFilterFree(BloomFilter *);
void BloomFilterPrint(BloomFilter *);
int BloomFilterAdd(BloomFilter *, void *, u_int16_t);
int BloomFilterTest(BloomFilter *, void *, u_int16_t);
inline int BloomFilterTest(BloomFilter *, void *, u_int16_t);
u_int32_t BloomFilterMemoryCnt(BloomFilter *);
u_int32_t BloomFilterMemorySize(BloomFilter *);

@ -121,8 +121,8 @@ int HashListTableAdd(HashListTable *ht, void *data, u_int16_t datalen) {
ht->listhead = hb;
ht->listtail = hb;
} else {
hb->listprev = ht->listtail;
ht->listtail->listnext = hb;
hb->listprev = ht->listtail->listnext;
ht->listtail = hb;
}
@ -312,6 +312,71 @@ end:
return result;
}
static int HashListTableTestAdd03 (void) {
int result = 0;
HashListTable *ht = HashListTableInit(32, HashListTableGenericHash, NULL, NULL);
if (ht == NULL)
goto end;
int r = HashListTableAdd(ht, "test", 0);
if (r != 0)
goto end;
if (ht->listhead == NULL) {
printf("ht->listhead == NULL: ");
goto end;
}
if (ht->listtail == NULL) {
printf("ht->listtail == NULL: ");
goto end;
}
/* all is good! */
result = 1;
end:
if (ht != NULL) HashListTableFree(ht);
return result;
}
static int HashListTableTestAdd04 (void) {
int result = 0;
HashListTable *ht = HashListTableInit(32, HashListTableGenericHash, NULL, NULL);
if (ht == NULL)
goto end;
int r = HashListTableAdd(ht, "test", 4);
if (r != 0)
goto end;
char *rp = HashListTableLookup(ht, "test", 4);
if (rp == NULL)
goto end;
HashListTableBucket *htb = HashListTableGetListHead(ht);
if (htb == NULL) {
printf("htb == NULL: ");
goto end;
}
char *rp2 = HashListTableGetListData(htb);
if (rp2 == NULL) {
printf("rp2 == NULL: ");
goto end;
}
if (rp != rp2) {
printf("rp != rp2: ");
goto end;
}
/* all is good! */
result = 1;
end:
if (ht != NULL) HashListTableFree(ht);
return result;
}
static int HashListTableTestFull01 (void) {
int result = 0;
HashListTable *ht = HashListTableInit(32, HashListTableGenericHash, NULL, NULL);
@ -370,6 +435,8 @@ void HashListTableRegisterTests(void) {
UtRegisterTest("HashListTableTestAdd01", HashListTableTestAdd01, 1);
UtRegisterTest("HashListTableTestAdd02", HashListTableTestAdd02, 1);
UtRegisterTest("HashListTableTestAdd03", HashListTableTestAdd03, 1);
UtRegisterTest("HashListTableTestAdd04", HashListTableTestAdd04, 1);
UtRegisterTest("HashListTableTestFull01", HashListTableTestFull01, 1);
UtRegisterTest("HashListTableTestFull02", HashListTableTestFull02, 1);

@ -12,22 +12,21 @@
*
*/
//#define PRINTMATCH
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "vips.h"
#include "detect.h"
#include "util-bloomfilter.h"
#include "util-mpm-b2g.h"
#include "util-unittest.h"
/* uppercase to lowercase conversion lookup table */
static u_int8_t lowercasetable[256];
/* marco to do the actual lookup */
#define bg_tolower(c) lowercasetable[(c)]
#define INIT_HASH_SIZE 65536
#ifdef B2G_COUNTERS
@ -37,12 +36,12 @@ static u_int8_t lowercasetable[256];
#define COUNT(counter)
#endif /* B2G_COUNTERS */
void B2gInitCtx (MpmCtx *mpm_ctx);
void B2gThreadInitCtx(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, u_int32_t);
void B2gDestroyCtx(MpmCtx *mpm_ctx);
void B2gThreadDestroyCtx(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx);
int B2gAddScanPatternCI(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen, u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid);
int B2gAddScanPatternCS(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen, u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid);
void B2gInitCtx (MpmCtx *);
void B2gThreadInitCtx(MpmCtx *, MpmThreadCtx *, u_int32_t);
void B2gDestroyCtx(MpmCtx *);
void B2gThreadDestroyCtx(MpmCtx *, MpmThreadCtx *);
int B2gAddScanPatternCI(MpmCtx *, u_int8_t *, u_int16_t, u_int16_t, u_int16_t, u_int32_t, u_int32_t, u_int8_t);
int B2gAddScanPatternCS(MpmCtx *, u_int8_t *, u_int16_t, u_int16_t, u_int16_t, u_int32_t, u_int32_t, u_int8_t);
int B2gAddPatternCI(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen, u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid);
int B2gAddPatternCS(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen, u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid);
int B2gPreparePatterns(MpmCtx *mpm_ctx);
@ -53,6 +52,7 @@ u_int32_t B2gScan2(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcher
u_int32_t B2gScan(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *, u_int8_t *buf, u_int16_t buflen);
u_int32_t B2gScanBNDMq(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, u_int8_t *buf, u_int16_t buflen);
u_int32_t B2gSearch1(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *, u_int8_t *buf, u_int16_t buflen);
u_int32_t B2gSearchBNDMq(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, u_int8_t *buf, u_int16_t buflen);
u_int32_t B2gSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *, u_int8_t *buf, u_int16_t buflen);
void B2gPrintInfo(MpmCtx *mpm_ctx);
void B2gPrintSearchStats(MpmThreadCtx *mpm_thread_ctx);
@ -70,27 +70,19 @@ void MpmB2gRegister (void) {
mpm_table[MPM_B2G].AddPatternNocase = B2gAddPatternCI;
mpm_table[MPM_B2G].Prepare = B2gPreparePatterns;
mpm_table[MPM_B2G].Scan = B2G_SCANFUNC; /* default to B2gSearch. We may fall back to 1 */
mpm_table[MPM_B2G].Search = B2gSearch; /* default to B2gSearch. We may fall back to 1 */
mpm_table[MPM_B2G].Search = B2G_SEARCHFUNC; /* default to B2gSearch. We may fall back to 1 */
mpm_table[MPM_B2G].Cleanup = MpmMatchCleanup;
mpm_table[MPM_B2G].PrintCtx = B2gPrintInfo;
mpm_table[MPM_B2G].PrintThreadCtx = B2gPrintSearchStats;
mpm_table[MPM_B2G].RegisterUnittests = B2gRegisterTests;
/* create table for O(1) lowercase conversion lookup */
u_int8_t c = 0;
for ( ; c < 255; c++) {
if (c >= 'A' && c <= 'Z')
lowercasetable[c] = (c + ('a' - 'A'));
else
lowercasetable[c] = c;
}
}
/* append an endmatch to a pattern
*
* Only used in the initialization phase */
static inline void B2gEndMatchAppend(MpmCtx *mpm_ctx, B2gPattern *p,
u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid)
u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid,
u_int8_t nosearch)
{
MpmEndMatch *em = MpmAllocEndMatch(mpm_ctx);
if (em == NULL) {
@ -103,6 +95,9 @@ static inline void B2gEndMatchAppend(MpmCtx *mpm_ctx, B2gPattern *p,
em->depth = depth;
em->offset = offset;
if (nosearch)
em->flags |= MPM_ENDMATCH_NOSEARCH;
if (p->em == NULL) {
p->em = em;
return;
@ -120,7 +115,7 @@ static void prt (u_int8_t *buf, u_int16_t buflen) {
for (i = 0; i < buflen; i++) {
if (isprint(buf[i])) printf("%c", buf[i]);
else printf("\\x%X", buf[i]);
else printf("\\x%02X", buf[i]);
}
//printf("\n");
}
@ -185,7 +180,7 @@ static void B2gHashFree(MpmCtx *mpm_ctx, B2gHashItem *hi) {
static inline void memcpy_tolower(u_int8_t *d, u_int8_t *s, u_int16_t len) {
u_int16_t i;
for (i = 0; i < len; i++) {
d[i] = bg_tolower(s[i]);
d[i] = u8_tolower(s[i]);
}
}
@ -298,7 +293,7 @@ void B2gFreePattern(MpmCtx *mpm_ctx, B2gPattern *p) {
* pid: pattern id
* sid: signature id (internal id)
*/
static inline int B2gAddPattern(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen, u_int16_t offset, u_int16_t depth, char nocase, char scan, u_int32_t pid, u_int32_t sid) {
static inline int B2gAddPattern(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen, u_int16_t offset, u_int16_t depth, char nocase, char scan, u_int32_t pid, u_int32_t sid, u_int8_t nosearch) {
B2gCtx *ctx = (B2gCtx *)mpm_ctx->ctx;
// printf("B2gAddPattern: ctx %p \"", mpm_ctx); prt(pat, patlen);
@ -354,6 +349,7 @@ static inline int B2gAddPattern(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen
printf("Max search words reached\n");
exit(1);
}
if (scan) mpm_ctx->scan_pattern_cnt++;
mpm_ctx->pattern_cnt++;
if (scan) { /* SCAN */
@ -369,7 +365,7 @@ static inline int B2gAddPattern(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen
}
/* we need a match */
B2gEndMatchAppend(mpm_ctx, p, offset, depth, pid, sid);
B2gEndMatchAppend(mpm_ctx, p, offset, depth, pid, sid, nosearch);
/* keep track of highest pattern id XXX still used? */
if (pid > mpm_ctx->max_pattern_id)
@ -385,37 +381,37 @@ error:
}
int B2gAddScanPatternCI(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen,
u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid)
u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid, u_int8_t nosearch)
{
return B2gAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */1, /* scan */1, pid, sid);
return B2gAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */1, /* scan */1, pid, sid, nosearch);
}
int B2gAddScanPatternCS(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen,
u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid)
u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid, u_int8_t nosearch)
{
return B2gAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */0, /* scan */1, pid, sid);
return B2gAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */0, /* scan */1, pid, sid, nosearch);
}
int B2gAddPatternCI(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen,
u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid)
{
return B2gAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */1, /* scan */0, pid, sid);
return B2gAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */1, /* scan */0, pid, sid, 0);
}
int B2gAddPatternCS(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen,
u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid)
{
return B2gAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */0, /* scan */0, pid, sid);
return B2gAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */0, /* scan */0, pid, sid, 0);
}
static u_int32_t B2gBloomHash(void *data, u_int16_t datalen, u_int8_t iter, u_int32_t hash_size) {
static inline u_int32_t B2gBloomHash(void *data, u_int16_t datalen, u_int8_t iter, u_int32_t hash_size) {
u_int8_t *d = (u_int8_t *)data;
u_int16_t i;
u_int32_t hash = (u_int32_t)bg_tolower(*d);
u_int32_t hash = (u_int32_t)u8_tolower(*d);
for (i = 1; i < datalen; i++) {
d++;
hash += (bg_tolower(*d)) ^ i;
hash += (u8_tolower(*d)) ^ i;
}
hash <<= (iter+1);
@ -436,6 +432,15 @@ static void B2gPrepareScanHash(MpmCtx *mpm_ctx) {
mpm_ctx->memory_cnt++;
mpm_ctx->memory_size += (sizeof(B2gHashItem *) * ctx->scan_hash_size);
#ifdef B2G_SCAN2
ctx->scan_hash2 = (B2gHashItem **)malloc(sizeof(B2gHashItem *) * ctx->scan_hash_size);
if (ctx->scan_hash2 == NULL) goto error;
memset(ctx->scan_hash2, 0, sizeof(B2gHashItem *) * ctx->scan_hash_size);
mpm_ctx->memory_cnt++;
mpm_ctx->memory_size += (sizeof(B2gHashItem *) * ctx->scan_hash_size);
#endif
/* alloc the pminlen array */
ctx->scan_pminlen = (u_int8_t *)malloc(sizeof(u_int8_t) * ctx->scan_hash_size);
if (ctx->scan_pminlen == NULL) goto error;
@ -466,19 +471,22 @@ static void B2gPrepareScanHash(MpmCtx *mpm_ctx) {
thi->nxt = hi;
}
ctx->scan_1_pat_cnt++;
#if B2G_SCAN2
#ifdef B2G_SCAN2
} else if(ctx->parray[i]->len == 2) {
idx = (u_int16_t)(ctx->parray[i]->ci[0] << 8 | ctx->parray[i]->ci[1]);
if (ctx->scan_hash2[idx].flags == 0) {
ctx->scan_hash2[idx].idx = i;
ctx->scan_hash2[idx].flags |= 0x01;
idx = B2G_HASH16(ctx->parray[i]->ci[0],ctx->parray[i]->ci[1]);
if (ctx->scan_hash2[idx] == NULL) {
B2gHashItem *hi = B2gAllocHashItem(mpm_ctx);
hi->idx = i;
hi->flags |= 0x01;
ctx->scan_hash2[idx] = hi;
} else {
B2gHashItem *hi = B2gAllocHashItem(mpm_ctx);
hi->idx = i;
hi->flags |= 0x01;
/* Append this HashItem to the list */
B2gHashItem *thi = &ctx->scan_hash2[idx];
B2gHashItem *thi = ctx->scan_hash2[idx];
while (thi->nxt) thi = thi->nxt;
thi->nxt = hi;
}
@ -676,7 +684,7 @@ int B2gBuildScanMatchArray(MpmCtx *mpm_ctx) {
if (ctx->parray[a]->len < ctx->scan_m)
continue;
u_int16_t h = B2G_HASH16(bg_tolower(ctx->parray[a]->ci[j]),bg_tolower(ctx->parray[a]->ci[j+1]));
u_int16_t h = B2G_HASH16(u8_tolower(ctx->parray[a]->ci[j]),u8_tolower(ctx->parray[a]->ci[j+1]));
ctx->scan_B2G[h] = ctx->scan_B2G[h] | (1 << (ctx->scan_m - j));
}
}
@ -709,8 +717,8 @@ int B2gBuildSearchMatchArray(MpmCtx *mpm_ctx) {
if (ctx->parray[a]->len < ctx->search_m)
continue;
u_int16_t h = B2G_HASH16(bg_tolower(ctx->parray[a]->ci[j]),bg_tolower(ctx->parray[a]->ci[j+1]));
//printf("h %u, %c.%c\n", h, bg_tolower(ctx->parray[a]->ci[j]),bg_tolower(ctx->parray[a]->ci[j+1]));
u_int16_t h = B2G_HASH16(u8_tolower(ctx->parray[a]->ci[j]),u8_tolower(ctx->parray[a]->ci[j+1]));
//printf("h %u, %c.%c\n", h, u8_tolower(ctx->parray[a]->ci[j]),u8_tolower(ctx->parray[a]->ci[j+1]));
ctx->search_B2G[h] = ctx->search_B2G[h] | (1 << (ctx->search_m - j));
}
}
@ -725,7 +733,7 @@ int B2gBuildSearchMatchArray(MpmCtx *mpm_ctx) {
if (strlen(pat) < m)
continue;
u_int16_t h = B2G_HASH16(bg_tolower(pat[a][m-2]),bg_tolower(pat[a][m-1]));
u_int16_t h = B2G_HASH16(u8_tolower(pat[a][m-2]),u8_tolower(pat[a][m-1]));
s = B2G[h];
printf("S0: h %u, %c.%c\n", h, pat[a][m-2], pat[a][m-1]);
@ -740,7 +748,7 @@ int B2gBuildSearchMatchArray(MpmCtx *mpm_ctx) {
printf(" ( nope ) ");
}
h = B2G_HASH16(bg_tolower(pat[a][i-1]),bg_tolower(pat[a][i-0]));
h = B2G_HASH16(u8_tolower(pat[a][i-1]),u8_tolower(pat[a][i-0]));
printf("S: h %u, %c.%c ", h, pat[a][i-1], pat[a][i-0]);
s = (s << 1) & B2G[h];
printf("B2G_S0 %d (s %u, b2g[h] %u)\n", B2G_S0, s, B2G[h]);
@ -787,7 +795,7 @@ int B2gPreparePatterns(MpmCtx *mpm_ctx) {
if (mpm_ctx->search_minlen == 1) {
mpm_ctx->Search = B2gSearch1;
ctx->MBSearch = B2gSearch;
ctx->MBSearch = B2G_SEARCHFUNC;
}
/* make sure 'm' stays in bounds */
if (ctx->scan_m > B2G_WORD_SIZE) {
@ -812,6 +820,7 @@ int B2gPreparePatterns(MpmCtx *mpm_ctx) {
if (ctx->scan_1_pat_cnt) {
mpm_ctx->Scan = B2gScan1;
#ifdef B2G_SCAN2
mpm_ctx->Scan = B2gScan2;
if (ctx->scan_2_pat_cnt) {
ctx->MBScan2 = B2gScan2;
}
@ -866,7 +875,7 @@ memcmp_lowercase(u_int8_t *s1, u_int8_t *s2, u_int16_t n) {
* 2 to 4 chars. This way we are more likely to detect
* a miss and thus speed up a little... */
for (i = n - 1; i; i--) {
if (bg_tolower(*(s2+i)) != s1[i])
if (u8_tolower(*(s2+i)) != s1[i])
return 1;
}
@ -1080,7 +1089,7 @@ u_int32_t B2gScanBNDMq(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMat
return 0;
while (pos <= (buflen - B2G_Q + 1)) {
u_int16_t h = B2G_HASH16(bg_tolower(buf[pos - 1]),bg_tolower(buf[pos]));
u_int16_t h = B2G_HASH16(u8_tolower(buf[pos - 1]),u8_tolower(buf[pos]));
d = ctx->scan_B2G[h];
if (d != 0) {
@ -1094,7 +1103,7 @@ u_int32_t B2gScanBNDMq(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMat
if (j > first) pos = j;
else {
/* get our patterns from the hash */
h = B2G_HASH16(bg_tolower(buf[j + ctx->scan_m - 2]),bg_tolower(buf[j + ctx->scan_m - 1]));
h = B2G_HASH16(u8_tolower(buf[j + ctx->scan_m - 2]),u8_tolower(buf[j + ctx->scan_m - 1]));
if (ctx->scan_bloom[h] != NULL) {
COUNT(tctx->scan_stat_pminlen_calls++);
@ -1161,7 +1170,7 @@ skip_loop:
}
}
h = B2G_HASH16(bg_tolower(buf[j - 1]),bg_tolower(buf[j]));
h = B2G_HASH16(u8_tolower(buf[j - 1]),u8_tolower(buf[j]));
d = (d << 1) & ctx->scan_B2G[h];
} while (d != 0);
}
@ -1192,7 +1201,7 @@ u_int32_t B2gScan(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQ
d = ~0;
do {
u_int16_t h = B2G_HASH16(bg_tolower(buf[pos + j - 1]),bg_tolower(buf[pos + j]));
u_int16_t h = B2G_HASH16(u8_tolower(buf[pos + j - 1]),u8_tolower(buf[pos + j]));
d = ((d << 1) & ctx->scan_B2G[h]);
j = j - 1;
} while (d != 0 && j != 0);
@ -1204,7 +1213,7 @@ u_int32_t B2gScan(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQ
//printf("output at pos %u: ", pos); prt(buf + pos, ctx->scan_m); printf("\n");
/* get our patterns from the hash */
u_int16_t h = B2G_HASH16(bg_tolower(buf[pos + ctx->scan_m - 2]),bg_tolower(buf[pos + ctx->scan_m - 1]));
u_int16_t h = B2G_HASH16(u8_tolower(buf[pos + ctx->scan_m - 2]),u8_tolower(buf[pos + ctx->scan_m - 1]));
if (ctx->scan_bloom[h] != NULL) {
COUNT(tctx->scan_stat_pminlen_calls++);
@ -1234,15 +1243,23 @@ u_int32_t B2gScan(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQ
continue;
if (memcmp_lowercase(p->ci, buf+pos, p->len) == 0) {
//printf("CI Exact match: "); prt(p->ci, p->len); printf("\n");
#ifdef PRINTMATCH
printf("CI Exact match: \""); prt(p->ci, p->len); printf("\" ");
#endif
COUNT(tctx->scan_stat_loop_match++);
MpmEndMatch *em;
for (em = p->em; em; em = em->next) {
#ifdef PRINTMATCH
printf("(%u%s) ", g_de_ctx->sig_array[em->sig_id]->id, em->flags & MPM_ENDMATCH_NOSEARCH ? "" : " (searchable)");
#endif
//printf("em %p id %u\n", em, em->id);
if (MpmMatchAppend(mpm_thread_ctx, pmq, em, &mpm_thread_ctx->match[em->id], pos, p->len))
matches++;
}
#ifdef PRINTMATCH
printf("\n");
#endif
} else {
COUNT(tctx->scan_stat_loop_no_match++);
}
@ -1251,15 +1268,23 @@ u_int32_t B2gScan(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQ
continue;
if (memcmp(p->cs, buf+pos, p->len) == 0) {
//printf("CS Exact match: "); prt(p->cs, p->len); printf("\n");
#ifdef PRINTMATCH
printf("CS Exact match: \""); prt(p->cs, p->len); printf("\" ");
#endif
COUNT(tctx->scan_stat_loop_match++);
MpmEndMatch *em;
for (em = p->em; em; em = em->next) {
#ifdef PRINTMATCH
printf("(%u%s) ", g_de_ctx->sig_array[em->sig_id]->id, em->flags & MPM_ENDMATCH_NOSEARCH ? "" : " (searchable)");
#endif
//printf("em %p id %u\n", em, em->id);
if (MpmMatchAppend(mpm_thread_ctx, pmq, em, &mpm_thread_ctx->match[em->id], pos, p->len))
matches++;
}
#ifdef PRINTMATCH
printf("\n");
#endif
} else {
COUNT(tctx->scan_stat_loop_no_match++);
}
@ -1296,18 +1321,15 @@ u_int32_t B2gScan2(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcher
//printf("BUF "); prt(buf,buflen); printf("\n");
while (buf <= bufend) {
u_int16_t h = bg_tolower(*buf) << 8 | bg_tolower(*(buf+1));
hi = &ctx->scan_hash2[h];
u_int8_t h8 = u8_tolower(*buf);
hi = &ctx->scan_hash1[h8];
if (hi->flags & 0x01) {
for (thi = hi; thi != NULL; thi = thi->nxt) {
p = ctx->parray[thi->idx];
if (p->len != 2)
continue;
if (p->flags & B2G_NOCASE) {
if (bg_tolower(*buf) == p->ci[0] && bg_tolower(*(buf+1)) == p->ci[1]) {
if (h8 == p->ci[0]) {
//printf("CI Exact match: "); prt(p->ci, p->len); printf(" in buf "); prt(buf, p->len);printf(" (B2gSearch1)\n");
for (em = p->em; em; em = em->next) {
if (MpmMatchAppend(mpm_thread_ctx, pmq, em, &mpm_thread_ctx->match[em->id],(buf+1 - bufmin), p->len))
@ -1315,7 +1337,7 @@ u_int32_t B2gScan2(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcher
}
}
} else {
if (*buf == p->cs[0] && *(buf+1) == p->cs[1]) {
if (*buf == p->cs[0]) {
//printf("CS Exact match: "); prt(p->cs, p->len); printf(" in buf "); prt(buf, p->len);printf(" (B2gSearch1)\n");
for (em = p->em; em; em = em->next) {
if (MpmMatchAppend(mpm_thread_ctx, pmq, em, &mpm_thread_ctx->match[em->id],(buf+1 - bufmin), p->len))
@ -1325,11 +1347,37 @@ u_int32_t B2gScan2(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcher
}
}
}
/* save one conversion by reusing h8 */
u_int16_t h16 = B2G_HASH16(h8, u8_tolower(*(buf+1)));
hi = ctx->scan_hash2[h16];
for (thi = hi; thi != NULL; thi = thi->nxt) {
p = ctx->parray[thi->idx];
if (p->flags & B2G_NOCASE) {
if (h8 == p->ci[0] && u8_tolower(*(buf+1)) == p->ci[1]) {
//printf("CI Exact match: "); prt(p->ci, p->len); printf(" in buf "); prt(buf, p->len);printf(" (B2gSearch1)\n");
for (em = p->em; em; em = em->next) {
if (MpmMatchAppend(mpm_thread_ctx, pmq, em, &mpm_thread_ctx->match[em->id],(buf+1 - bufmin), p->len))
cnt++;
}
}
} else {
if (*buf == p->cs[0] && *(buf+1) == p->cs[1]) {
//printf("CS Exact match: "); prt(p->cs, p->len); printf(" in buf "); prt(buf, p->len);printf(" (B2gSearch1)\n");
for (em = p->em; em; em = em->next) {
if (MpmMatchAppend(mpm_thread_ctx, pmq, em, &mpm_thread_ctx->match[em->id],(buf+1 - bufmin), p->len))
cnt++;
}
}
}
}
buf += 1;
}
//printf("B2gSearch2: after 2byte cnt %u\n", cnt);
if (ctx->scan_x_pat_cnt) {
if (ctx->scan_x_pat_cnt > 0) {
/* Pass bufmin on because buf no longer points to the
* start of the buffer. */
cnt += ctx->MBScan(mpm_ctx, mpm_thread_ctx, pmq, bufmin, buflen);
@ -1354,7 +1402,7 @@ u_int32_t B2gScan1(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcher
//printf("BUF "); prt(buf,buflen); printf("\n");
while (buf <= bufend) {
u_int8_t h = bg_tolower(*buf);
u_int8_t h = u8_tolower(*buf);
hi = &ctx->scan_hash1[h];
if (hi->flags & 0x01) {
@ -1365,7 +1413,7 @@ u_int32_t B2gScan1(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcher
continue;
if (p->flags & B2G_NOCASE) {
if (bg_tolower(*buf) == p->ci[0]) {
if (u8_tolower(*buf) == p->ci[0]) {
//printf("CI Exact match: "); prt(p->ci, p->len); printf(" in buf "); prt(buf, p->len);printf(" (B2gSearch1)\n");
for (em = p->em; em; em = em->next) {
if (MpmMatchAppend(mpm_thread_ctx, pmq, em, &mpm_thread_ctx->match[em->id],(buf+1 - bufmin), p->len))
@ -1401,6 +1449,113 @@ u_int32_t B2gScan1(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcher
return cnt;
}
u_int32_t B2gSearchBNDMq(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, u_int8_t *buf, u_int16_t buflen) {
B2gCtx *ctx = (B2gCtx *)mpm_ctx->ctx;
#ifdef B2G_COUNTERS
B2gThreadCtx *tctx = (B2gThreadCtx *)mpm_thread_ctx->ctx;
#endif
u_int32_t pos = ctx->search_m - B2G_Q + 1, matches = 0;
B2G_TYPE d;
COUNT(tctx->search_stat_calls++);
COUNT(tctx->search_stat_m_total+=ctx->search_m);
if (buflen < ctx->search_m)
return 0;
while (pos <= (buflen - B2G_Q + 1)) {
u_int16_t h = B2G_HASH16(u8_tolower(buf[pos - 1]),u8_tolower(buf[pos]));
d = ctx->search_B2G[h];
if (d != 0) {
COUNT(tctx->search_stat_d0++);
u_int j = pos;
u_int first = pos - (ctx->search_m - B2G_Q + 1);
do {
j = j - 1;
if (d >= (1 << (ctx->search_m - 1))) {
if (j > first) pos = j;
else {
/* get our patterns from the hash */
h = B2G_HASH16(u8_tolower(buf[j + ctx->search_m - 2]),u8_tolower(buf[j + ctx->search_m - 1]));
if (ctx->search_bloom[h] != NULL) {
COUNT(tctx->search_stat_pminlen_calls++);
COUNT(tctx->search_stat_pminlen_total+=ctx->search_pminlen[h]);
if ((buflen - j) < ctx->search_pminlen[h]) {
goto skip_loop;
} else {
COUNT(tctx->search_stat_bloom_calls++);
if (BloomFilterTest(ctx->search_bloom[h], buf+j, ctx->search_pminlen[h]) == 0) {
COUNT(tctx->search_stat_bloom_hits++);
//printf("Bloom: %p, buflen %u, pos %u, p_min_len %u\n", ctx->scan_bloom[h], buflen, pos, ctx->scan_pminlen[h]);
goto skip_loop;
}
}
}
B2gHashItem *hi = ctx->search_hash[h], *thi;
for (thi = hi; thi != NULL; thi = thi->nxt) {
COUNT(tctx->search_stat_d0_hashloop++);
B2gPattern *p = ctx->parray[thi->idx];
if (p->flags & B2G_NOCASE) {
if (buflen - j < p->len)
continue;
if (memcmp_lowercase(p->ci, buf+j, p->len) == 0) {
//printf("CI Exact match: "); prt(p->ci, p->len); printf("\n");
COUNT(tctx->search_stat_loop_match++);
MpmEndMatch *em;
for (em = p->em; em; em = em->next) {
//printf("em %p id %u\n", em, em->id);
if (MpmMatchAppend(mpm_thread_ctx, pmq, em, &mpm_thread_ctx->match[em->id], j, p->len))
matches++;
}
} else {
COUNT(tctx->search_stat_loop_no_match++);
}
} else {
if (buflen - j < p->len)
continue;
if (memcmp(p->cs, buf+j, p->len) == 0) {
//printf("CS Exact match: "); prt(p->cs, p->len); printf("\n");
COUNT(tctx->search_stat_loop_match++);
MpmEndMatch *em;
for (em = p->em; em; em = em->next) {
//printf("em %p id %u\n", em, em->id);
if (MpmMatchAppend(mpm_thread_ctx, pmq, em, &mpm_thread_ctx->match[em->id], j, p->len))
matches++;
}
} else {
COUNT(tctx->search_stat_loop_no_match++);
}
}
}
skip_loop:
//printf("output at pos %u: ", j); prt(buf + (j), ctx->scan_m); printf("\n");
;
}
}
h = B2G_HASH16(u8_tolower(buf[j - 1]),u8_tolower(buf[j]));
d = (d << 1) & ctx->search_B2G[h];
} while (d != 0);
}
COUNT(tctx->search_stat_num_shift++);
COUNT(tctx->search_stat_total_shift += (ctx->search_m - B2G_Q + 1));
pos = pos + ctx->search_m - B2G_Q + 1;
}
return matches;
}
u_int32_t B2gSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, u_int8_t *buf, u_int16_t buflen) {
B2gCtx *ctx = (B2gCtx *)mpm_ctx->ctx;
#ifdef B2G_COUNTERS
@ -1418,11 +1573,11 @@ u_int32_t B2gSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatche
d = ~0;
do {
u_int16_t h = B2G_HASH16(bg_tolower(buf[pos + j - 1]),bg_tolower(buf[pos + j]));
u_int16_t h = B2G_HASH16(u8_tolower(buf[pos + j - 1]),u8_tolower(buf[pos + j]));
d &= ctx->search_B2G[h];
d <<= 1;
j = j - 1;
//printf("h %u d %d %c.%c\n", h, d, bg_tolower(buf[pos + j - 1]),bg_tolower(buf[pos + j]));
//printf("h %u d %d %c.%c\n", h, d, u8_tolower(buf[pos + j - 1]),u8_tolower(buf[pos + j]));
} while (d != 0 && j != 0);
/* (partial) match, move on to verification */
@ -1430,7 +1585,7 @@ u_int32_t B2gSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatche
COUNT(tctx->search_stat_d0++);
/* get our patterns from the hash */
u_int16_t h = B2G_HASH16(bg_tolower(buf[pos + ctx->search_m - 2]),bg_tolower(buf[pos + ctx->search_m - 1]));
u_int16_t h = B2G_HASH16(u8_tolower(buf[pos + ctx->search_m - 2]),u8_tolower(buf[pos + ctx->search_m - 1]));
if (ctx->scan_bloom[h] != NULL) {
COUNT(tctx->scan_stat_pminlen_calls++);
@ -1522,7 +1677,7 @@ u_int32_t B2gSearch1(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatch
if (mpm_ctx->search_minlen == 1) {
while (buf <= bufend) {
u_int8_t h = bg_tolower(*buf);
u_int8_t h = u8_tolower(*buf);
hi = &ctx->search_hash1[h];
if (hi->flags & 0x01) {
@ -1533,7 +1688,7 @@ u_int32_t B2gSearch1(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatch
continue;
if (p->flags & B2G_NOCASE) {
if (bg_tolower(*buf) == p->ci[0]) {
if (u8_tolower(*buf) == p->ci[0]) {
//printf("CI Exact match: "); prt(p->ci, p->len); printf(" in buf "); prt(buf, p->len);printf(" (B2gSearch1)\n");
for (em = p->em; em; em = em->next) {
if (MpmMatchAppend(mpm_thread_ctx, pmq, em, &mpm_thread_ctx->match[em->id],(buf+1 - bufmin), p->len))
@ -1692,7 +1847,7 @@ static int B2gTestScan01 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_B2G);
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 0, 0); /* 1 match */
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 0, 0, 0); /* 1 match */
B2gPreparePatterns(&mpm_ctx);
B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */);
@ -1717,7 +1872,7 @@ static int B2gTestScan02 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_B2G);
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abce", 4, 0, 0, 0, 0); /* 1 match */
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abce", 4, 0, 0, 0, 0, 0); /* 1 match */
B2gPreparePatterns(&mpm_ctx);
B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */);
@ -1742,9 +1897,9 @@ static int B2gTestScan03 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_B2G);
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 0, 0); /* 1 match */
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"bcde", 4, 0, 0, 1, 0); /* 1 match */
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"fghj", 4, 0, 0, 2, 0); /* 1 match */
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 0, 0, 0); /* 1 match */
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"bcde", 4, 0, 0, 1, 0, 0); /* 1 match */
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"fghj", 4, 0, 0, 2, 0, 0); /* 1 match */
B2gPreparePatterns(&mpm_ctx);
B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 3 /* 3 patterns */);
@ -1770,9 +1925,9 @@ static int B2gTestScan04 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_B2G);
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 0, 0); /* 1 match */
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"bcdegh", 6, 0, 0, 1, 0); /* 1 match */
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"fghjxyz", 7, 0, 0, 2, 0); /* 1 match */
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 0, 0, 0); /* 1 match */
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"bcdegh", 6, 0, 0, 1, 0, 0); /* 1 match */
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"fghjxyz", 7, 0, 0, 2, 0, 0); /* 1 match */
B2gPreparePatterns(&mpm_ctx);
B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 3 /* 3 patterns */);
@ -1798,9 +1953,9 @@ static int B2gTestScan05 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_B2G);
B2gAddScanPatternCI(&mpm_ctx, (u_int8_t *)"ABCD", 4, 0, 0, 0, 0); /* 1 match */
B2gAddScanPatternCI(&mpm_ctx, (u_int8_t *)"bCdEfG", 6, 0, 0, 1, 0); /* 1 match */
B2gAddScanPatternCI(&mpm_ctx, (u_int8_t *)"fghJikl", 7, 0, 0, 2, 0); /* 1 match */
B2gAddScanPatternCI(&mpm_ctx, (u_int8_t *)"ABCD", 4, 0, 0, 0, 0, 0); /* 1 match */
B2gAddScanPatternCI(&mpm_ctx, (u_int8_t *)"bCdEfG", 6, 0, 0, 1, 0, 0); /* 1 match */
B2gAddScanPatternCI(&mpm_ctx, (u_int8_t *)"fghJikl", 7, 0, 0, 2, 0, 0); /* 1 match */
B2gPreparePatterns(&mpm_ctx);
B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 3 /* 3 patterns */);
@ -1825,7 +1980,7 @@ static int B2gTestScan06 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_B2G);
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 0, 0); /* 1 match */
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 0, 0, 0); /* 1 match */
B2gPreparePatterns(&mpm_ctx);
B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */);
@ -1851,12 +2006,12 @@ static int B2gTestScan07 (void) {
MpmInitCtx(&mpm_ctx, MPM_B2G);
//B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx;
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"A", 1, 0, 0, 0, 0); /* should match 30 times */
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"AA", 2, 0, 0, 1, 0); /* should match 29 times */
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"AAA", 3, 0, 0, 2, 0); /* should match 28 times */
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"AAAAA", 5, 0, 0, 3, 0); /* 26 */
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"AAAAAAAAAA", 10, 0, 0, 4, 0); /* 21 */
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 30, 0, 0, 5, 0); /* 1 */
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"A", 1, 0, 0, 0, 0, 0); /* should match 30 times */
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"AA", 2, 0, 0, 1, 0, 0); /* should match 29 times */
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"AAA", 3, 0, 0, 2, 0, 0); /* should match 28 times */
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"AAAAA", 5, 0, 0, 3, 0, 0); /* 26 */
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"AAAAAAAAAA", 10, 0, 0, 4, 0, 0); /* 21 */
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 30, 0, 0, 5, 0, 0); /* 1 */
/* total matches: 135 */
B2gPreparePatterns(&mpm_ctx);
@ -1882,7 +2037,7 @@ static int B2gTestScan08 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_B2G);
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 0, 0); /* 1 match */
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 0, 0, 0); /* 1 match */
B2gPreparePatterns(&mpm_ctx);
B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */);
@ -1907,7 +2062,7 @@ static int B2gTestScan09 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_B2G);
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"ab", 2, 0, 0, 0, 0); /* 1 match */
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"ab", 2, 0, 0, 0, 0, 0); /* 1 match */
B2gPreparePatterns(&mpm_ctx);
B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */);
@ -1932,7 +2087,7 @@ static int B2gTestScan10 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_B2G);
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abcdefgh", 8, 0, 0, 0, 0); /* 1 match */
B2gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abcdefgh", 8, 0, 0, 0, 0, 0); /* 1 match */
B2gPreparePatterns(&mpm_ctx);
B2gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */);

@ -9,62 +9,69 @@
//#define B2G_HASHSIZE 65536
//#define B2G_HASHSIZE 32768
#define B2G_HASHSIZE 16384
//#define B2G_HASHSIZE 16384
//#define B2G_HASHSIZE 8192
//#define B2G_HASHSIZE 4096
#define B2G_HASHSIZE 4096
//#define B2G_HASHSIZE 2048
//#define B2G_HASHSHIFT 8
//#define B2G_HASHSHIFT 7
#define B2G_HASHSHIFT 6
//#define B2G_HASHSHIFT 6
//#define B2G_HASHSHIFT 5
//#define B2G_HASHSHIFT 4
#define B2G_HASHSHIFT 4
//#define B2G_HASHSHIFT 3
//#define B2G_TYPE u_int64_t
#define B2G_TYPE u_int32_t
//#define B2G_TYPE u_int16_t
//#define B2G_TYPE u_int8_t
//#define B2G_WORD_SIZE 64
#define B2G_WORD_SIZE 32
//#define B2G_WORD_SIZE 16
//#define B2G_WORD_SIZE 8
#define B2G_WORD_SIZE 32
#define B2G_BLOOMSIZE 1024
#define B2G_HASH16(a,b) (((a)<<B2G_HASHSHIFT) | (b))
#define B2G_Q 2
//#define B2G_SCANFUNC B2gScanBNDMq
#define B2G_SCANFUNC B2gScan
#define B2G_SCANFUNC B2gScanBNDMq
//#define B2G_SCANFUNC B2gScan
#define B2G_SEARCHFUNC B2gSearchBNDMq
//#define B2G_SEARCHFUNC B2gSearch
//#define B2G_SCAN2
//#define B2G_COUNTERS
typedef struct _B2gPattern {
u_int8_t flags;
u_int16_t len;
u_int8_t *cs; /* case sensitive */
u_int8_t *ci; /* case INsensitive */
u_int16_t len;
struct _B2gPattern *next;
u_int8_t flags;
MpmEndMatch *em;
} B2gPattern;
typedef struct _B2gHashItem_ {
u_int8_t flags;
u_int16_t idx;
struct _B2gHashItem_ *nxt;
u_int8_t flags;
} B2gHashItem;
typedef struct _B2gCtx {
/* hash used during ctx initialization */
B2gPattern **init_hash;
B2G_TYPE *scan_B2G;
B2G_TYPE scan_m;
BloomFilter **scan_bloom;
u_int8_t *scan_pminlen; /* array containing the minimal length
of the patters in a hash bucket. Used
for the BloomFilter. */
/* pattern arrays */
B2gPattern **parray;
B2G_TYPE search_m;
B2G_TYPE *scan_B2G;
B2G_TYPE *search_B2G;
u_int8_t scan_s0;
u_int8_t search_s0;
u_int16_t scan_1_pat_cnt;
#ifdef B2G_SCAN2
u_int16_t scan_2_pat_cnt;
@ -73,13 +80,9 @@ typedef struct _B2gCtx {
u_int32_t scan_hash_size;
B2gHashItem **scan_hash;
BloomFilter **scan_bloom;
u_int8_t *scan_pminlen; /* array containing the minimal length
of the patters in a hash bucket. Used
for the BloomFilter. */
B2gHashItem scan_hash1[256];
#ifdef B2G_SCAN2
B2gHashItem scan_hash2[65536];
B2gHashItem **scan_hash2;
#endif
u_int32_t search_hash_size;
BloomFilter **search_bloom;
@ -89,14 +92,18 @@ typedef struct _B2gCtx {
B2gHashItem **search_hash;
B2gHashItem search_hash1[256];
/* hash used during ctx initialization */
B2gPattern **init_hash;
u_int8_t scan_s0;
u_int8_t search_s0;
/* we store our own multi byte scan ptr here for B2gSearch1 */
u_int32_t (*MBScan2)(struct _MpmCtx *, struct _MpmThreadCtx *, PatternMatcherQueue *, u_int8_t *, u_int16_t);
u_int32_t (*MBScan)(struct _MpmCtx *, struct _MpmThreadCtx *, PatternMatcherQueue *, u_int8_t *, u_int16_t);
/* we store our own multi byte search ptr here for B2gSearch1 */
u_int32_t (*MBSearch)(struct _MpmCtx *, struct _MpmThreadCtx *, PatternMatcherQueue *, u_int8_t *, u_int16_t);
/* pattern arrays */
B2gPattern **parray;
} B2gCtx;
typedef struct _B2gThreadCtx {

@ -18,16 +18,13 @@
#include <ctype.h>
#include <errno.h>
#include "vips.h"
#include "util-bloomfilter.h"
#include "util-mpm-b3g.h"
#include "util-unittest.h"
/* uppercase to lowercase conversion lookup table */
static u_int8_t lowercasetable[256];
/* marco to do the actual lookup */
#define bg_tolower(c) lowercasetable[(c)]
#define INIT_HASH_SIZE 65536
#ifdef B3G_COUNTERS
@ -37,28 +34,31 @@ static u_int8_t lowercasetable[256];
#define COUNT(counter)
#endif /* B3G_COUNTERS */
void B3gInitCtx (MpmCtx *mpm_ctx);
void B3gThreadInitCtx(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, u_int32_t);
void B3gDestroyCtx(MpmCtx *mpm_ctx);
void B3gThreadDestroyCtx(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx);
int B3gAddScanPatternCI(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen, u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid);
int B3gAddScanPatternCS(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen, u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid);
int B3gAddPatternCI(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen, u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid);
int B3gAddPatternCS(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen, u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid);
int B3gPreparePatterns(MpmCtx *mpm_ctx);
u_int32_t B3gScan1(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *, u_int8_t *buf, u_int16_t buflen);
u_int32_t B3gScan2(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *, u_int8_t *buf, u_int16_t buflen);
u_int32_t B3gScan(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *, u_int8_t *buf, u_int16_t buflen);
u_int32_t B3gScanBNDMq(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, u_int8_t *buf, u_int16_t buflen);
u_int32_t B3gSearch1(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *, u_int8_t *buf, u_int16_t buflen);
u_int32_t B3gSearch2(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *, u_int8_t *buf, u_int16_t buflen);
u_int32_t B3gSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *, u_int8_t *buf, u_int16_t buflen);
void B3gPrintInfo(MpmCtx *mpm_ctx);
void B3gPrintSearchStats(MpmThreadCtx *mpm_thread_ctx);
void B3gInitCtx (MpmCtx *);
void B3gThreadInitCtx(MpmCtx *, MpmThreadCtx *, u_int32_t);
void B3gDestroyCtx(MpmCtx *);
void B3gThreadDestroyCtx(MpmCtx *, MpmThreadCtx *);
int B3gAddScanPatternCI(MpmCtx *, u_int8_t *, u_int16_t, u_int16_t, u_int16_t, u_int32_t, u_int32_t, u_int8_t);
int B3gAddScanPatternCS(MpmCtx *, u_int8_t *, u_int16_t, u_int16_t, u_int16_t, u_int32_t, u_int32_t, u_int8_t);
int B3gAddPatternCI(MpmCtx *, u_int8_t *, u_int16_t, u_int16_t, u_int16_t, u_int32_t, u_int32_t);
int B3gAddPatternCS(MpmCtx *, u_int8_t *, u_int16_t, u_int16_t, u_int16_t, u_int32_t, u_int32_t);
int B3gPreparePatterns(MpmCtx *);
u_int32_t B3gScan1(MpmCtx *, MpmThreadCtx *, PatternMatcherQueue *, u_int8_t *, u_int16_t);
u_int32_t B3gScan2(MpmCtx *, MpmThreadCtx *, PatternMatcherQueue *, u_int8_t *, u_int16_t);
u_int32_t B3gScan12(MpmCtx *, MpmThreadCtx *, PatternMatcherQueue *, u_int8_t *, u_int16_t);
u_int32_t B3gScan(MpmCtx *, MpmThreadCtx *, PatternMatcherQueue *, u_int8_t *, u_int16_t);
u_int32_t B3gScanBNDMq(MpmCtx *, MpmThreadCtx *, PatternMatcherQueue *, u_int8_t *, u_int16_t);
u_int32_t B3gSearch1(MpmCtx *, MpmThreadCtx *, PatternMatcherQueue *, u_int8_t *, u_int16_t);
u_int32_t B3gSearch2(MpmCtx *, MpmThreadCtx *, PatternMatcherQueue *, u_int8_t *, u_int16_t);
u_int32_t B3gSearch12(MpmCtx *, MpmThreadCtx *, PatternMatcherQueue *, u_int8_t *, u_int16_t);
u_int32_t B3gSearch(MpmCtx *, MpmThreadCtx *, PatternMatcherQueue *, u_int8_t *, u_int16_t);
u_int32_t B3gSearchBNDMq(MpmCtx *, MpmThreadCtx *, PatternMatcherQueue *, u_int8_t *, u_int16_t);
void B3gPrintInfo(MpmCtx *);
void B3gPrintSearchStats(MpmThreadCtx *);
void B3gRegisterTests(void);
void MpmB3gRegister (void) {
mpm_table[MPM_B3G].name = "b2g";
mpm_table[MPM_B3G].name = "b3g";
mpm_table[MPM_B3G].InitCtx = B3gInitCtx;
mpm_table[MPM_B3G].InitThreadCtx = B3gThreadInitCtx;
mpm_table[MPM_B3G].DestroyCtx = B3gDestroyCtx;
@ -74,22 +74,14 @@ void MpmB3gRegister (void) {
mpm_table[MPM_B3G].PrintCtx = B3gPrintInfo;
mpm_table[MPM_B3G].PrintThreadCtx = B3gPrintSearchStats;
mpm_table[MPM_B3G].RegisterUnittests = B3gRegisterTests;
/* create table for O(1) lowercase conversion lookup */
u_int8_t c = 0;
for ( ; c < 255; c++) {
if (c >= 'A' && c <= 'Z')
lowercasetable[c] = (c + ('a' - 'A'));
else
lowercasetable[c] = c;
}
}
/* append an endmatch to a pattern
*
* Only used in the initialization phase */
static inline void B3gEndMatchAppend(MpmCtx *mpm_ctx, B3gPattern *p,
u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid)
u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid,
u_int8_t nosearch)
{
MpmEndMatch *em = MpmAllocEndMatch(mpm_ctx);
if (em == NULL) {
@ -102,6 +94,9 @@ static inline void B3gEndMatchAppend(MpmCtx *mpm_ctx, B3gPattern *p,
em->depth = depth;
em->offset = offset;
if (nosearch)
em->flags |= MPM_ENDMATCH_NOSEARCH;
if (p->em == NULL) {
p->em = em;
return;
@ -184,7 +179,7 @@ static void B3gHashFree(MpmCtx *mpm_ctx, B3gHashItem *hi) {
static inline void memcpy_tolower(u_int8_t *d, u_int8_t *s, u_int16_t len) {
u_int16_t i;
for (i = 0; i < len; i++) {
d[i] = bg_tolower(s[i]);
d[i] = u8_tolower(s[i]);
}
}
@ -297,7 +292,7 @@ void B3gFreePattern(MpmCtx *mpm_ctx, B3gPattern *p) {
* pid: pattern id
* sid: signature id (internal id)
*/
static inline int B3gAddPattern(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen, u_int16_t offset, u_int16_t depth, char nocase, char scan, u_int32_t pid, u_int32_t sid) {
static inline int B3gAddPattern(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen, u_int16_t offset, u_int16_t depth, char nocase, char scan, u_int32_t pid, u_int32_t sid, u_int8_t nosearch) {
B3gCtx *ctx = (B3gCtx *)mpm_ctx->ctx;
// printf("B3gAddPattern: ctx %p \"", mpm_ctx); prt(pat, patlen);
@ -353,6 +348,7 @@ static inline int B3gAddPattern(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen
printf("Max search words reached\n");
exit(1);
}
if (scan) mpm_ctx->scan_pattern_cnt++;
mpm_ctx->pattern_cnt++;
if (scan) { /* SCAN */
@ -368,7 +364,7 @@ static inline int B3gAddPattern(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen
}
/* we need a match */
B3gEndMatchAppend(mpm_ctx, p, offset, depth, pid, sid);
B3gEndMatchAppend(mpm_ctx, p, offset, depth, pid, sid, nosearch);
/* keep track of highest pattern id XXX still used? */
if (pid > mpm_ctx->max_pattern_id)
@ -384,37 +380,37 @@ error:
}
int B3gAddScanPatternCI(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen,
u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid)
u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid, u_int8_t nosearch)
{
return B3gAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */1, /* scan */1, pid, sid);
return B3gAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */1, /* scan */1, pid, sid, nosearch);
}
int B3gAddScanPatternCS(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen,
u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid)
u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid, u_int8_t nosearch)
{
return B3gAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */0, /* scan */1, pid, sid);
return B3gAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */0, /* scan */1, pid, sid, nosearch);
}
int B3gAddPatternCI(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen,
u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid)
{
return B3gAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */1, /* scan */0, pid, sid);
return B3gAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */1, /* scan */0, pid, sid, 0);
}
int B3gAddPatternCS(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen,
u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid)
{
return B3gAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */0, /* scan */0, pid, sid);
return B3gAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */0, /* scan */0, pid, sid, 0);
}
static u_int32_t B3gBloomHash(void *data, u_int16_t datalen, u_int8_t iter, u_int32_t hash_size) {
u_int8_t *d = (u_int8_t *)data;
u_int16_t i;
u_int32_t hash = (u_int32_t)bg_tolower(*d);
u_int32_t hash = (u_int32_t)u8_tolower(*d);
for (i = 1; i < datalen; i++) {
d++;
hash += (bg_tolower(*d)) ^ i;
hash += (u8_tolower(*d)) ^ i;
}
hash <<= (iter+1);
@ -435,6 +431,14 @@ static void B3gPrepareScanHash(MpmCtx *mpm_ctx) {
mpm_ctx->memory_cnt++;
mpm_ctx->memory_size += (sizeof(B3gHashItem *) * ctx->scan_hash_size);
/* 2 byte pattern hash */
ctx->scan_hash2 = (B3gHashItem **)malloc(sizeof(B3gHashItem *) * ctx->scan_hash_size);
if (ctx->scan_hash2 == NULL) goto error;
memset(ctx->scan_hash2, 0, sizeof(B3gHashItem *) * ctx->scan_hash_size);
mpm_ctx->memory_cnt++;
mpm_ctx->memory_size += (sizeof(B3gHashItem *) * ctx->scan_hash_size);
/* alloc the pminlen array */
ctx->scan_pminlen = (u_int8_t *)malloc(sizeof(u_int8_t) * ctx->scan_hash_size);
if (ctx->scan_pminlen == NULL) goto error;
@ -466,17 +470,20 @@ static void B3gPrepareScanHash(MpmCtx *mpm_ctx) {
}
ctx->scan_1_pat_cnt++;
} else if(ctx->parray[i]->len == 2) {
idx = (u_int16_t)(ctx->parray[i]->ci[0] << 8 | ctx->parray[i]->ci[1]);
if (ctx->scan_hash2[idx].flags == 0) {
ctx->scan_hash2[idx].idx = i;
ctx->scan_hash2[idx].flags |= 0x01;
idx = (u_int16_t)(ctx->parray[i]->ci[0] << B3G_HASHSHIFT | ctx->parray[i]->ci[1]);
if (ctx->scan_hash2[idx] == NULL) {
B3gHashItem *hi = B3gAllocHashItem(mpm_ctx);
hi->idx = i;
hi->flags |= 0x01;
ctx->scan_hash2[idx] = hi;
} else {
B3gHashItem *hi = B3gAllocHashItem(mpm_ctx);
hi->idx = i;
hi->flags |= 0x01;
/* Append this HashItem to the list */
B3gHashItem *thi = &ctx->scan_hash2[idx];
B3gHashItem *thi = ctx->scan_hash2[idx];
while (thi->nxt) thi = thi->nxt;
thi->nxt = hi;
}
@ -558,6 +565,22 @@ static void B3gPrepareSearchHash(MpmCtx *mpm_ctx) {
mpm_ctx->memory_cnt++;
mpm_ctx->memory_size += (sizeof(B3gHashItem *) * ctx->search_hash_size);
/* 2 byte pattern hash */
ctx->search_hash2 = (B3gHashItem **)malloc(sizeof(B3gHashItem *) * ctx->search_hash_size);
if (ctx->search_hash2 == NULL) goto error;
memset(ctx->search_hash2, 0, sizeof(B3gHashItem *) * ctx->search_hash_size);
mpm_ctx->memory_cnt++;
mpm_ctx->memory_size += (sizeof(B3gHashItem *) * ctx->scan_hash_size);
/* alloc the pminlen array */
ctx->search_pminlen = (u_int8_t *)malloc(sizeof(u_int8_t) * ctx->search_hash_size);
if (ctx->search_pminlen == NULL) goto error;
memset(ctx->search_pminlen, 0, sizeof(u_int8_t) * ctx->search_hash_size);
mpm_ctx->memory_cnt++;
mpm_ctx->memory_size += (sizeof(u_int8_t) * ctx->search_hash_size);
for (i = 0; i < mpm_ctx->pattern_cnt; i++)
{
/* ignore patterns that have the scan flag set */
@ -581,17 +604,20 @@ static void B3gPrepareSearchHash(MpmCtx *mpm_ctx) {
}
ctx->search_1_pat_cnt++;
} else if(ctx->parray[i]->len == 2) {
idx = (u_int16_t)(ctx->parray[i]->ci[0] << 8 | ctx->parray[i]->ci[1]);
if (ctx->search_hash2[idx].flags == 0) {
ctx->search_hash2[idx].idx = i;
ctx->search_hash2[idx].flags |= 0x01;
idx = (u_int16_t)(ctx->parray[i]->ci[0] << B3G_HASHSHIFT | ctx->parray[i]->ci[1]);
if (ctx->search_hash2[idx] == NULL) {
B3gHashItem *hi = B3gAllocHashItem(mpm_ctx);
hi->idx = i;
hi->flags |= 0x01;
ctx->search_hash2[idx] = hi;
} else {
B3gHashItem *hi = B3gAllocHashItem(mpm_ctx);
hi->idx = i;
hi->flags |= 0x01;
/* Append this HashItem to the list */
B3gHashItem *thi = &ctx->search_hash2[idx];
B3gHashItem *thi = ctx->search_hash2[idx];
while (thi->nxt) thi = thi->nxt;
thi->nxt = hi;
}
@ -604,6 +630,7 @@ static void B3gPrepareSearchHash(MpmCtx *mpm_ctx) {
B3gHashItem *hi = B3gAllocHashItem(mpm_ctx);
hi->idx = i;
hi->flags |= 0x01;
ctx->search_pminlen[idx] = ctx->parray[i]->len;
ctx->search_hash[idx] = hi;
} else {
@ -611,6 +638,9 @@ static void B3gPrepareSearchHash(MpmCtx *mpm_ctx) {
hi->idx = i;
hi->flags |= 0x01;
if (ctx->parray[i]->len < ctx->search_pminlen[idx])
ctx->search_pminlen[idx] = ctx->parray[i]->len;
/* Append this HashItem to the list */
B3gHashItem *thi = ctx->search_hash[idx];
while (thi->nxt) thi = thi->nxt;
@ -619,6 +649,38 @@ static void B3gPrepareSearchHash(MpmCtx *mpm_ctx) {
ctx->search_x_pat_cnt++;
}
}
/* alloc the bloom array */
ctx->search_bloom = (BloomFilter **)malloc(sizeof(BloomFilter *) * ctx->search_hash_size);
if (ctx->search_bloom == NULL) goto error;
memset(ctx->search_bloom, 0, sizeof(BloomFilter *) * ctx->search_hash_size);
mpm_ctx->memory_cnt++;
mpm_ctx->memory_size += (sizeof(BloomFilter *) * ctx->search_hash_size);
int h;
for (h = 0; h < ctx->search_hash_size; h++) {
B3gHashItem *hi = ctx->search_hash[h];
if (hi == NULL)
continue;
ctx->search_bloom[h] = BloomFilterInit(B3G_BLOOMSIZE, 2, B3gBloomHash);
if (ctx->search_bloom[h] == NULL)
continue;
mpm_ctx->memory_cnt += BloomFilterMemoryCnt(ctx->search_bloom[h]);
mpm_ctx->memory_size += BloomFilterMemorySize(ctx->search_bloom[h]);
if (ctx->search_pminlen[h] > 8)
ctx->search_pminlen[h] = 8;
B3gHashItem *thi = hi;
do {
BloomFilterAdd(ctx->search_bloom[h], ctx->parray[thi->idx]->ci, ctx->search_pminlen[h]);
thi = thi->nxt;
} while (thi != NULL);
}
return;
error:
return;
@ -648,8 +710,8 @@ int B3gBuildScanMatchArray(MpmCtx *mpm_ctx) {
if (ctx->parray[a]->len < ctx->scan_m)
continue;
u_int16_t h = B3G_HASH(bg_tolower(ctx->parray[a]->ci[j]),bg_tolower(ctx->parray[a]->ci[j+1]), bg_tolower(ctx->parray[a]->ci[j+2]));
//printf("B3gBuildScanMatchArray: h %u, %c.%c.%c\n", h, bg_tolower(ctx->parray[a]->ci[j]),bg_tolower(ctx->parray[a]->ci[j+1]), bg_tolower(ctx->parray[a]->ci[j+2]));
u_int16_t h = B3G_HASH(u8_tolower(ctx->parray[a]->ci[j]),u8_tolower(ctx->parray[a]->ci[j+1]), u8_tolower(ctx->parray[a]->ci[j+2]));
//printf("B3gBuildScanMatchArray: h %u, %c.%c.%c\n", h, u8_tolower(ctx->parray[a]->ci[j]),u8_tolower(ctx->parray[a]->ci[j+1]), u8_tolower(ctx->parray[a]->ci[j+2]));
ctx->scan_B3G[h] = ctx->scan_B3G[h] | (1 << (ctx->scan_m - j));
}
}
@ -682,8 +744,8 @@ int B3gBuildSearchMatchArray(MpmCtx *mpm_ctx) {
if (ctx->parray[a]->len < ctx->search_m)
continue;
u_int16_t h = B3G_HASH(bg_tolower(ctx->parray[a]->ci[j]),bg_tolower(ctx->parray[a]->ci[j+1]), bg_tolower(ctx->parray[a]->ci[j+2]));
//printf("h %u, %c.%c\n", h, bg_tolower(ctx->parray[a]->ci[j]),bg_tolower(ctx->parray[a]->ci[j+1]));
u_int16_t h = B3G_HASH(u8_tolower(ctx->parray[a]->ci[j]),u8_tolower(ctx->parray[a]->ci[j+1]), u8_tolower(ctx->parray[a]->ci[j+2]));
//printf("h %u, %c.%c\n", h, u8_tolower(ctx->parray[a]->ci[j]),u8_tolower(ctx->parray[a]->ci[j+1]));
ctx->search_B3G[h] = ctx->search_B3G[h] | (1 << (ctx->search_m - j));
}
}
@ -698,7 +760,7 @@ int B3gBuildSearchMatchArray(MpmCtx *mpm_ctx) {
if (strlen(pat) < m)
continue;
u_int16_t h = B3G_HASH16(bg_tolower(pat[a][m-2]),bg_tolower(pat[a][m-1]));
u_int16_t h = B3G_HASH16(u8_tolower(pat[a][m-2]),u8_tolower(pat[a][m-1]));
s = B3G[h];
printf("S0: h %u, %c.%c\n", h, pat[a][m-2], pat[a][m-1]);
@ -713,7 +775,7 @@ int B3gBuildSearchMatchArray(MpmCtx *mpm_ctx) {
printf(" ( nope ) ");
}
h = B3G_HASH16(bg_tolower(pat[a][i-1]),bg_tolower(pat[a][i-0]));
h = B3G_HASH16(u8_tolower(pat[a][i-1]),u8_tolower(pat[a][i-0]));
printf("S: h %u, %c.%c ", h, pat[a][i-1], pat[a][i-0]);
s = (s << 1) & B3G[h];
printf("B3G_S0 %d (s %u, b2g[h] %u)\n", B3G_S0, s, B3G[h]);
@ -781,7 +843,8 @@ int B3gPreparePatterns(MpmCtx *mpm_ctx) {
if (ctx->scan_1_pat_cnt) {
mpm_ctx->Scan = B3gScan1;
if (ctx->scan_2_pat_cnt) {
ctx->MBScan2 = B3gScan2;
mpm_ctx->Scan = B3gScan12;
ctx->MBScan = B3G_SCANFUNC;
}
ctx->MBScan = B3G_SCANFUNC;
} else if (ctx->scan_2_pat_cnt) {
@ -792,12 +855,13 @@ int B3gPreparePatterns(MpmCtx *mpm_ctx) {
if (ctx->search_1_pat_cnt) {
mpm_ctx->Search = B3gSearch1;
if (ctx->search_2_pat_cnt) {
ctx->MBSearch2 = B3gSearch2;
mpm_ctx->Search = B3gSearch12;
ctx->MBSearch = B3G_SEARCHFUNC;
}
ctx->MBSearch = B3gSearch;
ctx->MBSearch = B3G_SEARCHFUNC;
} else if (ctx->search_2_pat_cnt) {
mpm_ctx->Search = B3gSearch2;
ctx->MBSearch = B3gSearch;
ctx->MBSearch = B3G_SEARCHFUNC;
}
return 0;
@ -842,7 +906,7 @@ memcmp_lowercase(u_int8_t *s1, u_int8_t *s2, u_int16_t n) {
* 2 to 4 chars. This way we are more likely to detect
* a miss and thus speed up a little... */
for (i = n - 1; i; i--) {
if (bg_tolower(*(s2+i)) != s1[i])
if (u8_tolower(*(s2+i)) != s1[i])
return 1;
}
@ -939,7 +1003,7 @@ void B3gDestroyCtx(MpmCtx *mpm_ctx) {
mpm_ctx->memory_cnt--;
mpm_ctx->memory_size -= (sizeof(B3gHashItem) * ctx->scan_hash_size);
}
#if 0
if (ctx->search_bloom) {
int h;
for (h = 0; h < ctx->search_hash_size; h++) {
@ -957,7 +1021,7 @@ void B3gDestroyCtx(MpmCtx *mpm_ctx) {
mpm_ctx->memory_cnt--;
mpm_ctx->memory_size -= (sizeof(BloomFilter *) * ctx->search_hash_size);
}
#endif
if (ctx->search_hash) {
int h;
for (h = 0; h < ctx->search_hash_size; h++) {
@ -977,13 +1041,13 @@ void B3gDestroyCtx(MpmCtx *mpm_ctx) {
mpm_ctx->memory_cnt--;
mpm_ctx->memory_size -= (sizeof(u_int8_t) * ctx->scan_hash_size);
}
#if 0
if (ctx->search_pminlen) {
free(ctx->search_pminlen);
mpm_ctx->memory_cnt--;
mpm_ctx->memory_size -= (sizeof(u_int8_t) * ctx->search_hash_size);
}
#endif
free(mpm_ctx->ctx);
mpm_ctx->memory_cnt--;
mpm_ctx->memory_size -= sizeof(B3gCtx);
@ -1056,7 +1120,7 @@ u_int32_t B3gScanBNDMq(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMat
return 0;
while (pos <= (buflen - B3G_Q + 1)) {
u_int16_t h = B3G_HASH(bg_tolower(buf[pos - 1]), bg_tolower(buf[pos]),bg_tolower(buf[pos + 1]));
u_int16_t h = B3G_HASH(u8_tolower(buf[pos - 1]), u8_tolower(buf[pos]),u8_tolower(buf[pos + 1]));
d = ctx->scan_B3G[h];
if (d != 0) {
@ -1070,7 +1134,7 @@ u_int32_t B3gScanBNDMq(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMat
if (j > first) pos = j;
else {
/* get our patterns from the hash */
h = B3G_HASH(bg_tolower(buf[j + ctx->scan_m - 3]), bg_tolower(buf[j + ctx->scan_m - 2]),bg_tolower(buf[j + ctx->scan_m - 1]));
h = B3G_HASH(u8_tolower(buf[j + ctx->scan_m - 3]), u8_tolower(buf[j + ctx->scan_m - 2]),u8_tolower(buf[j + ctx->scan_m - 1]));
if (ctx->scan_bloom[h] != NULL) {
COUNT(tctx->scan_stat_pminlen_calls++);
@ -1137,7 +1201,7 @@ skip_loop:
}
}
h = B3G_HASH(bg_tolower(buf[j - 1]), bg_tolower(buf[j - 0]),bg_tolower(buf[j+1]));
h = B3G_HASH(u8_tolower(buf[j - 1]), u8_tolower(buf[j - 0]),u8_tolower(buf[j+1]));
d = (d << 1) & ctx->scan_B3G[h];
} while (d != 0);
}
@ -1168,8 +1232,8 @@ u_int32_t B3gScan(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQ
d = ~0;
do {
u_int16_t h = B3G_HASH(bg_tolower(buf[pos + j - 1]), bg_tolower(buf[pos + j - 0]),bg_tolower(buf[pos + j + 1]));
// printf("scan: h %u, %c.%c.%c\n", h, bg_tolower(buf[pos + j - 1]), bg_tolower(buf[pos + j - 0]),bg_tolower(buf[pos + j + 1]));
u_int16_t h = B3G_HASH(u8_tolower(buf[pos + j - 1]), u8_tolower(buf[pos + j - 0]),u8_tolower(buf[pos + j + 1]));
// printf("scan: h %u, %c.%c.%c\n", h, u8_tolower(buf[pos + j - 1]), u8_tolower(buf[pos + j - 0]),u8_tolower(buf[pos + j + 1]));
d = ((d << 1) & ctx->scan_B3G[h]);
j = j - 1;
} while (d != 0 && j != 0);
@ -1181,7 +1245,7 @@ u_int32_t B3gScan(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQ
//printf("output at pos %u: ", pos); prt(buf + pos, ctx->scan_m); printf("\n");
/* get our patterns from the hash */
u_int16_t h = B3G_HASH(bg_tolower(buf[pos + ctx->scan_m - 3]), bg_tolower(buf[pos + ctx->scan_m - 2]),bg_tolower(buf[pos + ctx->scan_m - 1]));
u_int16_t h = B3G_HASH(u8_tolower(buf[pos + ctx->scan_m - 3]), u8_tolower(buf[pos + ctx->scan_m - 2]),u8_tolower(buf[pos + ctx->scan_m - 1]));
if (ctx->scan_bloom[h] != NULL) {
COUNT(tctx->scan_stat_pminlen_calls++);
@ -1243,7 +1307,8 @@ u_int32_t B3gScan(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQ
}
}
skip_loop:
pos = pos + ctx->scan_s0;
pos = pos + 1;
//pos = pos + ctx->scan_s0;
} else {
COUNT(tctx->scan_stat_num_shift++);
COUNT(tctx->scan_stat_total_shift += (j + 1));
@ -1256,6 +1321,85 @@ skip_loop:
return matches;
}
u_int32_t B3gScan12(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, u_int8_t *buf, u_int16_t buflen) {
B3gCtx *ctx = (B3gCtx *)mpm_ctx->ctx;
u_int8_t *bufmin = buf;
u_int8_t *bufend = buf + buflen - 1;
u_int32_t cnt = 0;
B3gPattern *p;
MpmEndMatch *em;
B3gHashItem *thi, *hi;
//printf("BUF "); prt(buf,buflen); printf("\n");
while (buf <= bufend) {
u_int8_t h8 = u8_tolower(*buf);
hi = &ctx->scan_hash1[h8];
if (hi->flags & 0x01) {
for (thi = hi; thi != NULL; thi = thi->nxt) {
p = ctx->parray[thi->idx];
if (p->flags & B3G_NOCASE) {
if (h8 == p->ci[0]) {
//printf("CI Exact match: "); prt(p->ci, p->len); printf(" in buf "); prt(buf, p->len);printf(" (B2gSearch1)\n");
for (em = p->em; em; em = em->next) {
if (MpmMatchAppend(mpm_thread_ctx, pmq, em, &mpm_thread_ctx->match[em->id],(buf+1 - bufmin), p->len))
cnt++;
}
}
} else {
if (*buf == p->cs[0]) {
//printf("CS Exact match: "); prt(p->cs, p->len); printf(" in buf "); prt(buf, p->len);printf(" (B2gSearch1)\n");
for (em = p->em; em; em = em->next) {
if (MpmMatchAppend(mpm_thread_ctx, pmq, em, &mpm_thread_ctx->match[em->id],(buf+1 - bufmin), p->len))
cnt++;
}
}
}
}
}
if (buf != bufend) {
/* save one conversion by reusing h8 */
u_int16_t h16 = (u_int16_t)(h8 << B3G_HASHSHIFT | u8_tolower(*(buf+1)));
hi = ctx->scan_hash2[h16];
for (thi = hi; thi != NULL; thi = thi->nxt) {
p = ctx->parray[thi->idx];
if (p->flags & B3G_NOCASE) {
if (h8 == p->ci[0] && u8_tolower(*(buf+1)) == p->ci[1]) {
//printf("CI Exact match: "); prt(p->ci, p->len); printf(" in buf "); prt(buf, p->len);printf(" (B2gSearch1)\n");
for (em = p->em; em; em = em->next) {
if (MpmMatchAppend(mpm_thread_ctx, pmq, em, &mpm_thread_ctx->match[em->id],(buf+1 - bufmin), p->len))
cnt++;
}
}
} else {
if (*buf == p->cs[0] && *(buf+1) == p->cs[1]) {
//printf("CS Exact match: "); prt(p->cs, p->len); printf(" in buf "); prt(buf, p->len);printf(" (B2gSearch1)\n");
for (em = p->em; em; em = em->next) {
if (MpmMatchAppend(mpm_thread_ctx, pmq, em, &mpm_thread_ctx->match[em->id],(buf+1 - bufmin), p->len))
cnt++;
}
}
}
}
}
buf += 1;
}
//printf("B2gSearch12: after 1/2byte cnt %u\n", cnt);
if (ctx->scan_x_pat_cnt > 0) {
/* Pass bufmin on because buf no longer points to the
* start of the buffer. */
cnt += ctx->MBScan(mpm_ctx, mpm_thread_ctx, pmq, bufmin, buflen);
//printf("B2gSearch1: after 2+byte cnt %u\n", cnt);
}
return cnt;
}
u_int32_t B3gScan2(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, u_int8_t *buf, u_int16_t buflen) {
B3gCtx *ctx = (B3gCtx *)mpm_ctx->ctx;
u_int8_t *bufmin = buf;
@ -1271,10 +1415,10 @@ u_int32_t B3gScan2(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcher
//printf("BUF "); prt(buf,buflen); printf("\n");
while (buf <= bufend) {
u_int16_t h = bg_tolower(*buf) << 8 | bg_tolower(*(buf+1));
hi = &ctx->scan_hash2[h];
u_int16_t h = u8_tolower(*buf) << B3G_HASHSHIFT | u8_tolower(*(buf+1));
hi = ctx->scan_hash2[h];
if (hi->flags & 0x01) {
if (hi != NULL) {
for (thi = hi; thi != NULL; thi = thi->nxt) {
p = ctx->parray[thi->idx];
@ -1282,7 +1426,7 @@ u_int32_t B3gScan2(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcher
continue;
if (p->flags & B3G_NOCASE) {
if (bg_tolower(*buf) == p->ci[0] && bg_tolower(*(buf+1)) == p->ci[1]) {
if (u8_tolower(*buf) == p->ci[0] && u8_tolower(*(buf+1)) == p->ci[1]) {
//printf("CI Exact match: "); prt(p->ci, p->len); printf(" in buf "); prt(buf, p->len);printf(" (B3gSearch1)\n");
for (em = p->em; em; em = em->next) {
if (MpmMatchAppend(mpm_thread_ctx, pmq, em, &mpm_thread_ctx->match[em->id],(buf+1 - bufmin), p->len))
@ -1327,7 +1471,7 @@ u_int32_t B3gScan1(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcher
//printf("BUF "); prt(buf,buflen); printf("\n");
while (buf <= bufend) {
u_int8_t h = bg_tolower(*buf);
u_int8_t h = u8_tolower(*buf);
hi = &ctx->scan_hash1[h];
if (hi->flags & 0x01) {
@ -1338,7 +1482,7 @@ u_int32_t B3gScan1(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcher
continue;
if (p->flags & B3G_NOCASE) {
if (bg_tolower(*buf) == p->ci[0]) {
if (u8_tolower(*buf) == p->ci[0]) {
//printf("CI Exact match: "); prt(p->ci, p->len); printf(" in buf "); prt(buf, p->len);printf(" (B3gSearch1)\n");
for (em = p->em; em; em = em->next) {
if (MpmMatchAppend(mpm_thread_ctx, pmq, em, &mpm_thread_ctx->match[em->id],(buf+1 - bufmin), p->len))
@ -1371,6 +1515,113 @@ u_int32_t B3gScan1(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcher
return cnt;
}
u_int32_t B3gSearchBNDMq(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, u_int8_t *buf, u_int16_t buflen) {
B3gCtx *ctx = (B3gCtx *)mpm_ctx->ctx;
#ifdef B3G_COUNTERS
B3gThreadCtx *tctx = (B3gThreadCtx *)mpm_thread_ctx->ctx;
#endif
u_int32_t pos = ctx->search_m - B3G_Q + 1, matches = 0;
B3G_TYPE d;
COUNT(tctx->search_stat_calls++);
COUNT(tctx->search_stat_m_total+=ctx->search_m);
if (buflen < ctx->search_m)
return 0;
while (pos <= (buflen - B3G_Q + 1)) {
u_int16_t h = B3G_HASH(u8_tolower(buf[pos - 1]), u8_tolower(buf[pos]),u8_tolower(buf[pos + 1]));
d = ctx->search_B3G[h];
if (d != 0) {
COUNT(tctx->search_stat_d0++);
u_int j = pos;
u_int first = pos - (ctx->search_m - B3G_Q + 1);
do {
j = j - 1;
if (d >= (1 << (ctx->search_m - 1))) {
if (j > first) pos = j;
else {
/* get our patterns from the hash */
h = B3G_HASH(u8_tolower(buf[j + ctx->search_m - 3]), u8_tolower(buf[j + ctx->search_m - 2]),u8_tolower(buf[j + ctx->search_m - 1]));
if (ctx->search_bloom[h] != NULL) {
COUNT(tctx->search_stat_pminlen_calls++);
COUNT(tctx->search_stat_pminlen_total+=ctx->search_pminlen[h]);
if ((buflen - j) < ctx->search_pminlen[h]) {
goto skip_loop;
} else {
COUNT(tctx->search_stat_bloom_calls++);
if (BloomFilterTest(ctx->search_bloom[h], buf+j, ctx->search_pminlen[h]) == 0) {
COUNT(tctx->search_stat_bloom_hits++);
//printf("Bloom: %p, buflen %u, pos %u, p_min_len %u\n", ctx->scan_bloom[h], buflen, pos, ctx->scan_pminlen[h]);
goto skip_loop;
}
}
}
B3gHashItem *hi = ctx->search_hash[h], *thi;
for (thi = hi; thi != NULL; thi = thi->nxt) {
COUNT(tctx->search_stat_d0_hashloop++);
B3gPattern *p = ctx->parray[thi->idx];
if (p->flags & B3G_NOCASE) {
if (buflen - j < p->len)
continue;
if (memcmp_lowercase(p->ci, buf+j, p->len) == 0) {
//printf("CI Exact match: "); prt(p->ci, p->len); printf("\n");
COUNT(tctx->search_stat_loop_match++);
MpmEndMatch *em;
for (em = p->em; em; em = em->next) {
//printf("em %p id %u\n", em, em->id);
if (MpmMatchAppend(mpm_thread_ctx, pmq, em, &mpm_thread_ctx->match[em->id], j, p->len))
matches++;
}
} else {
COUNT(tctx->search_stat_loop_no_match++);
}
} else {
if (buflen - j < p->len)
continue;
if (memcmp(p->cs, buf+j, p->len) == 0) {
//printf("CS Exact match: "); prt(p->cs, p->len); printf("\n");
COUNT(tctx->search_stat_loop_match++);
MpmEndMatch *em;
for (em = p->em; em; em = em->next) {
//printf("em %p id %u\n", em, em->id);
if (MpmMatchAppend(mpm_thread_ctx, pmq, em, &mpm_thread_ctx->match[em->id], j, p->len))
matches++;
}
} else {
COUNT(tctx->search_stat_loop_no_match++);
}
}
}
skip_loop:
//printf("output at pos %u: ", j); prt(buf + (j), ctx->scan_m); printf("\n");
; /* gcc doesn't like the goto label without this :-S */
}
}
h = B3G_HASH(u8_tolower(buf[j - 1]), u8_tolower(buf[j - 0]),u8_tolower(buf[j+1]));
d = (d << 1) & ctx->search_B3G[h];
} while (d != 0);
}
COUNT(tctx->search_stat_num_shift++);
COUNT(tctx->search_stat_total_shift += (ctx->search_m - B3G_Q + 1));
pos = pos + ctx->search_m - B3G_Q + 1;
}
return matches;
}
u_int32_t B3gSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, u_int8_t *buf, u_int16_t buflen) {
B3gCtx *ctx = (B3gCtx *)mpm_ctx->ctx;
#ifdef B3G_COUNTERS
@ -1388,11 +1639,11 @@ u_int32_t B3gSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatche
d = ~0;
do {
u_int16_t h = B3G_HASH(bg_tolower(buf[pos + j - 1]), bg_tolower(buf[pos + j]),bg_tolower(buf[pos + j + 1]));
u_int16_t h = B3G_HASH(u8_tolower(buf[pos + j - 1]), u8_tolower(buf[pos + j]),u8_tolower(buf[pos + j + 1]));
d &= ctx->search_B3G[h];
d <<= 1;
j = j - 1;
//printf("h %u d %d %c.%c\n", h, d, bg_tolower(buf[pos + j - 1]),bg_tolower(buf[pos + j]));
//printf("h %u d %d %c.%c\n", h, d, u8_tolower(buf[pos + j - 1]),u8_tolower(buf[pos + j]));
} while (d != 0 && j != 0);
/* (partial) match, move on to verification */
@ -1400,7 +1651,26 @@ u_int32_t B3gSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatche
COUNT(tctx->search_stat_d0++);
/* get our patterns from the hash */
u_int16_t h = B3G_HASH(bg_tolower(buf[pos + ctx->search_m - 3]), bg_tolower(buf[pos + ctx->search_m - 2]),bg_tolower(buf[pos + ctx->search_m - 1]));
u_int16_t h = B3G_HASH(u8_tolower(buf[pos + ctx->search_m - 3]), u8_tolower(buf[pos + ctx->search_m - 2]),u8_tolower(buf[pos + ctx->search_m - 1]));
if (ctx->search_bloom[h] != NULL) {
COUNT(tctx->search_stat_pminlen_calls++);
COUNT(tctx->search_stat_pminlen_total+=ctx->search_pminlen[h]);
if ((buflen - pos) < ctx->search_pminlen[h]) {
goto skip_loop;
} else {
COUNT(tctx->search_stat_bloom_calls++);
if (BloomFilterTest(ctx->search_bloom[h], buf+pos, ctx->search_pminlen[h]) == 0) {
COUNT(tctx->search_stat_bloom_hits++);
//printf("Bloom: %p, buflen %u, pos %u, p_min_len %u\n", ctx->search_bloom[h], buflen, pos, ctx->search_pminlen[h]);
goto skip_loop;
}
}
}
B3gHashItem *hi = ctx->search_hash[h], *thi;
for (thi = hi; thi != NULL; thi = thi->nxt) {
B3gPattern *p = ctx->parray[thi->idx];
@ -1444,6 +1714,7 @@ u_int32_t B3gSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatche
}
//printf("output at pos %d: ", pos); prt(buf + pos, ctx->search_m); printf("\n");
skip_loop:
pos = pos + 1;
} else {
COUNT(tctx->search_stat_num_shift++);
@ -1456,6 +1727,85 @@ u_int32_t B3gSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatche
return matches;
}
u_int32_t B3gSearch12(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, u_int8_t *buf, u_int16_t buflen) {
B3gCtx *ctx = (B3gCtx *)mpm_ctx->ctx;
u_int8_t *bufmin = buf;
u_int8_t *bufend = buf + buflen - 1;
u_int32_t cnt = 0;
B3gPattern *p;
MpmEndMatch *em;
B3gHashItem *thi, *hi;
//printf("BUF "); prt(buf,buflen); printf("\n");
while (buf <= bufend) {
u_int8_t h8 = u8_tolower(*buf);
hi = &ctx->search_hash1[h8];
if (hi->flags & 0x01) {
for (thi = hi; thi != NULL; thi = thi->nxt) {
p = ctx->parray[thi->idx];
if (p->flags & B3G_NOCASE) {
if (h8 == p->ci[0]) {
//printf("CI Exact match: "); prt(p->ci, p->len); printf(" in buf "); prt(buf, p->len);printf(" (B2gSearch1)\n");
for (em = p->em; em; em = em->next) {
if (MpmMatchAppend(mpm_thread_ctx, pmq, em, &mpm_thread_ctx->match[em->id],(buf+1 - bufmin), p->len))
cnt++;
}
}
} else {
if (*buf == p->cs[0]) {
//printf("CS Exact match: "); prt(p->cs, p->len); printf(" in buf "); prt(buf, p->len);printf(" (B2gSearch1)\n");
for (em = p->em; em; em = em->next) {
if (MpmMatchAppend(mpm_thread_ctx, pmq, em, &mpm_thread_ctx->match[em->id],(buf+1 - bufmin), p->len))
cnt++;
}
}
}
}
}
if (buf != bufend) {
/* save one conversion by reusing h8 */
u_int16_t h16 = (u_int16_t)(h8 << B3G_HASHSHIFT | u8_tolower(*(buf+1)));
hi = ctx->search_hash2[h16];
for (thi = hi; thi != NULL; thi = thi->nxt) {
p = ctx->parray[thi->idx];
if (p->flags & B3G_NOCASE) {
if (h8 == p->ci[0] && u8_tolower(*(buf+1)) == p->ci[1]) {
//printf("CI Exact match: "); prt(p->ci, p->len); printf(" in buf "); prt(buf, p->len);printf(" (B2gSearch1)\n");
for (em = p->em; em; em = em->next) {
if (MpmMatchAppend(mpm_thread_ctx, pmq, em, &mpm_thread_ctx->match[em->id],(buf+1 - bufmin), p->len))
cnt++;
}
}
} else {
if (*buf == p->cs[0] && *(buf+1) == p->cs[1]) {
//printf("CS Exact match: "); prt(p->cs, p->len); printf(" in buf "); prt(buf, p->len);printf(" (B2gSearch1)\n");
for (em = p->em; em; em = em->next) {
if (MpmMatchAppend(mpm_thread_ctx, pmq, em, &mpm_thread_ctx->match[em->id],(buf+1 - bufmin), p->len))
cnt++;
}
}
}
}
}
buf += 1;
}
//printf("B2gSearch12: after 1/2byte cnt %u\n", cnt);
if (ctx->search_x_pat_cnt > 0) {
/* Pass bufmin on because buf no longer points to the
* start of the buffer. */
cnt += ctx->MBSearch(mpm_ctx, mpm_thread_ctx, pmq, bufmin, buflen);
//printf("B2gSearch1: after 2+byte cnt %u\n", cnt);
}
return cnt;
}
u_int32_t B3gSearch2(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatcherQueue *pmq, u_int8_t *buf, u_int16_t buflen) {
B3gCtx *ctx = (B3gCtx *)mpm_ctx->ctx;
u_int8_t *bufmin = buf;
@ -1471,10 +1821,10 @@ u_int32_t B3gSearch2(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatch
//printf("BUF "); prt(buf,buflen); printf("\n");
while (buf <= bufend) {
u_int16_t h = bg_tolower(*buf) << 8 | bg_tolower(*(buf+1));
hi = &ctx->search_hash2[h];
u_int16_t h = u8_tolower(*buf) << B3G_HASHSHIFT | u8_tolower(*(buf+1));
hi = ctx->search_hash2[h];
if (hi->flags & 0x01) {
if (hi != NULL) {
for (thi = hi; thi != NULL; thi = thi->nxt) {
p = ctx->parray[thi->idx];
@ -1482,7 +1832,7 @@ u_int32_t B3gSearch2(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatch
continue;
if (p->flags & B3G_NOCASE) {
if (bg_tolower(*buf) == p->ci[0] && bg_tolower(*(buf+1)) == p->ci[1]) {
if (u8_tolower(*buf) == p->ci[0] && u8_tolower(*(buf+1)) == p->ci[1]) {
//printf("CI Exact match: "); prt(p->ci, p->len); printf(" in buf "); prt(buf, p->len);printf(" (B3gSearch1)\n");
for (em = p->em; em; em = em->next) {
if (MpmMatchAppend(mpm_thread_ctx, pmq, em, &mpm_thread_ctx->match[em->id],(buf+1 - bufmin), p->len))
@ -1529,7 +1879,7 @@ u_int32_t B3gSearch1(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatch
if (mpm_ctx->search_minlen == 1) {
while (buf <= bufend) {
u_int8_t h = bg_tolower(*buf);
u_int8_t h = u8_tolower(*buf);
hi = &ctx->search_hash1[h];
if (hi->flags & 0x01) {
@ -1540,7 +1890,7 @@ u_int32_t B3gSearch1(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PatternMatch
continue;
if (p->flags & B3G_NOCASE) {
if (bg_tolower(*buf) == p->ci[0]) {
if (u8_tolower(*buf) == p->ci[0]) {
//printf("CI Exact match: "); prt(p->ci, p->len); printf(" in buf "); prt(buf, p->len);printf(" (B3gSearch1)\n");
for (em = p->em; em; em = em->next) {
if (MpmMatchAppend(mpm_thread_ctx, pmq, em, &mpm_thread_ctx->match[em->id],(buf+1 - bufmin), p->len))
@ -1703,7 +2053,7 @@ static int B3gTestScan01 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_B3G);
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 0, 0); /* 1 match */
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 0, 0, 0); /* 1 match */
B3gPreparePatterns(&mpm_ctx);
B3gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */);
@ -1728,7 +2078,7 @@ static int B3gTestScan02 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_B3G);
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abce", 4, 0, 0, 0, 0); /* 1 match */
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abce", 4, 0, 0, 0, 0, 0); /* 1 match */
B3gPreparePatterns(&mpm_ctx);
B3gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */);
@ -1753,9 +2103,9 @@ static int B3gTestScan03 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_B3G);
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 0, 0); /* 1 match */
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"bcde", 4, 0, 0, 1, 0); /* 1 match */
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"fghj", 4, 0, 0, 2, 0); /* 1 match */
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 0, 0, 0); /* 1 match */
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"bcde", 4, 0, 0, 1, 0, 0); /* 1 match */
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"fghj", 4, 0, 0, 2, 0, 0); /* 1 match */
B3gPreparePatterns(&mpm_ctx);
B3gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 3 /* 3 patterns */);
@ -1781,9 +2131,9 @@ static int B3gTestScan04 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_B3G);
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 0, 0); /* 1 match */
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"bcdegh", 6, 0, 0, 1, 0); /* 1 match */
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"fghjxyz", 7, 0, 0, 2, 0); /* 1 match */
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 0, 0, 0); /* 1 match */
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"bcdegh", 6, 0, 0, 1, 0, 0); /* 1 match */
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"fghjxyz", 7, 0, 0, 2, 0, 0); /* 1 match */
B3gPreparePatterns(&mpm_ctx);
B3gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 3 /* 3 patterns */);
@ -1809,9 +2159,9 @@ static int B3gTestScan05 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_B3G);
B3gAddScanPatternCI(&mpm_ctx, (u_int8_t *)"ABCD", 4, 0, 0, 0, 0); /* 1 match */
B3gAddScanPatternCI(&mpm_ctx, (u_int8_t *)"bCdEfG", 6, 0, 0, 1, 0); /* 1 match */
B3gAddScanPatternCI(&mpm_ctx, (u_int8_t *)"fghJikl", 7, 0, 0, 2, 0); /* 1 match */
B3gAddScanPatternCI(&mpm_ctx, (u_int8_t *)"ABCD", 4, 0, 0, 0, 0, 0); /* 1 match */
B3gAddScanPatternCI(&mpm_ctx, (u_int8_t *)"bCdEfG", 6, 0, 0, 1, 0, 0); /* 1 match */
B3gAddScanPatternCI(&mpm_ctx, (u_int8_t *)"fghJikl", 7, 0, 0, 2, 0, 0); /* 1 match */
B3gPreparePatterns(&mpm_ctx);
B3gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 3 /* 3 patterns */);
@ -1836,7 +2186,7 @@ static int B3gTestScan06 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_B3G);
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 0, 0); /* 1 match */
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 0, 0, 0); /* 1 match */
B3gPreparePatterns(&mpm_ctx);
B3gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */);
@ -1862,12 +2212,12 @@ static int B3gTestScan07 (void) {
MpmInitCtx(&mpm_ctx, MPM_B3G);
//B3gCtx *ctx = (B3gCtx *)mpm_ctx.ctx;
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"A", 1, 0, 0, 0, 0); /* should match 30 times */
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"AA", 2, 0, 0, 1, 0); /* should match 29 times */
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"AAA", 3, 0, 0, 2, 0); /* should match 28 times */
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"AAAAA", 5, 0, 0, 3, 0); /* 26 */
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"AAAAAAAAAA", 10, 0, 0, 4, 0); /* 21 */
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 30, 0, 0, 5, 0); /* 1 */
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"A", 1, 0, 0, 0, 0, 0); /* should match 30 times */
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"AA", 2, 0, 0, 1, 0, 0); /* should match 29 times */
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"AAA", 3, 0, 0, 2, 0, 0); /* should match 28 times */
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"AAAAA", 5, 0, 0, 3, 0, 0); /* 26 */
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"AAAAAAAAAA", 10, 0, 0, 4, 0, 0); /* 21 */
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 30, 0, 0, 5, 0, 0); /* 1 */
/* total matches: 135 */
B3gPreparePatterns(&mpm_ctx);
@ -1893,7 +2243,7 @@ static int B3gTestScan08 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_B3G);
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 0, 0); /* 1 match */
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 0, 0, 0); /* 1 match */
B3gPreparePatterns(&mpm_ctx);
B3gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */);
@ -1918,7 +2268,7 @@ static int B3gTestScan09 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_B3G);
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"ab", 2, 0, 0, 0, 0); /* 1 match */
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"ab", 2, 0, 0, 0, 0, 0); /* 1 match */
B3gPreparePatterns(&mpm_ctx);
B3gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */);
@ -1943,7 +2293,7 @@ static int B3gTestScan10 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_B3G);
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abcdefgh", 8, 0, 0, 0, 0); /* 1 match */
B3gAddScanPatternCS(&mpm_ctx, (u_int8_t *)"abcdefgh", 8, 0, 0, 0, 0, 0); /* 1 match */
B3gPreparePatterns(&mpm_ctx);
B3gThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1 /* 1 pattern */);

@ -8,16 +8,16 @@
#define B3G_SCAN 0x02
//#define B3G_HASHSIZE 65536
#define B3G_HASHSIZE 32768
//#define B3G_HASHSIZE 32768
//#define B3G_HASHSIZE 16384
//#define B3G_HASHSIZE 8192
//#define B3G_HASHSIZE 4096
#define B3G_HASHSIZE 4096
//#define B3G_HASHSHIFT 8
#define B3G_HASHSHIFT 7
//#define B3G_HASHSHIFT 7
//#define B3G_HASHSHIFT 6
//#define B3G_HASHSHIFT 5
//#define B3G_HASHSHIFT 4
#define B3G_HASHSHIFT 4
#define B3G_TYPE u_int32_t
//#define B3G_TYPE u_int16_t
@ -34,6 +34,9 @@
//#define B3G_SCANFUNC B3gScan
#define B3G_SCANFUNC B3gScanBNDMq
//#define B3G_SEARCHFUNC B3gSearch
#define B3G_SEARCHFUNC B3gSearchBNDMq
//#define B3G_COUNTERS
typedef struct _B3gPattern {
@ -78,11 +81,16 @@ typedef struct _B3gCtx {
of the patters in a hash bucket. Used
for the BloomFilter. */
B3gHashItem scan_hash1[256];
B3gHashItem scan_hash2[65536];
B3gHashItem **scan_hash2;
u_int32_t search_hash_size;
B3gHashItem **search_hash;
BloomFilter **search_bloom;
u_int8_t *search_pminlen; /* array containing the minimal length
of the patters in a hash bucket. Used
for the BloomFilter. */
B3gHashItem search_hash1[256];
B3gHashItem search_hash2[65536];
B3gHashItem **search_hash2;
/* we store our own multi byte scan ptr here for B3gSearch1 */
u_int32_t (*MBScan2)(struct _MpmCtx *, struct _MpmThreadCtx *, PatternMatcherQueue *, u_int8_t *, u_int16_t);

@ -43,8 +43,8 @@ void WmInitCtx (MpmCtx *mpm_ctx);
void WmThreadInitCtx(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, u_int32_t);
void WmDestroyCtx(MpmCtx *mpm_ctx);
void WmThreadDestroyCtx(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx);
int WmAddScanPatternCI(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen, u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid);
int WmAddScanPatternCS(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen, u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid);
int WmAddScanPatternCI(MpmCtx *, u_int8_t *, u_int16_t, u_int16_t, u_int16_t, u_int32_t, u_int32_t, u_int8_t);
int WmAddScanPatternCS(MpmCtx *, u_int8_t *, u_int16_t, u_int16_t, u_int16_t, u_int32_t, u_int32_t, u_int8_t);
int WmAddPatternCI(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen, u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid);
int WmAddPatternCS(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen, u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid);
int WmPreparePatterns(MpmCtx *mpm_ctx);
@ -108,7 +108,8 @@ void MpmWuManberRegister (void) {
*
* Only used in the initialization phase */
static inline void WmEndMatchAppend(MpmCtx *mpm_ctx, WmPattern *p,
u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid)
u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid,
u_int8_t nosearch)
{
MpmEndMatch *em = MpmAllocEndMatch(mpm_ctx);
if (em == NULL) {
@ -121,6 +122,9 @@ static inline void WmEndMatchAppend(MpmCtx *mpm_ctx, WmPattern *p,
em->depth = depth;
em->offset = offset;
if (nosearch)
em->flags |= MPM_ENDMATCH_NOSEARCH;
if (p->em == NULL) {
p->em = em;
return;
@ -353,7 +357,7 @@ void WmFreePattern(MpmCtx *mpm_ctx, WmPattern *p) {
* pid: pattern id
* sid: signature id (internal id)
*/
static inline int WmAddPattern(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen, u_int16_t offset, u_int16_t depth, char nocase, char scan, u_int32_t pid, u_int32_t sid) {
static inline int WmAddPattern(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen, u_int16_t offset, u_int16_t depth, char nocase, char scan, u_int32_t pid, u_int32_t sid, u_int8_t nosearch) {
WmCtx *ctx = (WmCtx *)mpm_ctx->ctx;
// printf("WmAddPattern: ctx %p \"", mpm_ctx); prt(pat, patlen);
@ -429,7 +433,7 @@ static inline int WmAddPattern(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen,
}
/* we need a match */
WmEndMatchAppend(mpm_ctx, p, offset, depth, pid, sid);
WmEndMatchAppend(mpm_ctx, p, offset, depth, pid, sid, nosearch);
/* keep track of highest pattern id XXX still used? */
if (pid > mpm_ctx->max_pattern_id)
@ -445,27 +449,27 @@ error:
}
int WmAddScanPatternCI(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen,
u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid)
u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid, u_int8_t nosearch)
{
return WmAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */1, /* scan */1, pid, sid);
return WmAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */1, /* scan */1, pid, sid, nosearch);
}
int WmAddScanPatternCS(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen,
u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid)
u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid, u_int8_t nosearch)
{
return WmAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */0, /* scan */1, pid, sid);
return WmAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */0, /* scan */1, pid, sid, nosearch);
}
int WmAddPatternCI(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen,
u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid)
{
return WmAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */1, /* scan */0, pid, sid);
return WmAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */1, /* scan */0, pid, sid, 0);
}
int WmAddPatternCS(MpmCtx *mpm_ctx, u_int8_t *pat, u_int16_t patlen,
u_int16_t offset, u_int16_t depth, u_int32_t pid, u_int32_t sid)
{
return WmAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */0, /* scan */0, pid, sid);
return WmAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */0, /* scan */0, pid, sid, 0);
}
static u_int32_t WmBloomHash(void *data, u_int16_t datalen, u_int8_t iter, u_int32_t hash_size) {
@ -2439,7 +2443,7 @@ int WmTestInitAddPattern01 (void) {
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1);
int ret = WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 1234, 0);
int ret = WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 1234, 0, 0);
if (ret == 0)
result = 1;
@ -2457,7 +2461,7 @@ int WmTestInitAddPattern02 (void) {
WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1);
WmCtx *ctx = (WmCtx *)mpm_ctx.ctx;
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 1234, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 1234, 0, 0);
if (ctx->init_hash != NULL)
result = 1;
@ -2475,7 +2479,7 @@ int WmTestInitAddPattern03 (void) {
WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1);
WmCtx *ctx = (WmCtx *)mpm_ctx.ctx;
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 1234, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 1234, 0, 0);
WmPattern *pat = WmInitHashLookup(ctx, (u_int8_t *)"abcd", 4, 1);
if (pat != NULL) {
if (pat->len == 4)
@ -2496,7 +2500,7 @@ int WmTestInitAddPattern04 (void) {
WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1);
WmCtx *ctx = (WmCtx *)mpm_ctx.ctx;
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 1234, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 1234, 0, 0);
WmPattern *pat = WmInitHashLookup(ctx, (u_int8_t *)"abcd", 4, 1);
if (pat != NULL) {
if (pat->flags & WUMANBER_NOCASE)
@ -2517,7 +2521,7 @@ int WmTestInitAddPattern05 (void) {
WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1);
WmCtx *ctx = (WmCtx *)mpm_ctx.ctx;
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 0, 0, 1234, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 0, 0, 1234, 0, 0);
WmPattern *pat = WmInitHashLookup(ctx, (u_int8_t *)"abcd", 4, 0);
if (pat != NULL) {
if (!(pat->flags & WUMANBER_NOCASE))
@ -2538,7 +2542,7 @@ int WmTestInitAddPattern06 (void) {
WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1);
WmCtx *ctx = (WmCtx *)mpm_ctx.ctx;
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 1234, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 1234, 0, 0);
WmPattern *pat = WmInitHashLookup(ctx, (u_int8_t *)"abcd", 4, 1);
if (pat != NULL) {
if (memcmp(pat->cs, "abcd", 4) == 0)
@ -2558,7 +2562,7 @@ int WmTestInitAddPattern07 (void) {
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 1234, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 1234, 0, 0);
if (mpm_ctx.max_pattern_id == 1234)
result = 1;
@ -2573,7 +2577,7 @@ int WmTestPrepare01 (void) {
MpmCtx mpm_ctx;
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmAddPattern(&mpm_ctx, (u_int8_t *)"a", 1, 0, 0, 1, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"a", 1, 0, 0, 1, 0, 0, 0, 0);
WmPreparePatterns(&mpm_ctx);
if (mpm_ctx.Search == WmSearch1)
@ -2588,7 +2592,7 @@ int WmTestPrepare02 (void) {
MpmCtx mpm_ctx;
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 0, 0, 0);
WmPreparePatterns(&mpm_ctx);
WmCtx *ctx = (WmCtx *)mpm_ctx.ctx;
@ -2604,7 +2608,7 @@ int WmTestPrepare03 (void) {
MpmCtx mpm_ctx;
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 0, 0, 0);
WmPreparePatterns(&mpm_ctx);
WmCtx *ctx = (WmCtx *)mpm_ctx.ctx;
@ -2622,7 +2626,7 @@ int WmTestPrepare04 (void) {
MpmCtx mpm_ctx;
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmAddPattern(&mpm_ctx, (u_int8_t *)"a", 1, 0, 0, 1, 1, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"a", 1, 0, 0, 1, 1, 0, 0, 0);
WmPreparePatterns(&mpm_ctx);
if (mpm_ctx.Scan == WmScan1)
@ -2637,7 +2641,7 @@ int WmTestPrepare05 (void) {
MpmCtx mpm_ctx;
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 1, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 1, 0, 0, 0);
WmPreparePatterns(&mpm_ctx);
WmCtx *ctx = (WmCtx *)mpm_ctx.ctx;
@ -2653,7 +2657,7 @@ int WmTestPrepare06 (void) {
MpmCtx mpm_ctx;
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 1, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 1, 0, 0, 0);
WmPreparePatterns(&mpm_ctx);
WmCtx *ctx = (WmCtx *)mpm_ctx.ctx;
@ -2673,7 +2677,7 @@ int WmTestSearch01 (void) {
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 0, 0, 0);
WmPreparePatterns(&mpm_ctx);
WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1);
//mpm_ctx.PrintCtx(&mpm_ctx);
@ -2699,7 +2703,7 @@ int WmTestSearch01Hash12 (void) {
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmCtx *ctx = (WmCtx *)mpm_ctx.ctx;
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 0, 0, 0);
ctx->search_hash_size = HASH12_SIZE;
WmPreparePatterns(&mpm_ctx);
@ -2727,7 +2731,7 @@ int WmTestSearch01Hash14 (void) {
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmCtx *ctx = (WmCtx *)mpm_ctx.ctx;
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 0, 0, 0);
ctx->search_hash_size = HASH14_SIZE;
WmPreparePatterns(&mpm_ctx);
@ -2755,7 +2759,7 @@ int WmTestSearch01Hash15 (void) {
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmCtx *ctx = (WmCtx *)mpm_ctx.ctx;
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 0, 0, 0);
ctx->search_hash_size = HASH15_SIZE;
WmPreparePatterns(&mpm_ctx);
@ -2783,7 +2787,7 @@ int WmTestSearch01Hash16 (void) {
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmCtx *ctx = (WmCtx *)mpm_ctx.ctx;
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 0, 0, 0);
ctx->search_hash_size = HASH16_SIZE;
WmPreparePatterns(&mpm_ctx);
@ -2809,7 +2813,7 @@ int WmTestSearch02 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 0, 0, 0);
WmPreparePatterns(&mpm_ctx);
WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1);
@ -2830,7 +2834,7 @@ int WmTestSearch03 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 1, 0, 0, 0, 0);
WmPreparePatterns(&mpm_ctx);
WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1);
@ -2852,7 +2856,7 @@ int WmTestSearch04 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmAddPattern(&mpm_ctx, (u_int8_t *)"bcde", 4, 0, 0, 1, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"bcde", 4, 0, 0, 1, 0, 0, 0, 0);
WmPreparePatterns(&mpm_ctx);
WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1);
@ -2873,7 +2877,7 @@ int WmTestSearch05 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmAddPattern(&mpm_ctx, (u_int8_t *)"efgh", 4, 0, 0, 1, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"efgh", 4, 0, 0, 1, 0, 0, 0, 0);
WmPreparePatterns(&mpm_ctx);
WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1);
@ -2894,7 +2898,7 @@ int WmTestSearch06 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmAddPattern(&mpm_ctx, (u_int8_t *)"eFgH", 4, 0, 0, 1, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"eFgH", 4, 0, 0, 1, 0, 0, 0, 0);
WmPreparePatterns(&mpm_ctx);
WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1);
@ -2915,8 +2919,8 @@ int WmTestSearch07 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 0, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"eFgH", 4, 0, 0, 1, 0, 1, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcd", 4, 0, 0, 0, 0, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"eFgH", 4, 0, 0, 1, 0, 1, 0, 0);
WmPreparePatterns(&mpm_ctx);
WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 2);
@ -2937,8 +2941,8 @@ int WmTestSearch08 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcde", 5, 0, 0, 1, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"bcde", 4, 0, 0, 1, 0, 1, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"abcde", 5, 0, 0, 1, 0, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"bcde", 4, 0, 0, 1, 0, 1, 0, 0);
WmPreparePatterns(&mpm_ctx);
WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 2);
@ -2959,7 +2963,7 @@ int WmTestSearch09 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmAddPattern(&mpm_ctx, (u_int8_t *)"ab", 2, 0, 0, 1, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"ab", 2, 0, 0, 1, 0, 0, 0, 0);
WmPreparePatterns(&mpm_ctx);
WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 1);
@ -2980,8 +2984,8 @@ int WmTestSearch10 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmAddPattern(&mpm_ctx, (u_int8_t *)"bc", 2, 0, 0, 1, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"gh", 2, 0, 0, 1, 0, 1, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"bc", 2, 0, 0, 1, 0, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"gh", 2, 0, 0, 1, 0, 1, 0, 0);
WmPreparePatterns(&mpm_ctx);
WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 2);
@ -3002,9 +3006,9 @@ int WmTestSearch11 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmAddPattern(&mpm_ctx, (u_int8_t *)"a", 1, 0, 0, 1, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"d", 1, 0, 0, 1, 0, 1, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"h", 1, 0, 0, 1, 0, 2, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"a", 1, 0, 0, 1, 0, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"d", 1, 0, 0, 1, 0, 1, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"h", 1, 0, 0, 1, 0, 2, 0, 0);
WmPreparePatterns(&mpm_ctx);
WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 3);
@ -3025,9 +3029,9 @@ int WmTestSearch12 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmAddPattern(&mpm_ctx, (u_int8_t *)"A", 1, 0, 0, 1, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"d", 1, 0, 0, 1, 0, 1, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"Z", 1, 0, 0, 1, 0, 2, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"A", 1, 0, 0, 1, 0, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"d", 1, 0, 0, 1, 0, 1, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"Z", 1, 0, 0, 1, 0, 2, 0, 0);
WmPreparePatterns(&mpm_ctx);
WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 3);
@ -3050,9 +3054,9 @@ int WmTestSearch13 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmAddPattern(&mpm_ctx, (u_int8_t *)"a", 1, 0, 0, 1, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"de",2, 0, 0, 1, 0, 1, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"h", 1, 0, 0, 1, 0, 2, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"a", 1, 0, 0, 1, 0, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"de",2, 0, 0, 1, 0, 1, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"h", 1, 0, 0, 1, 0, 2, 0, 0);
WmPreparePatterns(&mpm_ctx);
WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 3);
@ -3075,9 +3079,9 @@ int WmTestSearch14 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmAddPattern(&mpm_ctx, (u_int8_t *)"A", 1, 0, 0, 1, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"de",2, 0, 0, 1, 0, 1, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"Z", 1, 0, 0, 1, 0, 2, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"A", 1, 0, 0, 1, 0, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"de",2, 0, 0, 1, 0, 1, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"Z", 1, 0, 0, 1, 0, 2, 0, 0);
WmPreparePatterns(&mpm_ctx);
WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 3);
@ -3098,9 +3102,9 @@ int WmTestSearch15 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmAddPattern(&mpm_ctx, (u_int8_t *)"A", 1, 0, 0, 1, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"de",2, 0, 0, 1, 0, 1, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"Z", 1, 0, 0, 1, 0, 2, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"A", 1, 0, 0, 1, 0, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"de",2, 0, 0, 1, 0, 1, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"Z", 1, 0, 0, 1, 0, 2, 0, 0);
WmPreparePatterns(&mpm_ctx);
WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 3);
@ -3124,9 +3128,9 @@ int WmTestSearch16 (void) {
MpmThreadCtx mpm_thread_ctx;
MpmInitCtx(&mpm_ctx, MPM_WUMANBER);
WmAddPattern(&mpm_ctx, (u_int8_t *)"A", 1, 0, 0, 1, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"de",2, 0, 0, 1, 0, 1, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"Z", 1, 0, 0, 1, 0, 2, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"A", 1, 0, 0, 1, 0, 0, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"de",2, 0, 0, 1, 0, 1, 0, 0);
WmAddPattern(&mpm_ctx, (u_int8_t *)"Z", 1, 0, 0, 1, 0, 2, 0, 0);
WmPreparePatterns(&mpm_ctx);
WmThreadInitCtx(&mpm_ctx, &mpm_thread_ctx, 3);

@ -138,6 +138,11 @@ MpmMatchAppend(MpmThreadCtx *thread_ctx, PatternMatcherQueue *pmq, MpmEndMatch *
pmq->sig_id_array[pmq->sig_id_array_cnt] = em->sig_id;
pmq->sig_id_array_cnt++;
}
/* nosearch flag */
if (pmq->mode == PMQ_MODE_SCAN && !(em->flags & MPM_ENDMATCH_NOSEARCH)) {
pmq->searchable++;
}
}
#ifdef DEBUG

@ -3,9 +3,10 @@
#ifndef __UTIL_MPM_H__
#define __UTIL_MPM_H__
#define MPM_ENDMATCH_SINGLE 0x01 /* A single match is sufficient */
#define MPM_ENDMATCH_OFFSET 0x02 /* has offset setting */
#define MPM_ENDMATCH_DEPTH 0x04 /* has depth setting */
#define MPM_ENDMATCH_SINGLE 0x01 /* A single match is sufficient. No depth, offset, etc settings. */
#define MPM_ENDMATCH_OFFSET 0x02 /* has offset setting */
#define MPM_ENDMATCH_DEPTH 0x04 /* has depth setting */
#define MPM_ENDMATCH_NOSEARCH 0x08 /* if this matches, no search is required (for this pattern) */
enum {
MPM_TRIE,
@ -72,6 +73,8 @@ typedef struct _PatternMatcherQueue {
u_int32_t sig_id_array_cnt;
u_int8_t *sig_bitarray;
char mode; /* 0: scan, 1: search */
u_int32_t searchable; /* counter of the number of matches that
require a search-followup */
} PatternMatcherQueue;
typedef struct _MpmCtx {
@ -81,8 +84,8 @@ typedef struct _MpmCtx {
void (*InitThreadCtx)(struct _MpmCtx *, struct _MpmThreadCtx *, u_int32_t);
void (*DestroyCtx)(struct _MpmCtx *);
void (*DestroyThreadCtx)(struct _MpmCtx *, struct _MpmThreadCtx *);
int (*AddScanPattern)(struct _MpmCtx *, u_int8_t *, u_int16_t, u_int16_t, u_int16_t, u_int32_t, u_int32_t);
int (*AddScanPatternNocase)(struct _MpmCtx *, u_int8_t *, u_int16_t, u_int16_t, u_int16_t, u_int32_t, u_int32_t);
int (*AddScanPattern)(struct _MpmCtx *, u_int8_t *, u_int16_t, u_int16_t, u_int16_t, u_int32_t, u_int32_t, u_int8_t);
int (*AddScanPatternNocase)(struct _MpmCtx *, u_int8_t *, u_int16_t, u_int16_t, u_int16_t, u_int32_t, u_int32_t, u_int8_t);
int (*AddPattern)(struct _MpmCtx *, u_int8_t *, u_int16_t, u_int16_t, u_int16_t, u_int32_t, u_int32_t);
int (*AddPatternNocase)(struct _MpmCtx *, u_int8_t *, u_int16_t, u_int16_t, u_int16_t, u_int32_t, u_int32_t);
int (*Prepare)(struct _MpmCtx *);
@ -118,8 +121,8 @@ typedef struct MpmTableElmt {
void (*InitThreadCtx)(struct _MpmCtx *, struct _MpmThreadCtx *, u_int32_t);
void (*DestroyCtx)(struct _MpmCtx *);
void (*DestroyThreadCtx)(struct _MpmCtx *, struct _MpmThreadCtx *);
int (*AddScanPattern)(struct _MpmCtx *, u_int8_t *, u_int16_t, u_int16_t, u_int16_t, u_int32_t, u_int32_t);
int (*AddScanPatternNocase)(struct _MpmCtx *, u_int8_t *, u_int16_t, u_int16_t, u_int16_t, u_int32_t, u_int32_t);
int (*AddScanPattern)(struct _MpmCtx *, u_int8_t *, u_int16_t, u_int16_t, u_int16_t, u_int32_t, u_int32_t, u_int8_t);
int (*AddScanPatternNocase)(struct _MpmCtx *, u_int8_t *, u_int16_t, u_int16_t, u_int16_t, u_int32_t, u_int32_t, u_int8_t);
int (*AddPattern)(struct _MpmCtx *, u_int8_t *, u_int16_t, u_int16_t, u_int16_t, u_int32_t, u_int32_t);
int (*AddPatternNocase)(struct _MpmCtx *, u_int8_t *, u_int16_t, u_int16_t, u_int16_t, u_int32_t, u_int32_t);
int (*Prepare)(struct _MpmCtx *);

@ -179,6 +179,14 @@ int main(int argc, char **argv)
setup_signal_handler(SIGHUP, handle_sighup);
//pthread_sigmask(SIG_BLOCK, &set, 0);
/* create table for O(1) lowercase conversion lookup */
u_int8_t c = 0;
for ( ; c < 255; c++) {
if (c >= 'A' && c <= 'Z')
g_u8_lowercasetable[c] = (c + ('a' - 'A'));
else
g_u8_lowercasetable[c] = c;
}
/* hardcoded initialization code */
MpmTableSetup(); /* load the pattern matchers */
SigTableSetup(); /* load the rule keywords */
@ -216,9 +224,9 @@ int main(int argc, char **argv)
BloomFilterCountingRegisterTests();
MpmRegisterTests();
SigRegisterTests();
UtRunTests();
//UtRunTests();
UtCleanup();
exit(1);
//exit(1);
//LoadConfig();
//exit(1);
@ -457,21 +465,21 @@ int main(int argc, char **argv)
printf("ERROR: TmModuleGetByName DecodeNFQ failed\n");
exit(1);
}
TmVarSlotSetFuncAppend(tv_main,tm_module);
TmVarSlotSetFuncAppend(tv_main,tm_module,NULL);
tm_module = TmModuleGetByName("Detect");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName Detect failed\n");
exit(1);
}
TmVarSlotSetFuncAppend(tv_main,tm_module);
TmVarSlotSetFuncAppend(tv_main,tm_module,(void *)g_de_ctx);
tm_module = TmModuleGetByName("VerdictNFQ");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName VerdictNFQ failed\n");
exit(1);
}
TmVarSlotSetFuncAppend(tv_main,tm_module);
TmVarSlotSetFuncAppend(tv_main,tm_module,NULL);
/*
tm_module = TmModuleGetByName("RespondReject");
if (tm_module == NULL) {
@ -675,13 +683,17 @@ int main(int argc, char **argv)
printf("ERROR: TmModuleGetByName failed for ReceiveNFQ\n");
exit(1);
}
Tm1SlotSetFunc(tv_receivenfq,tm_module);
Tm1SlotSetFunc(tv_receivenfq,tm_module,NULL);
TmThreadSetCPUAffinity(tv_receivenfq,0);
if (TmThreadSpawn(tv_receivenfq) != 0) {
printf("ERROR: TmThreadSpawn failed\n");
exit(1);
}
/* wait for queue 0 to settle */
sleep(1);
/* create the threads */
ThreadVars *tv_receivenfq2 = TmThreadCreate("ReceiveNFQ2","packetpool","packetpool","pickup-queue2","simple","1slot_noinout");
if (tv_receivenfq2 == NULL) {
@ -693,7 +705,7 @@ int main(int argc, char **argv)
printf("ERROR: TmModuleGetByName failed for ReceiveNFQ\n");
exit(1);
}
Tm1SlotSetFunc(tv_receivenfq2,tm_module);
Tm1SlotSetFunc(tv_receivenfq2,tm_module,NULL);
TmThreadSetCPUAffinity(tv_receivenfq2,1);
if (TmThreadSpawn(tv_receivenfq2) != 0) {
@ -701,6 +713,7 @@ int main(int argc, char **argv)
exit(1);
}
sleep(1);
ThreadVars *tv_decode1 = TmThreadCreate("Decode1","pickup-queue1","simple","packetpool","packetpool","3slot");
if (tv_decode1 == NULL) {
printf("ERROR: TmThreadsCreate failed for Decode1\n");
@ -711,21 +724,21 @@ int main(int argc, char **argv)
printf("ERROR: TmModuleGetByName DecodeNFQ failed\n");
exit(1);
}
Tm3SlotSetFunc1(tv_decode1,tm_module);
Tm3SlotSetFunc1(tv_decode1,tm_module,NULL);
tm_module = TmModuleGetByName("Detect");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName DecodeNFQ failed\n");
exit(1);
}
Tm3SlotSetFunc2(tv_decode1,tm_module);
Tm3SlotSetFunc2(tv_decode1,tm_module,(void *)g_de_ctx);
tm_module = TmModuleGetByName("VerdictNFQ");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName VerdictNFQ failed\n");
exit(1);
}
Tm3SlotSetFunc3(tv_decode1,tm_module);
Tm3SlotSetFunc3(tv_decode1,tm_module,NULL);
TmThreadSetCPUAffinity(tv_decode1,0);
if (TmThreadSpawn(tv_decode1) != 0) {
@ -733,6 +746,7 @@ int main(int argc, char **argv)
exit(1);
}
sleep(1);
ThreadVars *tv_decode2 = TmThreadCreate("Decode2","pickup-queue2","simple","packetpool","packetpool","3slot");
if (tv_decode2 == NULL) {
@ -744,21 +758,21 @@ int main(int argc, char **argv)
printf("ERROR: TmModuleGetByName DecodeNFQ failed\n");
exit(1);
}
Tm3SlotSetFunc1(tv_decode2,tm_module);
Tm3SlotSetFunc1(tv_decode2,tm_module,NULL);
tm_module = TmModuleGetByName("Detect");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName DecodeNFQ failed\n");
exit(1);
}
Tm3SlotSetFunc2(tv_decode2,tm_module);
Tm3SlotSetFunc2(tv_decode2,tm_module,(void *)g_de_ctx);
tm_module = TmModuleGetByName("VerdictNFQ");
if (tm_module == NULL) {
printf("ERROR: TmModuleGetByName VerdictNFQ failed\n");
exit(1);
}
Tm3SlotSetFunc3(tv_decode2,tm_module);
Tm3SlotSetFunc3(tv_decode2,tm_module,NULL);
TmThreadSetCPUAffinity(tv_decode2,1);
if (TmThreadSpawn(tv_decode2) != 0) {

@ -34,5 +34,14 @@ PacketQueue packet_q;
/* queue's between various other threads */
PacketQueue trans_q[256];
/* uppercase to lowercase conversion lookup table */
u_int8_t g_u8_lowercasetable[256];
/* marco to do the actual lookup */
#define u8_tolower(c) g_u8_lowercasetable[(c)]
// these 2 are slower:
//#define u8_tolower(c) ((c) >= 'A' && (c) <= 'Z') ? g_u8_lowercasetable[(c)] : (c)
//#define u8_tolower(c) ((c) >= 'A' && (c) <= 'Z') ? ((c) + ('a' - 'A')) : (c)
#endif /* __VIPS_H__ */

Loading…
Cancel
Save