support fast pattern for http raw header. Also support relative modifiers for http raw header

remotes/origin/master-1.1.x
Anoop Saldanha 15 years ago committed by Victor Julien
parent 0c806f70bb
commit 7ec0382774

@ -26,27 +26,28 @@
/* Flags affecting this content */
#define DETECT_CONTENT_NOCASE 0x0001
#define DETECT_CONTENT_DISTANCE 0x0002
#define DETECT_CONTENT_WITHIN 0x0004
#define DETECT_CONTENT_OFFSET 0x0008
#define DETECT_CONTENT_DEPTH 0x0010
#define DETECT_CONTENT_FAST_PATTERN 0x0020
#define DETECT_CONTENT_FAST_PATTERN_ONLY 0x0040
#define DETECT_CONTENT_FAST_PATTERN_CHOP 0x0080
#define DETECT_CONTENT_NOCASE 0x00000001
#define DETECT_CONTENT_DISTANCE 0x00000002
#define DETECT_CONTENT_WITHIN 0x00000004
#define DETECT_CONTENT_OFFSET 0x00000008
#define DETECT_CONTENT_DEPTH 0x00000010
#define DETECT_CONTENT_FAST_PATTERN 0x00000020
#define DETECT_CONTENT_FAST_PATTERN_ONLY 0x00000040
#define DETECT_CONTENT_FAST_PATTERN_CHOP 0x00000080
/** content applies to a "raw"/undecoded field if applicable */
#define DETECT_CONTENT_RAWBYTES 0x0100
#define DETECT_CONTENT_RAWBYTES 0x00000100
/** content is negated */
#define DETECT_CONTENT_NEGATED 0x0200
#define DETECT_CONTENT_NEGATED 0x00000200
/** a relative match to this content is next, used in matching phase */
#define DETECT_CONTENT_RELATIVE_NEXT 0x0400
#define DETECT_CONTENT_RELATIVE_NEXT 0x00000400
#define DETECT_CONTENT_PACKET_MPM 0x0800
#define DETECT_CONTENT_STREAM_MPM 0x1000
#define DETECT_CONTENT_URI_MPM 0x2000
#define DETECT_CONTENT_HCBD_MPM 0x4000
#define DETECT_CONTENT_HHD_MPM 0x8000
#define DETECT_CONTENT_PACKET_MPM 0x00000800
#define DETECT_CONTENT_STREAM_MPM 0x00001000
#define DETECT_CONTENT_URI_MPM 0x00002000
#define DETECT_CONTENT_HCBD_MPM 0x00004000
#define DETECT_CONTENT_HHD_MPM 0x00008000
#define DETECT_CONTENT_HRHD_MPM 0x00010000
#define DETECT_CONTENT_IS_SINGLE(c) (!((c)->flags & DETECT_CONTENT_DISTANCE || \
(c)->flags & DETECT_CONTENT_WITHIN || \
@ -59,7 +60,10 @@
typedef struct DetectContentData_ {
uint8_t *content;
uint8_t content_len;
uint16_t flags;
/* would want to move PatIntId here and flags down to remove the padding
* gap, but I think the first four members was used as a template for
* casting. \todo check this and fix it if posssible */
uint32_t flags;
PatIntId id;
uint16_t depth;
uint16_t offset;

@ -83,15 +83,16 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths
break;
default:
pm = SigMatchGetLastSMFromLists(s, 8,
pm = SigMatchGetLastSMFromLists(s, 10,
DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH],
DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH],
DETECT_AL_HTTP_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]);
DETECT_AL_HTTP_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH],
DETECT_AL_HTTP_RAW_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]);
if (pm == NULL) {
SCLogError(SC_ERR_DEPTH_MISSING_CONTENT, "depth needs "
"preceeding content, uricontent option, http_client_body "
"or http_header option");
"preceeding content, uricontent option, http_client_body, "
"http_header option or http_raw_header option");
if (dubbed)
SCFree(str);
return -1;
@ -226,6 +227,34 @@ static int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, char *depths
break;
case DETECT_AL_HTTP_RAW_HEADER:
cd = (DetectContentData *)pm->ctx;
if (cd->flags & DETECT_CONTENT_NEGATED) {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative "
"negated keyword set along with a fast_pattern");
goto error;
}
} else {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative "
"keyword set along with a fast_pattern:only;");
goto error;
}
}
cd->depth = (uint32_t)atoi(str);
if (cd->depth < cd->content_len) {
cd->depth = cd->content_len;
SCLogDebug("depth increased to %"PRIu32" to match pattern len ",
cd->depth);
}
/* Now update the real limit, as depth is relative to the offset */
cd->depth += cd->offset;
cd->flags |= DETECT_CONTENT_DEPTH;
break;
default:
SCLogError(SC_ERR_DEPTH_MISSING_CONTENT, "depth needs a preceeding "
"content (or uricontent) option");

@ -66,9 +66,9 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
SigMatch *pm = NULL;
/* strip "'s */
if (distancestr[0] == '\"' && distancestr[strlen(distancestr)-1] == '\"') {
str = SCStrdup(distancestr+1);
str[strlen(distancestr)-2] = '\0';
if (distancestr[0] == '\"' && distancestr[strlen(distancestr) - 1] == '\"') {
str = SCStrdup(distancestr + 1);
str[strlen(distancestr) - 2] = '\0';
dubbed = 1;
}
@ -166,15 +166,16 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
}
}
} else {
pm = SigMatchGetLastSMFromLists(s, 8,
pm = SigMatchGetLastSMFromLists(s, 10,
DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH],
DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH],
DETECT_AL_HTTP_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]);
DETECT_AL_HTTP_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH],
DETECT_AL_HTTP_RAW_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]);
if (pm == NULL) {
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs"
"preceeding content, uricontent option, http_client_body "
"or http_header option");
"preceeding content, uricontent option, http_client_body, "
"http_header or http_raw_header option");
if (dubbed)
SCFree(str);
return -1;
@ -458,6 +459,52 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
break;
case DETECT_AL_HTTP_RAW_HEADER:
cd = (DetectContentData *)pm->ctx;
if (cd->flags & DETECT_CONTENT_NEGATED) {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative "
"negated keyword set along with a fast_pattern");
goto error;
}
} else {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative "
"keyword set along with a fast_pattern:only;");
goto error;
}
}
cd->distance = strtol(str, NULL, 10);
if (cd->flags & DETECT_CONTENT_WITHIN) {
if ((cd->distance + cd->content_len) > cd->within) {
cd->within = cd->distance + cd->content_len;
}
}
cd->flags |= DETECT_CONTENT_DISTANCE;
/* reassigning pm */
pm = SigMatchGetLastSMFromLists(s, 2,
DETECT_AL_HTTP_RAW_HEADER, pm->prev);
if (pm == NULL) {
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance for "
"http_raw_header needs preceeding http_raw_header "
"content");
goto error;
}
/* reassigning cd */
cd = (DetectContentData *)pm->ctx;
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Previous keyword "
"has a fast_pattern:only; set. You can't "
"have relative keywords around a fast_pattern "
"only content");
goto error;
}
cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;
break;
default:
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance needs two "
"preceeding content or uricontent options");

@ -270,7 +270,7 @@ static uint32_t DetectEngineInspectHttpClientBodyMpmInspect(DetectEngineCtx *de_
/* if the buffer already exists, use it */
if (det_ctx->hcbd_buffers[i] != NULL) {
/* we only call the mpm if the hcbd mpm has been set */
if (s->flags & SIG_FLAG_MPM_HCBDCONTENT) {
if (s->mpm_flags & SIG_FLAG_MPM_HCBDCONTENT) {
cnt += HttpClientBodyPatternSearch(det_ctx,
det_ctx->hcbd_buffers[i],
det_ctx->hcbd_buffers_len[i]);
@ -331,7 +331,7 @@ static uint32_t DetectEngineInspectHttpClientBodyMpmInspect(DetectEngineCtx *de_
det_ctx->hcbd_buffers_len[i] = chunks_buffer_len;
/* carry out the mpm if we have hcbd mpm set */
if (s->flags & SIG_FLAG_MPM_HCBDCONTENT)
if (s->mpm_flags & SIG_FLAG_MPM_HCBDCONTENT)
cnt += HttpClientBodyPatternSearch(det_ctx, chunks_buffer, chunks_buffer_len);
} /* else - if (htud->body.nchunks == 0) */
} /* for (idx = AppLayerTransactionGetInspectId(f); .. */
@ -408,7 +408,7 @@ int DetectEngineInspectHttpClientBody(DetectEngineCtx *de_ctx,
memset(det_ctx->hcbd_buffers_len, 0, det_ctx->hcbd_buffers_list_len * sizeof(uint32_t));
} /* if (det_ctx->hcbd_buffers_list_len == 0) */
if (s->flags & SIG_FLAG_MPM_HCBDCONTENT) {
if (s->mpm_flags & SIG_FLAG_MPM_HCBDCONTENT) {
if (det_ctx->de_mpm_scanned_hcbd == FALSE) {
uint32_t cnt = DetectEngineInspectHttpClientBodyMpmInspect(de_ctx,
det_ctx, s,
@ -424,16 +424,16 @@ int DetectEngineInspectHttpClientBody(DetectEngineCtx *de_ctx,
}
if (det_ctx->de_have_hcbd == FALSE &&
s->flags & SIG_FLAG_MPM_HCBDCONTENT &&
!(s->flags & SIG_FLAG_MPM_HCBDCONTENT_NEG)) {
s->mpm_flags & SIG_FLAG_MPM_HCBDCONTENT &&
!(s->mpm_flags & SIG_FLAG_MPM_HCBDCONTENT_NEG)) {
SCLogDebug("mpm results failure for client_body. Get out of here");
goto end;
}
if ((s->flags & SIG_FLAG_MPM_HCBDCONTENT) && (det_ctx->de_mpm_scanned_hcbd == TRUE)) {
if ((s->mpm_flags & SIG_FLAG_MPM_HCBDCONTENT) && (det_ctx->de_mpm_scanned_hcbd == TRUE)) {
/* filter out the sig that needs a match, but have no matches */
if (!(det_ctx->pmq.pattern_id_bitarray[(s->mpm_hcbdpattern_id / 8)] & (1 << (s->mpm_hcbdpattern_id % 8))) &&
!(s->flags & SIG_FLAG_MPM_HCBDCONTENT_NEG)) {
!(s->mpm_flags & SIG_FLAG_MPM_HCBDCONTENT_NEG)) {
goto end;
}
}

@ -254,8 +254,7 @@ match:
* \param f Pointer to the flow.
* \param htp_state http state.
*
* \retval cnt The match count from the mpm call. If call_mpm is 0, the retval
* is ignored.
* \retval cnt The match count from the mpm call.
*/
static uint32_t DetectEngineInspectHttpHeaderMpmInspect(DetectEngineThreadCtx *det_ctx,
Signature *s, Flow *f,

File diff suppressed because it is too large Load Diff

@ -0,0 +1,32 @@
/* Copyright (C) 2007-2010 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/** \file
*
* \author Anoop Saldanha <poonaatsoc@gmail.com>
*/
#ifndef __DETECT_ENGINE_HRHD_H__
#define __DETECT_ENGINE_HRHD_H__
int DetectEngineInspectHttpRawHeader(DetectEngineCtx *, DetectEngineThreadCtx *,
Signature *, Flow *, uint8_t, void *);
void DetectEngineCleanHRHDBuffers(DetectEngineThreadCtx *);
void DetectEngineHttpRawHeaderRegisterTests(void);
#endif /* __DETECT_ENGINE_HHD_H__ */

@ -313,6 +313,31 @@ uint32_t HttpHeaderPatternSearch(DetectEngineThreadCtx *det_ctx,
SCReturnUInt(ret);
}
/**
* \brief Http raw header match -- searches for one pattern per signature.
*
* \param det_ctx Detection engine thread ctx.
* \param headers Raw headers to inspect.
* \param headers_len Raw headers length.
*
* \retval ret Number of matches.
*/
uint32_t HttpRawHeaderPatternSearch(DetectEngineThreadCtx *det_ctx,
uint8_t *raw_headers, uint32_t raw_headers_len)
{
SCEnter();
if (det_ctx->sgh->mpm_hrhd_ctx == NULL)
SCReturnUInt(0);
uint32_t ret;
ret = mpm_table[det_ctx->sgh->mpm_hrhd_ctx->mpm_type].
Search(det_ctx->sgh->mpm_hrhd_ctx, &det_ctx->mtcu,
&det_ctx->pmq, raw_headers, raw_headers_len);
SCReturnUInt(ret);
}
/** \brief Pattern match -- searches for only one pattern per signature.
*
* \param tv threadvars
@ -609,6 +634,7 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx,
DetectContentData *ud = NULL;
DetectContentData *hcbd = NULL;
DetectContentData *hhd = NULL;
DetectContentData *hrhd = NULL;
switch (mpm_sm->type) {
case DETECT_CONTENT:
{
@ -826,10 +852,10 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx,
}
}
/* tell matcher we are inspecting uri */
s->flags |= SIG_FLAG_MPM_HCBDCONTENT;
s->mpm_flags |= SIG_FLAG_MPM_HCBDCONTENT;
s->mpm_hcbdpattern_id = hcbd->id;
if (hcbd->flags & DETECT_CONTENT_NEGATED)
s->flags |= SIG_FLAG_MPM_HCBDCONTENT_NEG;
s->mpm_flags |= SIG_FLAG_MPM_HCBDCONTENT_NEG;
break;
} /* case DETECT_AL_HTTP_CLIENT_BODY */
@ -887,6 +913,59 @@ static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx,
break;
} /* case DETECT_AL_HTTP_HEADER */
case DETECT_AL_HTTP_RAW_HEADER:
{
hrhd = (DetectContentData *)mpm_sm->ctx;
if (hrhd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) {
/* add the content to the "hrhd" mpm */
if (hrhd->flags & DETECT_CONTENT_NOCASE) {
mpm_table[sgh->mpm_hrhd_ctx->mpm_type].
AddPatternNocase(sgh->mpm_hrhd_ctx,
hrhd->content + hrhd->fp_chop_offset,
hrhd->fp_chop_len,
0, 0, hrhd->id, s->num, flags);
} else {
mpm_table[sgh->mpm_hrhd_ctx->mpm_type].
AddPattern(sgh->mpm_hrhd_ctx,
hrhd->content + hrhd->fp_chop_offset,
hrhd->fp_chop_len,
0, 0, hrhd->id, s->num, flags);
}
} else {
if (hrhd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
if (DETECT_CONTENT_IS_SINGLE(hrhd)) {
hrhd->flags |= DETECT_CONTENT_HRHD_MPM;
}
/* see if we can bypass the match validation for this pattern */
} else {
if (DETECT_CONTENT_IS_SINGLE(hrhd)) {
hrhd->flags |= DETECT_CONTENT_HRHD_MPM;
}
} /* else - if (hrhd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) */
/* add the content to the "hrhd" mpm */
if (hrhd->flags & DETECT_CONTENT_NOCASE) {
mpm_table[sgh->mpm_hrhd_ctx->mpm_type].
AddPatternNocase(sgh->mpm_hrhd_ctx,
hrhd->content, hrhd->content_len,
0, 0, hrhd->id, s->num, flags);
} else {
mpm_table[sgh->mpm_hrhd_ctx->mpm_type].
AddPattern(sgh->mpm_hrhd_ctx,
hrhd->content, hrhd->content_len,
0, 0, hrhd->id, s->num, flags);
}
}
/* tell matcher we are inspecting uri */
s->mpm_flags |= SIG_FLAG_MPM_HRHDCONTENT;
s->mpm_hrhdpattern_id = hrhd->id;
if (hrhd->flags & DETECT_CONTENT_NEGATED)
s->mpm_flags |= SIG_FLAG_MPM_HRHDCONTENT_NEG;
break;
} /* case DETECT_AL_HTTP_RAW_HEADER */
} /* switch (mpm_sm->type) */
SCLogDebug("%"PRIu32" adding cd->id %"PRIu32" to the mpm phase "
@ -1938,6 +2017,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
uint32_t has_co_hcbd = 0;
/* used to indicate if sgh has atleast one sig with http_header */
uint32_t has_co_hhd = 0;
/* used to indicate if sgh has atleast one sig with http_raw_header */
uint32_t has_co_hrhd = 0;
//uint32_t cnt = 0;
uint32_t sig = 0;
@ -1977,6 +2058,10 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
has_co_hhd = 1;
}
if (s->sm_lists[DETECT_SM_LIST_HRHDMATCH] != NULL) {
has_co_hrhd = 1;
}
}
if (has_co_packet > 0) {
@ -1994,6 +2079,9 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
if (has_co_hhd > 0) {
sh->flags |= SIG_GROUP_HAVEHHDCONTENT;
}
if (has_co_hrhd > 0) {
sh->flags |= SIG_GROUP_HAVEHRHDCONTENT;
}
/* intialize contexes */
if (sh->flags & SIG_GROUP_HAVECONTENT) {
@ -2086,6 +2174,24 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
#endif
}
if (sh->flags & SIG_GROUP_HAVEHRHDCONTENT) {
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
sh->mpm_hrhd_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx->sgh_mpm_context_hrhd);
} else {
sh->mpm_hrhd_ctx = MpmFactoryGetMpmCtxForProfile(MPM_CTX_FACTORY_UNIQUE_CONTEXT);
}
if (sh->mpm_hrhd_ctx == NULL) {
SCLogDebug("sh->mpm_hrhd_ctx == NULL. This should never happen");
exit(EXIT_FAILURE);
}
#ifndef __SC_CUDA_SUPPORT__
MpmInitCtx(sh->mpm_hrhd_ctx, de_ctx->mpm_matcher, -1);
#else
MpmInitCtx(sh->mpm_hrhd_ctx, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
#endif
}
/* for each signature in this group do */
//for (sig = 0; sig < sh->sig_cnt; sig++) {
// s = sh->match_array[sig];
@ -2219,7 +2325,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
sh->flags & SIG_GROUP_HAVESTREAMCONTENT ||
sh->flags & SIG_GROUP_HAVEURICONTENT ||
sh->flags & SIG_GROUP_HAVEHCBDCONTENT ||
sh->flags & SIG_GROUP_HAVEHHDCONTENT) {
sh->flags & SIG_GROUP_HAVEHHDCONTENT ||
sh->flags & SIG_GROUP_HAVEHRHDCONTENT) {
PatternMatchPreparePopulateMpm(de_ctx, sh);
@ -2279,6 +2386,17 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
}
}
}
if (sh->mpm_hrhd_ctx != NULL) {
if (sh->mpm_hrhd_ctx->pattern_cnt == 0) {
MpmFactoryReClaimMpmCtx(sh->mpm_hrhd_ctx);
sh->mpm_hrhd_ctx = NULL;
} else {
if (sh->flags & SIG_GROUP_HAVEHRHDCONTENT) {
if (mpm_table[sh->mpm_hrhd_ctx->mpm_type].Prepare != NULL)
mpm_table[sh->mpm_hrhd_ctx->mpm_type].Prepare(sh->mpm_hrhd_ctx);
}
}
}
} /* if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) */
} else {
@ -2292,6 +2410,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
sh->mpm_hcbd_ctx = NULL;
MpmFactoryReClaimMpmCtx(sh->mpm_hhd_ctx);
sh->mpm_hhd_ctx = NULL;
MpmFactoryReClaimMpmCtx(sh->mpm_hrhd_ctx);
sh->mpm_hrhd_ctx = NULL;
}
///* uricontent */

@ -38,6 +38,7 @@ uint32_t UriPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint16_t);
uint32_t StreamPatternSearch(ThreadVars *, DetectEngineThreadCtx *, Packet *, StreamMsg *, uint8_t);
uint32_t HttpClientBodyPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t);
uint32_t HttpHeaderPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t);
uint32_t HttpRawHeaderPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint32_t);
void PacketPatternCleanup(ThreadVars *, DetectEngineThreadCtx *);
void StreamPatternCleanup(ThreadVars *t, DetectEngineThreadCtx *det_ctx, StreamMsg *smsg);

@ -33,6 +33,7 @@
#include "detect-engine-uri.h"
#include "detect-engine-hcbd.h"
#include "detect-engine-hhd.h"
#include "detect-engine-hrhd.h"
#include "detect-engine-dcepayload.h"
#include "stream-tcp.h"
@ -207,7 +208,7 @@ int DeStateUpdateInspectTransactionId(Flow *f, char direction) {
*/
static void DeStateSignatureAppend(DetectEngineState *state, Signature *s,
SigMatch *sm, char uri, char dce, char hcbd,
char hhd) {
char hhd, char hrhd) {
DeStateStore *store = state->tail;
if (store == NULL) {
@ -247,6 +248,9 @@ static void DeStateSignatureAppend(DetectEngineState *state, Signature *s,
if (hhd) {
store->store[idx].flags |= DE_STATE_FLAG_HHD_MATCH;
}
if (hrhd) {
store->store[idx].flags |= DE_STATE_FLAG_HRHD_MATCH;
}
store->store[idx].nm = sm;
state->cnt++;
@ -310,6 +314,8 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
char hcbdinspect = 0;
char hhdmatch = 0;
char hhdinspect = 0;
char hrhdmatch = 0;
char hrhdinspect = 0;
char dmatch = 0;
char dinspect = 0;
char appinspect = 0;
@ -351,7 +357,15 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
flags, alstate) == 1) {
hhdmatch = 1;
}
SCLogDebug("inspecting http client body");
SCLogDebug("inspecting http header");
}
if (s->sm_lists[DETECT_SM_LIST_HRHDMATCH] != NULL) {
hrhdinspect = 1;
if (DetectEngineInspectHttpRawHeader(de_ctx, det_ctx, s, f,
flags, alstate) == 1) {
hrhdmatch = 1;
}
SCLogDebug("inspecting http raw header");
}
} else if (alproto == ALPROTO_DCERPC || alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) {
@ -384,8 +398,8 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
}
}
appinspect = uinspect + dinspect + hcbdinspect + hhdinspect;
appmatch = umatch + dmatch + hcbdmatch + hhdmatch;
appinspect = uinspect + dinspect + hcbdinspect + hhdinspect + hrhdinspect;
appmatch = umatch + dmatch + hcbdmatch + hhdmatch + hrhdmatch;
if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) {
for ( ; sm != NULL; sm = sm->next) {
@ -427,8 +441,8 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
}
}
SCLogDebug("detection done, store results: sm %p, uri %d, dce %d, hcbd %d "
"hhd %d", sm, umatch, dmatch, hcbdmatch, hhdmatch);
SCLogDebug("detection done, store results: sm %p, uri %d, dce %d, hcbd %d, "
"hhd %d, hrhd %d", sm, umatch, dmatch, hcbdmatch, hhdmatch, hrhdmatch);
SCMutexLock(&f->de_state_m);
/* match or no match, we store the state anyway
@ -439,7 +453,7 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
}
if (f->de_state != NULL) {
/* \todo shift to an array to transfer these match values*/
DeStateSignatureAppend(f->de_state, s, sm, umatch, dmatch, hcbdmatch, hhdmatch);
DeStateSignatureAppend(f->de_state, s, sm, umatch, dmatch, hcbdmatch, hhdmatch, hrhdmatch);
}
SCMutexUnlock(&f->de_state_m);
@ -465,6 +479,8 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete
char hcbdinspect = 0;
char hhdmatch = 0;
char hhdinspect = 0;
char hrhdmatch = 0;
char hrhdinspect = 0;
char dmatch = 0;
char dinspect = 0;
char appinspect = 0;
@ -495,6 +511,8 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete
hcbdinspect = 0;
hhdmatch = 0;
hhdinspect = 0;
hrhdmatch = 0;
hrhdinspect = 0;
dmatch = 0;
dinspect = 0;
appinspect = 0;
@ -564,6 +582,20 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete
}
}
}
if (s->sm_lists[DETECT_SM_LIST_HRHDMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_HRHD_MATCH)) {
SCLogDebug("inspecting http raw header data");
hrhdinspect = 1;
if (DetectEngineInspectHttpRawHeader(de_ctx, det_ctx, s, f,
flags, alstate) == 1) {
SCLogDebug("http raw header matched");
item->flags |= DE_STATE_FLAG_HRHD_MATCH;
hrhdmatch = 1;
}
}
}
} else if (alproto == ALPROTO_DCERPC || alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) {
if (s->sm_lists[DETECT_SM_LIST_DMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_DCE_MATCH)) {
@ -601,8 +633,8 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete
}
appinspect = uinspect + dinspect + hcbdinspect + hhdinspect;
appmatch = umatch + dmatch + hcbdmatch + hhdmatch;
appinspect = uinspect + dinspect + hcbdinspect + hhdinspect + hrhdinspect;
appmatch = umatch + dmatch + hcbdmatch + hhdmatch + hrhdmatch;
SCLogDebug("appinspect %d, appmatch %d", appinspect, appmatch);
/* next, check the other sig matches */
@ -742,39 +774,39 @@ static int DeStateTest02(void) {
memset(&s, 0x00, sizeof(s));
s.num = 0;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0);
s.num = 11;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0);
s.num = 22;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0);
s.num = 33;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0);
s.num = 44;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0);
s.num = 55;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0);
s.num = 66;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0);
s.num = 77;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0);
s.num = 88;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0);
s.num = 99;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0);
s.num = 100;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0);
s.num = 111;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0);
s.num = 122;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0);
s.num = 133;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0);
s.num = 144;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0);
s.num = 155;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0);
s.num = 166;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0);
if (state->head == NULL) {
goto end;
@ -817,9 +849,9 @@ static int DeStateTest03(void) {
memset(&s, 0x00, sizeof(s));
s.num = 11;
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 0, 0, 0, 0, 0);
s.num = 22;
DeStateSignatureAppend(state, &s, NULL, 1, 0, 0, 0);
DeStateSignatureAppend(state, &s, NULL, 1, 0, 0, 0, 0);
if (state->head == NULL) {
goto end;

@ -48,8 +48,9 @@
#define DE_STATE_FLAG_URI_MATCH 0x02 /**< uri part of the sig matched */
#define DE_STATE_FLAG_DCE_MATCH 0x04 /**< dce payload inspection part matched */
#define DE_STATE_FLAG_HCBD_MATCH 0x08 /**< hcbd payload inspection part matched */
#define DE_STATE_FLAG_HHD_MATCH 0x10 /**< hcbd payload inspection part matched */
#define DE_STATE_FLAG_FULL_MATCH 0x20 /**< sig already fully matched */
#define DE_STATE_FLAG_HHD_MATCH 0x10 /**< hhd payload inspection part matched */
#define DE_STATE_FLAG_HRHD_MATCH 0x20 /**< hrhd payload inspection part matched */
#define DE_STATE_FLAG_FULL_MATCH 0x40 /**< sig already fully matched */
/** per signature detection engine state */
typedef enum {

File diff suppressed because it is too large Load Diff

@ -65,13 +65,15 @@ void DetectHttpHeaderRegister(void)
{
sigmatch_table[DETECT_AL_HTTP_HEADER].name = "http_header";
sigmatch_table[DETECT_AL_HTTP_HEADER].Match = NULL;
sigmatch_table[DETECT_AL_HTTP_HEADER].AppLayerMatch = DetectHttpHeaderMatch;
sigmatch_table[DETECT_AL_HTTP_HEADER].alproto = ALPROTO_HTTP;
sigmatch_table[DETECT_AL_HTTP_HEADER].AppLayerMatch = NULL;
sigmatch_table[DETECT_AL_HTTP_HEADER].Setup = DetectHttpHeaderSetup;
sigmatch_table[DETECT_AL_HTTP_HEADER].Free = DetectHttpHeaderFree;
sigmatch_table[DETECT_AL_HTTP_HEADER].RegisterTests = DetectHttpHeaderRegisterTests;
sigmatch_table[DETECT_AL_HTTP_HEADER].alproto = ALPROTO_HTTP;
sigmatch_table[DETECT_AL_HTTP_HEADER].flags |= SIGMATCH_PAYLOAD ;
return;
}
/**
@ -258,7 +260,7 @@ error:
if (cd != NULL)
DetectHttpHeaderFree(cd);
if(sm != NULL)
if (sm != NULL)
SCFree(sm);
return -1;

@ -33,6 +33,7 @@
#include "detect-engine-mpm.h"
#include "detect-engine-state.h"
#include "detect-content.h"
#include "detect-pcre.h"
#include "flow.h"
#include "flow-var.h"
@ -64,13 +65,16 @@ void DetectHttpRawHeaderRegister(void)
{
sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].name = "http_raw_header";
sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].Match = NULL;
sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].AppLayerMatch = DetectHttpRawHeaderMatch;
sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].alproto = ALPROTO_HTTP;
sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].AppLayerMatch = NULL;
//sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].AppLayerMatch = DetectHttpRawHeaderMatch;
sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].Setup = DetectHttpRawHeaderSetup;
sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].Free = DetectHttpRawHeaderFree;
sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].RegisterTests = DetectHttpRawHeaderRegisterTests;
sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].alproto = ALPROTO_HTTP;
sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].flags |= SIGMATCH_PAYLOAD ;
sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].flags |= SIGMATCH_PAYLOAD;
return;
}
/**
@ -88,8 +92,8 @@ void DetectHttpRawHeaderRegister(void)
* \retval 0 On no match.
*/
int DetectHttpRawHeaderMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
Flow *f, uint8_t flags, void *state, Signature *s,
SigMatch *m)
Flow *f, uint8_t flags, void *state, Signature *s,
SigMatch *m)
{
SCEnter();
@ -150,12 +154,12 @@ int DetectHttpRawHeaderMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
*/
void DetectHttpRawHeaderFree(void *ptr)
{
DetectContentData *hrhd = (DetectContentData *)ptr;
if (hrhd == NULL)
DetectContentData *cd = (DetectContentData *)ptr;
if (cd == NULL)
return;
if (hrhd->content != NULL)
SCFree(hrhd->content);
SCFree(hrhd);
if (cd->content != NULL)
SCFree(cd->content);
SCFree(cd);
return;
}
@ -175,9 +179,7 @@ void DetectHttpRawHeaderFree(void *ptr)
*/
int DetectHttpRawHeaderSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg)
{
/* http_raw_header_data (hrhd) */
DetectContentData *hrhd = NULL;
SigMatch *nm = NULL;
DetectContentData *cd = NULL;
SigMatch *sm = NULL;
if (arg != NULL && strcmp(arg, "") != 0) {
@ -185,14 +187,8 @@ int DetectHttpRawHeaderSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg)
return -1;
}
if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "http_raw_header found inside the "
"rule, without any preceding content keywords");
return -1;
}
sm = DetectContentGetLastPattern(s->sm_lists_tail[DETECT_SM_LIST_PMATCH]);
/* if still we are unable to find any content previous keywords, it is an
/* if still we are unable to find any previous content keywords, it is an
* invalid rule */
if (sm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "\"http_raw_header\" keyword "
@ -202,59 +198,56 @@ int DetectHttpRawHeaderSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg)
return -1;
}
if (((DetectContentData *)sm->ctx)->flags & DETECT_CONTENT_FAST_PATTERN) {
SCLogWarning(SC_WARN_COMPATIBILITY,
"http_header cannot be used with \"fast_pattern\" currently."
"Unsetting fast_pattern on this modifier. Signature ==> %s", s->sig_str);
((DetectContentData *)sm->ctx)->flags &= ~DETECT_CONTENT_FAST_PATTERN;
}
cd = (DetectContentData *)sm->ctx;
/* http_header should not be used with the rawbytes rule */
if (((DetectContentData *)sm->ctx)->flags & DETECT_CONTENT_RAWBYTES) {
if (cd->flags & DETECT_CONTENT_RAWBYTES) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "http_header rule can not "
"be used with the rawbytes rule keyword");
return -1;
}
if (s->alproto != ALPROTO_UNKNOWN && s->alproto != ALPROTO_HTTP) {
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains conflicting keywords");
SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "rule contains a non http "
"alproto set");
goto error;
}
/* setup the HttpHeaderData's data from content data structure's data */
hrhd = SCMalloc(sizeof(DetectContentData));
if (hrhd == NULL) {
SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
exit(EXIT_FAILURE);
}
memset(hrhd, 0, sizeof(DetectContentData));
/* transfer the pattern details from the content struct to the clientbody struct */
DetectContentData *cd = (DetectContentData *)sm->ctx;
hrhd->content = cd->content;
hrhd->content_len = cd->content_len;
hrhd->flags |= cd->flags & DETECT_CONTENT_NOCASE ? DETECT_CONTENT_NOCASE : 0;
hrhd->flags |= cd->flags & DETECT_CONTENT_NEGATED ? DETECT_CONTENT_NEGATED : 0;
//hrhd->id = ((DetectContentData *)sm->ctx)->id;
hrhd->id = DetectPatternGetId(de_ctx->mpm_pattern_id_store, hrhd, DETECT_AL_HTTP_HEADER);
nm = SigMatchAlloc();
if (nm == NULL) {
SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
goto error;
}
nm->type = DETECT_AL_HTTP_HEADER;
nm->ctx = (void *)hrhd;
if (cd->flags & DETECT_CONTENT_WITHIN || cd->flags & DETECT_CONTENT_DISTANCE) {
SigMatch *pm = SigMatchGetLastSMFromLists(s, 4,
DETECT_CONTENT, sm->prev,
DETECT_PCRE, sm->prev);
/* pm is never NULL. So no NULL check */
if (pm->type == DETECT_CONTENT) {
DetectContentData *tmp_cd = (DetectContentData *)pm->ctx;
tmp_cd->flags &= ~DETECT_CONTENT_RELATIVE_NEXT;
} else {
DetectPcreData *tmp_pd = (DetectPcreData *)pm->ctx;
tmp_pd->flags &= ~DETECT_PCRE_RELATIVE_NEXT;
}
/* pull the previous content from the pmatch list, append
* the new match to the match list */
SigMatchReplaceContent(s, sm, nm);
/* please note. reassigning pm */
pm = SigMatchGetLastSMFromLists(s, 2,
DETECT_AL_HTTP_RAW_HEADER,
s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]);
if (pm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "http_raw_header seen with a "
"distance or within without a previous http_raw_header "
"content. Invalidating signature.");
goto error;
}
DetectContentData *tmp_cd = (DetectContentData *)pm->ctx;
tmp_cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;
}
cd->id = DetectPatternGetId(de_ctx->mpm_pattern_id_store, cd, DETECT_AL_HTTP_RAW_HEADER);
sm->type = DETECT_AL_HTTP_RAW_HEADER;
/* free the old content sigmatch, the content pattern memory
* is taken over by the new sigmatch */
BoyerMooreCtxDeInit(((DetectContentData *)sm->ctx)->bm_ctx);
SCFree(sm->ctx);
SCFree(sm);
/* transfer the sm from the pmatch list to hrhdmatch list */
SigMatchTransferSigMatchAcrossLists(sm,
&s->sm_lists[DETECT_SM_LIST_PMATCH],
&s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
&s->sm_lists[DETECT_SM_LIST_HRHDMATCH],
&s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]);
/* flag the signature to indicate that we scan the app layer data */
s->flags |= SIG_FLAG_APPLAYER;
@ -263,9 +256,9 @@ int DetectHttpRawHeaderSetup(DetectEngineCtx *de_ctx, Signature *s, char *arg)
return 0;
error:
if (hrhd != NULL)
DetectHttpRawHeaderFree(hrhd);
if(nm != NULL)
if (cd != NULL)
DetectHttpRawHeaderFree(cd);
if (sm != NULL)
SCFree(sm);
return -1;
@ -302,11 +295,12 @@ static int DetectHttpRawHeaderTest01(void)
goto end;
}
sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_MATCH];
sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH];
if (sm != NULL) {
result &= (sm->type == DETECT_AL_HTTP_HEADER);
result &= (sm->type == DETECT_AL_HTTP_RAW_HEADER);
result &= (sm->next == NULL);
} else {
result = 0;
printf("Error updating content pattern to http_header pattern: ");
}
@ -1333,13 +1327,13 @@ int DetectHttpRawHeaderTest14(void)
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_AMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_AMATCH] == NULL\n");
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH] == NULL\n");
goto end;
}
DetectContentData *cd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
DetectContentData *hrhd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_AMATCH]->ctx;
DetectContentData *hrhd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->ctx;
if (cd->id == hrhd->id)
goto end;
@ -1372,13 +1366,13 @@ int DetectHttpRawHeaderTest15(void)
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_AMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_AMATCH] == NULL\n");
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH] == NULL\n");
goto end;
}
DetectContentData *cd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
DetectContentData *hrhd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_AMATCH]->ctx;
DetectContentData *hrhd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->ctx;
if (cd->id == hrhd->id)
goto end;
@ -1411,13 +1405,13 @@ int DetectHttpRawHeaderTest16(void)
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_AMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_AMATCH] == NULL\n");
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH] == NULL\n");
goto end;
}
DetectContentData *cd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
DetectContentData *hrhd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_AMATCH]->ctx;
DetectContentData *hrhd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->ctx;
if (cd->id != 0 || hrhd->id != 1)
goto end;
@ -1450,13 +1444,13 @@ int DetectHttpRawHeaderTest17(void)
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_AMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_AMATCH] == NULL\n");
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH] == NULL\n");
goto end;
}
DetectContentData *cd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
DetectContentData *hrhd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_AMATCH]->ctx;
DetectContentData *hrhd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->ctx;
if (cd->id != 1 || hrhd->id != 0)
goto end;
@ -1490,14 +1484,14 @@ int DetectHttpRawHeaderTest18(void)
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_AMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_AMATCH] == NULL\n");
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH] == NULL\n");
goto end;
}
DetectContentData *cd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
DetectContentData *hrhd1 = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_AMATCH]->ctx;
DetectContentData *hrhd2 = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_AMATCH]->prev->ctx;
DetectContentData *hrhd1 = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->ctx;
DetectContentData *hrhd2 = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->prev->ctx;
if (cd->id != 1 || hrhd1->id != 0 || hrhd2->id != 0)
goto end;
@ -1531,14 +1525,14 @@ int DetectHttpRawHeaderTest19(void)
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_AMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_AMATCH] == NULL\n");
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH] == NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_HRHDMATCH] == NULL\n");
goto end;
}
DetectContentData *cd = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
DetectContentData *hrhd1 = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_AMATCH]->ctx;
DetectContentData *hrhd2 = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_AMATCH]->prev->ctx;
DetectContentData *hrhd1 = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->ctx;
DetectContentData *hrhd2 = de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]->prev->ctx;
if (cd->id != 2 || hrhd1->id != 0 || hrhd2->id != 0)
goto end;

@ -21,10 +21,9 @@
* \author Pablo Rincon <pablo.rincon.crespo@gmail.com>
*/
#ifndef __DETECT_HTTP_HEADER_H__
#define __DETECT_HTTP_HEADER_H__
#ifndef __DETECT_HTTP_RAW_HEADER_H__
#define __DETECT_HTTP_RAW_HEADER_H__
void DetectHttpHeaderRegister(void);
void DetectHttpRawHeaderRegister(void);
#endif /* __DETECT_HTTP_HEADER_H__ */
#endif /* __DETECT_HTTP_RAW_HEADER_H__ */

@ -181,11 +181,12 @@ static int DetectNocaseSetup (DetectEngineCtx *de_ctx, Signature *s, char *nulls
/* Search for the first previous SigMatch that supports nocase */
//SigMatch *pm = SigMatchGetLastNocasePattern(s);
SigMatch *pm = SigMatchGetLastSMFromLists(s, 12,
SigMatch *pm = SigMatchGetLastSMFromLists(s, 14,
DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH],
DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH],
DETECT_AL_HTTP_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH],
DETECT_AL_HTTP_RAW_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH],
DETECT_AL_HTTP_COOKIE, s->sm_lists_tail[DETECT_SM_LIST_AMATCH],
DETECT_AL_HTTP_METHOD, s->sm_lists_tail[DETECT_SM_LIST_AMATCH]);
if (pm == NULL) {
@ -199,6 +200,7 @@ static int DetectNocaseSetup (DetectEngineCtx *de_ctx, Signature *s, char *nulls
DetectContentData *dhcb = NULL;
DetectContentData *dhcd = NULL;
DetectContentData *dhhd = NULL;
DetectContentData *dhrhd = NULL;
DetectContentData *dhmd = NULL;
switch (pm->type) {
@ -233,6 +235,10 @@ static int DetectNocaseSetup (DetectEngineCtx *de_ctx, Signature *s, char *nulls
dhhd =(DetectContentData *) pm->ctx;
dhhd->flags |= DETECT_CONTENT_NOCASE;
break;
case DETECT_AL_HTTP_RAW_HEADER:
dhrhd =(DetectContentData *) pm->ctx;
dhrhd->flags |= DETECT_CONTENT_NOCASE;
break;
case DETECT_AL_HTTP_METHOD:
dhmd =(DetectContentData *) pm->ctx;
dhmd->flags |= DETECT_CONTENT_NOCASE;

@ -80,14 +80,16 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr)
break;
default:
pm = SigMatchGetLastSMFromLists(s, 8,
pm = SigMatchGetLastSMFromLists(s, 10,
DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH],
DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH],
DETECT_AL_HTTP_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]);
DETECT_AL_HTTP_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH],
DETECT_AL_HTTP_RAW_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]);
if (pm == NULL) {
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "offset needs"
"preceeding content or uricontent option or http_client_body option");
"preceeding content or uricontent option, http_client_body "
"http_header or http_raw_header option");
if (dubbed)
SCFree(str);
return -1;
@ -238,6 +240,37 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, char *offsetstr)
break;
case DETECT_AL_HTTP_RAW_HEADER:
cd = (DetectContentData *)pm->ctx;
if (cd->flags & DETECT_CONTENT_NEGATED) {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative "
"negated keyword set along with a fast_pattern");
goto error;
}
} else {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative "
"keyword set along with a fast_pattern:only;");
goto error;
}
}
cd->offset = (uint32_t)atoi(str);
if (cd->depth != 0) {
if (cd->depth < cd->content_len) {
SCLogDebug("depth increased to %"PRIu32" to match pattern len",
cd->content_len);
cd->depth = cd->content_len;
}
/* Updating the depth as is relative to the offset */
cd->depth += cd->offset;
}
cd->flags |= DETECT_CONTENT_OFFSET;
break;
default:
SCLogError(SC_ERR_OFFSET_MISSING_CONTENT, "offset needs a preceeding"
" content or uricontent option");

@ -169,15 +169,16 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
}
}
} else {
pm = SigMatchGetLastSMFromLists(s, 8,
pm = SigMatchGetLastSMFromLists(s, 10,
DETECT_CONTENT, s->sm_lists_tail[DETECT_SM_LIST_PMATCH],
DETECT_URICONTENT, s->sm_lists_tail[DETECT_SM_LIST_UMATCH],
DETECT_AL_HTTP_CLIENT_BODY, s->sm_lists_tail[DETECT_SM_LIST_HCBDMATCH],
DETECT_AL_HTTP_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH]);
DETECT_AL_HTTP_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HHDMATCH],
DETECT_AL_HTTP_RAW_HEADER, s->sm_lists_tail[DETECT_SM_LIST_HRHDMATCH]);
if (pm == NULL) {
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs"
"preceeding content, uricontent, http_client_body or "
"http_header option");
"preceeding content, uricontent, http_client_body, "
"http_header or http_raw_header option");
if (dubbed)
SCFree(str);
return -1;
@ -465,7 +466,7 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
pm = SigMatchGetLastSMFromLists(s, 2,
DETECT_AL_HTTP_HEADER, pm->prev);
if (pm == NULL) {
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance for http_header_body "
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance for http_header "
"needs preceeding http_header content");
goto error;
}
@ -482,6 +483,53 @@ static int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, char *withi
break;
case DETECT_AL_HTTP_RAW_HEADER:
cd = (DetectContentData *)pm->ctx;
if (cd->flags & DETECT_CONTENT_NEGATED) {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative "
"negated keyword set along with a fast_pattern");
goto error;
}
} else {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "You can't have a relative "
"keyword set along with a fast_pattern:only;");
goto error;
}
}
cd->within = strtol(str, NULL, 10);
if (cd->within < (int32_t)cd->content_len) {
SCLogError(SC_ERR_WITHIN_INVALID, "within argument \"%"PRIi32"\" is "
"less than the content length \"%"PRIu32"\" which is invalid, since "
"this will never match. Invalidating signature", ud->within,
ud->content_len);
goto error;
}
cd->flags |= DETECT_CONTENT_WITHIN;
/* reassigning pm */
pm = SigMatchGetLastSMFromLists(s, 2,
DETECT_AL_HTTP_RAW_HEADER, pm->prev);
if (pm == NULL) {
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance for http_raw_header "
"needs preceeding http_raw_header content");
goto error;
}
/* reassigning cd */
cd = (DetectContentData *)pm->ctx;
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Previous keyword "
"has a fast_pattern:only; set. You can't "
"have relative keywords around a fast_pattern "
"only content");
goto error;
}
cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;
break;
default:
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs two "
"preceeding content or uricontent options");

@ -117,6 +117,7 @@
#include "detect-http-stat-msg.h"
#include "detect-engine-hcbd.h"
#include "detect-engine-hhd.h"
#include "detect-engine-hrhd.h"
#include "util-rule-vars.h"
@ -695,7 +696,7 @@ static void SigMatchSignaturesBuildMatchArray(DetectEngineCtx *de_ctx,
* or just partially match */
if (s->flags & SIG_FLAG_AMATCH || s->flags & SIG_FLAG_UMATCH ||
s->flags & SIG_FLAG_DMATCH || s->flags & SIG_FLAG_HCBDMATCH ||
s->flags & SIG_FLAG_HHDMATCH)
s->flags & SIG_FLAG_HHDMATCH || s->flags & SIG_FLAG_HRHDMATCH)
{
/* we run after DeStateDetectContinueDetection, so we might have
* state NEW here. In that case we'd want to continue detection
@ -892,6 +893,9 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
det_ctx->de_have_hhd = TRUE;
det_ctx->de_mpm_scanned_hhd = FALSE;
det_ctx->de_have_hrhd = TRUE;
det_ctx->de_mpm_scanned_hrhd = FALSE;
SCEnter();
/* No need to perform any detection on this packet, if the the given flag is set.*/
@ -1190,7 +1194,8 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
s->sm_lists[DETECT_SM_LIST_UMATCH] != NULL ||
s->sm_lists[DETECT_SM_LIST_DMATCH] != NULL ||
s->sm_lists[DETECT_SM_LIST_HCBDMATCH] != NULL ||
s->sm_lists[DETECT_SM_LIST_HHDMATCH] != NULL) {
s->sm_lists[DETECT_SM_LIST_HHDMATCH] != NULL ||
s->sm_lists[DETECT_SM_LIST_HRHDMATCH] != NULL) {
if (alstate == NULL) {
SCLogDebug("state matches but no state, we can't match");
@ -1330,6 +1335,7 @@ end:
DetectEngineCleanHCBDBuffers(det_ctx);
DetectEngineCleanHHDBuffers(det_ctx);
DetectEngineCleanHRHDBuffers(det_ctx);
/* store the found sgh (or NULL) in the flow to save us from looking it
* up again for the next packet. Also return any stream chunk we processed
@ -1507,6 +1513,9 @@ int SignatureIsIPOnly(DetectEngineCtx *de_ctx, Signature *s) {
if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] != NULL)
return 0;
if (s->sm_lists[DETECT_SM_LIST_HRHDMATCH] != NULL)
return 0;
if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL)
return 0;
@ -1584,6 +1593,9 @@ static int SignatureIsDEOnly(DetectEngineCtx *de_ctx, Signature *s) {
if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] != NULL)
return 0;
if (s->sm_lists[DETECT_SM_LIST_HRHDMATCH] != NULL)
return 0;
SigMatch *sm = s->sm_lists[DETECT_SM_LIST_MATCH];
/* check for conflicting keywords */
for ( ;sm != NULL; sm = sm->next) {
@ -1681,6 +1693,11 @@ static int SignatureCreateMask(Signature *s) {
SCLogDebug("sig requires http app state");
}
if (s->sm_lists[DETECT_SM_LIST_HRHDMATCH] != NULL) {
s->mask |= SIG_MASK_REQUIRE_HTTP_STATE;
SCLogDebug("sig requires http app state");
}
SigMatch *sm;
for (sm = s->sm_lists[DETECT_SM_LIST_AMATCH] ; sm != NULL; sm = sm->next) {
switch(sm->type) {
@ -1759,6 +1776,9 @@ static void SigInitStandardMpmFactoryContexts(DetectEngineCtx *de_ctx)
de_ctx->sgh_mpm_context_hhd =
MpmFactoryRegisterMpmCtxProfile("hhd",
MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD);
de_ctx->sgh_mpm_context_hrhd =
MpmFactoryRegisterMpmCtxProfile("hrhd",
MPM_CTX_FACTORY_FLAGS_PREPARE_WITH_SIG_GROUP_BUILD);
de_ctx->sgh_mpm_context_app_proto_detect =
MpmFactoryRegisterMpmCtxProfile("app_proto_detect", 0);
@ -3719,6 +3739,12 @@ int SigGroupBuild (DetectEngineCtx *de_ctx) {
}
//printf("hhd- %d\n", mpm_ctx->pattern_cnt);
mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx->sgh_mpm_context_hrhd);
if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) {
mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx);
}
//printf("hrhd- %d\n", mpm_ctx->pattern_cnt);
mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx->sgh_mpm_context_stream);
if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) {
mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx);

@ -235,21 +235,24 @@ typedef struct DetectPort_ {
#define SIG_FLAG_DMATCH 0x00100000
#define SIG_FLAG_HCBDMATCH 0x00200000
#define SIG_FLAG_HHDMATCH 0x00400000
#define SIG_FLAG_HRHDMATCH 0x00800000
#define SIG_FLAG_MPM_PACKET 0x00800000
#define SIG_FLAG_MPM_PACKET_NEG 0x01000000
#define SIG_FLAG_MPM_STREAM 0x02000000
#define SIG_FLAG_MPM_STREAM_NEG 0x04000000
#define SIG_FLAG_MPM_URICONTENT 0x08000000
#define SIG_FLAG_MPM_URICONTENT_NEG 0x10000000
#define SIG_FLAG_MPM_HCBDCONTENT 0x20000000
#define SIG_FLAG_MPM_HCBDCONTENT_NEG 0x40000000
#define SIG_FLAG_MPM_PACKET 0x01000000
#define SIG_FLAG_MPM_PACKET_NEG 0x02000000
#define SIG_FLAG_MPM_STREAM 0x04000000
#define SIG_FLAG_MPM_STREAM_NEG 0x08000000
#define SIG_FLAG_MPM_URICONTENT 0x10000000
#define SIG_FLAG_MPM_URICONTENT_NEG 0x20000000
#define SIG_FLAG_HAS_NO_PKT_AND_STREAM_CONTENT 0x80000000
#define SIG_FLAG_HAS_NO_PKT_AND_STREAM_CONTENT 0x40000000
/* the mpm specific flags in Signature, held in Signature->mpm_flags */
#define SIG_FLAG_MPM_HHDCONTENT 0x00000001
#define SIG_FLAG_MPM_HHDCONTENT_NEG 0x00000002
#define SIG_FLAG_MPM_HHDCONTENT 0x00000001
#define SIG_FLAG_MPM_HHDCONTENT_NEG 0x00000002
#define SIG_FLAG_MPM_HRHDCONTENT 0x00000004
#define SIG_FLAG_MPM_HRHDCONTENT_NEG 0x00000008
#define SIG_FLAG_MPM_HCBDCONTENT 0x00000010
#define SIG_FLAG_MPM_HCBDCONTENT_NEG 0x00000020
/* signature mask flags */
@ -371,6 +374,7 @@ typedef struct Signature_ {
PatIntId mpm_uripattern_id;
PatIntId mpm_hcbdpattern_id;
PatIntId mpm_hhdpattern_id;
PatIntId mpm_hrhdpattern_id;
/* the fast pattern added from this signature */
SigMatch *mpm_sm;
@ -638,6 +642,7 @@ typedef struct DetectEngineCtx_ {
int32_t sgh_mpm_context_uri;
int32_t sgh_mpm_context_hcbd;
int32_t sgh_mpm_context_hhd;
int32_t sgh_mpm_context_hrhd;
int32_t sgh_mpm_context_app_proto_detect;
/** sgh for signatures that match against invalid packets. In those cases
@ -689,6 +694,10 @@ typedef struct DetectionEngineThreadCtx_ {
char de_have_hhd;
char de_mpm_scanned_hhd;
/* detectione engine context for hrhd mpm */
char de_have_hrhd;
char de_mpm_scanned_hrhd;
uint8_t **hcbd_buffers;
uint32_t *hcbd_buffers_len;
uint16_t hcbd_buffers_list_len;
@ -697,6 +706,10 @@ typedef struct DetectionEngineThreadCtx_ {
uint32_t *hhd_buffers_len;
uint16_t hhd_buffers_list_len;
uint8_t **hrhd_buffers;
uint32_t *hrhd_buffers_len;
uint16_t hrhd_buffers_list_len;
/** id for alert counter */
uint16_t counter_alerts;
@ -789,11 +802,12 @@ typedef struct SigTableElmt_ {
#define SIG_GROUP_HAVESTREAMCONTENT 0x0004
#define SIG_GROUP_HAVEHCBDCONTENT 0x0008
#define SIG_GROUP_HAVEHHDCONTENT 0x0010
#define SIG_GROUP_HEAD_MPM_COPY 0x0020
#define SIG_GROUP_HEAD_MPM_URI_COPY 0x0040
#define SIG_GROUP_HEAD_MPM_STREAM_COPY 0x0080
#define SIG_GROUP_HEAD_FREE 0x0100
#define SIG_GROUP_HEAD_REFERENCED 0x0200 /**< sgh is being referenced by others, don't clear */
#define SIG_GROUP_HAVEHRHDCONTENT 0x0020
#define SIG_GROUP_HEAD_MPM_COPY 0x0040
#define SIG_GROUP_HEAD_MPM_URI_COPY 0x0080
#define SIG_GROUP_HEAD_MPM_STREAM_COPY 0x0100
#define SIG_GROUP_HEAD_FREE 0x0200
#define SIG_GROUP_HEAD_REFERENCED 0x0400 /**< sgh is being referenced by others, don't clear */
typedef struct SigGroupHeadInitData_ {
/* list of content containers
@ -837,6 +851,7 @@ typedef struct SigGroupHead_ {
MpmCtx *mpm_uri_ctx;
MpmCtx *mpm_hcbd_ctx;
MpmCtx *mpm_hhd_ctx;
MpmCtx *mpm_hrhd_ctx;
uint16_t mpm_uricontent_maxlen;
uint16_t pad1;
#if __WORDSIZE == 64

@ -55,6 +55,7 @@
#include "detect-engine-uri.h"
#include "detect-engine-hcbd.h"
#include "detect-engine-hhd.h"
#include "detect-engine-hrhd.h"
#include "detect-engine-state.h"
#include "detect-engine-tag.h"
#include "detect-fast-pattern.h"
@ -971,6 +972,7 @@ int main(int argc, char **argv)
MemcmpRegisterTests();
DetectEngineHttpClientBodyRegisterTests();
DetectEngineHttpHeaderRegisterTests();
DetectEngineHttpRawHeaderRegisterTests();
DetectEngineRegisterTests();
SCLogRegisterTests();
if (list_unittests) {

@ -206,101 +206,101 @@ static inline int SCMemcmpLowercase(void *s1, void *s2, size_t len) {
#elif defined(__SSE3__)
#include <pmmintrin.h> /* for SSE3 */
#define SCMEMCMP_BYTES 16
static inline int SCMemcmp(void *s1, void *s2, size_t len) {
size_t offset = 0;
__m128i b1, b2, c;
do {
/* do unaligned loads using _mm_loadu_si128. On my Core2 E6600 using
* _mm_lddqu_si128 was about 2% slower even though it's supposed to
* be faster. */
b1 = _mm_loadu_si128((const __m128i *) s1);
b2 = _mm_loadu_si128((const __m128i *) s2);
c = _mm_cmpeq_epi8(b1, b2);
int diff = len - offset;
if (diff < 16) {
int rmask = ~(0xFFFFFFFF << diff);
if ((_mm_movemask_epi8(c) & rmask) != rmask) {
return 1;
}
} else {
if (_mm_movemask_epi8(c) != 0x0000FFFF) {
return 1;
}
}
offset += SCMEMCMP_BYTES;
s1 += SCMEMCMP_BYTES;
s2 += SCMEMCMP_BYTES;
} while (len > offset);
return 0;
}
#define UPPER_LOW 0x40 /* "A" - 1 */
#define UPPER_HIGH 0x5B /* "Z" + 1 */
#define UPPER_DELTA 0xDF /* 0xFF - 0x20 */
static inline int SCMemcmpLowercase(void *s1, void *s2, size_t len) {
size_t offset = 0;
__m128i b1, b2, mask1, mask2, upper1, upper2, delta;
/* setup registers for upper to lower conversion */
upper1 = _mm_set1_epi8(UPPER_LOW);
upper2 = _mm_set1_epi8(UPPER_HIGH);
delta = _mm_set1_epi8(UPPER_DELTA);
do {
/* unaligned loading of the bytes to compare */
b1 = _mm_loadu_si128((const __m128i *) s1);
b2 = _mm_loadu_si128((const __m128i *) s2);
/* mark all chars bigger than upper1 */
mask1 = _mm_cmpgt_epi8(b2, upper1);
/* mark all chars lower than upper2 */
mask2 = _mm_cmplt_epi8(b2, upper2);
/* merge the two, leaving only those that are true in both */
mask1 = _mm_cmpeq_epi8(mask1, mask2);
/* sub delta leaves 0x20 only for uppercase positions, the
rest is 0x00 due to the saturation (reuse mask1 reg)*/
mask1 = _mm_subs_epu8(mask1, delta);
/* add to b2, converting uppercase to lowercase */
b2 = _mm_add_epi8(b2, mask1);
/* now all is lowercase, let's do the actual compare (reuse mask1 reg) */
mask1 = _mm_cmpeq_epi8(b1, b2);
int diff = len - offset;
if (diff < 16) {
int rmask = ~(0xFFFFFFFF << diff);
if ((_mm_movemask_epi8(mask1) & rmask) != rmask) {
return 1;
}
} else {
if (_mm_movemask_epi8(mask1) != 0x0000FFFF) {
return 1;
}
}
offset += SCMEMCMP_BYTES;
s1 += SCMEMCMP_BYTES;
s2 += SCMEMCMP_BYTES;
} while (len > offset);
return 0;
}
//#elif defined(__SSE3__)
//
//#include <pmmintrin.h> /* for SSE3 */
//
//#define SCMEMCMP_BYTES 16
//
//static inline int SCMemcmp(void *s1, void *s2, size_t len) {
// size_t offset = 0;
// __m128i b1, b2, c;
//
// do {
// /* do unaligned loads using _mm_loadu_si128. On my Core2 E6600 using
// * _mm_lddqu_si128 was about 2% slower even though it's supposed to
// * be faster. */
// b1 = _mm_loadu_si128((const __m128i *) s1);
// b2 = _mm_loadu_si128((const __m128i *) s2);
// c = _mm_cmpeq_epi8(b1, b2);
//
// int diff = len - offset;
// if (diff < 16) {
// int rmask = ~(0xFFFFFFFF << diff);
//
// if ((_mm_movemask_epi8(c) & rmask) != rmask) {
// return 1;
// }
// } else {
// if (_mm_movemask_epi8(c) != 0x0000FFFF) {
// return 1;
// }
// }
//
// offset += SCMEMCMP_BYTES;
// s1 += SCMEMCMP_BYTES;
// s2 += SCMEMCMP_BYTES;
// } while (len > offset);
//
// return 0;
//}
//
//#define UPPER_LOW 0x40 /* "A" - 1 */
//#define UPPER_HIGH 0x5B /* "Z" + 1 */
//#define UPPER_DELTA 0xDF /* 0xFF - 0x20 */
//
//static inline int SCMemcmpLowercase(void *s1, void *s2, size_t len) {
// size_t offset = 0;
// __m128i b1, b2, mask1, mask2, upper1, upper2, delta;
//
// /* setup registers for upper to lower conversion */
// upper1 = _mm_set1_epi8(UPPER_LOW);
// upper2 = _mm_set1_epi8(UPPER_HIGH);
// delta = _mm_set1_epi8(UPPER_DELTA);
//
// do {
// /* unaligned loading of the bytes to compare */
// b1 = _mm_loadu_si128((const __m128i *) s1);
// b2 = _mm_loadu_si128((const __m128i *) s2);
//
// /* mark all chars bigger than upper1 */
// mask1 = _mm_cmpgt_epi8(b2, upper1);
// /* mark all chars lower than upper2 */
// mask2 = _mm_cmplt_epi8(b2, upper2);
// /* merge the two, leaving only those that are true in both */
// mask1 = _mm_cmpeq_epi8(mask1, mask2);
//
// /* sub delta leaves 0x20 only for uppercase positions, the
// rest is 0x00 due to the saturation (reuse mask1 reg)*/
// mask1 = _mm_subs_epu8(mask1, delta);
//
// /* add to b2, converting uppercase to lowercase */
// b2 = _mm_add_epi8(b2, mask1);
//
// /* now all is lowercase, let's do the actual compare (reuse mask1 reg) */
// mask1 = _mm_cmpeq_epi8(b1, b2);
//
// int diff = len - offset;
// if (diff < 16) {
// int rmask = ~(0xFFFFFFFF << diff);
//
// if ((_mm_movemask_epi8(mask1) & rmask) != rmask) {
// return 1;
// }
// } else {
// if (_mm_movemask_epi8(mask1) != 0x0000FFFF) {
// return 1;
// }
// }
//
// offset += SCMEMCMP_BYTES;
// s1 += SCMEMCMP_BYTES;
// s2 += SCMEMCMP_BYTES;
// } while (len > offset);
//
// return 0;
//}
//
#else
/* No SIMD support, fall back to plain memcmp and a home grown lowercase one */

Loading…
Cancel
Save