mirror of https://github.com/OISF/suricata
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2852 lines
109 KiB
C
2852 lines
109 KiB
C
/* 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 Victor Julien <victor@inliniac.net>
|
|
* \author Anoop Saldanha <anoopsaldanha@gmail.com>
|
|
*
|
|
* Multi pattern matcher
|
|
*/
|
|
|
|
#include "suricata.h"
|
|
#include "suricata-common.h"
|
|
|
|
#include "app-layer-protos.h"
|
|
|
|
#include "decode.h"
|
|
#include "detect.h"
|
|
#include "detect-engine.h"
|
|
#include "detect-engine-siggroup.h"
|
|
#include "detect-engine-mpm.h"
|
|
#include "detect-engine-iponly.h"
|
|
#include "detect-parse.h"
|
|
#include "util-mpm.h"
|
|
#include "conf.h"
|
|
#include "detect-fast-pattern.h"
|
|
|
|
#include "flow.h"
|
|
#include "flow-var.h"
|
|
#include "detect-flow.h"
|
|
|
|
#include "detect-content.h"
|
|
#include "detect-uricontent.h"
|
|
|
|
#include "stream.h"
|
|
|
|
#include "util-cuda-handlers.h"
|
|
#include "util-mpm-b2g-cuda.h"
|
|
|
|
#include "util-enum.h"
|
|
#include "util-debug.h"
|
|
#include "util-print.h"
|
|
#include "util-memcmp.h"
|
|
|
|
/** \todo make it possible to use multiple pattern matcher algorithms next to
|
|
eachother. */
|
|
#ifdef __SC_CUDA_SUPPORT__
|
|
#define PM MPM_B2G_CUDA
|
|
#else
|
|
#define PM MPM_B2G
|
|
#endif
|
|
|
|
#define POPULATE_MPM_AVOID_PACKET_MPM_PATTERNS 0x01
|
|
#define POPULATE_MPM_AVOID_STREAM_MPM_PATTERNS 0x02
|
|
#define POPULATE_MPM_AVOID_URI_MPM_PATTERNS 0x04
|
|
|
|
/**
|
|
* \brief check if a signature has patterns that are to be inspected
|
|
* against a packets payload (as opposed to the stream payload)
|
|
*
|
|
* \param s signature
|
|
*
|
|
* \retval 1 true
|
|
* \retval 0 false
|
|
*/
|
|
int SignatureHasPacketContent(Signature *s) {
|
|
SCEnter();
|
|
|
|
if (s == NULL) {
|
|
SCReturnInt(0);
|
|
}
|
|
|
|
if (!(s->proto.proto[6 / 8] & 1 << (6 % 8))) {
|
|
SCReturnInt(1);
|
|
}
|
|
|
|
if (s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
|
|
SCLogDebug("no mpm");
|
|
SCReturnInt(0);
|
|
}
|
|
|
|
if (!(s->flags & SIG_FLAG_REQUIRE_PACKET)) {
|
|
SCReturnInt(0);
|
|
}
|
|
|
|
SCReturnInt(1);
|
|
}
|
|
|
|
/**
|
|
* \brief check if a signature has patterns that are to be inspected
|
|
* against the stream payload (as opposed to the individual packets
|
|
* payload(s))
|
|
*
|
|
* \param s signature
|
|
*
|
|
* \retval 1 true
|
|
* \retval 0 false
|
|
*/
|
|
int SignatureHasStreamContent(Signature *s) {
|
|
SCEnter();
|
|
|
|
if (s == NULL) {
|
|
SCReturnInt(0);
|
|
}
|
|
|
|
if (!(s->proto.proto[6 / 8] & 1 << (6 % 8))) {
|
|
SCReturnInt(0);
|
|
}
|
|
|
|
if (s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL) {
|
|
SCLogDebug("no mpm");
|
|
SCReturnInt(0);
|
|
}
|
|
|
|
if (!(s->flags & SIG_FLAG_REQUIRE_STREAM)) {
|
|
SCReturnInt(0);
|
|
}
|
|
|
|
SCReturnInt(1);
|
|
}
|
|
|
|
|
|
/**
|
|
* \brief Function to return the multi pattern matcher algorithm to be
|
|
* used by the engine, based on the mpm-algo setting in yaml
|
|
* Use the default mpm non is found in yaml.
|
|
*
|
|
* \retval mpm algo value
|
|
*/
|
|
uint16_t PatternMatchDefaultMatcher(void) {
|
|
char *mpm_algo;
|
|
uint16_t mpm_algo_val = PM;
|
|
|
|
/* Get the mpm algo defined in config file by the user */
|
|
if ((ConfGet("mpm-algo", &mpm_algo)) == 1) {
|
|
uint16_t u;
|
|
|
|
if (mpm_algo != NULL) {
|
|
for (u = 0; u < MPM_TABLE_SIZE; u++) {
|
|
if (mpm_table[u].name == NULL)
|
|
continue;
|
|
|
|
if (strcmp(mpm_table[u].name, mpm_algo) == 0) {
|
|
return u;
|
|
}
|
|
}
|
|
}
|
|
|
|
SCLogError(SC_ERR_INVALID_YAML_CONF_ENTRY, "Invalid mpm algo supplied "
|
|
"in the yaml conf file: \"%s\"", mpm_algo);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
return mpm_algo_val;
|
|
}
|
|
|
|
uint32_t PacketPatternSearchWithStreamCtx(DetectEngineThreadCtx *det_ctx,
|
|
Packet *p)
|
|
{
|
|
SCEnter();
|
|
|
|
uint32_t ret = 0;
|
|
|
|
if (p->flowflags & FLOW_PKT_TOSERVER) {
|
|
if (det_ctx->sgh->mpm_stream_ctx_ts == NULL)
|
|
SCReturnInt(0);
|
|
|
|
ret = mpm_table[det_ctx->sgh->mpm_stream_ctx_ts->mpm_type].
|
|
Search(det_ctx->sgh->mpm_stream_ctx_ts, &det_ctx->mtc, &det_ctx->pmq,
|
|
p->payload, p->payload_len);
|
|
} else {
|
|
if (det_ctx->sgh->mpm_stream_ctx_tc == NULL)
|
|
SCReturnInt(0);
|
|
|
|
ret = mpm_table[det_ctx->sgh->mpm_stream_ctx_tc->mpm_type].
|
|
Search(det_ctx->sgh->mpm_stream_ctx_tc, &det_ctx->mtc, &det_ctx->pmq,
|
|
p->payload, p->payload_len);
|
|
}
|
|
|
|
SCReturnInt(ret);
|
|
}
|
|
|
|
/** \brief Pattern match -- searches for only one pattern per signature.
|
|
*
|
|
* \param det_ctx detection engine thread ctx
|
|
* \param p packet to inspect
|
|
*
|
|
* \retval ret number of matches
|
|
*/
|
|
uint32_t PacketPatternSearch(DetectEngineThreadCtx *det_ctx, Packet *p)
|
|
{
|
|
SCEnter();
|
|
|
|
uint32_t ret;
|
|
MpmCtx *mpm_ctx = NULL;
|
|
|
|
if (p->proto == IPPROTO_TCP) {
|
|
if (p->flowflags & FLOW_PKT_TOSERVER) {
|
|
mpm_ctx = det_ctx->sgh->mpm_proto_tcp_ctx_ts;
|
|
} else {
|
|
mpm_ctx = det_ctx->sgh->mpm_proto_tcp_ctx_tc;
|
|
}
|
|
} else if (p->proto == IPPROTO_UDP) {
|
|
if (p->flowflags & FLOW_PKT_TOSERVER) {
|
|
mpm_ctx = det_ctx->sgh->mpm_proto_udp_ctx_ts;
|
|
} else {
|
|
mpm_ctx = det_ctx->sgh->mpm_proto_udp_ctx_tc;
|
|
}
|
|
} else {
|
|
mpm_ctx = det_ctx->sgh->mpm_proto_other_ctx;
|
|
}
|
|
|
|
if (mpm_ctx == NULL)
|
|
SCReturnInt(0);
|
|
|
|
#ifndef __SC_CUDA_SUPPORT__
|
|
ret = mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx,
|
|
&det_ctx->mtc,
|
|
&det_ctx->pmq,
|
|
p->payload,
|
|
p->payload_len);
|
|
#else
|
|
/* if the user has enabled cuda support, but is not using the cuda mpm
|
|
* algo, then we shouldn't take the path of the dispatcher. Call the mpm
|
|
* directly */
|
|
if (mpm_ctx->mpm_type != MPM_B2G_CUDA) {
|
|
ret = mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx,
|
|
&det_ctx->mtc,
|
|
&det_ctx->pmq,
|
|
p->payload,
|
|
p->payload_len);
|
|
SCReturnInt(ret);
|
|
}
|
|
|
|
if (p->cuda_mpm_enabled) {
|
|
ret = B2gCudaResultsPostProcessing(p, mpm_ctx, &det_ctx->mtc,
|
|
&det_ctx->pmq);
|
|
} else {
|
|
ret = mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx,
|
|
&det_ctx->mtc,
|
|
&det_ctx->pmq,
|
|
p->payload,
|
|
p->payload_len);
|
|
}
|
|
#endif
|
|
|
|
SCReturnInt(ret);
|
|
}
|
|
|
|
/** \brief Uri Pattern match -- searches for one pattern per signature.
|
|
*
|
|
* \param det_ctx detection engine thread ctx
|
|
* \param p packet to inspect
|
|
*
|
|
* \retval ret number of matches
|
|
*/
|
|
uint32_t UriPatternSearch(DetectEngineThreadCtx *det_ctx,
|
|
uint8_t *uri, uint16_t uri_len, uint8_t flags)
|
|
{
|
|
SCEnter();
|
|
|
|
uint32_t ret;
|
|
if (flags & STREAM_TOSERVER) {
|
|
if (det_ctx->sgh->mpm_uri_ctx_ts == NULL)
|
|
SCReturnUInt(0U);
|
|
|
|
ret = mpm_table[det_ctx->sgh->mpm_uri_ctx_ts->mpm_type].
|
|
Search(det_ctx->sgh->mpm_uri_ctx_ts,
|
|
&det_ctx->mtcu, &det_ctx->pmq, uri, uri_len);
|
|
} else {
|
|
if (det_ctx->sgh->mpm_uri_ctx_tc == NULL)
|
|
SCReturnUInt(0U);
|
|
|
|
ret = mpm_table[det_ctx->sgh->mpm_uri_ctx_tc->mpm_type].
|
|
Search(det_ctx->sgh->mpm_uri_ctx_tc,
|
|
&det_ctx->mtcu, &det_ctx->pmq, uri, uri_len);
|
|
}
|
|
|
|
//PrintRawDataFp(stdout, uri, uri_len);
|
|
|
|
SCReturnUInt(ret);
|
|
}
|
|
|
|
/** \brief Http client body pattern match -- searches for one pattern per
|
|
* signature.
|
|
*
|
|
* \param det_ctx Detection engine thread ctx.
|
|
* \param body The request body to inspect.
|
|
* \param body_len Body length.
|
|
*
|
|
* \retval ret Number of matches.
|
|
*/
|
|
uint32_t HttpClientBodyPatternSearch(DetectEngineThreadCtx *det_ctx,
|
|
uint8_t *body, uint32_t body_len, uint8_t flags)
|
|
{
|
|
SCEnter();
|
|
|
|
uint32_t ret;
|
|
if (flags & STREAM_TOSERVER) {
|
|
if (det_ctx->sgh->mpm_hcbd_ctx_ts == NULL)
|
|
SCReturnUInt(0);
|
|
|
|
ret = mpm_table[det_ctx->sgh->mpm_hcbd_ctx_ts->mpm_type].
|
|
Search(det_ctx->sgh->mpm_hcbd_ctx_ts, &det_ctx->mtcu,
|
|
&det_ctx->pmq, body, body_len);
|
|
} else {
|
|
if (det_ctx->sgh->mpm_hcbd_ctx_tc == NULL)
|
|
SCReturnUInt(0);
|
|
|
|
ret = mpm_table[det_ctx->sgh->mpm_hcbd_ctx_tc->mpm_type].
|
|
Search(det_ctx->sgh->mpm_hcbd_ctx_tc, &det_ctx->mtcu,
|
|
&det_ctx->pmq, body, body_len);
|
|
}
|
|
|
|
SCReturnUInt(ret);
|
|
}
|
|
|
|
/** \brief Http server body pattern match -- searches for one pattern per
|
|
* signature.
|
|
*
|
|
* \param det_ctx Detection engine thread ctx.
|
|
* \param body The request body to inspect.
|
|
* \param body_len Body length.
|
|
*
|
|
* \retval ret Number of matches.
|
|
*/
|
|
uint32_t HttpServerBodyPatternSearch(DetectEngineThreadCtx *det_ctx,
|
|
uint8_t *body, uint32_t body_len, uint8_t flags)
|
|
{
|
|
SCEnter();
|
|
|
|
uint32_t ret;
|
|
if (flags & STREAM_TOSERVER) {
|
|
if (det_ctx->sgh->mpm_hsbd_ctx_ts == NULL)
|
|
SCReturnUInt(0);
|
|
|
|
ret = mpm_table[det_ctx->sgh->mpm_hsbd_ctx_ts->mpm_type].
|
|
Search(det_ctx->sgh->mpm_hsbd_ctx_ts, &det_ctx->mtcu,
|
|
&det_ctx->pmq, body, body_len);
|
|
} else {
|
|
if (det_ctx->sgh->mpm_hsbd_ctx_tc == NULL)
|
|
SCReturnUInt(0);
|
|
|
|
ret = mpm_table[det_ctx->sgh->mpm_hsbd_ctx_tc->mpm_type].
|
|
Search(det_ctx->sgh->mpm_hsbd_ctx_tc, &det_ctx->mtcu,
|
|
&det_ctx->pmq, body, body_len);
|
|
}
|
|
|
|
SCReturnUInt(ret);
|
|
}
|
|
|
|
/**
|
|
* \brief Http header match -- searches for one pattern per signature.
|
|
*
|
|
* \param det_ctx Detection engine thread ctx.
|
|
* \param headers Headers to inspect.
|
|
* \param headers_len Headers length.
|
|
*
|
|
* \retval ret Number of matches.
|
|
*/
|
|
uint32_t HttpHeaderPatternSearch(DetectEngineThreadCtx *det_ctx,
|
|
uint8_t *headers, uint32_t headers_len, uint8_t flags)
|
|
{
|
|
SCEnter();
|
|
|
|
uint32_t ret;
|
|
if (flags & STREAM_TOSERVER) {
|
|
if (det_ctx->sgh->mpm_hhd_ctx_ts == NULL)
|
|
SCReturnUInt(0);
|
|
|
|
ret = mpm_table[det_ctx->sgh->mpm_hhd_ctx_ts->mpm_type].
|
|
Search(det_ctx->sgh->mpm_hhd_ctx_ts, &det_ctx->mtcu,
|
|
&det_ctx->pmq, headers, headers_len);
|
|
} else {
|
|
if (det_ctx->sgh->mpm_hhd_ctx_tc == NULL)
|
|
SCReturnUInt(0);
|
|
|
|
ret = mpm_table[det_ctx->sgh->mpm_hhd_ctx_tc->mpm_type].
|
|
Search(det_ctx->sgh->mpm_hhd_ctx_tc, &det_ctx->mtcu,
|
|
&det_ctx->pmq, headers, headers_len);
|
|
}
|
|
|
|
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, uint8_t flags)
|
|
{
|
|
SCEnter();
|
|
|
|
uint32_t ret;
|
|
if (flags & STREAM_TOSERVER) {
|
|
if (det_ctx->sgh->mpm_hrhd_ctx_ts == NULL)
|
|
SCReturnUInt(0);
|
|
|
|
ret = mpm_table[det_ctx->sgh->mpm_hrhd_ctx_ts->mpm_type].
|
|
Search(det_ctx->sgh->mpm_hrhd_ctx_ts, &det_ctx->mtcu,
|
|
&det_ctx->pmq, raw_headers, raw_headers_len);
|
|
} else {
|
|
if (det_ctx->sgh->mpm_hrhd_ctx_tc == NULL)
|
|
SCReturnUInt(0);
|
|
|
|
ret = mpm_table[det_ctx->sgh->mpm_hrhd_ctx_tc->mpm_type].
|
|
Search(det_ctx->sgh->mpm_hrhd_ctx_tc, &det_ctx->mtcu,
|
|
&det_ctx->pmq, raw_headers, raw_headers_len);
|
|
}
|
|
|
|
SCReturnUInt(ret);
|
|
}
|
|
|
|
/**
|
|
* \brief Http method match -- searches for one pattern per signature.
|
|
*
|
|
* \param det_ctx Detection engine thread ctx.
|
|
* \param method Method to inspect.
|
|
* \param method_len Method length.
|
|
*
|
|
* \retval ret Number of matches.
|
|
*/
|
|
uint32_t HttpMethodPatternSearch(DetectEngineThreadCtx *det_ctx,
|
|
uint8_t *raw_method, uint32_t raw_method_len, uint8_t flags)
|
|
{
|
|
SCEnter();
|
|
|
|
uint32_t ret;
|
|
if (flags & STREAM_TOSERVER) {
|
|
if (det_ctx->sgh->mpm_hmd_ctx_ts == NULL)
|
|
SCReturnUInt(0);
|
|
|
|
ret = mpm_table[det_ctx->sgh->mpm_hmd_ctx_ts->mpm_type].
|
|
Search(det_ctx->sgh->mpm_hmd_ctx_ts, &det_ctx->mtcu,
|
|
&det_ctx->pmq, raw_method, raw_method_len);
|
|
} else {
|
|
if (det_ctx->sgh->mpm_hmd_ctx_tc == NULL)
|
|
SCReturnUInt(0);
|
|
|
|
ret = mpm_table[det_ctx->sgh->mpm_hmd_ctx_tc->mpm_type].
|
|
Search(det_ctx->sgh->mpm_hmd_ctx_tc, &det_ctx->mtcu,
|
|
&det_ctx->pmq, raw_method, raw_method_len);
|
|
}
|
|
|
|
SCReturnUInt(ret);
|
|
}
|
|
|
|
/**
|
|
* \brief Http cookie match -- searches for one pattern per signature.
|
|
*
|
|
* \param det_ctx Detection engine thread ctx.
|
|
* \param cookie Cookie to inspect.
|
|
* \param cookie_len Cookie length.
|
|
*
|
|
* \retval ret Number of matches.
|
|
*/
|
|
uint32_t HttpCookiePatternSearch(DetectEngineThreadCtx *det_ctx,
|
|
uint8_t *cookie, uint32_t cookie_len, uint8_t flags)
|
|
{
|
|
SCEnter();
|
|
|
|
uint32_t ret;
|
|
if (flags & STREAM_TOSERVER) {
|
|
if (det_ctx->sgh->mpm_hcd_ctx_ts == NULL)
|
|
SCReturnUInt(0);
|
|
|
|
ret = mpm_table[det_ctx->sgh->mpm_hcd_ctx_ts->mpm_type].
|
|
Search(det_ctx->sgh->mpm_hcd_ctx_ts, &det_ctx->mtcu,
|
|
&det_ctx->pmq, cookie, cookie_len);
|
|
} else {
|
|
if (det_ctx->sgh->mpm_hcd_ctx_tc == NULL)
|
|
SCReturnUInt(0);
|
|
|
|
ret = mpm_table[det_ctx->sgh->mpm_hcd_ctx_tc->mpm_type].
|
|
Search(det_ctx->sgh->mpm_hcd_ctx_tc, &det_ctx->mtcu,
|
|
&det_ctx->pmq, cookie, cookie_len);
|
|
}
|
|
|
|
SCReturnUInt(ret);
|
|
}
|
|
|
|
/**
|
|
* \brief Http raw uri match -- searches for one pattern per signature.
|
|
*
|
|
* \param det_ctx Detection engine thread ctx.
|
|
* \param uri Raw uri to inspect.
|
|
* \param uri_len Raw uri length.
|
|
*
|
|
* \retval ret Number of matches.
|
|
*/
|
|
uint32_t HttpRawUriPatternSearch(DetectEngineThreadCtx *det_ctx,
|
|
uint8_t *uri, uint32_t uri_len, uint8_t flags)
|
|
{
|
|
SCEnter();
|
|
|
|
uint32_t ret;
|
|
if (flags & STREAM_TOSERVER) {
|
|
if (det_ctx->sgh->mpm_hrud_ctx_ts == NULL)
|
|
SCReturnUInt(0);
|
|
|
|
ret = mpm_table[det_ctx->sgh->mpm_hrud_ctx_ts->mpm_type].
|
|
Search(det_ctx->sgh->mpm_hrud_ctx_ts, &det_ctx->mtcu,
|
|
&det_ctx->pmq, uri, uri_len);
|
|
} else {
|
|
if (det_ctx->sgh->mpm_hrud_ctx_tc == NULL)
|
|
SCReturnUInt(0);
|
|
|
|
ret = mpm_table[det_ctx->sgh->mpm_hrud_ctx_tc->mpm_type].
|
|
Search(det_ctx->sgh->mpm_hrud_ctx_tc, &det_ctx->mtcu,
|
|
&det_ctx->pmq, uri, uri_len);
|
|
}
|
|
|
|
SCReturnUInt(ret);
|
|
}
|
|
|
|
/**
|
|
* \brief Http stat msg match -- searches for one pattern per signature.
|
|
*
|
|
* \param det_ctx Detection engine thread ctx.
|
|
* \param stat_msg Stat msg to inspect.
|
|
* \param stat_msg_len Stat msg length.
|
|
*
|
|
* \retval ret Number of matches.
|
|
*/
|
|
uint32_t HttpStatMsgPatternSearch(DetectEngineThreadCtx *det_ctx,
|
|
uint8_t *stat_msg, uint32_t stat_msg_len, uint8_t flags)
|
|
{
|
|
SCEnter();
|
|
|
|
uint32_t ret;
|
|
if (flags & STREAM_TOSERVER) {
|
|
if (det_ctx->sgh->mpm_hsmd_ctx_ts == NULL)
|
|
SCReturnUInt(0);
|
|
|
|
ret = mpm_table[det_ctx->sgh->mpm_hsmd_ctx_ts->mpm_type].
|
|
Search(det_ctx->sgh->mpm_hsmd_ctx_ts, &det_ctx->mtcu,
|
|
&det_ctx->pmq, stat_msg, stat_msg_len);
|
|
} else {
|
|
if (det_ctx->sgh->mpm_hsmd_ctx_tc == NULL)
|
|
SCReturnUInt(0);
|
|
|
|
ret = mpm_table[det_ctx->sgh->mpm_hsmd_ctx_tc->mpm_type].
|
|
Search(det_ctx->sgh->mpm_hsmd_ctx_tc, &det_ctx->mtcu,
|
|
&det_ctx->pmq, stat_msg, stat_msg_len);
|
|
}
|
|
|
|
SCReturnUInt(ret);
|
|
}
|
|
|
|
/**
|
|
* \brief Http stat code match -- searches for one pattern per signature.
|
|
*
|
|
* \param det_ctx Detection engine thread ctx.
|
|
* \param stat_code Stat code to inspect.
|
|
* \param stat_code_len Stat code length.
|
|
*
|
|
* \retval ret Number of matches.
|
|
*/
|
|
uint32_t HttpStatCodePatternSearch(DetectEngineThreadCtx *det_ctx,
|
|
uint8_t *stat_code, uint32_t stat_code_len, uint8_t flags)
|
|
{
|
|
SCEnter();
|
|
|
|
uint32_t ret;
|
|
if (flags & STREAM_TOSERVER) {
|
|
if (det_ctx->sgh->mpm_hscd_ctx_ts == NULL)
|
|
SCReturnUInt(0);
|
|
|
|
ret = mpm_table[det_ctx->sgh->mpm_hscd_ctx_ts->mpm_type].
|
|
Search(det_ctx->sgh->mpm_hscd_ctx_ts, &det_ctx->mtcu,
|
|
&det_ctx->pmq, stat_code, stat_code_len);
|
|
} else {
|
|
if (det_ctx->sgh->mpm_hscd_ctx_tc == NULL)
|
|
SCReturnUInt(0);
|
|
|
|
ret = mpm_table[det_ctx->sgh->mpm_hscd_ctx_tc->mpm_type].
|
|
Search(det_ctx->sgh->mpm_hscd_ctx_tc, &det_ctx->mtcu,
|
|
&det_ctx->pmq, stat_code, stat_code_len);
|
|
}
|
|
|
|
SCReturnUInt(ret);
|
|
}
|
|
|
|
/**
|
|
* \brief Http user agent match -- searches for one pattern per signature.
|
|
*
|
|
* \param det_ctx Detection engine thread ctx.
|
|
* \param cookie User-Agent to inspect.
|
|
* \param cookie_len User-Agent buffer length.
|
|
*
|
|
* \retval ret Number of matches.
|
|
*/
|
|
uint32_t HttpUAPatternSearch(DetectEngineThreadCtx *det_ctx,
|
|
uint8_t *ua, uint32_t ua_len, uint8_t flags)
|
|
{
|
|
SCEnter();
|
|
|
|
uint32_t ret;
|
|
if (flags & STREAM_TOSERVER) {
|
|
if (det_ctx->sgh->mpm_huad_ctx_ts == NULL)
|
|
SCReturnUInt(0);
|
|
|
|
ret = mpm_table[det_ctx->sgh->mpm_huad_ctx_ts->mpm_type].
|
|
Search(det_ctx->sgh->mpm_huad_ctx_ts, &det_ctx->mtcu,
|
|
&det_ctx->pmq, ua, ua_len);
|
|
} else {
|
|
if (det_ctx->sgh->mpm_huad_ctx_tc == NULL)
|
|
SCReturnUInt(0);
|
|
|
|
ret = mpm_table[det_ctx->sgh->mpm_huad_ctx_tc->mpm_type].
|
|
Search(det_ctx->sgh->mpm_huad_ctx_tc, &det_ctx->mtcu,
|
|
&det_ctx->pmq, ua, ua_len);
|
|
}
|
|
|
|
SCReturnUInt(ret);
|
|
}
|
|
|
|
/** \brief Pattern match -- searches for only one pattern per signature.
|
|
*
|
|
* \param det_ctx detection engine thread ctx
|
|
* \param p packet
|
|
* \param smsg stream msg (reassembled stream data)
|
|
* \param flags stream flags
|
|
*
|
|
* \retval ret number of matches
|
|
*/
|
|
uint32_t StreamPatternSearch(DetectEngineThreadCtx *det_ctx, Packet *p,
|
|
StreamMsg *smsg, uint8_t flags)
|
|
{
|
|
SCEnter();
|
|
|
|
uint32_t ret = 0;
|
|
uint8_t cnt = 0;
|
|
|
|
//PrintRawDataFp(stdout, smsg->data.data, smsg->data.data_len);
|
|
|
|
uint32_t r;
|
|
if (flags & STREAM_TOSERVER) {
|
|
for ( ; smsg != NULL; smsg = smsg->next) {
|
|
r = mpm_table[det_ctx->sgh->mpm_stream_ctx_ts->mpm_type].
|
|
Search(det_ctx->sgh->mpm_stream_ctx_ts, &det_ctx->mtcs,
|
|
&det_ctx->smsg_pmq[cnt], smsg->data.data,
|
|
smsg->data.data_len);
|
|
if (r > 0) {
|
|
ret += r;
|
|
|
|
SCLogDebug("smsg match stored in det_ctx->smsg_pmq[%u]", cnt);
|
|
|
|
/* merge results with overall pmq */
|
|
PmqMerge(&det_ctx->smsg_pmq[cnt], &det_ctx->pmq);
|
|
}
|
|
|
|
cnt++;
|
|
}
|
|
} else {
|
|
for ( ; smsg != NULL; smsg = smsg->next) {
|
|
r = mpm_table[det_ctx->sgh->mpm_stream_ctx_tc->mpm_type].
|
|
Search(det_ctx->sgh->mpm_stream_ctx_tc, &det_ctx->mtcs,
|
|
&det_ctx->smsg_pmq[cnt], smsg->data.data,
|
|
smsg->data.data_len);
|
|
if (r > 0) {
|
|
ret += r;
|
|
|
|
SCLogDebug("smsg match stored in det_ctx->smsg_pmq[%u]", cnt);
|
|
|
|
/* merge results with overall pmq */
|
|
PmqMerge(&det_ctx->smsg_pmq[cnt], &det_ctx->pmq);
|
|
}
|
|
|
|
cnt++;
|
|
}
|
|
}
|
|
|
|
SCReturnInt(ret);
|
|
}
|
|
|
|
/** \brief cleans up the mpm instance after a match */
|
|
void PacketPatternCleanup(ThreadVars *t, DetectEngineThreadCtx *det_ctx) {
|
|
PmqReset(&det_ctx->pmq);
|
|
|
|
if (det_ctx->sgh == NULL)
|
|
return;
|
|
|
|
/* content */
|
|
if (det_ctx->sgh->mpm_proto_tcp_ctx_ts != NULL &&
|
|
mpm_table[det_ctx->sgh->mpm_proto_tcp_ctx_ts->mpm_type].Cleanup != NULL) {
|
|
mpm_table[det_ctx->sgh->mpm_proto_tcp_ctx_ts->mpm_type].Cleanup(&det_ctx->mtc);
|
|
}
|
|
if (det_ctx->sgh->mpm_proto_tcp_ctx_tc != NULL &&
|
|
mpm_table[det_ctx->sgh->mpm_proto_tcp_ctx_tc->mpm_type].Cleanup != NULL) {
|
|
mpm_table[det_ctx->sgh->mpm_proto_tcp_ctx_tc->mpm_type].Cleanup(&det_ctx->mtc);
|
|
}
|
|
|
|
if (det_ctx->sgh->mpm_proto_udp_ctx_ts != NULL &&
|
|
mpm_table[det_ctx->sgh->mpm_proto_udp_ctx_ts->mpm_type].Cleanup != NULL) {
|
|
mpm_table[det_ctx->sgh->mpm_proto_udp_ctx_ts->mpm_type].Cleanup(&det_ctx->mtc);
|
|
}
|
|
if (det_ctx->sgh->mpm_proto_udp_ctx_tc != NULL &&
|
|
mpm_table[det_ctx->sgh->mpm_proto_udp_ctx_tc->mpm_type].Cleanup != NULL) {
|
|
mpm_table[det_ctx->sgh->mpm_proto_udp_ctx_tc->mpm_type].Cleanup(&det_ctx->mtc);
|
|
}
|
|
|
|
if (det_ctx->sgh->mpm_proto_other_ctx != NULL &&
|
|
mpm_table[det_ctx->sgh->mpm_proto_other_ctx->mpm_type].Cleanup != NULL) {
|
|
mpm_table[det_ctx->sgh->mpm_proto_other_ctx->mpm_type].Cleanup(&det_ctx->mtc);
|
|
}
|
|
|
|
/* uricontent */
|
|
if (det_ctx->sgh->mpm_uri_ctx_ts != NULL && mpm_table[det_ctx->sgh->mpm_uri_ctx_ts->mpm_type].Cleanup != NULL) {
|
|
mpm_table[det_ctx->sgh->mpm_uri_ctx_ts->mpm_type].Cleanup(&det_ctx->mtcu);
|
|
}
|
|
if (det_ctx->sgh->mpm_uri_ctx_tc != NULL && mpm_table[det_ctx->sgh->mpm_uri_ctx_tc->mpm_type].Cleanup != NULL) {
|
|
mpm_table[det_ctx->sgh->mpm_uri_ctx_tc->mpm_type].Cleanup(&det_ctx->mtcu);
|
|
}
|
|
|
|
/* stream content */
|
|
if (det_ctx->sgh->mpm_stream_ctx_ts != NULL && mpm_table[det_ctx->sgh->mpm_stream_ctx_ts->mpm_type].Cleanup != NULL) {
|
|
mpm_table[det_ctx->sgh->mpm_stream_ctx_ts->mpm_type].Cleanup(&det_ctx->mtcs);
|
|
}
|
|
if (det_ctx->sgh->mpm_stream_ctx_tc != NULL && mpm_table[det_ctx->sgh->mpm_stream_ctx_tc->mpm_type].Cleanup != NULL) {
|
|
mpm_table[det_ctx->sgh->mpm_stream_ctx_tc->mpm_type].Cleanup(&det_ctx->mtcs);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void StreamPatternCleanup(ThreadVars *t, DetectEngineThreadCtx *det_ctx, StreamMsg *smsg) {
|
|
uint8_t cnt = 0;
|
|
|
|
while (smsg != NULL) {
|
|
PmqReset(&det_ctx->smsg_pmq[cnt]);
|
|
|
|
smsg = smsg->next;
|
|
cnt++;
|
|
}
|
|
}
|
|
|
|
void PatternMatchDestroy(MpmCtx *mpm_ctx, uint16_t mpm_matcher) {
|
|
SCLogDebug("mpm_ctx %p, mpm_matcher %"PRIu16"", mpm_ctx, mpm_matcher);
|
|
mpm_table[mpm_matcher].DestroyCtx(mpm_ctx);
|
|
}
|
|
|
|
void PatternMatchPrepare(MpmCtx *mpm_ctx, uint16_t mpm_matcher) {
|
|
SCLogDebug("mpm_ctx %p, mpm_matcher %"PRIu16"", mpm_ctx, mpm_matcher);
|
|
MpmInitCtx(mpm_ctx, mpm_matcher, -1);
|
|
}
|
|
|
|
void PatternMatchThreadPrint(MpmThreadCtx *mpm_thread_ctx, uint16_t mpm_matcher) {
|
|
SCLogDebug("mpm_thread_ctx %p, mpm_matcher %"PRIu16" defunct", mpm_thread_ctx, mpm_matcher);
|
|
//mpm_table[mpm_matcher].PrintThreadCtx(mpm_thread_ctx);
|
|
}
|
|
void PatternMatchThreadDestroy(MpmThreadCtx *mpm_thread_ctx, uint16_t mpm_matcher) {
|
|
SCLogDebug("mpm_thread_ctx %p, mpm_matcher %"PRIu16"", mpm_thread_ctx, mpm_matcher);
|
|
mpm_table[mpm_matcher].DestroyThreadCtx(NULL, mpm_thread_ctx);
|
|
}
|
|
void PatternMatchThreadPrepare(MpmThreadCtx *mpm_thread_ctx, uint16_t mpm_matcher, uint32_t max_id) {
|
|
SCLogDebug("mpm_thread_ctx %p, type %"PRIu16", max_id %"PRIu32"", mpm_thread_ctx, mpm_matcher, max_id);
|
|
MpmInitThreadCtx(mpm_thread_ctx, mpm_matcher, max_id);
|
|
}
|
|
|
|
|
|
/* free the pattern matcher part of a SigGroupHead */
|
|
void PatternMatchDestroyGroup(SigGroupHead *sh) {
|
|
/* content */
|
|
if (!(sh->flags & SIG_GROUP_HEAD_MPM_COPY)) {
|
|
SCLogDebug("destroying mpm_ctx %p (sh %p)",
|
|
sh->mpm_proto_tcp_ctx_ts, sh);
|
|
if (sh->mpm_proto_tcp_ctx_ts != NULL &&
|
|
!sh->mpm_proto_tcp_ctx_ts->global) {
|
|
mpm_table[sh->mpm_proto_tcp_ctx_ts->mpm_type].
|
|
DestroyCtx(sh->mpm_proto_tcp_ctx_ts);
|
|
SCFree(sh->mpm_proto_tcp_ctx_ts);
|
|
}
|
|
/* ready for reuse */
|
|
sh->mpm_proto_tcp_ctx_ts = NULL;
|
|
|
|
SCLogDebug("destroying mpm_ctx %p (sh %p)",
|
|
sh->mpm_proto_tcp_ctx_tc, sh);
|
|
if (sh->mpm_proto_tcp_ctx_tc != NULL &&
|
|
!sh->mpm_proto_tcp_ctx_tc->global) {
|
|
mpm_table[sh->mpm_proto_tcp_ctx_tc->mpm_type].
|
|
DestroyCtx(sh->mpm_proto_tcp_ctx_tc);
|
|
SCFree(sh->mpm_proto_tcp_ctx_tc);
|
|
}
|
|
/* ready for reuse */
|
|
sh->mpm_proto_tcp_ctx_tc = NULL;
|
|
|
|
SCLogDebug("destroying mpm_ctx %p (sh %p)",
|
|
sh->mpm_proto_udp_ctx_ts, sh);
|
|
if (sh->mpm_proto_udp_ctx_ts != NULL &&
|
|
!sh->mpm_proto_udp_ctx_ts->global) {
|
|
mpm_table[sh->mpm_proto_udp_ctx_ts->mpm_type].
|
|
DestroyCtx(sh->mpm_proto_udp_ctx_ts);
|
|
SCFree(sh->mpm_proto_udp_ctx_ts);
|
|
}
|
|
/* ready for reuse */
|
|
sh->mpm_proto_udp_ctx_ts = NULL;
|
|
|
|
SCLogDebug("destroying mpm_ctx %p (sh %p)",
|
|
sh->mpm_proto_udp_ctx_tc, sh);
|
|
if (sh->mpm_proto_udp_ctx_tc != NULL &&
|
|
!sh->mpm_proto_udp_ctx_tc->global) {
|
|
mpm_table[sh->mpm_proto_udp_ctx_tc->mpm_type].
|
|
DestroyCtx(sh->mpm_proto_udp_ctx_tc);
|
|
SCFree(sh->mpm_proto_udp_ctx_tc);
|
|
}
|
|
/* ready for reuse */
|
|
sh->mpm_proto_udp_ctx_tc = NULL;
|
|
|
|
SCLogDebug("destroying mpm_ctx %p (sh %p)",
|
|
sh->mpm_proto_other_ctx, sh);
|
|
if (sh->mpm_proto_other_ctx != NULL &&
|
|
!sh->mpm_proto_other_ctx->global) {
|
|
mpm_table[sh->mpm_proto_other_ctx->mpm_type].
|
|
DestroyCtx(sh->mpm_proto_other_ctx);
|
|
SCFree(sh->mpm_proto_other_ctx);
|
|
}
|
|
/* ready for reuse */
|
|
sh->mpm_proto_other_ctx = NULL;
|
|
}
|
|
|
|
/* uricontent */
|
|
if ((sh->mpm_uri_ctx_ts != NULL || sh->mpm_uri_ctx_tc != NULL) &&
|
|
!(sh->flags & SIG_GROUP_HEAD_MPM_URI_COPY)) {
|
|
if (sh->mpm_uri_ctx_ts != NULL) {
|
|
SCLogDebug("destroying mpm_uri_ctx %p (sh %p)", sh->mpm_uri_ctx_ts, sh);
|
|
if (!sh->mpm_uri_ctx_ts->global) {
|
|
mpm_table[sh->mpm_uri_ctx_ts->mpm_type].DestroyCtx(sh->mpm_uri_ctx_ts);
|
|
SCFree(sh->mpm_uri_ctx_ts);
|
|
}
|
|
/* ready for reuse */
|
|
sh->mpm_uri_ctx_ts = NULL;
|
|
}
|
|
if (sh->mpm_uri_ctx_tc != NULL) {
|
|
SCLogDebug("destroying mpm_uri_ctx %p (sh %p)", sh->mpm_uri_ctx_tc, sh);
|
|
if (!sh->mpm_uri_ctx_tc->global) {
|
|
mpm_table[sh->mpm_uri_ctx_tc->mpm_type].DestroyCtx(sh->mpm_uri_ctx_tc);
|
|
SCFree(sh->mpm_uri_ctx_tc);
|
|
}
|
|
/* ready for reuse */
|
|
sh->mpm_uri_ctx_tc = NULL;
|
|
}
|
|
}
|
|
|
|
/* stream content */
|
|
if ((sh->mpm_stream_ctx_ts != NULL || sh->mpm_stream_ctx_tc != NULL) &&
|
|
!(sh->flags & SIG_GROUP_HEAD_MPM_STREAM_COPY)) {
|
|
if (sh->mpm_stream_ctx_ts != NULL) {
|
|
SCLogDebug("destroying mpm_stream_ctx %p (sh %p)", sh->mpm_stream_ctx_ts, sh);
|
|
if (!sh->mpm_stream_ctx_ts->global) {
|
|
mpm_table[sh->mpm_stream_ctx_ts->mpm_type].DestroyCtx(sh->mpm_stream_ctx_ts);
|
|
SCFree(sh->mpm_stream_ctx_ts);
|
|
}
|
|
/* ready for reuse */
|
|
sh->mpm_stream_ctx_ts = NULL;
|
|
}
|
|
if (sh->mpm_stream_ctx_tc != NULL) {
|
|
SCLogDebug("destroying mpm_stream_ctx %p (sh %p)", sh->mpm_stream_ctx_tc, sh);
|
|
if (!sh->mpm_stream_ctx_tc->global) {
|
|
mpm_table[sh->mpm_stream_ctx_tc->mpm_type].DestroyCtx(sh->mpm_stream_ctx_tc);
|
|
SCFree(sh->mpm_stream_ctx_tc);
|
|
}
|
|
/* ready for reuse */
|
|
sh->mpm_stream_ctx_tc = NULL;
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/** \brief Hash for looking up contents that are most used,
|
|
* always used, etc. */
|
|
typedef struct ContentHash_ {
|
|
DetectContentData *ptr;
|
|
uint16_t cnt;
|
|
uint8_t use; /* use no matter what */
|
|
} ContentHash;
|
|
|
|
typedef struct UricontentHash_ {
|
|
DetectContentData *ptr;
|
|
uint16_t cnt;
|
|
uint8_t use; /* use no matter what */
|
|
} UricontentHash;
|
|
|
|
uint32_t ContentHashFunc(HashTable *ht, void *data, uint16_t datalen) {
|
|
ContentHash *ch = (ContentHash *)data;
|
|
DetectContentData *co = ch->ptr;
|
|
uint32_t hash = 0;
|
|
int i;
|
|
for (i = 0; i < co->content_len; i++) {
|
|
hash += co->content[i];
|
|
}
|
|
hash = hash % ht->array_size;
|
|
SCLogDebug("hash %" PRIu32 "", hash);
|
|
return hash;
|
|
}
|
|
|
|
uint32_t UricontentHashFunc(HashTable *ht, void *data, uint16_t datalen) {
|
|
UricontentHash *ch = (UricontentHash *)data;
|
|
DetectContentData *ud = ch->ptr;
|
|
uint32_t hash = 0;
|
|
int i;
|
|
for (i = 0; i < ud->content_len; i++) {
|
|
hash += ud->content[i];
|
|
}
|
|
hash = hash % ht->array_size;
|
|
SCLogDebug("hash %" PRIu32 "", hash);
|
|
return hash;
|
|
}
|
|
|
|
char ContentHashCompareFunc(void *data1, uint16_t len1, void *data2, uint16_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 &&
|
|
((co1->flags & DETECT_CONTENT_NOCASE) == (co2->flags & DETECT_CONTENT_NOCASE)) &&
|
|
SCMemcmp(co1->content, co2->content, co1->content_len) == 0)
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
char UricontentHashCompareFunc(void *data1, uint16_t len1, void *data2, uint16_t len2) {
|
|
UricontentHash *ch1 = (UricontentHash *)data1;
|
|
UricontentHash *ch2 = (UricontentHash *)data2;
|
|
DetectContentData *ud1 = ch1->ptr;
|
|
DetectContentData *ud2 = ch2->ptr;
|
|
|
|
if (ud1->content_len == ud2->content_len &&
|
|
((ud1->flags & DETECT_CONTENT_NOCASE) == (ud2->flags & DETECT_CONTENT_NOCASE)) &&
|
|
SCMemcmp(ud1->content, ud2->content, ud1->content_len) == 0)
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
ContentHash *ContentHashAlloc(DetectContentData *ptr) {
|
|
ContentHash *ch = SCMalloc(sizeof(ContentHash));
|
|
if (ch == NULL)
|
|
return NULL;
|
|
|
|
ch->ptr = ptr;
|
|
ch->cnt = 1;
|
|
ch->use = 0;
|
|
|
|
return ch;
|
|
}
|
|
|
|
UricontentHash *UricontentHashAlloc(DetectContentData *ptr) {
|
|
UricontentHash *ch = SCMalloc(sizeof(UricontentHash));
|
|
if (ch == NULL)
|
|
return NULL;
|
|
|
|
ch->ptr = ptr;
|
|
ch->cnt = 1;
|
|
ch->use = 0;
|
|
|
|
return ch;
|
|
}
|
|
|
|
void ContentHashFree(void *ch) {
|
|
SCFree(ch);
|
|
}
|
|
|
|
void UricontentHashFree(void *ch) {
|
|
SCFree(ch);
|
|
}
|
|
|
|
/** \brief Predict a strength value for patterns
|
|
*
|
|
* Patterns with high character diversity score higher.
|
|
* Alpha chars score not so high
|
|
* Other printable + a few common codes a little higher
|
|
* Everything else highest.
|
|
* Longer patterns score better than short patters.
|
|
*
|
|
* \param pat pattern
|
|
* \param patlen length of the patternn
|
|
*
|
|
* \retval s pattern score
|
|
*/
|
|
uint32_t PatternStrength(uint8_t *pat, uint16_t patlen) {
|
|
uint8_t a[256];
|
|
memset(&a, 0 ,sizeof(a));
|
|
|
|
uint32_t s = 0;
|
|
uint16_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;
|
|
|
|
a[pat[u]] = 1;
|
|
} else {
|
|
s++;
|
|
}
|
|
}
|
|
|
|
return s;
|
|
}
|
|
|
|
static void PopulateMpmHelperAddPatternToPktCtx(MpmCtx *mpm_ctx,
|
|
DetectContentData *cd,
|
|
Signature *s, uint8_t flags,
|
|
int chop)
|
|
{
|
|
if (cd->flags & DETECT_CONTENT_NOCASE) {
|
|
if (chop) {
|
|
mpm_table[mpm_ctx->mpm_type].
|
|
AddPatternNocase(mpm_ctx,
|
|
cd->content + cd->fp_chop_offset,
|
|
cd->fp_chop_len,
|
|
0, 0, cd->id, s->num, flags);
|
|
} else {
|
|
mpm_table[mpm_ctx->mpm_type].
|
|
AddPatternNocase(mpm_ctx,
|
|
cd->content,
|
|
cd->content_len,
|
|
0, 0, cd->id, s->num, flags);
|
|
}
|
|
} else {
|
|
if (chop) {
|
|
mpm_table[mpm_ctx->mpm_type].
|
|
AddPattern(mpm_ctx,
|
|
cd->content + cd->fp_chop_offset,
|
|
cd->fp_chop_len,
|
|
0, 0, cd->id, s->num, flags);
|
|
} else {
|
|
mpm_table[mpm_ctx->mpm_type].
|
|
AddPattern(mpm_ctx,
|
|
cd->content,
|
|
cd->content_len,
|
|
0, 0, cd->id, s->num, flags);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
static void PopulateMpmAddPatternToMpm(DetectEngineCtx *de_ctx,
|
|
SigGroupHead *sgh, Signature *s,
|
|
SigMatch *mpm_sm)
|
|
{
|
|
s->mpm_sm = mpm_sm;
|
|
|
|
if (mpm_sm == NULL) {
|
|
SCLogDebug("%"PRIu32" no mpm pattern selected", s->id);
|
|
return;
|
|
}
|
|
|
|
int sm_list = SigMatchListSMBelongsTo(s, mpm_sm);
|
|
if (sm_list == -1)
|
|
BUG_ON(SigMatchListSMBelongsTo(s, mpm_sm) == -1);
|
|
|
|
uint8_t flags = 0;
|
|
|
|
DetectContentData *cd = NULL;
|
|
|
|
switch (sm_list) {
|
|
case DETECT_SM_LIST_PMATCH:
|
|
{
|
|
cd = (DetectContentData *)mpm_sm->ctx;
|
|
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) {
|
|
/* add the content to the "packet" mpm */
|
|
if (SignatureHasPacketContent(s)) {
|
|
if (s->proto.proto[6 / 8] & 1 << (6 % 8)) {
|
|
if (s->flags & SIG_FLAG_TOSERVER) {
|
|
PopulateMpmHelperAddPatternToPktCtx(sgh->mpm_proto_tcp_ctx_ts,
|
|
cd, s, flags, 1);
|
|
}
|
|
if (s->flags & SIG_FLAG_TOCLIENT) {
|
|
PopulateMpmHelperAddPatternToPktCtx(sgh->mpm_proto_tcp_ctx_tc,
|
|
cd, s, flags, 1);
|
|
}
|
|
}
|
|
if (s->proto.proto[17 / 8] & 1 << (17 % 8)) {
|
|
if (s->flags & SIG_FLAG_TOSERVER) {
|
|
PopulateMpmHelperAddPatternToPktCtx(sgh->mpm_proto_udp_ctx_ts,
|
|
cd, s, flags, 1);
|
|
}
|
|
if (s->flags & SIG_FLAG_TOCLIENT) {
|
|
PopulateMpmHelperAddPatternToPktCtx(sgh->mpm_proto_udp_ctx_tc,
|
|
cd, s, flags, 1);
|
|
}
|
|
}
|
|
int i;
|
|
for (i = 0; i < 256; i++) {
|
|
if (i == 6 || i == 17)
|
|
continue;
|
|
if (s->proto.proto[i / 8] & (1 << (i % 8))) {
|
|
PopulateMpmHelperAddPatternToPktCtx(sgh->mpm_proto_other_ctx,
|
|
cd, s, flags, 1);
|
|
break;
|
|
}
|
|
}
|
|
/* tell matcher we are inspecting packet */
|
|
s->flags |= SIG_FLAG_MPM_PACKET;
|
|
s->mpm_pattern_id_div_8 = cd->id / 8;
|
|
s->mpm_pattern_id_mod_8 = 1 << (cd->id % 8);
|
|
if (cd->flags & DETECT_CONTENT_NEGATED) {
|
|
SCLogDebug("flagging sig %"PRIu32" to be looking for negated mpm", s->id);
|
|
s->flags |= SIG_FLAG_MPM_PACKET_NEG;
|
|
}
|
|
}
|
|
if (SignatureHasStreamContent(s)) {
|
|
if (cd->flags & DETECT_CONTENT_NOCASE) {
|
|
if (s->flags & SIG_FLAG_TOSERVER) {
|
|
mpm_table[sgh->mpm_stream_ctx_ts->mpm_type].
|
|
AddPatternNocase(sgh->mpm_stream_ctx_ts,
|
|
cd->content + cd->fp_chop_offset,
|
|
cd->fp_chop_len,
|
|
0, 0, cd->id, s->num, flags);
|
|
}
|
|
if (s->flags & SIG_FLAG_TOCLIENT) {
|
|
mpm_table[sgh->mpm_stream_ctx_tc->mpm_type].
|
|
AddPatternNocase(sgh->mpm_stream_ctx_tc,
|
|
cd->content + cd->fp_chop_offset,
|
|
cd->fp_chop_len,
|
|
0, 0, cd->id, s->num, flags);
|
|
}
|
|
} else {
|
|
if (s->flags & SIG_FLAG_TOSERVER) {
|
|
mpm_table[sgh->mpm_stream_ctx_ts->mpm_type].
|
|
AddPattern(sgh->mpm_stream_ctx_ts,
|
|
cd->content + cd->fp_chop_offset,
|
|
cd->fp_chop_len,
|
|
0, 0, cd->id, s->num, flags);
|
|
}
|
|
if (s->flags & SIG_FLAG_TOCLIENT) {
|
|
mpm_table[sgh->mpm_stream_ctx_tc->mpm_type].
|
|
AddPattern(sgh->mpm_stream_ctx_tc,
|
|
cd->content + cd->fp_chop_offset,
|
|
cd->fp_chop_len,
|
|
0, 0, cd->id, s->num, flags);
|
|
}
|
|
}
|
|
/* tell matcher we are inspecting stream */
|
|
s->flags |= SIG_FLAG_MPM_STREAM;
|
|
s->mpm_pattern_id_div_8 = cd->id / 8;
|
|
s->mpm_pattern_id_mod_8 = 1 << (cd->id % 8);
|
|
if (cd->flags & DETECT_CONTENT_NEGATED) {
|
|
SCLogDebug("flagging sig %"PRIu32" to be looking for negated mpm", s->id);
|
|
s->flags |= SIG_FLAG_MPM_STREAM_NEG;
|
|
}
|
|
}
|
|
} else {
|
|
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
|
|
if (DETECT_CONTENT_IS_SINGLE(cd)) {
|
|
if (SignatureHasPacketContent(s))
|
|
cd->flags |= DETECT_CONTENT_PACKET_MPM;
|
|
if (SignatureHasStreamContent(s))
|
|
cd->flags |= DETECT_CONTENT_STREAM_MPM;
|
|
}
|
|
|
|
/* see if we can bypass the match validation for this pattern */
|
|
} else {
|
|
if (DETECT_CONTENT_IS_SINGLE(cd)) {
|
|
if (SignatureHasPacketContent(s))
|
|
cd->flags |= DETECT_CONTENT_PACKET_MPM;
|
|
if (SignatureHasStreamContent(s))
|
|
cd->flags |= DETECT_CONTENT_STREAM_MPM;
|
|
}
|
|
} /* else - if (co->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) */
|
|
|
|
if (SignatureHasPacketContent(s)) {
|
|
/* add the content to the "packet" mpm */
|
|
if (s->proto.proto[6 / 8] & 1 << (6 % 8)) {
|
|
if (s->flags & SIG_FLAG_TOSERVER) {
|
|
PopulateMpmHelperAddPatternToPktCtx(sgh->mpm_proto_tcp_ctx_ts,
|
|
cd, s, flags, 0);
|
|
}
|
|
if (s->flags & SIG_FLAG_TOCLIENT) {
|
|
PopulateMpmHelperAddPatternToPktCtx(sgh->mpm_proto_tcp_ctx_tc,
|
|
cd, s, flags, 0);
|
|
}
|
|
}
|
|
if (s->proto.proto[17 / 8] & 1 << (17 % 8)) {
|
|
if (s->flags & SIG_FLAG_TOSERVER) {
|
|
PopulateMpmHelperAddPatternToPktCtx(sgh->mpm_proto_udp_ctx_ts,
|
|
cd, s, flags, 0);
|
|
}
|
|
if (s->flags & SIG_FLAG_TOCLIENT) {
|
|
PopulateMpmHelperAddPatternToPktCtx(sgh->mpm_proto_udp_ctx_tc,
|
|
cd, s, flags, 0);
|
|
}
|
|
}
|
|
int i;
|
|
for (i = 0; i < 256; i++) {
|
|
if (i == 6 || i == 17)
|
|
continue;
|
|
if (s->proto.proto[i / 8] & (1 << (i % 8))) {
|
|
PopulateMpmHelperAddPatternToPktCtx(sgh->mpm_proto_other_ctx,
|
|
cd, s, flags, 0);
|
|
break;
|
|
}
|
|
}
|
|
/* tell matcher we are inspecting packet */
|
|
s->flags |= SIG_FLAG_MPM_PACKET;
|
|
s->mpm_pattern_id_div_8 = cd->id / 8;
|
|
s->mpm_pattern_id_mod_8 = 1 << (cd->id % 8);
|
|
if (cd->flags & DETECT_CONTENT_NEGATED) {
|
|
SCLogDebug("flagging sig %"PRIu32" to be looking for negated mpm", s->id);
|
|
s->flags |= SIG_FLAG_MPM_PACKET_NEG;
|
|
}
|
|
}
|
|
if (SignatureHasStreamContent(s)) {
|
|
/* add the content to the "packet" mpm */
|
|
if (cd->flags & DETECT_CONTENT_NOCASE) {
|
|
if (s->flags & SIG_FLAG_TOSERVER) {
|
|
mpm_table[sgh->mpm_stream_ctx_ts->mpm_type].
|
|
AddPatternNocase(sgh->mpm_stream_ctx_ts,
|
|
cd->content, cd->content_len,
|
|
0, 0, cd->id, s->num, flags);
|
|
}
|
|
if (s->flags & SIG_FLAG_TOCLIENT) {
|
|
mpm_table[sgh->mpm_stream_ctx_tc->mpm_type].
|
|
AddPatternNocase(sgh->mpm_stream_ctx_tc,
|
|
cd->content, cd->content_len,
|
|
0, 0, cd->id, s->num, flags);
|
|
}
|
|
} else {
|
|
if (s->flags & SIG_FLAG_TOSERVER) {
|
|
mpm_table[sgh->mpm_stream_ctx_ts->mpm_type].
|
|
AddPattern(sgh->mpm_stream_ctx_ts,
|
|
cd->content, cd->content_len,
|
|
0, 0, cd->id, s->num, flags);
|
|
}
|
|
if (s->flags & SIG_FLAG_TOCLIENT) {
|
|
mpm_table[sgh->mpm_stream_ctx_tc->mpm_type].
|
|
AddPattern(sgh->mpm_stream_ctx_tc,
|
|
cd->content, cd->content_len,
|
|
0, 0, cd->id, s->num, flags);
|
|
}
|
|
}
|
|
/* tell matcher we are inspecting stream */
|
|
s->flags |= SIG_FLAG_MPM_STREAM;
|
|
s->mpm_pattern_id_div_8 = cd->id / 8;
|
|
s->mpm_pattern_id_mod_8 = 1 << (cd->id % 8);
|
|
if (cd->flags & DETECT_CONTENT_NEGATED) {
|
|
SCLogDebug("flagging sig %"PRIu32" to be looking for negated mpm", s->id);
|
|
s->flags |= SIG_FLAG_MPM_STREAM_NEG;
|
|
}
|
|
}
|
|
}
|
|
if (SignatureHasPacketContent(s)) {
|
|
sgh->flags |= SIG_GROUP_HEAD_MPM_PACKET;
|
|
}
|
|
if (SignatureHasStreamContent(s)) {
|
|
sgh->flags |= SIG_GROUP_HEAD_MPM_STREAM;
|
|
}
|
|
|
|
break;
|
|
} /* case DETECT_CONTENT */
|
|
|
|
case DETECT_SM_LIST_UMATCH:
|
|
case DETECT_SM_LIST_HRUDMATCH:
|
|
case DETECT_SM_LIST_HCBDMATCH:
|
|
case DETECT_SM_LIST_HSBDMATCH:
|
|
case DETECT_SM_LIST_HHDMATCH:
|
|
case DETECT_SM_LIST_HRHDMATCH:
|
|
case DETECT_SM_LIST_HMDMATCH:
|
|
case DETECT_SM_LIST_HCDMATCH:
|
|
case DETECT_SM_LIST_HSMDMATCH:
|
|
case DETECT_SM_LIST_HSCDMATCH:
|
|
case DETECT_SM_LIST_HUADMATCH:
|
|
{
|
|
MpmCtx *mpm_ctx_ts = NULL;
|
|
MpmCtx *mpm_ctx_tc = NULL;
|
|
uint32_t sgh_flags = 0;
|
|
uint32_t cd_flags = 0;
|
|
uint32_t sig_flags = 0;
|
|
|
|
cd = (DetectContentData *)mpm_sm->ctx;
|
|
|
|
if (sm_list == DETECT_SM_LIST_UMATCH) {
|
|
if (s->flags & SIG_FLAG_TOSERVER)
|
|
mpm_ctx_ts = sgh->mpm_uri_ctx_ts;
|
|
if (s->flags & SIG_FLAG_TOCLIENT)
|
|
mpm_ctx_tc = sgh->mpm_uri_ctx_tc;
|
|
sgh_flags = SIG_GROUP_HEAD_MPM_URI;
|
|
cd_flags = DETECT_CONTENT_URI_MPM;
|
|
sig_flags |= SIG_FLAG_MPM_HTTP;
|
|
if (cd->flags & DETECT_CONTENT_NEGATED)
|
|
sig_flags |= SIG_FLAG_MPM_HTTP_NEG;
|
|
} else if (sm_list == DETECT_SM_LIST_HCBDMATCH) {
|
|
if (s->flags & SIG_FLAG_TOSERVER)
|
|
mpm_ctx_ts = sgh->mpm_hcbd_ctx_ts;
|
|
if (s->flags & SIG_FLAG_TOCLIENT)
|
|
mpm_ctx_tc = sgh->mpm_hcbd_ctx_tc;
|
|
sgh_flags = SIG_GROUP_HEAD_MPM_HCBD;
|
|
cd_flags = DETECT_CONTENT_HCBD_MPM;
|
|
sig_flags |= SIG_FLAG_MPM_HTTP;
|
|
if (cd->flags & DETECT_CONTENT_NEGATED)
|
|
sig_flags |= SIG_FLAG_MPM_HTTP_NEG;
|
|
} else if (sm_list == DETECT_SM_LIST_HSBDMATCH) {
|
|
if (s->flags & SIG_FLAG_TOSERVER)
|
|
mpm_ctx_ts = sgh->mpm_hsbd_ctx_ts;
|
|
if (s->flags & SIG_FLAG_TOCLIENT)
|
|
mpm_ctx_tc = sgh->mpm_hsbd_ctx_tc;
|
|
sgh_flags = SIG_GROUP_HEAD_MPM_HSBD;
|
|
cd_flags = DETECT_CONTENT_HSBD_MPM;
|
|
sig_flags |= SIG_FLAG_MPM_HTTP;
|
|
if (cd->flags & DETECT_CONTENT_NEGATED)
|
|
sig_flags |= SIG_FLAG_MPM_HTTP_NEG;
|
|
} else if (sm_list == DETECT_SM_LIST_HHDMATCH) {
|
|
if (s->flags & SIG_FLAG_TOSERVER)
|
|
mpm_ctx_ts = sgh->mpm_hhd_ctx_ts;
|
|
if (s->flags & SIG_FLAG_TOCLIENT)
|
|
mpm_ctx_tc = sgh->mpm_hhd_ctx_tc;
|
|
sgh_flags = SIG_GROUP_HEAD_MPM_HHD;
|
|
cd_flags = DETECT_CONTENT_HHD_MPM;
|
|
sig_flags |= SIG_FLAG_MPM_HTTP;
|
|
if (cd->flags & DETECT_CONTENT_NEGATED)
|
|
sig_flags |= SIG_FLAG_MPM_HTTP_NEG;
|
|
} else if (sm_list == DETECT_SM_LIST_HRHDMATCH) {
|
|
if (s->flags & SIG_FLAG_TOSERVER)
|
|
mpm_ctx_ts = sgh->mpm_hrhd_ctx_ts;
|
|
if (s->flags & SIG_FLAG_TOCLIENT)
|
|
mpm_ctx_tc = sgh->mpm_hrhd_ctx_tc;
|
|
sgh_flags = SIG_GROUP_HEAD_MPM_HRHD;
|
|
cd_flags = DETECT_CONTENT_HRHD_MPM;
|
|
sig_flags |= SIG_FLAG_MPM_HTTP;
|
|
if (cd->flags & DETECT_CONTENT_NEGATED)
|
|
sig_flags |= SIG_FLAG_MPM_HTTP_NEG;
|
|
} else if (sm_list == DETECT_SM_LIST_HMDMATCH) {
|
|
if (s->flags & SIG_FLAG_TOSERVER)
|
|
mpm_ctx_ts = sgh->mpm_hmd_ctx_ts;
|
|
if (s->flags & SIG_FLAG_TOCLIENT)
|
|
mpm_ctx_tc = sgh->mpm_hmd_ctx_tc;
|
|
sgh_flags = SIG_GROUP_HEAD_MPM_HMD;
|
|
cd_flags = DETECT_CONTENT_HMD_MPM;
|
|
sig_flags |= SIG_FLAG_MPM_HTTP;
|
|
if (cd->flags & DETECT_CONTENT_NEGATED)
|
|
sig_flags |= SIG_FLAG_MPM_HTTP_NEG;
|
|
} else if (sm_list == DETECT_SM_LIST_HCDMATCH) {
|
|
if (s->flags & SIG_FLAG_TOSERVER)
|
|
mpm_ctx_ts = sgh->mpm_hcd_ctx_ts;
|
|
if (s->flags & SIG_FLAG_TOCLIENT)
|
|
mpm_ctx_tc = sgh->mpm_hcd_ctx_tc;
|
|
sgh_flags = SIG_GROUP_HEAD_MPM_HCD;
|
|
cd_flags = DETECT_CONTENT_HCD_MPM;
|
|
sig_flags |= SIG_FLAG_MPM_HTTP;
|
|
if (cd->flags & DETECT_CONTENT_NEGATED)
|
|
sig_flags |= SIG_FLAG_MPM_HTTP_NEG;
|
|
} else if (sm_list == DETECT_SM_LIST_HRUDMATCH) {
|
|
if (s->flags & SIG_FLAG_TOSERVER)
|
|
mpm_ctx_ts = sgh->mpm_hrud_ctx_ts;
|
|
if (s->flags & SIG_FLAG_TOCLIENT)
|
|
mpm_ctx_tc = sgh->mpm_hrud_ctx_tc;
|
|
sgh_flags = SIG_GROUP_HEAD_MPM_HRUD;
|
|
cd_flags = DETECT_CONTENT_HRUD_MPM;
|
|
sig_flags |= SIG_FLAG_MPM_HTTP;
|
|
if (cd->flags & DETECT_CONTENT_NEGATED)
|
|
sig_flags |= SIG_FLAG_MPM_HTTP_NEG;
|
|
} else if (sm_list == DETECT_SM_LIST_HSMDMATCH) {
|
|
if (s->flags & SIG_FLAG_TOSERVER)
|
|
mpm_ctx_ts = sgh->mpm_hsmd_ctx_ts;
|
|
if (s->flags & SIG_FLAG_TOCLIENT)
|
|
mpm_ctx_tc = sgh->mpm_hsmd_ctx_tc;
|
|
sgh_flags = SIG_GROUP_HEAD_MPM_HSMD;
|
|
cd_flags = DETECT_CONTENT_HSMD_MPM;
|
|
sig_flags |= SIG_FLAG_MPM_HTTP;
|
|
if (cd->flags & DETECT_CONTENT_NEGATED)
|
|
sig_flags |= SIG_FLAG_MPM_HTTP_NEG;
|
|
} else if (sm_list == DETECT_SM_LIST_HSCDMATCH) {
|
|
if (s->flags & SIG_FLAG_TOSERVER)
|
|
mpm_ctx_ts = sgh->mpm_hscd_ctx_ts;
|
|
if (s->flags & SIG_FLAG_TOCLIENT)
|
|
mpm_ctx_tc = sgh->mpm_hscd_ctx_tc;
|
|
sgh_flags = SIG_GROUP_HEAD_MPM_HSCD;
|
|
cd_flags = DETECT_CONTENT_HSCD_MPM;
|
|
sig_flags |= SIG_FLAG_MPM_HTTP;
|
|
if (cd->flags & DETECT_CONTENT_NEGATED)
|
|
sig_flags |= SIG_FLAG_MPM_HTTP_NEG;
|
|
} else if (sm_list == DETECT_SM_LIST_HUADMATCH) {
|
|
if (s->flags & SIG_FLAG_TOSERVER)
|
|
mpm_ctx_ts = sgh->mpm_huad_ctx_ts;
|
|
if (s->flags & SIG_FLAG_TOCLIENT)
|
|
mpm_ctx_tc = sgh->mpm_huad_ctx_tc;
|
|
sgh_flags = SIG_GROUP_HEAD_MPM_HUAD;
|
|
cd_flags = DETECT_CONTENT_HUAD_MPM;
|
|
sig_flags |= SIG_FLAG_MPM_HTTP;
|
|
if (cd->flags & DETECT_CONTENT_NEGATED)
|
|
sig_flags |= SIG_FLAG_MPM_HTTP_NEG;
|
|
}
|
|
|
|
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) {
|
|
/* add the content to the mpm */
|
|
if (cd->flags & DETECT_CONTENT_NOCASE) {
|
|
if (mpm_ctx_ts != NULL) {
|
|
mpm_table[mpm_ctx_ts->mpm_type].
|
|
AddPatternNocase(mpm_ctx_ts,
|
|
cd->content + cd->fp_chop_offset,
|
|
cd->fp_chop_len,
|
|
0, 0, cd->id, s->num, flags);
|
|
}
|
|
if (mpm_ctx_tc != NULL) {
|
|
mpm_table[mpm_ctx_tc->mpm_type].
|
|
AddPatternNocase(mpm_ctx_tc,
|
|
cd->content + cd->fp_chop_offset,
|
|
cd->fp_chop_len,
|
|
0, 0, cd->id, s->num, flags);
|
|
}
|
|
} else {
|
|
if (mpm_ctx_ts != NULL) {
|
|
mpm_table[mpm_ctx_ts->mpm_type].
|
|
AddPattern(mpm_ctx_ts,
|
|
cd->content + cd->fp_chop_offset,
|
|
cd->fp_chop_len,
|
|
0, 0, cd->id, s->num, flags);
|
|
}
|
|
if (mpm_ctx_tc != NULL) {
|
|
mpm_table[mpm_ctx_tc->mpm_type].
|
|
AddPattern(mpm_ctx_tc,
|
|
cd->content + cd->fp_chop_offset,
|
|
cd->fp_chop_len,
|
|
0, 0, cd->id, s->num, flags);
|
|
}
|
|
}
|
|
} else {
|
|
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
|
|
if (DETECT_CONTENT_IS_SINGLE(cd)) {
|
|
cd->flags |= cd_flags;
|
|
}
|
|
|
|
/* see if we can bypass the match validation for this pattern */
|
|
} else {
|
|
if (DETECT_CONTENT_IS_SINGLE(cd)) {
|
|
cd->flags |= cd_flags;
|
|
}
|
|
} /* else - if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) */
|
|
|
|
/* add the content to the "uri" mpm */
|
|
if (cd->flags & DETECT_CONTENT_NOCASE) {
|
|
if (mpm_ctx_ts != NULL) {
|
|
mpm_table[mpm_ctx_ts->mpm_type].
|
|
AddPatternNocase(mpm_ctx_ts,
|
|
cd->content, cd->content_len,
|
|
0, 0, cd->id, s->num, flags);
|
|
}
|
|
if (mpm_ctx_tc != NULL) {
|
|
mpm_table[mpm_ctx_tc->mpm_type].
|
|
AddPatternNocase(mpm_ctx_tc,
|
|
cd->content, cd->content_len,
|
|
0, 0, cd->id, s->num, flags);
|
|
}
|
|
} else {
|
|
if (mpm_ctx_ts != NULL) {
|
|
mpm_table[mpm_ctx_ts->mpm_type].
|
|
AddPattern(mpm_ctx_ts,
|
|
cd->content, cd->content_len,
|
|
0, 0, cd->id, s->num, flags);
|
|
}
|
|
if (mpm_ctx_tc != NULL) {
|
|
mpm_table[mpm_ctx_tc->mpm_type].
|
|
AddPattern(mpm_ctx_tc,
|
|
cd->content, cd->content_len,
|
|
0, 0, cd->id, s->num, flags);
|
|
}
|
|
}
|
|
}
|
|
/* tell matcher we are inspecting uri */
|
|
s->flags |= sig_flags;
|
|
s->mpm_pattern_id_div_8 = cd->id / 8;
|
|
s->mpm_pattern_id_mod_8 = 1 << (cd->id % 8);
|
|
sgh->flags |= sgh_flags;
|
|
|
|
break;
|
|
}
|
|
} /* switch (mpm_sm->type) */
|
|
|
|
SCLogDebug("%"PRIu32" adding cd->id %"PRIu32" to the mpm phase "
|
|
"(s->num %"PRIu32")", s->id,
|
|
((DetectContentData *)mpm_sm->ctx)->id, s->num);
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* \internal
|
|
* \brief Setup the mpm content.
|
|
*
|
|
* \param de_ctx Pointer to the detect engine context.
|
|
* \param sgh Pointer to the signature group head against which we are
|
|
* adding patterns to the mpm ctx.
|
|
*
|
|
* \retval 0 Always.
|
|
*/
|
|
static int PatternMatchPreparePopulateMpm(DetectEngineCtx *de_ctx,
|
|
SigGroupHead *sgh)
|
|
{
|
|
uint32_t sig;
|
|
uint32_t *fast_pattern = NULL;
|
|
|
|
fast_pattern = (uint32_t *)SCMalloc(sgh->sig_cnt * sizeof(uint32_t));
|
|
if (fast_pattern == NULL) {
|
|
SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
memset(fast_pattern, 0, sgh->sig_cnt * sizeof(uint32_t));
|
|
|
|
/* add all mpm candidates to a hash */
|
|
for (sig = 0; sig < sgh->sig_cnt; sig++) {
|
|
Signature *s = sgh->match_array[sig];
|
|
if (s == NULL)
|
|
continue;
|
|
|
|
/* we already have a sm set as fp for this sig. Add it to the current
|
|
* mpm context */
|
|
if (s->mpm_sm != NULL) {
|
|
PopulateMpmAddPatternToMpm(de_ctx, sgh, s, s->mpm_sm);
|
|
continue;
|
|
}
|
|
|
|
int list_id = 0;
|
|
for ( ; list_id < DETECT_SM_LIST_MAX; list_id++) {
|
|
/* we have no keywords that support fp in this Signature sm list */
|
|
if (!FastPatternSupportEnabledForSigMatchList(list_id))
|
|
continue;
|
|
|
|
SigMatch *sm = NULL;
|
|
/* get the total no of patterns in this Signature, as well as find out
|
|
* if we have a fast_pattern set in this Signature */
|
|
for (sm = s->sm_lists[list_id]; sm != NULL; sm = sm->next) {
|
|
/* this keyword isn't registered for fp support */
|
|
if (sm->type != DETECT_CONTENT)
|
|
continue;
|
|
|
|
//if (PopulateMpmSkipContent(sgh, s, sm)) {
|
|
// continue;
|
|
//}
|
|
|
|
DetectContentData *cd = (DetectContentData *)sm->ctx;
|
|
if (cd->flags & DETECT_CONTENT_FAST_PATTERN) {
|
|
fast_pattern[sig] = 1;
|
|
break;
|
|
}
|
|
} /* for (sm = s->sm_lists[list_id]; sm != NULL; sm = sm->next) */
|
|
|
|
/* found a fast pattern for the sig. Let's get outta here */
|
|
if (fast_pattern[sig])
|
|
break;
|
|
} /* for ( ; list_id < DETECT_SM_LIST_MAX; list_id++) */
|
|
} /* for (sig = 0; sig < sgh->sig_cnt; sig++) { */
|
|
|
|
/* now determine which one to add to the mpm phase */
|
|
for (sig = 0; sig < sgh->sig_cnt; sig++) {
|
|
Signature *s = sgh->match_array[sig];
|
|
if (s == NULL)
|
|
continue;
|
|
/* have taken care of this in the previous loop. move on to the next sig */
|
|
if (s->mpm_sm != NULL) {
|
|
continue;
|
|
}
|
|
|
|
int max_len = 0;
|
|
/* get the longest pattern in the sig */
|
|
if (!fast_pattern[sig]) {
|
|
SigMatch *sm = NULL;
|
|
int list_id = 0;
|
|
for ( ; list_id < DETECT_SM_LIST_MAX; list_id++) {
|
|
if (!FastPatternSupportEnabledForSigMatchList(list_id))
|
|
continue;
|
|
|
|
for (sm = s->sm_lists[list_id]; sm != NULL; sm = sm->next) {
|
|
if (sm->type != DETECT_CONTENT)
|
|
continue;
|
|
|
|
//if (PopulateMpmSkipContent(sgh, s, sm)) {
|
|
// continue;
|
|
//}
|
|
|
|
DetectContentData *cd = (DetectContentData *)sm->ctx;
|
|
if (max_len < cd->content_len)
|
|
max_len = cd->content_len;
|
|
}
|
|
}
|
|
}
|
|
|
|
SigMatch *mpm_sm = NULL;
|
|
SigMatch *sm = NULL;
|
|
int list_id = 0;
|
|
for ( ; list_id < DETECT_SM_LIST_MAX; list_id++) {
|
|
if (!FastPatternSupportEnabledForSigMatchList(list_id))
|
|
continue;
|
|
|
|
for (sm = s->sm_lists[list_id]; sm != NULL; sm = sm->next) {
|
|
if (sm->type != DETECT_CONTENT)
|
|
continue;
|
|
|
|
/* skip in case of:
|
|
* 1. we expect a fastpattern but this isn't it */
|
|
if (fast_pattern[sig]) {
|
|
/* can be any content based keyword since all of them
|
|
* now use a unified structure - DetectContentData */
|
|
DetectContentData *cd = (DetectContentData *)sm->ctx;
|
|
if (!(cd->flags & DETECT_CONTENT_FAST_PATTERN)) {
|
|
SCLogDebug("not a fast pattern %"PRIu32"", cd->id);
|
|
continue;
|
|
}
|
|
SCLogDebug("fast pattern %"PRIu32"", cd->id);
|
|
} else {
|
|
//if (PopulateMpmSkipContent(sgh, s, sm)) {
|
|
// continue;
|
|
//}
|
|
|
|
DetectContentData *cd = (DetectContentData *)sm->ctx;
|
|
if (cd->content_len < max_len)
|
|
continue;
|
|
|
|
} /* else - if (fast_pattern[sig] == 1) */
|
|
|
|
if (mpm_sm == NULL) {
|
|
mpm_sm = sm;
|
|
if (fast_pattern[sig])
|
|
break;
|
|
} else {
|
|
DetectContentData *data1 = (DetectContentData *)sm->ctx;
|
|
DetectContentData *data2 = (DetectContentData *)mpm_sm->ctx;
|
|
uint32_t ls = PatternStrength(data1->content, data1->content_len);
|
|
uint32_t ss = PatternStrength(data2->content, data2->content_len);
|
|
if (ls > ss) {
|
|
mpm_sm = sm;
|
|
} else if (ls == ss) {
|
|
/* if 2 patterns are of equal strength, we pick the longest */
|
|
if (data1->content_len > data2->content_len)
|
|
mpm_sm = sm;
|
|
} else {
|
|
SCLogDebug("sticking with mpm_sm");
|
|
}
|
|
} /* else - if (mpm == NULL) */
|
|
} /* for (sm = s->sm_lists[list_id]; sm != NULL; sm = sm->next) */
|
|
if (mpm_sm != NULL && fast_pattern[sig])
|
|
break;
|
|
} /* for ( ; list_id < DETECT_SM_LIST_MAX; list_id++) */
|
|
|
|
PopulateMpmAddPatternToMpm(de_ctx, sgh, s, mpm_sm);
|
|
} /* for (sig = 0; sig < sgh->sig_cnt; sig++) */
|
|
|
|
if (fast_pattern != NULL)
|
|
SCFree(fast_pattern);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/** \brief Prepare the pattern matcher ctx in a sig group head.
|
|
*
|
|
* \todo determine if a content match can set the 'single' flag
|
|
* \todo do error checking
|
|
* \todo rewrite the COPY stuff
|
|
*/
|
|
int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
|
|
{
|
|
Signature *s = NULL;
|
|
uint32_t has_co_packet = 0; /**< our sgh has packet payload inspecting content */
|
|
uint32_t has_co_stream = 0; /**< our sgh has stream inspecting content */
|
|
uint32_t has_co_uri = 0; /**< our sgh has uri inspecting content */
|
|
/* used to indicate if sgh has atleast one sig with http_client_body */
|
|
uint32_t has_co_hcbd = 0;
|
|
/* used to indicate if sgh has atleast one sig with http_server_body */
|
|
uint32_t has_co_hsbd = 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;
|
|
/* used to indicate if sgh has atleast one sig with http_method */
|
|
uint32_t has_co_hmd = 0;
|
|
/* used to indicate if sgh has atleast one sig with http_cookie */
|
|
uint32_t has_co_hcd = 0;
|
|
/* used to indicate if sgh has atleast one sig with http_raw_uri */
|
|
uint32_t has_co_hrud = 0;
|
|
/* used to indicate if sgh has atleast one sig with http_stat_msg */
|
|
uint32_t has_co_hsmd = 0;
|
|
/* used to indicate if sgh has atleast one sig with http_stat_code */
|
|
uint32_t has_co_hscd = 0;
|
|
/* used to indicate if sgh has atleast one sig with http_user_agent */
|
|
uint32_t has_co_huad = 0;
|
|
//uint32_t cnt = 0;
|
|
uint32_t sig = 0;
|
|
|
|
/* see if this head has content and/or uricontent */
|
|
for (sig = 0; sig < sh->sig_cnt; sig++) {
|
|
s = sh->match_array[sig];
|
|
if (s == NULL)
|
|
continue;
|
|
|
|
if (SignatureHasPacketContent(s) == 1) {
|
|
has_co_packet = 1;
|
|
}
|
|
if (SignatureHasStreamContent(s) == 1) {
|
|
has_co_stream = 1;
|
|
}
|
|
|
|
if (s->sm_lists[DETECT_SM_LIST_UMATCH] != NULL) {
|
|
has_co_uri = 1;
|
|
}
|
|
|
|
if (s->sm_lists[DETECT_SM_LIST_HCBDMATCH] != NULL) {
|
|
has_co_hcbd = 1;
|
|
}
|
|
|
|
if (s->sm_lists[DETECT_SM_LIST_HSBDMATCH] != NULL) {
|
|
has_co_hsbd = 1;
|
|
}
|
|
|
|
if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] != NULL) {
|
|
has_co_hhd = 1;
|
|
}
|
|
|
|
if (s->sm_lists[DETECT_SM_LIST_HRHDMATCH] != NULL) {
|
|
has_co_hrhd = 1;
|
|
}
|
|
|
|
if (s->sm_lists[DETECT_SM_LIST_HMDMATCH] != NULL) {
|
|
has_co_hmd = 1;
|
|
}
|
|
|
|
if (s->sm_lists[DETECT_SM_LIST_HCDMATCH] != NULL) {
|
|
has_co_hcd = 1;
|
|
}
|
|
|
|
if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL) {
|
|
has_co_hrud = 1;
|
|
}
|
|
|
|
if (s->sm_lists[DETECT_SM_LIST_HSMDMATCH] != NULL) {
|
|
has_co_hsmd = 1;
|
|
}
|
|
|
|
if (s->sm_lists[DETECT_SM_LIST_HSCDMATCH] != NULL) {
|
|
has_co_hscd = 1;
|
|
}
|
|
|
|
if (s->sm_lists[DETECT_SM_LIST_HUADMATCH] != NULL) {
|
|
has_co_huad = 1;
|
|
}
|
|
}
|
|
|
|
/* intialize contexes */
|
|
if (has_co_packet) {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
|
|
sh->mpm_proto_tcp_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_proto_tcp_packet, 0);
|
|
sh->mpm_proto_tcp_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_proto_tcp_packet, 1);
|
|
} else {
|
|
sh->mpm_proto_tcp_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0);
|
|
sh->mpm_proto_tcp_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 1);
|
|
}
|
|
if (sh->mpm_proto_tcp_ctx_ts == NULL || sh->mpm_proto_tcp_ctx_tc == NULL) {
|
|
SCLogDebug("sh->mpm_proto_tcp_ctx == NULL. This should never happen");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
#ifndef __SC_CUDA_SUPPORT__
|
|
MpmInitCtx(sh->mpm_proto_tcp_ctx_ts, de_ctx->mpm_matcher, -1);
|
|
MpmInitCtx(sh->mpm_proto_tcp_ctx_tc, de_ctx->mpm_matcher, -1);
|
|
#else
|
|
MpmInitCtx(sh->mpm_proto_tcp_ctx_ts, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
MpmInitCtx(sh->mpm_proto_tcp_ctx_tc, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
#endif
|
|
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
|
|
sh->mpm_proto_udp_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_proto_udp_packet, 0);
|
|
sh->mpm_proto_udp_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_proto_udp_packet, 1);
|
|
} else {
|
|
sh->mpm_proto_udp_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0);
|
|
sh->mpm_proto_udp_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 1);
|
|
}
|
|
if (sh->mpm_proto_udp_ctx_ts == NULL || sh->mpm_proto_udp_ctx_tc == NULL) {
|
|
SCLogDebug("sh->mpm_proto_udp_ctx == NULL. This should never happen");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
#ifndef __SC_CUDA_SUPPORT__
|
|
MpmInitCtx(sh->mpm_proto_udp_ctx_ts, de_ctx->mpm_matcher, -1);
|
|
MpmInitCtx(sh->mpm_proto_udp_ctx_tc, de_ctx->mpm_matcher, -1);
|
|
#else
|
|
MpmInitCtx(sh->mpm_proto_udp_ctx_ts, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
MpmInitCtx(sh->mpm_proto_udp_ctx_tc, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
#endif
|
|
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
|
|
sh->mpm_proto_other_ctx =
|
|
MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_proto_other_packet, 0);
|
|
} else {
|
|
sh->mpm_proto_other_ctx =
|
|
MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0);
|
|
}
|
|
if (sh->mpm_proto_other_ctx == NULL) {
|
|
SCLogDebug("sh->mpm_proto_other_ctx == NULL. This should never happen");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
#ifndef __SC_CUDA_SUPPORT__
|
|
MpmInitCtx(sh->mpm_proto_other_ctx, de_ctx->mpm_matcher, -1);
|
|
#else
|
|
MpmInitCtx(sh->mpm_proto_other_ctx, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
#endif
|
|
} /* if (has_co_packet) */
|
|
|
|
if (has_co_stream) {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
|
|
sh->mpm_stream_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_stream, 0);
|
|
sh->mpm_stream_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_stream, 1);
|
|
} else {
|
|
sh->mpm_stream_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0);
|
|
sh->mpm_stream_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 1);
|
|
}
|
|
if (sh->mpm_stream_ctx_tc == NULL || sh->mpm_stream_ctx_tc == NULL) {
|
|
SCLogDebug("sh->mpm_stream_ctx == NULL. This should never happen");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
#ifndef __SC_CUDA_SUPPORT__
|
|
MpmInitCtx(sh->mpm_stream_ctx_ts, de_ctx->mpm_matcher, -1);
|
|
MpmInitCtx(sh->mpm_stream_ctx_tc, de_ctx->mpm_matcher, -1);
|
|
#else
|
|
MpmInitCtx(sh->mpm_stream_ctx_ts, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
MpmInitCtx(sh->mpm_stream_ctx_tc, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
#endif
|
|
}
|
|
|
|
if (has_co_uri) {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
|
|
sh->mpm_uri_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_uri, 0);
|
|
sh->mpm_uri_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_uri, 1);
|
|
} else {
|
|
sh->mpm_uri_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0);
|
|
sh->mpm_uri_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 1);
|
|
}
|
|
if (sh->mpm_uri_ctx_ts == NULL || sh->mpm_uri_ctx_tc == NULL) {
|
|
SCLogDebug("sh->mpm_uri_ctx == NULL. This should never happen");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
#ifndef __SC_CUDA_SUPPORT__
|
|
MpmInitCtx(sh->mpm_uri_ctx_ts, de_ctx->mpm_matcher, -1);
|
|
MpmInitCtx(sh->mpm_uri_ctx_tc, de_ctx->mpm_matcher, -1);
|
|
#else
|
|
MpmInitCtx(sh->mpm_uri_ctx_ts, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
MpmInitCtx(sh->mpm_uri_ctx_tc, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
#endif
|
|
}
|
|
|
|
if (has_co_hcbd) {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
|
|
sh->mpm_hcbd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hcbd, 0);
|
|
sh->mpm_hcbd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hcbd, 1);
|
|
} else {
|
|
sh->mpm_hcbd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0);
|
|
sh->mpm_hcbd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 1);
|
|
}
|
|
if (sh->mpm_hcbd_ctx_ts == NULL || sh->mpm_hcbd_ctx_tc == NULL) {
|
|
SCLogDebug("sh->mpm_hcbd_ctx == NULL. This should never happen");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
#ifndef __SC_CUDA_SUPPORT__
|
|
MpmInitCtx(sh->mpm_hcbd_ctx_ts, de_ctx->mpm_matcher, -1);
|
|
MpmInitCtx(sh->mpm_hcbd_ctx_tc, de_ctx->mpm_matcher, -1);
|
|
#else
|
|
MpmInitCtx(sh->mpm_hcbd_ctx_ts, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
MpmInitCtx(sh->mpm_hcbd_ctx_tc, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
#endif
|
|
}
|
|
|
|
if (has_co_hsbd) {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
|
|
sh->mpm_hsbd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hsbd, 0);
|
|
sh->mpm_hsbd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hsbd, 1);
|
|
} else {
|
|
sh->mpm_hsbd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0);
|
|
sh->mpm_hsbd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 1);
|
|
}
|
|
if (sh->mpm_hsbd_ctx_ts == NULL || sh->mpm_hsbd_ctx_tc == NULL) {
|
|
SCLogDebug("sh->mpm_hsbd_ctx == NULL. This should never happen");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
#ifndef __SC_CUDA_SUPPORT__
|
|
MpmInitCtx(sh->mpm_hsbd_ctx_ts, de_ctx->mpm_matcher, -1);
|
|
MpmInitCtx(sh->mpm_hsbd_ctx_tc, de_ctx->mpm_matcher, -1);
|
|
#else
|
|
MpmInitCtx(sh->mpm_hsbd_ctx_ts, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
MpmInitCtx(sh->mpm_hsbd_ctx_tc, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
#endif
|
|
}
|
|
|
|
if (has_co_hhd) {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
|
|
sh->mpm_hhd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hhd, 0);
|
|
sh->mpm_hhd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hhd, 1);
|
|
} else {
|
|
sh->mpm_hhd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0);
|
|
sh->mpm_hhd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 1);
|
|
}
|
|
if (sh->mpm_hhd_ctx_ts == NULL || sh->mpm_hhd_ctx_tc == NULL) {
|
|
SCLogDebug("sh->mpm_hhd_ctx == NULL. This should never happen");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
#ifndef __SC_CUDA_SUPPORT__
|
|
MpmInitCtx(sh->mpm_hhd_ctx_ts, de_ctx->mpm_matcher, -1);
|
|
MpmInitCtx(sh->mpm_hhd_ctx_tc, de_ctx->mpm_matcher, -1);
|
|
#else
|
|
MpmInitCtx(sh->mpm_hhd_ctx_ts, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
MpmInitCtx(sh->mpm_hhd_ctx_tc, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
#endif
|
|
}
|
|
|
|
if (has_co_hrhd) {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
|
|
sh->mpm_hrhd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hrhd, 0);
|
|
sh->mpm_hrhd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hrhd, 1);
|
|
} else {
|
|
sh->mpm_hrhd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0);
|
|
sh->mpm_hrhd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 1);
|
|
}
|
|
if (sh->mpm_hrhd_ctx_ts == NULL || sh->mpm_hrhd_ctx_tc == NULL) {
|
|
SCLogDebug("sh->mpm_hrhd_ctx == NULL. This should never happen");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
#ifndef __SC_CUDA_SUPPORT__
|
|
MpmInitCtx(sh->mpm_hrhd_ctx_ts, de_ctx->mpm_matcher, -1);
|
|
MpmInitCtx(sh->mpm_hrhd_ctx_tc, de_ctx->mpm_matcher, -1);
|
|
#else
|
|
MpmInitCtx(sh->mpm_hrhd_ctx_ts, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
MpmInitCtx(sh->mpm_hrhd_ctx_tc, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
#endif
|
|
}
|
|
|
|
if (has_co_hmd) {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
|
|
sh->mpm_hmd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hmd, 0);
|
|
sh->mpm_hmd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hmd, 1);
|
|
} else {
|
|
sh->mpm_hmd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0);
|
|
sh->mpm_hmd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 1);
|
|
}
|
|
if (sh->mpm_hmd_ctx_ts == NULL || sh->mpm_hmd_ctx_tc == NULL) {
|
|
SCLogDebug("sh->mpm_hmd_ctx == NULL. This should never happen");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
#ifndef __SC_CUDA_SUPPORT__
|
|
MpmInitCtx(sh->mpm_hmd_ctx_ts, de_ctx->mpm_matcher, -1);
|
|
MpmInitCtx(sh->mpm_hmd_ctx_tc, de_ctx->mpm_matcher, -1);
|
|
#else
|
|
MpmInitCtx(sh->mpm_hmd_ctx_ts, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
MpmInitCtx(sh->mpm_hmd_ctx_tc, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
#endif
|
|
}
|
|
|
|
if (has_co_hcd) {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
|
|
sh->mpm_hcd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hcd, 0);
|
|
sh->mpm_hcd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hcd, 1);
|
|
} else {
|
|
sh->mpm_hcd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0);
|
|
sh->mpm_hcd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 1);
|
|
}
|
|
if (sh->mpm_hcd_ctx_ts == NULL || sh->mpm_hcd_ctx_tc == NULL) {
|
|
SCLogDebug("sh->mpm_hcd_ctx == NULL. This should never happen");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
#ifndef __SC_CUDA_SUPPORT__
|
|
MpmInitCtx(sh->mpm_hcd_ctx_ts, de_ctx->mpm_matcher, -1);
|
|
MpmInitCtx(sh->mpm_hcd_ctx_tc, de_ctx->mpm_matcher, -1);
|
|
#else
|
|
MpmInitCtx(sh->mpm_hcd_ctx_ts, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
MpmInitCtx(sh->mpm_hcd_ctx_tc, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
#endif
|
|
}
|
|
|
|
if (has_co_hrud) {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
|
|
sh->mpm_hrud_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hrud, 0);
|
|
sh->mpm_hrud_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hrud, 1);
|
|
} else {
|
|
sh->mpm_hrud_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0);
|
|
sh->mpm_hrud_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 1);
|
|
}
|
|
if (sh->mpm_hrud_ctx_ts == NULL || sh->mpm_hrud_ctx_tc == NULL) {
|
|
SCLogDebug("sh->mpm_hrud_ctx == NULL. This should never happen");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
#ifndef __SC_CUDA_SUPPORT__
|
|
MpmInitCtx(sh->mpm_hrud_ctx_ts, de_ctx->mpm_matcher, -1);
|
|
MpmInitCtx(sh->mpm_hrud_ctx_tc, de_ctx->mpm_matcher, -1);
|
|
#else
|
|
MpmInitCtx(sh->mpm_hrud_ctx_ts, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
MpmInitCtx(sh->mpm_hrud_ctx_tc, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
#endif
|
|
}
|
|
|
|
if (has_co_hsmd) {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
|
|
sh->mpm_hsmd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hsmd, 0);
|
|
sh->mpm_hsmd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hsmd, 1);
|
|
} else {
|
|
sh->mpm_hsmd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0);
|
|
sh->mpm_hsmd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 1);
|
|
}
|
|
if (sh->mpm_hsmd_ctx_ts == NULL || sh->mpm_hsmd_ctx_tc == NULL) {
|
|
SCLogDebug("sh->mpm_hsmd_ctx == NULL. This should never happen");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
#ifndef __SC_CUDA_SUPPORT__
|
|
MpmInitCtx(sh->mpm_hsmd_ctx_ts, de_ctx->mpm_matcher, -1);
|
|
MpmInitCtx(sh->mpm_hsmd_ctx_tc, de_ctx->mpm_matcher, -1);
|
|
#else
|
|
MpmInitCtx(sh->mpm_hsmd_ctx_ts, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
MpmInitCtx(sh->mpm_hsmd_ctx_tc, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
#endif
|
|
}
|
|
|
|
if (has_co_hscd) {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
|
|
sh->mpm_hscd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hscd, 0);
|
|
sh->mpm_hscd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_hscd, 1);
|
|
} else {
|
|
sh->mpm_hscd_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0);
|
|
sh->mpm_hscd_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 1);
|
|
}
|
|
if (sh->mpm_hscd_ctx_ts == NULL || sh->mpm_hscd_ctx_tc == NULL) {
|
|
SCLogDebug("sh->mpm_hscd_ctx == NULL. This should never happen");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
#ifndef __SC_CUDA_SUPPORT__
|
|
MpmInitCtx(sh->mpm_hscd_ctx_ts, de_ctx->mpm_matcher, -1);
|
|
MpmInitCtx(sh->mpm_hscd_ctx_tc, de_ctx->mpm_matcher, -1);
|
|
#else
|
|
MpmInitCtx(sh->mpm_hscd_ctx_ts, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
MpmInitCtx(sh->mpm_hscd_ctx_tc, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
#endif
|
|
}
|
|
|
|
if (has_co_huad) {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
|
|
sh->mpm_huad_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_huad, 0);
|
|
sh->mpm_huad_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_huad, 1);
|
|
} else {
|
|
sh->mpm_huad_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0);
|
|
sh->mpm_huad_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 1);
|
|
}
|
|
if (sh->mpm_huad_ctx_ts == NULL || sh->mpm_huad_ctx_tc == NULL) {
|
|
SCLogDebug("sh->mpm_huad_ctx == NULL. This should never happen");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
#ifndef __SC_CUDA_SUPPORT__
|
|
MpmInitCtx(sh->mpm_huad_ctx_ts, de_ctx->mpm_matcher, -1);
|
|
MpmInitCtx(sh->mpm_huad_ctx_tc, de_ctx->mpm_matcher, -1);
|
|
#else
|
|
MpmInitCtx(sh->mpm_huad_ctx_ts, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
MpmInitCtx(sh->mpm_huad_ctx_tc, de_ctx->mpm_matcher, de_ctx->cuda_rc_mod_handle);
|
|
#endif
|
|
}
|
|
|
|
if (has_co_packet ||
|
|
has_co_stream ||
|
|
has_co_uri ||
|
|
has_co_hcbd ||
|
|
has_co_hsbd ||
|
|
has_co_hhd ||
|
|
has_co_hrhd ||
|
|
has_co_hmd ||
|
|
has_co_hcd ||
|
|
has_co_hsmd ||
|
|
has_co_hscd ||
|
|
has_co_hrud ||
|
|
has_co_huad) {
|
|
|
|
PatternMatchPreparePopulateMpm(de_ctx, sh);
|
|
|
|
//if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (sh->mpm_proto_tcp_ctx_ts != NULL) {
|
|
if (sh->mpm_proto_tcp_ctx_ts->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_tcp_ctx_ts);
|
|
sh->mpm_proto_tcp_ctx_ts = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_proto_tcp_ctx_ts->mpm_type].Prepare != NULL) {
|
|
mpm_table[sh->mpm_proto_tcp_ctx_ts->mpm_type].
|
|
Prepare(sh->mpm_proto_tcp_ctx_ts);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (sh->mpm_proto_tcp_ctx_tc != NULL) {
|
|
if (sh->mpm_proto_tcp_ctx_tc->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_tcp_ctx_tc);
|
|
sh->mpm_proto_tcp_ctx_tc = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_proto_tcp_ctx_tc->mpm_type].Prepare != NULL) {
|
|
mpm_table[sh->mpm_proto_tcp_ctx_tc->mpm_type].
|
|
Prepare(sh->mpm_proto_tcp_ctx_tc);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sh->mpm_proto_udp_ctx_ts != NULL) {
|
|
if (sh->mpm_proto_udp_ctx_ts->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_udp_ctx_ts);
|
|
sh->mpm_proto_udp_ctx_ts = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_proto_udp_ctx_ts->mpm_type].Prepare != NULL) {
|
|
mpm_table[sh->mpm_proto_udp_ctx_ts->mpm_type].
|
|
Prepare(sh->mpm_proto_udp_ctx_ts);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (sh->mpm_proto_udp_ctx_tc != NULL) {
|
|
if (sh->mpm_proto_udp_ctx_tc->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_udp_ctx_tc);
|
|
sh->mpm_proto_udp_ctx_tc = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_proto_udp_ctx_tc->mpm_type].Prepare != NULL) {
|
|
mpm_table[sh->mpm_proto_udp_ctx_tc->mpm_type].
|
|
Prepare(sh->mpm_proto_udp_ctx_tc);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sh->mpm_proto_other_ctx != NULL) {
|
|
if (sh->mpm_proto_other_ctx->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_other_ctx);
|
|
sh->mpm_proto_other_ctx = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_proto_other_ctx->mpm_type].Prepare != NULL) {
|
|
mpm_table[sh->mpm_proto_other_ctx->mpm_type].
|
|
Prepare(sh->mpm_proto_other_ctx);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sh->mpm_stream_ctx_ts != NULL) {
|
|
if (sh->mpm_stream_ctx_ts->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_stream_ctx_ts);
|
|
sh->mpm_stream_ctx_ts = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_stream_ctx_ts->mpm_type].Prepare != NULL)
|
|
mpm_table[sh->mpm_stream_ctx_ts->mpm_type].Prepare(sh->mpm_stream_ctx_ts);
|
|
}
|
|
}
|
|
}
|
|
if (sh->mpm_stream_ctx_tc != NULL) {
|
|
if (sh->mpm_stream_ctx_tc->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_stream_ctx_tc);
|
|
sh->mpm_stream_ctx_tc = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_stream_ctx_tc->mpm_type].Prepare != NULL)
|
|
mpm_table[sh->mpm_stream_ctx_tc->mpm_type].Prepare(sh->mpm_stream_ctx_tc);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sh->mpm_uri_ctx_ts != NULL) {
|
|
if (sh->mpm_uri_ctx_ts->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_uri_ctx_ts);
|
|
sh->mpm_uri_ctx_ts = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_uri_ctx_ts->mpm_type].Prepare != NULL)
|
|
mpm_table[sh->mpm_uri_ctx_ts->mpm_type].Prepare(sh->mpm_uri_ctx_ts);
|
|
}
|
|
}
|
|
}
|
|
if (sh->mpm_uri_ctx_tc != NULL) {
|
|
if (sh->mpm_uri_ctx_tc->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_uri_ctx_tc);
|
|
sh->mpm_uri_ctx_tc = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_uri_ctx_tc->mpm_type].Prepare != NULL)
|
|
mpm_table[sh->mpm_uri_ctx_tc->mpm_type].Prepare(sh->mpm_uri_ctx_tc);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sh->mpm_hcbd_ctx_ts != NULL) {
|
|
if (sh->mpm_hcbd_ctx_ts->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hcbd_ctx_ts);
|
|
sh->mpm_hcbd_ctx_ts = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_hcbd_ctx_ts->mpm_type].Prepare != NULL)
|
|
mpm_table[sh->mpm_hcbd_ctx_ts->mpm_type].Prepare(sh->mpm_hcbd_ctx_ts);
|
|
}
|
|
}
|
|
}
|
|
if (sh->mpm_hcbd_ctx_tc != NULL) {
|
|
if (sh->mpm_hcbd_ctx_tc->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hcbd_ctx_tc);
|
|
sh->mpm_hcbd_ctx_tc = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_hcbd_ctx_tc->mpm_type].Prepare != NULL)
|
|
mpm_table[sh->mpm_hcbd_ctx_tc->mpm_type].Prepare(sh->mpm_hcbd_ctx_tc);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sh->mpm_hsbd_ctx_ts != NULL) {
|
|
if (sh->mpm_hsbd_ctx_ts->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hsbd_ctx_ts);
|
|
sh->mpm_hsbd_ctx_ts = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_hsbd_ctx_ts->mpm_type].Prepare != NULL)
|
|
mpm_table[sh->mpm_hsbd_ctx_ts->mpm_type].Prepare(sh->mpm_hsbd_ctx_ts);
|
|
}
|
|
}
|
|
}
|
|
if (sh->mpm_hsbd_ctx_tc != NULL) {
|
|
if (sh->mpm_hsbd_ctx_tc->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hsbd_ctx_tc);
|
|
sh->mpm_hsbd_ctx_tc = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_hsbd_ctx_tc->mpm_type].Prepare != NULL)
|
|
mpm_table[sh->mpm_hsbd_ctx_tc->mpm_type].Prepare(sh->mpm_hsbd_ctx_tc);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sh->mpm_hhd_ctx_ts != NULL) {
|
|
if (sh->mpm_hhd_ctx_ts->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hhd_ctx_ts);
|
|
sh->mpm_hhd_ctx_ts = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_hhd_ctx_ts->mpm_type].Prepare != NULL)
|
|
mpm_table[sh->mpm_hhd_ctx_ts->mpm_type].Prepare(sh->mpm_hhd_ctx_ts);
|
|
}
|
|
}
|
|
}
|
|
if (sh->mpm_hhd_ctx_tc != NULL) {
|
|
if (sh->mpm_hhd_ctx_tc->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hhd_ctx_tc);
|
|
sh->mpm_hhd_ctx_tc = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_hhd_ctx_tc->mpm_type].Prepare != NULL)
|
|
mpm_table[sh->mpm_hhd_ctx_tc->mpm_type].Prepare(sh->mpm_hhd_ctx_tc);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sh->mpm_hrhd_ctx_ts != NULL) {
|
|
if (sh->mpm_hrhd_ctx_ts->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hrhd_ctx_ts);
|
|
sh->mpm_hrhd_ctx_ts = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_hrhd_ctx_ts->mpm_type].Prepare != NULL)
|
|
mpm_table[sh->mpm_hrhd_ctx_ts->mpm_type].Prepare(sh->mpm_hrhd_ctx_ts);
|
|
}
|
|
}
|
|
}
|
|
if (sh->mpm_hrhd_ctx_tc != NULL) {
|
|
if (sh->mpm_hrhd_ctx_tc->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hrhd_ctx_tc);
|
|
sh->mpm_hrhd_ctx_tc = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_hrhd_ctx_tc->mpm_type].Prepare != NULL)
|
|
mpm_table[sh->mpm_hrhd_ctx_tc->mpm_type].Prepare(sh->mpm_hrhd_ctx_tc);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sh->mpm_hmd_ctx_ts != NULL) {
|
|
if (sh->mpm_hmd_ctx_ts->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hmd_ctx_ts);
|
|
sh->mpm_hmd_ctx_ts = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_hmd_ctx_ts->mpm_type].Prepare != NULL)
|
|
mpm_table[sh->mpm_hmd_ctx_ts->mpm_type].Prepare(sh->mpm_hmd_ctx_ts);
|
|
}
|
|
}
|
|
}
|
|
if (sh->mpm_hmd_ctx_tc != NULL) {
|
|
if (sh->mpm_hmd_ctx_tc->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hmd_ctx_tc);
|
|
sh->mpm_hmd_ctx_tc = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_hmd_ctx_tc->mpm_type].Prepare != NULL)
|
|
mpm_table[sh->mpm_hmd_ctx_tc->mpm_type].Prepare(sh->mpm_hmd_ctx_tc);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sh->mpm_hcd_ctx_ts != NULL) {
|
|
if (sh->mpm_hcd_ctx_ts->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hcd_ctx_ts);
|
|
sh->mpm_hcd_ctx_ts = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_hcd_ctx_ts->mpm_type].Prepare != NULL)
|
|
mpm_table[sh->mpm_hcd_ctx_ts->mpm_type].Prepare(sh->mpm_hcd_ctx_ts);
|
|
}
|
|
}
|
|
}
|
|
if (sh->mpm_hcd_ctx_tc != NULL) {
|
|
if (sh->mpm_hcd_ctx_tc->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hcd_ctx_tc);
|
|
sh->mpm_hcd_ctx_tc = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_hcd_ctx_tc->mpm_type].Prepare != NULL)
|
|
mpm_table[sh->mpm_hcd_ctx_tc->mpm_type].Prepare(sh->mpm_hcd_ctx_tc);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sh->mpm_hrud_ctx_ts != NULL) {
|
|
if (sh->mpm_hrud_ctx_ts->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hrud_ctx_ts);
|
|
sh->mpm_hrud_ctx_ts = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_hrud_ctx_ts->mpm_type].Prepare != NULL)
|
|
mpm_table[sh->mpm_hrud_ctx_ts->mpm_type].Prepare(sh->mpm_hrud_ctx_ts);
|
|
}
|
|
}
|
|
}
|
|
if (sh->mpm_hrud_ctx_tc != NULL) {
|
|
if (sh->mpm_hrud_ctx_tc->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hrud_ctx_tc);
|
|
sh->mpm_hrud_ctx_tc = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_hrud_ctx_tc->mpm_type].Prepare != NULL)
|
|
mpm_table[sh->mpm_hrud_ctx_tc->mpm_type].Prepare(sh->mpm_hrud_ctx_tc);
|
|
}
|
|
}
|
|
}
|
|
if (sh->mpm_hsmd_ctx_ts != NULL) {
|
|
if (sh->mpm_hsmd_ctx_ts->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hsmd_ctx_ts);
|
|
sh->mpm_hsmd_ctx_ts = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_hsmd_ctx_ts->mpm_type].Prepare != NULL)
|
|
mpm_table[sh->mpm_hsmd_ctx_ts->mpm_type].Prepare(sh->mpm_hsmd_ctx_ts);
|
|
}
|
|
}
|
|
}
|
|
if (sh->mpm_hsmd_ctx_tc != NULL) {
|
|
if (sh->mpm_hsmd_ctx_tc->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hsmd_ctx_tc);
|
|
sh->mpm_hsmd_ctx_tc = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_hsmd_ctx_tc->mpm_type].Prepare != NULL)
|
|
mpm_table[sh->mpm_hsmd_ctx_tc->mpm_type].Prepare(sh->mpm_hsmd_ctx_tc);
|
|
}
|
|
}
|
|
}
|
|
if (sh->mpm_hscd_ctx_ts != NULL) {
|
|
if (sh->mpm_hscd_ctx_ts->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hscd_ctx_ts);
|
|
sh->mpm_hscd_ctx_ts = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_hscd_ctx_ts->mpm_type].Prepare != NULL)
|
|
mpm_table[sh->mpm_hscd_ctx_ts->mpm_type].Prepare(sh->mpm_hscd_ctx_ts);
|
|
}
|
|
}
|
|
}
|
|
if (sh->mpm_hscd_ctx_tc != NULL) {
|
|
if (sh->mpm_hscd_ctx_tc->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hscd_ctx_tc);
|
|
sh->mpm_hscd_ctx_tc = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_hscd_ctx_tc->mpm_type].Prepare != NULL)
|
|
mpm_table[sh->mpm_hscd_ctx_tc->mpm_type].Prepare(sh->mpm_hscd_ctx_tc);
|
|
}
|
|
}
|
|
}
|
|
if (sh->mpm_huad_ctx_ts != NULL) {
|
|
if (sh->mpm_huad_ctx_ts->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_huad_ctx_ts);
|
|
sh->mpm_huad_ctx_ts = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_huad_ctx_ts->mpm_type].Prepare != NULL)
|
|
mpm_table[sh->mpm_huad_ctx_ts->mpm_type].Prepare(sh->mpm_huad_ctx_ts);
|
|
}
|
|
}
|
|
}
|
|
if (sh->mpm_huad_ctx_tc != NULL) {
|
|
if (sh->mpm_huad_ctx_tc->pattern_cnt == 0) {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_huad_ctx_tc);
|
|
sh->mpm_huad_ctx_tc = NULL;
|
|
} else {
|
|
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
|
|
if (mpm_table[sh->mpm_huad_ctx_tc->mpm_type].Prepare != NULL)
|
|
mpm_table[sh->mpm_huad_ctx_tc->mpm_type].Prepare(sh->mpm_huad_ctx_tc);
|
|
}
|
|
}
|
|
}
|
|
//} /* if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) */
|
|
} else {
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_other_ctx);
|
|
sh->mpm_proto_other_ctx = NULL;
|
|
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_tcp_ctx_ts);
|
|
sh->mpm_proto_tcp_ctx_ts = NULL;
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_udp_ctx_ts);
|
|
sh->mpm_proto_udp_ctx_ts = NULL;
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_stream_ctx_ts);
|
|
sh->mpm_stream_ctx_ts = NULL;
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_uri_ctx_ts);
|
|
sh->mpm_uri_ctx_ts = NULL;
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hcbd_ctx_ts);
|
|
sh->mpm_hcbd_ctx_ts = NULL;
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hhd_ctx_ts);
|
|
sh->mpm_hhd_ctx_ts = NULL;
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hrhd_ctx_ts);
|
|
sh->mpm_hrhd_ctx_ts = NULL;
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hmd_ctx_ts);
|
|
sh->mpm_hmd_ctx_ts = NULL;
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hcd_ctx_ts);
|
|
sh->mpm_hcd_ctx_ts = NULL;
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hrud_ctx_ts);
|
|
sh->mpm_hrud_ctx_ts = NULL;
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hsmd_ctx_ts);
|
|
sh->mpm_hsmd_ctx_ts = NULL;
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hscd_ctx_ts);
|
|
sh->mpm_hscd_ctx_ts = NULL;
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_huad_ctx_ts);
|
|
sh->mpm_huad_ctx_ts = NULL;
|
|
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_tcp_ctx_tc);
|
|
sh->mpm_proto_tcp_ctx_tc = NULL;
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_udp_ctx_tc);
|
|
sh->mpm_proto_udp_ctx_tc = NULL;
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_stream_ctx_tc);
|
|
sh->mpm_stream_ctx_tc = NULL;
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_uri_ctx_tc);
|
|
sh->mpm_uri_ctx_tc = NULL;
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hcbd_ctx_tc);
|
|
sh->mpm_hcbd_ctx_tc = NULL;
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hhd_ctx_tc);
|
|
sh->mpm_hhd_ctx_tc = NULL;
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hrhd_ctx_tc);
|
|
sh->mpm_hrhd_ctx_tc = NULL;
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hmd_ctx_tc);
|
|
sh->mpm_hmd_ctx_tc = NULL;
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hcd_ctx_tc);
|
|
sh->mpm_hcd_ctx_tc = NULL;
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hrud_ctx_tc);
|
|
sh->mpm_hrud_ctx_tc = NULL;
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hsmd_ctx_tc);
|
|
sh->mpm_hsmd_ctx_tc = NULL;
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hscd_ctx_tc);
|
|
sh->mpm_hscd_ctx_tc = NULL;
|
|
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_huad_ctx_tc);
|
|
sh->mpm_huad_ctx_tc = NULL;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/** \brief Pattern ID Hash for sharing pattern id's
|
|
*
|
|
* A per detection engine hash to make sure each pattern has a unique
|
|
* global id but patterns that are the same share id's.
|
|
*/
|
|
typedef struct MpmPatternIdTableElmt_ {
|
|
uint8_t *pattern; /**< ptr to the pattern */
|
|
uint16_t pattern_len; /**< pattern len */
|
|
PatIntId id; /**< pattern id */
|
|
uint16_t dup_count; /**< duplicate count */
|
|
uint8_t sm_list; /**< SigMatch list */
|
|
} MpmPatternIdTableElmt;
|
|
|
|
/** \brief Hash compare func for MpmPatternId api
|
|
* \retval 1 patterns are the same
|
|
* \retval 0 patterns are not the same
|
|
**/
|
|
static char MpmPatternIdCompare(void *p1, uint16_t len1, void *p2, uint16_t len2) {
|
|
SCEnter();
|
|
BUG_ON(len1 < sizeof(MpmPatternIdTableElmt));
|
|
BUG_ON(len2 < sizeof(MpmPatternIdTableElmt));
|
|
|
|
MpmPatternIdTableElmt *e1 = (MpmPatternIdTableElmt *)p1;
|
|
MpmPatternIdTableElmt *e2 = (MpmPatternIdTableElmt *)p2;
|
|
|
|
if (e1->pattern_len != e2->pattern_len ||
|
|
e1->sm_list != e2->sm_list) {
|
|
SCReturnInt(0);
|
|
}
|
|
|
|
if (SCMemcmp(e1->pattern, e2->pattern, e1->pattern_len) != 0) {
|
|
SCReturnInt(0);
|
|
}
|
|
|
|
SCReturnInt(1);
|
|
}
|
|
|
|
/** \brief Hash func for MpmPatternId api
|
|
* \retval hash hash value
|
|
*/
|
|
static uint32_t MpmPatternIdHashFunc(HashTable *ht, void *p, uint16_t len) {
|
|
SCEnter();
|
|
BUG_ON(len < sizeof(MpmPatternIdTableElmt));
|
|
|
|
MpmPatternIdTableElmt *e = (MpmPatternIdTableElmt *)p;
|
|
uint32_t hash = e->pattern_len;
|
|
uint16_t u = 0;
|
|
|
|
for (u = 0; u < e->pattern_len; u++) {
|
|
hash += e->pattern[u];
|
|
}
|
|
|
|
SCReturnUInt(hash % ht->array_size);
|
|
}
|
|
|
|
/** \brief free a MpmPatternIdTableElmt */
|
|
static void MpmPatternIdTableElmtFree(void *e) {
|
|
SCEnter();
|
|
MpmPatternIdTableElmt *c = (MpmPatternIdTableElmt *)e;
|
|
SCFree(c->pattern);
|
|
SCFree(c);
|
|
SCReturn;
|
|
}
|
|
|
|
/** \brief alloc initialize the MpmPatternIdHash */
|
|
MpmPatternIdStore *MpmPatternIdTableInitHash(void) {
|
|
SCEnter();
|
|
|
|
MpmPatternIdStore *ht = SCMalloc(sizeof(MpmPatternIdStore));
|
|
BUG_ON(ht == NULL);
|
|
memset(ht, 0x00, sizeof(MpmPatternIdStore));
|
|
|
|
ht->hash = HashTableInit(65536, MpmPatternIdHashFunc, MpmPatternIdCompare, MpmPatternIdTableElmtFree);
|
|
BUG_ON(ht->hash == NULL);
|
|
|
|
SCReturnPtr(ht, "MpmPatternIdStore");
|
|
}
|
|
|
|
void MpmPatternIdTableFreeHash(MpmPatternIdStore *ht) {
|
|
SCEnter();
|
|
|
|
if (ht == NULL) {
|
|
SCReturn;
|
|
}
|
|
|
|
if (ht->hash != NULL) {
|
|
HashTableFree(ht->hash);
|
|
}
|
|
|
|
SCFree(ht);
|
|
SCReturn;
|
|
}
|
|
|
|
uint32_t MpmPatternIdStoreGetMaxId(MpmPatternIdStore *ht) {
|
|
if (ht == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
return ht->max_id;
|
|
}
|
|
|
|
/**
|
|
* \brief Get the pattern id for a content pattern
|
|
*
|
|
* \param ht mpm pattern id hash table store
|
|
* \param co content pattern data
|
|
*
|
|
* \retval id pattern id
|
|
* \initonly
|
|
*/
|
|
uint32_t DetectContentGetId(MpmPatternIdStore *ht, DetectContentData *co) {
|
|
SCEnter();
|
|
|
|
BUG_ON(ht == NULL || ht->hash == NULL);
|
|
|
|
MpmPatternIdTableElmt *e = NULL;
|
|
MpmPatternIdTableElmt *r = NULL;
|
|
uint32_t id = 0;
|
|
|
|
e = SCMalloc(sizeof(MpmPatternIdTableElmt));
|
|
BUG_ON(e == NULL);
|
|
memset(e, 0, sizeof(MpmPatternIdTableElmt));
|
|
e->pattern = SCMalloc(co->content_len);
|
|
BUG_ON(e->pattern == NULL);
|
|
memcpy(e->pattern, co->content, co->content_len);
|
|
e->pattern_len = co->content_len;
|
|
e->id = 0;
|
|
|
|
r = HashTableLookup(ht->hash, (void *)e, sizeof(MpmPatternIdTableElmt));
|
|
if (r == NULL) {
|
|
e->id = ht->max_id;
|
|
ht->max_id++;
|
|
id = e->id;
|
|
|
|
int ret = HashTableAdd(ht->hash, e, sizeof(MpmPatternIdTableElmt));
|
|
BUG_ON(ret != 0);
|
|
|
|
e = NULL;
|
|
|
|
ht->unique_patterns++;
|
|
} else {
|
|
id = r->id;
|
|
|
|
ht->shared_patterns++;
|
|
}
|
|
|
|
if (e != NULL)
|
|
MpmPatternIdTableElmtFree(e);
|
|
|
|
SCReturnUInt(id);
|
|
}
|
|
|
|
/**
|
|
* \brief Get the pattern id for a uricontent pattern
|
|
*
|
|
* \param ht mpm pattern id hash table store
|
|
* \param co content pattern data
|
|
*
|
|
* \retval id pattern id
|
|
*/
|
|
uint32_t DetectUricontentGetId(MpmPatternIdStore *ht, DetectContentData *co) {
|
|
SCEnter();
|
|
|
|
BUG_ON(ht == NULL || ht->hash == NULL);
|
|
|
|
MpmPatternIdTableElmt *e = NULL;
|
|
MpmPatternIdTableElmt *r = NULL;
|
|
uint32_t id = 0;
|
|
|
|
e = SCMalloc(sizeof(MpmPatternIdTableElmt));
|
|
BUG_ON(e == NULL);
|
|
e->pattern = SCMalloc(co->content_len);
|
|
BUG_ON(e->pattern == NULL);
|
|
memcpy(e->pattern, co->content, co->content_len);
|
|
e->pattern_len = co->content_len;
|
|
e->sm_list = DETECT_SM_LIST_UMATCH;
|
|
e->dup_count = 1;
|
|
e->id = 0;
|
|
|
|
r = HashTableLookup(ht->hash, (void *)e, sizeof(MpmPatternIdTableElmt));
|
|
if (r == NULL) {
|
|
e->id = ht->max_id;
|
|
ht->max_id++;
|
|
id = e->id;
|
|
|
|
int ret = HashTableAdd(ht->hash, e, sizeof(MpmPatternIdTableElmt));
|
|
BUG_ON(ret != 0);
|
|
|
|
e = NULL;
|
|
|
|
ht->unique_patterns++;
|
|
} else {
|
|
id = r->id;
|
|
r->dup_count++;
|
|
|
|
ht->shared_patterns++;
|
|
}
|
|
|
|
if (e != NULL)
|
|
MpmPatternIdTableElmtFree(e);
|
|
|
|
SCReturnUInt(id);
|
|
}
|
|
|
|
/**
|
|
* \brief Get the pattern id for a for any content related keyword.
|
|
*
|
|
* Supported keywords are content, http_client_body,
|
|
* http_method, http_uri, http_header, http_cookie.
|
|
*
|
|
* Please note that you can't use it to get a pattern id for
|
|
* uricontent. To retrieve a uricontent pattern id please
|
|
* use DetectUricontentGetId().
|
|
*
|
|
* \param ht Mpm pattern id hash table store.
|
|
* \param ctx The keyword context.
|
|
* \param type The SigMatch context.
|
|
*
|
|
* \retval id Pattern id.
|
|
*/
|
|
uint32_t DetectPatternGetId(MpmPatternIdStore *ht, void *ctx, uint8_t sm_list)
|
|
{
|
|
SCEnter();
|
|
|
|
MpmPatternIdTableElmt *e = NULL;
|
|
MpmPatternIdTableElmt *r = NULL;
|
|
PatIntId id = 0;
|
|
|
|
e = SCMalloc(sizeof(MpmPatternIdTableElmt));
|
|
if (e == NULL) {
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
DetectContentData *cd = ctx;
|
|
e->pattern = SCMalloc(cd->content_len);
|
|
if (e->pattern == NULL) {
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
memcpy(e->pattern, cd->content, cd->content_len);
|
|
e->pattern_len = cd->content_len;
|
|
e->dup_count = 1;
|
|
e->sm_list = sm_list;
|
|
e->id = 0;
|
|
|
|
r = HashTableLookup(ht->hash, (void *)e, sizeof(MpmPatternIdTableElmt));
|
|
if (r == NULL) {
|
|
/* we don't have a duplicate with this pattern + id type. If the id is
|
|
* for content, then it is the first entry for such a
|
|
* pattern + id combination. Let us create an entry for it */
|
|
if (sm_list == DETECT_SM_LIST_PMATCH) {
|
|
e->id = ht->max_id;
|
|
ht->max_id++;
|
|
id = e->id;
|
|
|
|
int ret = HashTableAdd(ht->hash, e, sizeof(MpmPatternIdTableElmt));
|
|
BUG_ON(ret != 0);
|
|
|
|
e = NULL;
|
|
|
|
/* the id type is not content or uricontent. It would be one of
|
|
* those http_ modifiers against content then */
|
|
} else {
|
|
/* we know that this is one of those http_ modifiers against content.
|
|
* So we would have seen a content before coming across this http_
|
|
* modifier. Let's retrieve this content entry that has already
|
|
* been registered. */
|
|
e->sm_list = DETECT_SM_LIST_PMATCH;
|
|
MpmPatternIdTableElmt *tmp_r = HashTableLookup(ht->hash, (void *)e, sizeof(MpmPatternIdTableElmt));
|
|
if (tmp_r == NULL) {
|
|
SCLogError(SC_ERR_FATAL, "How can this happen? We have to have "
|
|
"a content of type DETECT_CONTENT already registered "
|
|
"at this point. Impossible");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* we have retrieved the content, and the content registered was the
|
|
* first entry made(dup_count is 1) for that content. Let us just
|
|
* reset the sm_type to the http_ keyword's sm_type */
|
|
if (tmp_r->dup_count == 1) {
|
|
tmp_r->sm_list = sm_list;
|
|
id = tmp_r->id;
|
|
|
|
/* interestingly we have more than one entry for this content.
|
|
* Out of these tmp_r->dup_count entries, one would be for the content
|
|
* entry made for this http_ modifier. Erase this entry and make
|
|
* a separate entry for the http_ modifier(of course with a new id) */
|
|
} else {
|
|
tmp_r->dup_count--;
|
|
/* reset the sm_type, since we changed it to DETECT_CONTENT prev */
|
|
e->sm_list = sm_list;
|
|
e->id = ht->max_id;
|
|
ht->max_id++;
|
|
id = e->id;
|
|
|
|
int ret = HashTableAdd(ht->hash, e, sizeof(MpmPatternIdTableElmt));
|
|
BUG_ON(ret != 0);
|
|
|
|
e = NULL;
|
|
}
|
|
}
|
|
|
|
/* we do seem to have an entry for this already */
|
|
} else {
|
|
/* oh cool! It is a duplicate for content, uricontent types. Update the
|
|
* dup_count and get out */
|
|
if (sm_list == DETECT_SM_LIST_PMATCH) {
|
|
r->dup_count++;
|
|
id = r->id;
|
|
goto end;
|
|
}
|
|
|
|
/* uh oh! a duplicate for a http_ modifier type. Let's increase the
|
|
* dup_count for the entry */
|
|
r->dup_count++;
|
|
id = r->id;
|
|
|
|
/* let's get the content entry associated with the http keyword we are
|
|
* currently operating on */
|
|
e->sm_list = DETECT_SM_LIST_PMATCH;
|
|
MpmPatternIdTableElmt *tmp_r = HashTableLookup(ht->hash, (void *)e, sizeof(MpmPatternIdTableElmt));
|
|
if (tmp_r == NULL) {
|
|
SCLogError(SC_ERR_FATAL, "How can this happen? We have to have "
|
|
"a content of type DETECT_CONTENT already registered "
|
|
"at this point. Impossible");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
/* so there are more than one content keyword entries for this pattern.
|
|
* Reduce the dup_count */
|
|
if (tmp_r->dup_count > 1) {
|
|
tmp_r->dup_count--;
|
|
|
|
/* We have just one entry. Remove this hash table entry */
|
|
} else {
|
|
HashTableRemove(ht->hash, tmp_r, sizeof(MpmPatternIdTableElmt));
|
|
ht->max_id--;
|
|
}
|
|
}
|
|
|
|
end:
|
|
if (e != NULL)
|
|
MpmPatternIdTableElmtFree(e);
|
|
|
|
SCReturnUInt(id);
|
|
}
|