mirror of
https://github.com/OISF/suricata.git
synced 2026-10-11 22:09:53 +00:00
detect/template: merge template and template2
Ticket: 7278 Do a single packet match template merging best of both current templates
This commit is contained in:
committed by
Victor Julien
parent
8d254f5630
commit
512bbe4de8
@@ -1,106 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Script to setup a new 'simple' detect module.
|
||||
# Written by Victor Julien <[email protected]>
|
||||
#
|
||||
|
||||
set -e
|
||||
#set -x
|
||||
|
||||
function Usage {
|
||||
echo
|
||||
echo "$(basename $0) -- script to provision a detect module. The script"
|
||||
echo "makes a copy of detect-template, sets the name and updates"
|
||||
echo "the build system."
|
||||
echo
|
||||
echo "Call from the 'src' directory, with one argument: the detect module"
|
||||
echo "name."
|
||||
echo
|
||||
echo "E.g. inside 'src': ../scripts/$(basename $0) helloworld"
|
||||
echo
|
||||
}
|
||||
|
||||
function Done {
|
||||
echo
|
||||
echo "Detect module $NR has been set up in $FILE_C and $FILE_H"
|
||||
echo "and the build system has been updated."
|
||||
echo
|
||||
echo "The detect module should now compile cleanly. Try running 'make'."
|
||||
echo
|
||||
echo "Next steps are to edit the files to implement the actual"
|
||||
echo "detection logic of $NR."
|
||||
echo
|
||||
}
|
||||
|
||||
# Make sure we are running from the correct directory.
|
||||
set_dir() {
|
||||
if [ -e ./suricata.c ]; then
|
||||
# Do nothing.
|
||||
true
|
||||
elif [ -e ./src/suricata.c ]; then
|
||||
cd src
|
||||
else
|
||||
echo "error: this does not appear to be a suricata source directory."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
if [ $# -ne "1" ]; then
|
||||
Usage
|
||||
echo "ERROR: call with one argument"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
INPUT=$1
|
||||
# lowercase
|
||||
LC=${INPUT,,}
|
||||
#echo $LC
|
||||
# UPPERCASE
|
||||
UC=${LC^^}
|
||||
#echo $UC
|
||||
# Normal
|
||||
NR=${LC^}
|
||||
#echo $NR
|
||||
|
||||
FILE_C="detect-${LC}.c"
|
||||
FILE_H="detect-${LC}.h"
|
||||
|
||||
set_dir
|
||||
|
||||
if [ ! -e detect-template2.c ] || [ ! -e detect-template2.h ]; then
|
||||
Usage
|
||||
echo "ERROR: input files detect-template.c and/or detect-template.h are missing"
|
||||
exit 1
|
||||
fi
|
||||
if [ -e $FILE_C ] || [ -e $FILE_H ]; then
|
||||
Usage
|
||||
echo "ERROR: file(s) $FILE_C and/or $FILE_H already exist, won't overwrite"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
FILE_C="detect-${LC}.c"
|
||||
FILE_H="detect-${LC}.h"
|
||||
cp detect-template2.c $FILE_C
|
||||
cp detect-template2.h $FILE_H
|
||||
|
||||
# search and replaces
|
||||
sed -i "s/TEMPLATE2/${UC}/g" $FILE_C
|
||||
sed -i "s/TEMPLATE2/${UC}/g" $FILE_H
|
||||
sed -i "s/Template2/${NR}/g" $FILE_C
|
||||
sed -i "s/Template2/${NR}/g" $FILE_H
|
||||
sed -i "s/template2/${LC}/g" $FILE_C
|
||||
sed -i "s/template2/${LC}/g" $FILE_H
|
||||
# add to Makefile.am
|
||||
sed -i "s/detect-template2.c detect-template2.h \\\/detect-template2.c detect-template2.h \\\\\n${FILE_C} ${FILE_H} \\\/g" Makefile.am
|
||||
|
||||
# update enum
|
||||
sed -i "s/DETECT_TEMPLATE2,/DETECT_TEMPLATE2,\\n DETECT_${UC},/g" detect-engine-register.h
|
||||
|
||||
# add include to detect-engine-register.c
|
||||
sed -i "s/#include \"detect-template2.h\"/#include \"detect-template2.h\"\\n#include \"${FILE_H}\"/g" detect-engine-register.c
|
||||
|
||||
# add reg func to detect-engine-register.c
|
||||
sed -i "s/DetectTemplate2Register();/DetectTemplate2Register();\\n Detect${NR}Register();/g" detect-engine-register.c
|
||||
|
||||
Done
|
||||
exit 0
|
||||
@@ -285,7 +285,6 @@ noinst_HEADERS = \
|
||||
detect-tcphdr.h \
|
||||
detect-tcpmss.h \
|
||||
detect-template.h \
|
||||
detect-template2.h \
|
||||
detect-threshold.h \
|
||||
detect-tls-alpn.h \
|
||||
detect-tls-cert-fingerprint.h \
|
||||
@@ -866,7 +865,6 @@ libsuricata_c_a_SOURCES = \
|
||||
detect-tcphdr.c \
|
||||
detect-tcpmss.c \
|
||||
detect-template.c \
|
||||
detect-template2.c \
|
||||
detect-threshold.c \
|
||||
detect-tls-alpn.c \
|
||||
detect-tls-cert-fingerprint.c \
|
||||
|
||||
@@ -187,7 +187,6 @@
|
||||
#include "detect-geoip.h"
|
||||
#include "detect-app-layer-protocol.h"
|
||||
#include "detect-template.h"
|
||||
#include "detect-template2.h"
|
||||
#include "detect-tcphdr.h"
|
||||
#include "detect-tcpmss.h"
|
||||
#include "detect-udphdr.h"
|
||||
@@ -692,7 +691,6 @@ void SigTableSetup(void)
|
||||
DetectBase64DecodeRegister();
|
||||
DetectBase64DataRegister();
|
||||
DetectTemplateRegister();
|
||||
DetectTemplate2Register();
|
||||
DetectTcphdrRegister();
|
||||
DetectUdphdrRegister();
|
||||
DetectTcpmssRegister();
|
||||
|
||||
@@ -265,7 +265,6 @@ enum DetectKeywordId {
|
||||
DETECT_SIP_METHOD,
|
||||
DETECT_SIP_URI,
|
||||
DETECT_TEMPLATE,
|
||||
DETECT_TEMPLATE2,
|
||||
DETECT_ETHERHDR,
|
||||
DETECT_IPV4HDR,
|
||||
DETECT_IPV6HDR,
|
||||
|
||||
+100
-132
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2015-2020 Open Information Security Foundation
|
||||
/* Copyright (C) 2007-2026 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
|
||||
@@ -18,166 +18,70 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \author XXX Yourname <youremail@yourdomain>
|
||||
* \author XXX
|
||||
*
|
||||
* XXX Short description of the purpose of this keyword
|
||||
*/
|
||||
|
||||
#include "suricata-common.h"
|
||||
#include "util-unittest.h"
|
||||
#include "util-byte.h"
|
||||
|
||||
#include "detect.h"
|
||||
#include "detect-parse.h"
|
||||
#include "detect-engine.h"
|
||||
#include "detect-engine-prefilter-common.h"
|
||||
#include "detect-engine-uint.h"
|
||||
|
||||
#include "detect-template.h"
|
||||
|
||||
/**
|
||||
* \brief Regex for parsing our keyword options
|
||||
*/
|
||||
#define PARSE_REGEX "^\\s*([0-9]+)?\\s*,s*([0-9]+)?\\s*$"
|
||||
static DetectParseRegex parse_regex;
|
||||
|
||||
/* Prototypes of functions registered in DetectTemplateRegister below */
|
||||
static int DetectTemplateMatch (DetectEngineThreadCtx *,
|
||||
Packet *, const Signature *, const SigMatchCtx *);
|
||||
static int DetectTemplateSetup (DetectEngineCtx *, Signature *, const char *);
|
||||
static void DetectTemplateFree (DetectEngineCtx *, void *);
|
||||
#ifdef UNITTESTS
|
||||
static void DetectTemplateRegisterTests (void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Registration function for template: keyword
|
||||
*
|
||||
* This function is called once in the 'lifetime' of the engine.
|
||||
*/
|
||||
void DetectTemplateRegister(void) {
|
||||
/* keyword name: this is how the keyword is used in a rule */
|
||||
sigmatch_table[DETECT_TEMPLATE].name = "template";
|
||||
/* description: listed in "suricata --list-keywords=all" */
|
||||
sigmatch_table[DETECT_TEMPLATE].desc = "give an introduction into how a detection module works";
|
||||
/* link to further documentation of the keyword. Normally on the Suricata redmine/wiki */
|
||||
sigmatch_table[DETECT_TEMPLATE].url = "https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Suricata_Developers_Guide";
|
||||
/* match function is called when the signature is inspected on a packet */
|
||||
sigmatch_table[DETECT_TEMPLATE].Match = DetectTemplateMatch;
|
||||
/* setup function is called during signature parsing, when the template
|
||||
* keyword is encountered in the rule */
|
||||
sigmatch_table[DETECT_TEMPLATE].Setup = DetectTemplateSetup;
|
||||
/* free function is called when the detect engine is freed. Normally at
|
||||
* shutdown, but also during rule reloads. */
|
||||
sigmatch_table[DETECT_TEMPLATE].Free = DetectTemplateFree;
|
||||
#ifdef UNITTESTS
|
||||
/* registers unittests into the system */
|
||||
sigmatch_table[DETECT_TEMPLATE].RegisterTests = DetectTemplateRegisterTests;
|
||||
#endif
|
||||
/* set up the PCRE for keyword parsing */
|
||||
DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief This function is used to match TEMPLATE rule option on a packet
|
||||
* \brief This function is used to match TEMPLATE rule option on a packet with those passed via
|
||||
* template:
|
||||
*
|
||||
* \param t pointer to thread vars
|
||||
* \param det_ctx pointer to the pattern matcher thread
|
||||
* \param p pointer to the current packet
|
||||
* \param m pointer to the sigmatch with context that we will cast into DetectTemplateData
|
||||
* \param m pointer to the sigmatch that we will cast into DetectU8Data
|
||||
*
|
||||
* \retval 0 no match
|
||||
* \retval 1 match
|
||||
*/
|
||||
static int DetectTemplateMatch (DetectEngineThreadCtx *det_ctx, Packet *p,
|
||||
const Signature *s, const SigMatchCtx *ctx)
|
||||
static int DetectTemplateMatch(
|
||||
DetectEngineThreadCtx *det_ctx, Packet *p, const Signature *s, const SigMatchCtx *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
const DetectTemplateData *templated = (const DetectTemplateData *) ctx;
|
||||
#if 0
|
||||
if (PKT_IS_PSEUDOPKT(p)) {
|
||||
/* fake pkt */
|
||||
}
|
||||
DEBUG_VALIDATE_BUG_ON(PKT_IS_PSEUDOPKT(p));
|
||||
|
||||
/* TODO replace this */
|
||||
uint8_t ptemplate;
|
||||
if (PacketIsIPv4(p)) {
|
||||
/* ipv4 pkt */
|
||||
const IPV4Hdr *ip4h = PacketGetIPv4(p);
|
||||
ptemplate = IPV4_GET_RAW_IPTTL(ip4h);
|
||||
} else if (PacketIsIPv6(p)) {
|
||||
/* ipv6 pkt */
|
||||
const IPV6Hdr *ip6h = PacketGetIPv6(p);
|
||||
ptemplate = IPV6_GET_RAW_HLIM(ip6h);
|
||||
} else {
|
||||
SCLogDebug("packet is of not IPv4 or IPv6");
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
/* packet payload access */
|
||||
if (p->payload != NULL && p->payload_len > 0) {
|
||||
if (templated->arg1 == p->payload[0] &&
|
||||
templated->arg2 == p->payload[p->payload_len - 1])
|
||||
{
|
||||
ret = 1;
|
||||
}
|
||||
SCLogDebug("Packet is of not IPv4 or IPv6");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
const DetectU8Data *templated = (const DetectU8Data *)ctx;
|
||||
return DetectU8Match(ptemplate, templated);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief This function is used to parse template options passed via template: keyword
|
||||
* \brief this function will free memory associated with DetectU8Data
|
||||
*
|
||||
* \param templatestr Pointer to the user provided template options
|
||||
*
|
||||
* \retval templated pointer to DetectTemplateData on success
|
||||
* \retval NULL on failure
|
||||
* \param ptr pointer to DetectU8Data
|
||||
*/
|
||||
static DetectTemplateData *DetectTemplateParse (const char *templatestr)
|
||||
static void DetectTemplateFree(DetectEngineCtx *de_ctx, void *ptr)
|
||||
{
|
||||
char arg1[4] = "";
|
||||
char arg2[4] = "";
|
||||
|
||||
pcre2_match_data *match = NULL;
|
||||
int ret = DetectParsePcreExec(&parse_regex, &match, templatestr, 0, 0);
|
||||
if (ret != 3) {
|
||||
SCLogError("parse error, ret %" PRId32 "", ret);
|
||||
goto error;
|
||||
}
|
||||
|
||||
size_t pcre2len = sizeof(arg1);
|
||||
ret = pcre2_substring_copy_bynumber(match, 1, (PCRE2_UCHAR8 *)arg1, &pcre2len);
|
||||
if (ret < 0) {
|
||||
SCLogError("pcre2_substring_copy_bynumber failed");
|
||||
goto error;
|
||||
}
|
||||
SCLogDebug("Arg1 \"%s\"", arg1);
|
||||
|
||||
pcre2len = sizeof(arg2);
|
||||
ret = pcre2_substring_copy_bynumber(match, 2, (PCRE2_UCHAR8 *)arg2, &pcre2len);
|
||||
if (ret < 0) {
|
||||
SCLogError("pcre2_substring_copy_bynumber failed");
|
||||
goto error;
|
||||
}
|
||||
SCLogDebug("Arg2 \"%s\"", arg2);
|
||||
|
||||
DetectTemplateData *templated = SCMalloc(sizeof (DetectTemplateData));
|
||||
if (unlikely(templated == NULL))
|
||||
goto error;
|
||||
|
||||
if (ByteExtractStringUint8(&templated->arg1, 10, 0, (const char *)arg1) < 0) {
|
||||
SCFree(templated);
|
||||
goto error;
|
||||
}
|
||||
if (ByteExtractStringUint8(&templated->arg2, 10, 0, (const char *)arg2) < 0) {
|
||||
SCFree(templated);
|
||||
goto error;
|
||||
}
|
||||
pcre2_match_data_free(match);
|
||||
return templated;
|
||||
|
||||
error:
|
||||
if (match) {
|
||||
pcre2_match_data_free(match);
|
||||
}
|
||||
return NULL;
|
||||
SCDetectU8Free(ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief parse the options from the 'template' keyword in the rule into
|
||||
* the Signature data structure.
|
||||
* \brief this function is used to add the parsed template data into the current signature
|
||||
*
|
||||
* \param de_ctx pointer to the Detection Engine Context
|
||||
* \param s pointer to the Current Signature
|
||||
@@ -188,7 +92,7 @@ error:
|
||||
*/
|
||||
static int DetectTemplateSetup (DetectEngineCtx *de_ctx, Signature *s, const char *templatestr)
|
||||
{
|
||||
DetectTemplateData *templated = DetectTemplateParse(templatestr);
|
||||
DetectU8Data *templated = DetectU8Parse(templatestr);
|
||||
if (templated == NULL)
|
||||
return -1;
|
||||
|
||||
@@ -202,18 +106,82 @@ static int DetectTemplateSetup (DetectEngineCtx *de_ctx, Signature *s, const cha
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief this function will free memory associated with DetectTemplateData
|
||||
*
|
||||
* \param ptr pointer to DetectTemplateData
|
||||
*/
|
||||
static void DetectTemplateFree(DetectEngineCtx *de_ctx, void *ptr)
|
||||
/* prefilter code */
|
||||
|
||||
static void PrefilterPacketTemplateMatch(
|
||||
DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx)
|
||||
{
|
||||
DetectTemplateData *templated = (DetectTemplateData *)ptr;
|
||||
DEBUG_VALIDATE_BUG_ON(PKT_IS_PSEUDOPKT(p));
|
||||
|
||||
/* do more specific cleanup here, if needed */
|
||||
uint8_t ptemplate;
|
||||
/* TODO update */
|
||||
if (PacketIsIPv4(p)) {
|
||||
const IPV4Hdr *ip4h = PacketGetIPv4(p);
|
||||
ptemplate = IPV4_GET_RAW_IPTTL(ip4h);
|
||||
} else if (PacketIsIPv6(p)) {
|
||||
const IPV6Hdr *ip6h = PacketGetIPv6(p);
|
||||
ptemplate = IPV6_GET_RAW_HLIM(ip6h);
|
||||
} else {
|
||||
SCLogDebug("Packet is of not IPv4 or IPv6");
|
||||
return;
|
||||
}
|
||||
|
||||
SCFree(templated);
|
||||
/* during setup Suricata will automatically see if there is another
|
||||
* check that can be added: alproto, sport or dport */
|
||||
const PrefilterPacketHeaderCtx *ctx = pectx;
|
||||
if (!PrefilterPacketHeaderExtraMatch(ctx, p))
|
||||
return;
|
||||
|
||||
DetectU8Data du8;
|
||||
du8.mode = ctx->v1.u8[0];
|
||||
du8.arg1 = ctx->v1.u8[1];
|
||||
du8.arg2 = ctx->v1.u8[2];
|
||||
/* if we match, add all the sigs that use this prefilter. This means
|
||||
* that these will be inspected further */
|
||||
if (DetectU8Match(ptemplate, &du8)) {
|
||||
SCLogDebug("packet matches template/hl %u", ptemplate);
|
||||
PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
|
||||
}
|
||||
}
|
||||
|
||||
static int PrefilterSetupTemplate(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
|
||||
{
|
||||
return PrefilterSetupPacketHeader(de_ctx, sgh, DETECT_TEMPLATE, SIG_MASK_REQUIRE_REAL_PKT,
|
||||
PrefilterPacketU8Set, PrefilterPacketU8Compare, PrefilterPacketTemplateMatch);
|
||||
}
|
||||
|
||||
static bool PrefilterTemplateIsPrefilterable(const Signature *s)
|
||||
{
|
||||
return PrefilterIsPrefilterableById(s, DETECT_TEMPLATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Registration function for template: keyword
|
||||
*/
|
||||
|
||||
void DetectTemplateRegister(void)
|
||||
{
|
||||
/* keyword name: this is how the keyword is used in a rule */
|
||||
sigmatch_table[DETECT_TEMPLATE].name = "template";
|
||||
/* description: listed in "suricata --list-keywords=all" */
|
||||
sigmatch_table[DETECT_TEMPLATE].desc = "TODO describe the keyword";
|
||||
/* link to further documentation of the keyword. */
|
||||
sigmatch_table[DETECT_TEMPLATE].url = "/rules/header-keywords.html#template";
|
||||
/* match function is called when the signature is inspected on a packet */
|
||||
sigmatch_table[DETECT_TEMPLATE].Match = DetectTemplateMatch;
|
||||
/* setup function is called during signature parsing, when the template
|
||||
* keyword is encountered in the rule */
|
||||
sigmatch_table[DETECT_TEMPLATE].Setup = DetectTemplateSetup;
|
||||
/* free function is called when the detect engine is freed. Normally at
|
||||
* shutdown, but also during rule reloads. */
|
||||
sigmatch_table[DETECT_TEMPLATE].Free = DetectTemplateFree;
|
||||
sigmatch_table[DETECT_TEMPLATE].SupportsPrefilter = PrefilterTemplateIsPrefilterable;
|
||||
sigmatch_table[DETECT_TEMPLATE].SetupPrefilter = PrefilterSetupTemplate;
|
||||
sigmatch_table[DETECT_TEMPLATE].flags = SIGMATCH_INFO_UINT8;
|
||||
#ifdef UNITTESTS
|
||||
/* registers unittests into the system */
|
||||
sigmatch_table[DETECT_TEMPLATE].RegisterTests = DetectTemplateRegisterTests;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef UNITTESTS
|
||||
|
||||
@@ -24,16 +24,6 @@
|
||||
#ifndef SURICATA_DETECT_TEMPLATE_H
|
||||
#define SURICATA_DETECT_TEMPLATE_H
|
||||
|
||||
/** Per keyword data. This is set up by the DetectTemplateSetup() function.
|
||||
* Each signature will have an instance of DetectTemplateData per occurrence
|
||||
* of the keyword.
|
||||
* The structure should be considered static/readonly after initialization.
|
||||
*/
|
||||
typedef struct DetectTemplateData_ {
|
||||
uint8_t arg1;
|
||||
uint8_t arg2;
|
||||
} DetectTemplateData;
|
||||
|
||||
/** \brief registers the keyword into the engine. Called from
|
||||
* detect.c::SigTableSetup() */
|
||||
void DetectTemplateRegister(void);
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/* Copyright (C) 2007-2018 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 XXX
|
||||
*/
|
||||
|
||||
#ifndef _DETECT_TEMPLATE2_H
|
||||
#define _DETECT_TEMPLATE2_H
|
||||
|
||||
|
||||
void DetectTemplate2Register(void);
|
||||
|
||||
#endif /* _DETECT_TEMPLATE2_H */
|
||||
|
||||
@@ -29,9 +29,9 @@
|
||||
|
||||
static int DetectTemplateParseTest01 (void)
|
||||
{
|
||||
DetectTemplateData *templated = DetectTemplateParse("1,10");
|
||||
DetectU8Data *templated = DetectU8Parse("10");
|
||||
FAIL_IF_NULL(templated);
|
||||
FAIL_IF(!(templated->arg1 == 1 && templated->arg2 == 10));
|
||||
FAIL_IF(!(templated->arg1 == 10 && templated->mode == DetectUintModeEqual));
|
||||
DetectTemplateFree(NULL, templated);
|
||||
PASS;
|
||||
}
|
||||
@@ -45,7 +45,8 @@ static int DetectTemplateSignatureTest01 (void)
|
||||
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
|
||||
FAIL_IF_NULL(de_ctx);
|
||||
|
||||
Signature *sig = DetectEngineAppendSig(de_ctx, "alert ip any any -> any any (template:1,10; sid:1; rev:1;)");
|
||||
Signature *sig = DetectEngineAppendSig(
|
||||
de_ctx, "alert ip any any -> any any (template:<10; sid:1; rev:1;)");
|
||||
FAIL_IF_NULL(sig);
|
||||
|
||||
DetectEngineCtxFree(de_ctx);
|
||||
|
||||
Reference in New Issue
Block a user