suricata
detect-template.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2026 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author XXX
22  *
23  * XXX Short description of the purpose of this keyword
24  */
25 
26 #include "suricata-common.h"
27 
28 #include "detect.h"
29 #include "detect-parse.h"
31 #include "detect-engine-uint.h"
32 
33 #include "detect-template.h"
34 
35 #ifdef UNITTESTS
36 static void DetectTemplateRegisterTests (void);
37 #endif
38 
39 /**
40  * \brief This function is used to match TEMPLATE rule option on a packet with those passed via
41  * template:
42  *
43  * \param t pointer to thread vars
44  * \param det_ctx pointer to the pattern matcher thread
45  * \param p pointer to the current packet
46  * \param m pointer to the sigmatch that we will cast into DetectU8Data
47  *
48  * \retval 0 no match
49  * \retval 1 match
50  */
51 static int DetectTemplateMatch(
52  DetectEngineThreadCtx *det_ctx, Packet *p, const Signature *s, const SigMatchCtx *ctx)
53 {
55 
56  /* TODO replace this */
57  uint8_t ptemplate;
58  if (PacketIsIPv4(p)) {
59  const IPV4Hdr *ip4h = PacketGetIPv4(p);
60  ptemplate = IPV4_GET_RAW_IPTTL(ip4h);
61  } else if (PacketIsIPv6(p)) {
62  const IPV6Hdr *ip6h = PacketGetIPv6(p);
63  ptemplate = IPV6_GET_RAW_HLIM(ip6h);
64  } else {
65  SCLogDebug("Packet is of not IPv4 or IPv6");
66  return 0;
67  }
68 
69  const DetectU8Data *templated = (const DetectU8Data *)ctx;
70  return DetectU8Match(ptemplate, templated);
71 }
72 
73 /**
74  * \brief this function will free memory associated with DetectU8Data
75  *
76  * \param ptr pointer to DetectU8Data
77  */
78 static void DetectTemplateFree(DetectEngineCtx *de_ctx, void *ptr)
79 {
80  SCDetectU8Free(ptr);
81 }
82 
83 /**
84  * \brief this function is used to add the parsed template data into the current signature
85  *
86  * \param de_ctx pointer to the Detection Engine Context
87  * \param s pointer to the Current Signature
88  * \param templatestr pointer to the user provided template options
89  *
90  * \retval 0 on Success
91  * \retval -1 on Failure
92  */
93 static int DetectTemplateSetup (DetectEngineCtx *de_ctx, Signature *s, const char *templatestr)
94 {
95  DetectU8Data *templated = DetectU8Parse(templatestr);
96  if (templated == NULL)
97  return -1;
98 
100  DETECT_SM_LIST_MATCH) == NULL) {
101  DetectTemplateFree(de_ctx, templated);
102  return -1;
103  }
105 
106  return 0;
107 }
108 
109 /* prefilter code */
110 
111 static void PrefilterPacketTemplateMatch(
112  DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx)
113 {
115 
116  uint8_t ptemplate;
117  /* TODO update */
118  if (PacketIsIPv4(p)) {
119  const IPV4Hdr *ip4h = PacketGetIPv4(p);
120  ptemplate = IPV4_GET_RAW_IPTTL(ip4h);
121  } else if (PacketIsIPv6(p)) {
122  const IPV6Hdr *ip6h = PacketGetIPv6(p);
123  ptemplate = IPV6_GET_RAW_HLIM(ip6h);
124  } else {
125  SCLogDebug("Packet is of not IPv4 or IPv6");
126  return;
127  }
128 
129  /* during setup Suricata will automatically see if there is another
130  * check that can be added: alproto, sport or dport */
131  const PrefilterPacketHeaderCtx *ctx = pectx;
132  if (!PrefilterPacketHeaderExtraMatch(ctx, p))
133  return;
134 
135  DetectU8Data du8;
136  du8.mode = ctx->v1.u8[0];
137  du8.arg1 = ctx->v1.u8[1];
138  du8.arg2 = ctx->v1.u8[2];
139  /* if we match, add all the sigs that use this prefilter. This means
140  * that these will be inspected further */
141  if (DetectU8Match(ptemplate, &du8)) {
142  SCLogDebug("packet matches template/hl %u", ptemplate);
143  PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
144  }
145 }
146 
147 static int PrefilterSetupTemplate(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
148 {
150  PrefilterPacketU8Set, PrefilterPacketU8Compare, PrefilterPacketTemplateMatch);
151 }
152 
153 static bool PrefilterTemplateIsPrefilterable(const Signature *s)
154 {
155  return PrefilterIsPrefilterableById(s, DETECT_TEMPLATE);
156 }
157 
158 /**
159  * \brief Registration function for template: keyword
160  */
161 
163 {
164  /* keyword name: this is how the keyword is used in a rule */
165  sigmatch_table[DETECT_TEMPLATE].name = "template";
166  /* description: listed in "suricata --list-keywords=all" */
167  sigmatch_table[DETECT_TEMPLATE].desc = "TODO describe the keyword";
168  /* link to further documentation of the keyword. */
169  sigmatch_table[DETECT_TEMPLATE].url = "/rules/header-keywords.html#template";
170  /* match function is called when the signature is inspected on a packet */
171  sigmatch_table[DETECT_TEMPLATE].Match = DetectTemplateMatch;
172  /* setup function is called during signature parsing, when the template
173  * keyword is encountered in the rule */
174  sigmatch_table[DETECT_TEMPLATE].Setup = DetectTemplateSetup;
175  /* free function is called when the detect engine is freed. Normally at
176  * shutdown, but also during rule reloads. */
177  sigmatch_table[DETECT_TEMPLATE].Free = DetectTemplateFree;
178  sigmatch_table[DETECT_TEMPLATE].SupportsPrefilter = PrefilterTemplateIsPrefilterable;
179  sigmatch_table[DETECT_TEMPLATE].SetupPrefilter = PrefilterSetupTemplate;
181 #ifdef UNITTESTS
182  /* registers unittests into the system */
184 #endif
185 }
186 
187 #ifdef UNITTESTS
188 #include "tests/detect-template.c"
189 #endif
detect-engine-uint.h
SigTableElmt_::url
const char * url
Definition: detect.h:1471
DETECT_TEMPLATE
@ DETECT_TEMPLATE
Definition: detect-engine-register.h:265
DetectTemplateRegister
void DetectTemplateRegister(void)
Registration function for template: keyword.
Definition: detect-template.c:162
SIG_MASK_REQUIRE_REAL_PKT
#define SIG_MASK_REQUIRE_REAL_PKT
Definition: detect.h:316
SigTableElmt_::desc
const char * desc
Definition: detect.h:1470
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:79
IPV6_GET_RAW_HLIM
#define IPV6_GET_RAW_HLIM(ip6h)
Definition: decode-ipv6.h:67
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1455
SigTableElmt_::name
const char * name
Definition: detect.h:1468
PKT_IS_PSEUDOPKT
#define PKT_IS_PSEUDOPKT(p)
return 1 if the packet is a pseudo packet
Definition: decode.h:1346
SigGroupHead_
Container for matching data for a signature group.
Definition: detect.h:1638
SigTableElmt_::flags
uint32_t flags
Definition: detect.h:1459
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:282
SIGMATCH_INFO_UINT8
#define SIGMATCH_INFO_UINT8
Definition: detect-engine-register.h:342
DetectEngineThreadCtx_::pmq
PrefilterRuleStore pmq
Definition: detect.h:1358
ctx
struct Thresholds ctx
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:937
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1450
SigTableElmt_::SetupPrefilter
int(* SetupPrefilter)(DetectEngineCtx *de_ctx, struct SigGroupHead_ *sgh)
Definition: detect.h:1453
DetectU8Parse
DetectUintData_u8 * DetectU8Parse(const char *u8str)
This function is used to parse u8 options passed via some u8 keyword.
Definition: detect-engine-uint.c:85
PrefilterPacketHeaderCtx_
Definition: detect-engine-prefilter-common.h:35
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:19
DetectEngineThreadCtx_
Definition: detect.h:1252
SCSigMatchAppendSMToList
SigMatch * SCSigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:387
detect.h
DetectU8Data
DetectUintData_u8 DetectU8Data
Definition: detect-engine-uint.h:43
DETECT_SM_LIST_MATCH
@ DETECT_SM_LIST_MATCH
Definition: detect.h:117
PrefilterPacketU8Set
void PrefilterPacketU8Set(PrefilterPacketHeaderValue *v, void *smctx)
Definition: detect-engine-uint.c:90
Signature_::flags
uint32_t flags
Definition: detect.h:673
IPV6Hdr_
Definition: decode-ipv6.h:32
Packet_
Definition: decode.h:505
IPV4_GET_RAW_IPTTL
#define IPV4_GET_RAW_IPTTL(ip4h)
Definition: decode-ipv4.h:102
PrefilterSetupPacketHeader
int PrefilterSetupPacketHeader(DetectEngineCtx *de_ctx, SigGroupHead *sgh, int sm_type, SignatureMask mask, void(*Set)(PrefilterPacketHeaderValue *v, void *), bool(*Compare)(PrefilterPacketHeaderValue v, void *), void(*Match)(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx))
Definition: detect-engine-prefilter-common.c:470
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1430
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:351
IPV4Hdr_
Definition: decode-ipv4.h:72
detect-template.c
DetectU8Match
int DetectU8Match(const uint8_t parg, const DetectUintData_u8 *du8)
Definition: detect-engine-uint.c:71
suricata-common.h
detect-template.h
SigTableElmt_::SupportsPrefilter
bool(* SupportsPrefilter)(const Signature *s)
Definition: detect.h:1452
detect-parse.h
Signature_
Signature container.
Definition: detect.h:672
PrefilterPacketU8Compare
bool PrefilterPacketU8Compare(PrefilterPacketHeaderValue v, void *smctx)
Definition: detect-engine-uint.c:98
DetectTemplateRegisterTests
void DetectTemplateRegisterTests(void)
this function registers unit tests for DetectTemplate
Definition: detect-template.c:59
detect-engine-prefilter-common.h
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:102
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1457
SIG_FLAG_REQUIRE_PACKET
#define SIG_FLAG_REQUIRE_PACKET
Definition: detect.h:253