suricata
detect-ttl.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2020 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 Gurvinder Singh <gurvindersighdahiya@gmail.com>
22 * \author Victor Julien <victor@inliniac.net>
23 *
24 * Implements the ttl keyword including prefilter support.
25 */
26
27#include "suricata-common.h"
28#include "stream-tcp.h"
29
30#include "detect.h"
31#include "detect-parse.h"
33#include "detect-engine-uint.h"
34
35#include "detect-ttl.h"
36#include "util-debug.h"
37#include "util-byte.h"
38
39/* prototypes */
40static int DetectTtlMatch (DetectEngineThreadCtx *, Packet *,
41 const Signature *, const SigMatchCtx *);
42static int DetectTtlSetup (DetectEngineCtx *, Signature *, const char *);
43void DetectTtlFree (DetectEngineCtx *, void *);
44#ifdef UNITTESTS
45void DetectTtlRegisterTests (void);
46#endif
47static int PrefilterSetupTtl(DetectEngineCtx *de_ctx, SigGroupHead *sgh);
48static bool PrefilterTtlIsPrefilterable(const Signature *s);
49
50/**
51 * \brief Registration function for ttl: keyword
52 */
53
55{
57 sigmatch_table[DETECT_TTL].desc = "check for a specific IP time-to-live value";
58 sigmatch_table[DETECT_TTL].url = "/rules/header-keywords.html#ttl";
59 sigmatch_table[DETECT_TTL].Match = DetectTtlMatch;
60 sigmatch_table[DETECT_TTL].Setup = DetectTtlSetup;
62#ifdef UNITTESTS
64#endif
65 sigmatch_table[DETECT_TTL].SupportsPrefilter = PrefilterTtlIsPrefilterable;
66 sigmatch_table[DETECT_TTL].SetupPrefilter = PrefilterSetupTtl;
67}
68
69/**
70 * \brief This function is used to match TTL rule option on a packet with
71 * those passed via ttl
72 *
73 * \param t pointer to thread vars
74 * \param det_ctx pointer to the pattern matcher thread
75 * \param p pointer to the current packet
76 * \param m pointer to the sigmatch that we will cast into DetectU8Data
77 *
78 * \retval 0 no match
79 * \retval 1 match
80 */
81static int DetectTtlMatch (DetectEngineThreadCtx *det_ctx, Packet *p,
82 const Signature *s, const SigMatchCtx *ctx)
83{
85
86 uint8_t pttl;
87 if (PacketIsIPv4(p)) {
88 const IPV4Hdr *ip4h = PacketGetIPv4(p);
89 pttl = IPV4_GET_RAW_IPTTL(ip4h);
90 } else if (PacketIsIPv6(p)) {
91 const IPV6Hdr *ip6h = PacketGetIPv6(p);
92 pttl = IPV6_GET_RAW_HLIM(ip6h);
93 } else {
94 SCLogDebug("Packet is not IPv4 or IPv6");
95 return 0;
96 }
97
98 const DetectU8Data *ttld = (const DetectU8Data *)ctx;
99 return DetectU8Match(pttl, ttld);
100}
101
102/**
103 * \brief this function is used to attld the parsed ttl data into the current signature
104 *
105 * \param de_ctx pointer to the Detection Engine Context
106 * \param s pointer to the Current Signature
107 * \param ttlstr pointer to the user provided ttl options
108 *
109 * \retval 0 on Success
110 * \retval -1 on Failure
111 */
112static int DetectTtlSetup (DetectEngineCtx *de_ctx, Signature *s, const char *ttlstr)
113{
114 DetectU8Data *ttld = DetectU8Parse(ttlstr);
115 if (ttld == NULL)
116 return -1;
117
119 de_ctx, s, DETECT_TTL, (SigMatchCtx *)ttld, DETECT_SM_LIST_MATCH) == NULL) {
120 DetectTtlFree(de_ctx, ttld);
121 return -1;
122 }
124 return 0;
125}
126
127/**
128 * \brief this function will free memory associated with DetectU8Data
129 *
130 * \param ptr pointer to DetectU8Data
131 */
133{
134 SCDetectU8Free(ptr);
135}
136
137/* prefilter code */
138
139static void
140PrefilterPacketTtlMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx)
141{
143
144 uint8_t pttl;
145 if (PacketIsIPv4(p)) {
146 const IPV4Hdr *ip4h = PacketGetIPv4(p);
147 pttl = IPV4_GET_RAW_IPTTL(ip4h);
148 } else if (PacketIsIPv6(p)) {
149 const IPV6Hdr *ip6h = PacketGetIPv6(p);
150 pttl = IPV6_GET_RAW_HLIM(ip6h);
151 } else {
152 SCLogDebug("Packet is not IPv4 or IPv6");
153 return;
154 }
155
156 const PrefilterPacketHeaderCtx *ctx = pectx;
157 if (!PrefilterPacketHeaderExtraMatch(ctx, p))
158 return;
159
160 DetectU8Data du8;
161 du8.mode = ctx->v1.u8[0];
162 du8.arg1 = ctx->v1.u8[1];
163 du8.arg2 = ctx->v1.u8[2];
164 if (DetectU8Match(pttl, &du8)) {
165 SCLogDebug("packet matches ttl/hl %u", pttl);
166 PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
167 }
168}
169
170static int PrefilterSetupTtl(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
171{
173 PrefilterPacketU8Set, PrefilterPacketU8Compare, PrefilterPacketTtlMatch);
174}
175
176static bool PrefilterTtlIsPrefilterable(const Signature *s)
177{
178 const SigMatch *sm;
179 for (sm = s->init_data->smlists[DETECT_SM_LIST_MATCH] ; sm != NULL; sm = sm->next) {
180 switch (sm->type) {
181 case DETECT_TTL:
182 return true;
183 }
184 }
185 return false;
186}
187
188#ifdef UNITTESTS
189#include "tests/detect-ttl.c"
190#endif
#define IPV4_GET_RAW_IPTTL(ip4h)
#define IPV6_GET_RAW_HLIM(ip6h)
Definition decode-ipv6.h:67
#define PKT_IS_PSEUDOPKT(p)
return 1 if the packet is a pseudo packet
Definition decode.h:1321
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))
DetectUintData_u8 * DetectU8Parse(const char *u8str)
This function is used to parse u8 options passed via some u8 keyword.
void PrefilterPacketU8Set(PrefilterPacketHeaderValue *v, void *smctx)
int DetectU8Match(const uint8_t parg, const DetectUintData_u8 *du8)
bool PrefilterPacketU8Compare(PrefilterPacketHeaderValue v, void *smctx)
DetectUintData_u8 DetectU8Data
SigMatch * SCSigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
SigTableElmt * sigmatch_table
void DetectTtlRegister(void)
Registration function for ttl: keyword.
Definition detect-ttl.c:54
void DetectTtlFree(DetectEngineCtx *, void *)
this function will free memory associated with DetectU8Data
Definition detect-ttl.c:132
void DetectTtlRegisterTests(void)
this function registers unit tests for DetectTtl
Definition detect-ttl.c:212
#define SIG_FLAG_REQUIRE_PACKET
Definition detect.h:254
#define SIG_MASK_REQUIRE_REAL_PKT
Definition detect.h:316
@ DETECT_SM_LIST_MATCH
Definition detect.h:117
DetectEngineCtx * de_ctx
struct Thresholds ctx
main detection engine ctx
Definition detect.h:932
PrefilterRuleStore pmq
Definition detect.h:1349
Container for matching data for a signature group.
Definition detect.h:1629
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition detect.h:351
a single match condition for a signature
Definition detect.h:356
uint16_t type
Definition detect.h:357
struct SigMatch_ * next
Definition detect.h:360
const char * url
Definition detect.h:1462
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition detect.h:1441
int(* SetupPrefilter)(DetectEngineCtx *de_ctx, struct SigGroupHead_ *sgh)
Definition detect.h:1444
void(* Free)(DetectEngineCtx *, void *)
Definition detect.h:1446
const char * desc
Definition detect.h:1461
void(* RegisterTests)(void)
Definition detect.h:1448
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition detect.h:1421
const char * name
Definition detect.h:1459
bool(* SupportsPrefilter)(const Signature *s)
Definition detect.h:1443
struct SigMatch_ * smlists[DETECT_SM_LIST_MAX]
Definition detect.h:642
Signature container.
Definition detect.h:668
uint32_t flags
Definition detect.h:669
SignatureInitData * init_data
Definition detect.h:747
#define SCLogDebug(...)
Definition util-debug.h:275
#define DEBUG_VALIDATE_BUG_ON(exp)