suricata
detect-prefilter.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2016 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 Victor Julien <victor@inliniac.net>
22  *
23  * Implements the prefilter keyword
24  */
25 
26 #include "suricata-common.h"
27 #include "decode.h"
28 
29 #include "detect.h"
30 #include "detect-parse.h"
31 #include "detect-content.h"
33 #include "detect-engine-mpm.h"
34 #include "detect-prefilter.h"
35 #include "util-debug.h"
36 
37 static int DetectPrefilterSetup (DetectEngineCtx *, Signature *, const char *);
38 
40 {
41  sigmatch_table[DETECT_PREFILTER].name = "prefilter";
42  sigmatch_table[DETECT_PREFILTER].desc = "force a condition to be used as prefilter";
43  sigmatch_table[DETECT_PREFILTER].url = "/rules/prefilter-keywords.html#prefilter";
44  sigmatch_table[DETECT_PREFILTER].Setup = DetectPrefilterSetup;
46 }
47 
48 /**
49  * \internal
50  * \brief Apply the prefilter keyword to the last match
51  * \param det_ctx detection engine ctx
52  * \param s signature
53  * \param nullstr should be null
54  * \retval 0 ok
55  * \retval -1 failure
56  */
57 static int DetectPrefilterSetup (DetectEngineCtx *de_ctx, Signature *s, const char *nullstr)
58 {
59  SCEnter();
60 
61  if (nullstr != NULL) {
62  SCLogError("prefilter has value");
63  SCReturnInt(-1);
64  }
65 
66  if (s->flags & SIG_FLAG_PREFILTER) {
67  SCLogError("prefilter already set");
68  SCReturnInt(-1);
69  }
70 
71  SigMatch *sm = DetectGetLastSM(s);
72  if (sm == NULL) {
73  SCLogError("prefilter needs preceding match");
74  SCReturnInt(-1);
75  }
76 
77  /* if the sig match is content, prefilter should act like
78  * 'fast_pattern' w/o options. */
79  if (sm->type == DETECT_CONTENT) {
80  if (s->flags & SIG_FLAG_TXBOTHDIR && s->init_data->curbuf != NULL) {
83  SCLogError("prefilter cannot be used on to_client keyword for "
84  "transactional rule %u",
85  s->id);
86  SCReturnInt(-1);
87  } else {
89  }
90  }
91  }
92 
94  if ((cd->flags & DETECT_CONTENT_NEGATED) &&
95  ((cd->flags & DETECT_CONTENT_DISTANCE) ||
96  (cd->flags & DETECT_CONTENT_WITHIN) ||
97  (cd->flags & DETECT_CONTENT_OFFSET) ||
98  (cd->flags & DETECT_CONTENT_DEPTH)))
99  {
100  SCLogError("prefilter; cannot be "
101  "used with negated content, along with relative modifiers");
102  SCReturnInt(-1);
103  }
105  } else {
106  if (sigmatch_table[sm->type].SupportsPrefilter == NULL) {
107  SCLogError("prefilter is not supported for %s", sigmatch_table[sm->type].name);
108  SCReturnInt(-1);
109  }
110 
111  /* A multi-value app-layer-protocol keyword stores its values in a
112  * bitmask that the single-valued prefilter bucket key can't carry, so
113  * forcing prefilter would bucket the rule under ALPROTO_UNKNOWN and
114  * silently never match. */
115  if (sm->type == DETECT_APP_LAYER_PROTOCOL &&
116  ((const DetectAppLayerProtocolData *)sm->ctx)->is_list) {
117  SCLogError("prefilter is not supported for multi-value app-layer-protocol");
118  SCReturnInt(-1);
119  }
120 
121  /* make sure setup function runs for this type. */
122  de_ctx->sm_types_prefilter[sm->type] = true;
123  }
124 
125  s->init_data->prefilter_sm = sm;
126  SCLogDebug(
127  "sid %u: prefilter is on \"%s\" (%u)", s->id, sigmatch_table[sm->type].name, sm->type);
128 
129  SCReturnInt(0);
130 }
SigTableElmt_::url
const char * url
Definition: detect.h:1521
detect-content.h
detect-app-layer-protocol.h
SIGMATCH_NOOPT
#define SIGMATCH_NOOPT
Definition: detect-engine-register.h:306
SigTableElmt_::desc
const char * desc
Definition: detect.h:1520
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:79
SigTableElmt_::name
const char * name
Definition: detect.h:1518
DETECT_CONTENT
@ DETECT_CONTENT
Definition: detect-engine-register.h:76
SigTableElmt_::flags
uint32_t flags
Definition: detect.h:1509
SignatureInitData_::prefilter_sm
SigMatch * prefilter_sm
Definition: detect.h:632
Signature_::alproto
AppProto alproto
Definition: detect.h:687
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:282
SIG_FLAG_INIT_TXDIR_FAST_TOCLIENT
#define SIG_FLAG_INIT_TXDIR_FAST_TOCLIENT
Definition: detect.h:306
DetectAppLayerProtocolData_
Per-rule keyword data for app-layer-protocol:.
Definition: detect-app-layer-protocol.h:45
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:981
DETECT_PREFILTER
@ DETECT_PREFILTER
Definition: detect-engine-register.h:278
SIG_FLAG_TXBOTHDIR
#define SIG_FLAG_TXBOTHDIR
Definition: detect.h:249
SignatureInitData_::init_flags
uint32_t init_flags
Definition: detect.h:615
DetectContentData_
Definition: detect-content.h:93
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1500
DETECT_APP_LAYER_PROTOCOL
@ DETECT_APP_LAYER_PROTOCOL
Definition: detect-engine-register.h:35
decode.h
util-debug.h
DETECT_CONTENT_DISTANCE
#define DETECT_CONTENT_DISTANCE
Definition: detect-content.h:30
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:22
DETECT_CONTENT_DEPTH
#define DETECT_CONTENT_DEPTH
Definition: detect-content.h:33
SCEnter
#define SCEnter(...)
Definition: util-debug.h:284
detect-engine-mpm.h
detect.h
DetectEngineCtx_::sm_types_prefilter
bool * sm_types_prefilter
Definition: detect.h:1167
detect-prefilter.h
DETECT_CONTENT_NEGATED
#define DETECT_CONTENT_NEGATED
Definition: detect-content.h:40
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:359
DetectBufferToClient
bool DetectBufferToClient(const DetectEngineCtx *de_ctx, int buf_id, AppProto alproto)
Definition: detect-engine-mpm.c:1162
Signature_::flags
uint32_t flags
Definition: detect.h:683
DetectContentData_::flags
uint32_t flags
Definition: detect-content.h:104
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:761
DetectPrefilterRegister
void DetectPrefilterRegister(void)
Definition: detect-prefilter.c:39
DetectGetLastSM
SigMatch * DetectGetLastSM(const Signature *s)
Returns the sm with the largest index (added latest) from this sig.
Definition: detect-parse.c:708
suricata-common.h
SigMatch_::type
uint16_t type
Definition: detect.h:357
SignatureInitData_::curbuf
SignatureInitDataBuffer * curbuf
Definition: detect.h:664
SIG_FLAG_INIT_TXDIR_STREAMING_TOSERVER
#define SIG_FLAG_INIT_TXDIR_STREAMING_TOSERVER
Definition: detect.h:304
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:274
SigTableElmt_::SupportsPrefilter
bool(* SupportsPrefilter)(const Signature *s)
Definition: detect.h:1502
Signature_::id
uint32_t id
Definition: detect.h:727
DETECT_CONTENT_OFFSET
#define DETECT_CONTENT_OFFSET
Definition: detect-content.h:32
detect-parse.h
SignatureInitDataBuffer_::id
uint32_t id
Definition: detect.h:527
Signature_
Signature container.
Definition: detect.h:682
SigMatch_
a single match condition for a signature
Definition: detect.h:356
DETECT_CONTENT_FAST_PATTERN
#define DETECT_CONTENT_FAST_PATTERN
Definition: detect-content.h:34
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:288
SIG_FLAG_PREFILTER
#define SIG_FLAG_PREFILTER
Definition: detect.h:277
DETECT_CONTENT_WITHIN
#define DETECT_CONTENT_WITHIN
Definition: detect-content.h:31