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 Victor Julien <victor@inliniac.net>
22  */
23 
24 #ifndef __DETECT_H__
25 #define __DETECT_H__
26 
27 #include "suricata-common.h"
28 
29 #include "flow.h"
30 
31 #include "detect-engine-proto.h"
32 #include "detect-reference.h"
33 #include "detect-metadata.h"
34 #include "detect-engine-register.h"
35 #include "packet-queue.h"
36 
37 #include "util-prefilter.h"
38 #include "util-mpm.h"
39 #include "util-spm.h"
40 #include "util-hash.h"
41 #include "util-hashlist.h"
42 #include "util-debug.h"
43 #include "util-error.h"
44 #include "util-radix-tree.h"
45 #include "util-file.h"
46 #include "reputation.h"
47 
48 #include "detect-mark.h"
49 
50 #include "stream.h"
51 
52 #include "util-var-name.h"
53 
54 #include "app-layer-events.h"
55 
56 #define DETECT_MAX_RULE_SIZE 8192
57 
58 #define DETECT_TRANSFORMS_MAX 16
59 
60 /** default rule priority if not set through priority keyword or via
61  *  classtype. */
62 #define DETECT_DEFAULT_PRIO 3
63 
64 /* forward declarations for the structures from detect-engine-sigorder.h */
65 struct SCSigOrderFunc_;
66 struct SCSigSignatureWrapper_;
67 
68 /*
69   The detection engine groups similar signatures/rules together. Internally a
70   tree of different types of data is created on initialization. This is it's
71   global layout:
72 
73    For TCP/UDP
74 
75    - Flow direction
76    -- Protocol
77    -=- Dst port
78 
79    For the other protocols
80 
81    - Flow direction
82    -- Protocol
83 */
84 
85 /* holds the values for different possible lists in struct Signature.
86  * These codes are access points to particular lists in the array
87  * Signature->sm_lists[DETECT_SM_LIST_MAX]. */
88 enum DetectSigmatchListEnum {
89     DETECT_SM_LIST_MATCH = 0,
90     DETECT_SM_LIST_PMATCH,
91 
92     /* base64_data keyword uses some hardcoded logic so consider
93      * built-in
94      * TODO convert to inspect engine */
95     DETECT_SM_LIST_BASE64_DATA,
96 
97     /* list for post match actions: flowbit set, flowint increment, etc */
98     DETECT_SM_LIST_POSTMATCH,
99 
100     DETECT_SM_LIST_TMATCH, /**< post-detection tagging */
101 
102     /* lists for alert thresholding and suppression */
103     DETECT_SM_LIST_SUPPRESS,
104     DETECT_SM_LIST_THRESHOLD,
105 
106     DETECT_SM_LIST_MAX,
107 
108     /* start of dynamically registered lists */
109     DETECT_SM_LIST_DYNAMIC_START = DETECT_SM_LIST_MAX,
110 };
111 
112 /* used for Signature->list, which indicates which list
113  * we're adding keywords to in cases of sticky buffers like
114  * file_data */
115 #define DETECT_SM_LIST_NOTSET INT_MAX
116 
117 /*
118  * DETECT ADDRESS
119  */
120 
121 /* a is ... than b */
122 enum {
123     ADDRESS_ER = -1, /**< error e.g. compare ipv4 and ipv6 */
124     ADDRESS_LT,      /**< smaller              [aaa] [bbb] */
125     ADDRESS_LE,      /**< smaller with overlap [aa[bab]bb] */
126     ADDRESS_EQ,      /**< exactly equal        [abababab]  */
127     ADDRESS_ES,      /**< within               [bb[aaa]bb] and [[abab]bbb] and [bbb[abab]] */
128     ADDRESS_EB,      /**< completely overlaps  [aa[bbb]aa] and [[baba]aaa] and [aaa[baba]] */
129     ADDRESS_GE,      /**< bigger with overlap  [bb[aba]aa] */
130     ADDRESS_GT,      /**< bigger               [bbb] [aaa] */
131 };
132 
133 #define ADDRESS_FLAG_NOT            0x01 /**< address is negated */
134 
135 /** \brief address structure for use in the detection engine.
136  *
137  *  Contains the address information and matching information.
138  */
139 typedef struct DetectAddress_ {
140     /** address data for this group */
141     Address ip;
142     Address ip2;
143 
144     /** flags affecting this address */
145     uint8_t flags;
146 
147     /** ptr to the previous address in the list */
148     struct DetectAddress_ *prev;
149     /** ptr to the next address in the list */
150     struct DetectAddress_ *next;
151 } DetectAddress;
152 
153 /** Address grouping head. IPv4 and IPv6 are split out */
154 typedef struct DetectAddressHead_ {
155     DetectAddress *ipv4_head;
156     DetectAddress *ipv6_head;
157 } DetectAddressHead;
158 
159 
160 typedef struct DetectMatchAddressIPv4_ {
161     uint32_t ip;    /**< address in host order, start of range */
162     uint32_t ip2;   /**< address in host order, end of range */
163 } DetectMatchAddressIPv4;
164 
165 typedef struct DetectMatchAddressIPv6_ {
166     uint32_t ip[4];
167     uint32_t ip2[4];
168 } DetectMatchAddressIPv6;
169 
170 /*
171  * DETECT PORT
172  */
173 
174 /* a is ... than b */
175 enum {
176     PORT_ER = -1, /* error e.g. compare ipv4 and ipv6 */
177     PORT_LT,      /* smaller              [aaa] [bbb] */
178     PORT_LE,      /* smaller with overlap [aa[bab]bb] */
179     PORT_EQ,      /* exactly equal        [abababab]  */
180     PORT_ES,      /* within               [bb[aaa]bb] and [[abab]bbb] and [bbb[abab]] */
181     PORT_EB,      /* completely overlaps  [aa[bbb]aa] and [[baba]aaa] and [aaa[baba]] */
182     PORT_GE,      /* bigger with overlap  [bb[aba]aa] */
183     PORT_GT,      /* bigger               [bbb] [aaa] */
184 };
185 
186 #define PORT_FLAG_ANY           0x01 /**< 'any' special port */
187 #define PORT_FLAG_NOT           0x02 /**< negated port */
188 #define PORT_SIGGROUPHEAD_COPY  0x04 /**< sgh is a ptr copy */
189 
190 /** \brief Port structure for detection engine */
191 typedef struct DetectPort_ {
192     uint16_t port;
193     uint16_t port2;
194 
195     uint8_t flags;  /**< flags for this port */
196 
197     /* signatures that belong in this group
198      *
199      * If the PORT_SIGGROUPHEAD_COPY flag is set, we don't own this pointer
200      * (memory is freed elsewhere).
201      */
202     struct SigGroupHead_ *sh;
203 
204     struct DetectPort_ *prev;
205     struct DetectPort_ *next;
206 } DetectPort;
207 
208 /* Signature flags */
209 /** \note: additions should be added to the rule analyzer as well */
210 
211 #define SIG_FLAG_SRC_ANY                BIT_U32(0)  /**< source is any */
212 #define SIG_FLAG_DST_ANY                BIT_U32(1)  /**< destination is any */
213 #define SIG_FLAG_SP_ANY                 BIT_U32(2)  /**< source port is any */
214 #define SIG_FLAG_DP_ANY                 BIT_U32(3)  /**< destination port is any */
215 
216 #define SIG_FLAG_NOALERT                BIT_U32(4)  /**< no alert flag is set */
217 #define SIG_FLAG_DSIZE                  BIT_U32(5)  /**< signature has a dsize setting */
218 #define SIG_FLAG_APPLAYER               BIT_U32(6)  /**< signature applies to app layer instead of packets */
219 #define SIG_FLAG_IPONLY                 BIT_U32(7)  /**< ip only signature */
220 
221 // vacancy
222 
223 #define SIG_FLAG_REQUIRE_PACKET         BIT_U32(9)  /**< signature is requiring packet match */
224 #define SIG_FLAG_REQUIRE_STREAM         BIT_U32(10) /**< signature is requiring stream match */
225 
226 #define SIG_FLAG_MPM_NEG                BIT_U32(11)
227 
228 #define SIG_FLAG_FLUSH                  BIT_U32(12) /**< detection logic needs stream flush notification */
229 
230 // vacancies
231 
232 #define SIG_FLAG_REQUIRE_FLOWVAR        BIT_U32(17) /**< signature can only match if a flowbit, flowvar or flowint is available. */
233 
234 #define SIG_FLAG_FILESTORE              BIT_U32(18) /**< signature has filestore keyword */
235 
236 #define SIG_FLAG_TOSERVER               BIT_U32(19)
237 #define SIG_FLAG_TOCLIENT               BIT_U32(20)
238 
239 #define SIG_FLAG_TLSSTORE               BIT_U32(21)
240 
241 #define SIG_FLAG_BYPASS                 BIT_U32(22)
242 
243 #define SIG_FLAG_PREFILTER              BIT_U32(23) /**< sig is part of a prefilter engine */
244 
245 /** Proto detect only signature.
246  *  Inspected once per direction when protocol detection is done. */
247 #define SIG_FLAG_PDONLY                 BIT_U32(24)
248 /** Info for Source and Target identification */
249 #define SIG_FLAG_SRC_IS_TARGET          BIT_U32(25)
250 /** Info for Source and Target identification */
251 #define SIG_FLAG_DEST_IS_TARGET         BIT_U32(26)
252 
253 #define SIG_FLAG_HAS_TARGET             (SIG_FLAG_DEST_IS_TARGET|SIG_FLAG_SRC_IS_TARGET)
254 
255 /* signature init flags */
256 #define SIG_FLAG_INIT_DEONLY                BIT_U32(0)  /**< decode event only signature */
257 #define SIG_FLAG_INIT_PACKET                BIT_U32(1)  /**< signature has matches against a packet (as opposed to app layer) */
258 #define SIG_FLAG_INIT_FLOW                  BIT_U32(2)  /**< signature has a flow setting */
259 #define SIG_FLAG_INIT_BIDIREC               BIT_U32(3)  /**< signature has bidirectional operator */
260 #define SIG_FLAG_INIT_FIRST_IPPROTO_SEEN    BIT_U32(4)  /** < signature has seen the first ip_proto keyword */
261 #define SIG_FLAG_INIT_HAS_TRANSFORM         BIT_U32(5)
262 #define SIG_FLAG_INIT_STATE_MATCH           BIT_U32(6)  /**< signature has matches that require stateful inspection */
263 #define SIG_FLAG_INIT_NEED_FLUSH            BIT_U32(7)
264 #define SIG_FLAG_INIT_PRIO_EXPLICT          BIT_U32(8)  /**< priority is explicitly set by the priority keyword */
265 #define SIG_FLAG_INIT_FILEDATA              BIT_U32(9)  /**< signature has filedata keyword */
266 #define SIG_FLAG_INIT_DCERPC                BIT_U32(10) /**< signature has DCERPC keyword */
267 
268 /* signature mask flags */
269 /** \note: additions should be added to the rule analyzer as well */
270 #define SIG_MASK_REQUIRE_PAYLOAD            BIT_U8(0)
271 #define SIG_MASK_REQUIRE_FLOW               BIT_U8(1)
272 #define SIG_MASK_REQUIRE_FLAGS_INITDEINIT   BIT_U8(2)    /* SYN, FIN, RST */
273 #define SIG_MASK_REQUIRE_FLAGS_UNUSUAL      BIT_U8(3)    /* URG, ECN, CWR */
274 #define SIG_MASK_REQUIRE_NO_PAYLOAD         BIT_U8(4)
275 #define SIG_MASK_REQUIRE_DCERPC             BIT_U8(5)    /* require either SMB+DCE or raw DCE */
276 // vacancy
277 #define SIG_MASK_REQUIRE_ENGINE_EVENT       BIT_U8(7)
278 
279 /* for now a uint8_t is enough */
280 #define SignatureMask uint8_t
281 
282 #define DETECT_ENGINE_THREAD_CTX_STREAM_CONTENT_MATCH 0x0004
283 
284 #define FILE_SIG_NEED_FILE          0x01
285 #define FILE_SIG_NEED_FILENAME      0x02
286 #define FILE_SIG_NEED_MAGIC         0x04    /**< need the start of the file */
287 #define FILE_SIG_NEED_FILECONTENT   0x08
288 #define FILE_SIG_NEED_MD5           0x10
289 #define FILE_SIG_NEED_SHA1          0x20
290 #define FILE_SIG_NEED_SHA256        0x40
291 #define FILE_SIG_NEED_SIZE          0x80
292 
293 /* Detection Engine flags */
294 #define DE_QUIET           0x01     /**< DE is quiet (esp for unittests) */
295 
296 typedef struct IPOnlyCIDRItem_ {
297     /* address data for this item */
298     uint8_t family;
299     /* netmask in CIDR values (ex. /16 /18 /24..) */
300     uint8_t netmask;
301     /* If this host or net is negated for the signum */
302     uint8_t negated;
303 
304     uint32_t ip[4];
305     SigIntId signum; /**< our internal id */
306 
307     /* linked list, the header should be the biggest network */
308     struct IPOnlyCIDRItem_ *next;
309 
310 } IPOnlyCIDRItem;
311 
312 /** \brief Used to start a pointer to SigMatch context
313  * Should never be dereferenced without casting to something else.
314  */
315 typedef struct SigMatchCtx_ {
316     int foo;
317 } SigMatchCtx;
318 
319 /** \brief a single match condition for a signature */
320 typedef struct SigMatch_ {
321     uint8_t type; /**< match type */
322     uint16_t idx; /**< position in the signature */
323     SigMatchCtx *ctx; /**< plugin specific data */
324     struct SigMatch_ *next;
325     struct SigMatch_ *prev;
326 } SigMatch;
327 
328 /** \brief Data needed for Match() */
329 typedef struct SigMatchData_ {
330     uint8_t type; /**< match type */
331     uint8_t is_last; /**< Last element of the list */
332     SigMatchCtx *ctx; /**< plugin specific data */
333 } SigMatchData;
334 
335 struct DetectEngineThreadCtx_;// DetectEngineThreadCtx;
336 
337 /* inspection buffer is a simple structure that is passed between prefilter,
338  * transformation functions and inspection functions.
339  * Initially setup with 'orig' ptr and len, transformations can then take
340  * then and fill the 'buf'. Multiple transformations can update the buffer,
341  * both growing and shrinking it.
342  * Prefilter and inspection will only deal with 'inspect'. */
343 
344 typedef struct InspectionBuffer {
345     const uint8_t *inspect; /**< active pointer, points either to ::buf or ::orig */
346     uint64_t inspect_offset;
347     uint32_t inspect_len;   /**< size of active data. See to ::len or ::orig_len */
348     uint8_t flags;          /**< DETECT_CI_FLAGS_* for use with DetectEngineContentInspection */
349 #ifdef DEBUG_VALIDATION
350     bool multi;
351 #endif
352     uint32_t len;           /**< how much is in use */
353     uint8_t *buf;
354     uint32_t size;          /**< size of the memory allocation */
355 
356     uint32_t orig_len;
357     const uint8_t *orig;
358 } InspectionBuffer;
359 
360 /* inspection buffers are kept per tx (in det_ctx), but some protocols
361  * need a bit more. A single TX might have multiple buffers, e.g. files in
362  * SMTP or DNS queries. Since all prefilters+transforms run before the
363  * individual rules need the same buffers, we need a place to store the
364  * transformed data. This array of arrays is that place. */
365 
366 typedef struct InspectionBufferMultipleForList {
367     InspectionBuffer *inspection_buffers;
368     uint32_t size;      /**< size in number of elements */
369     uint32_t max:31;    /**< max id in use in this run */
370     uint32_t init:1;    /**< first time used this run. Used for clean logic */
371 } InspectionBufferMultipleForList;
372 
373 typedef struct TransformData_ {
374     int transform;
375     void *options;
376 } TransformData;
377 
378 typedef struct DetectEngineTransforms {
379     TransformData transforms[DETECT_TRANSFORMS_MAX];
380     int cnt;
381 } DetectEngineTransforms;
382 
383 /** callback for getting the buffer we need to prefilter/inspect */
384 typedef InspectionBuffer *(*InspectionBufferGetDataPtr)(
385         struct DetectEngineThreadCtx_ *det_ctx,
386         const DetectEngineTransforms *transforms,
387         Flow *f, const uint8_t flow_flags,
388         void *txv, const int list_id);
389 
390 typedef int (*InspectEngineFuncPtr)(ThreadVars *tv,
391         struct DetectEngineCtx_ *de_ctx, struct DetectEngineThreadCtx_ *det_ctx,
392         const struct Signature_ *sig, const SigMatchData *smd,
393         Flow *f, uint8_t flags, void *alstate,
394         void *tx, uint64_t tx_id);
395 
396 struct DetectEngineAppInspectionEngine_;
397 
398 typedef int (*InspectEngineFuncPtr2)(
399         struct DetectEngineCtx_ *de_ctx, struct DetectEngineThreadCtx_ *det_ctx,
400         const struct DetectEngineAppInspectionEngine_ *engine,
401         const struct Signature_ *s,
402         Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id);
403 
404 typedef struct DetectEngineAppInspectionEngine_ {
405     AppProto alproto;
406     uint8_t dir;
407     uint8_t id;     /**< per sig id used in state keeping */
408     bool mpm;
409     bool stream;
410     uint16_t sm_list;
411     uint16_t sm_list_base; /**< base buffer being transformed */
412     int16_t progress;
413 
414     /* \retval 0 No match.  Don't discontinue matching yet.  We need more data.
415      *         1 Match.
416      *         2 Sig can't match.
417      *         3 Special value used by filestore sigs to indicate disabling
418      *           filestore for the tx.
419      */
420     InspectEngineFuncPtr Callback;
421 
422     struct {
423         InspectionBufferGetDataPtr GetData;
424         InspectEngineFuncPtr2 Callback;
425         /** pointer to the transforms in the 'DetectBuffer entry for this list */
426         const DetectEngineTransforms *transforms;
427     } v2;
428 
429     SigMatchData *smd;
430 
431     struct DetectEngineAppInspectionEngine_ *next;
432 } DetectEngineAppInspectionEngine;
433 
434 typedef struct DetectBufferType_ {
435     const char *string;
436     const char *description;
437     int id;
438     int parent_id;
439     bool mpm;
440     bool packet; /**< compat to packet matches */
441     bool supports_transforms;
442     void (*SetupCallback)(const struct DetectEngineCtx_ *, struct Signature_ *);
443     bool (*ValidateCallback)(const struct Signature_ *, const char **sigerror);
444     DetectEngineTransforms transforms;
445 } DetectBufferType;
446 
447 struct DetectEnginePktInspectionEngine;
448 
449 /**
450  *  \param alert_flags[out] for setting PACKET_ALERT_FLAG_*
451  */
452 typedef int (*InspectionBufferPktInspectFunc)(
453         struct DetectEngineThreadCtx_ *,
454         const struct DetectEnginePktInspectionEngine *engine,
455         const struct Signature_ *s,
456         Packet *p, uint8_t *alert_flags);
457 
458 /** callback for getting the buffer we need to prefilter/inspect */
459 typedef InspectionBuffer *(*InspectionBufferGetPktDataPtr)(
460         struct DetectEngineThreadCtx_ *det_ctx,
461         const DetectEngineTransforms *transforms,
462         Packet *p, const int list_id);
463 
464 typedef struct DetectEnginePktInspectionEngine {
465     SigMatchData *smd;
466     bool mpm;
467     uint16_t sm_list;
468     uint16_t sm_list_base;
469     struct {
470         InspectionBufferGetPktDataPtr GetData;
471         InspectionBufferPktInspectFunc Callback;
472         /** pointer to the transforms in the 'DetectBuffer entry for this list */
473         const DetectEngineTransforms *transforms;
474     } v1;
475     struct DetectEnginePktInspectionEngine *next;
476 } DetectEnginePktInspectionEngine;
477 
478 #ifdef UNITTESTS
479 #define sm_lists init_data->smlists
480 #define sm_lists_tail init_data->smlists_tail
481 #endif
482 
483 typedef struct SignatureInitData_ {
484     /** Number of sigmatches. Used for assigning SigMatch::idx */
485     uint16_t sm_cnt;
486 
487     /** option was prefixed with '!'. Only set for sigmatches that
488      *  have the SIGMATCH_HANDLE_NEGATION flag set. */
489     bool negated;
490 
491     /* track if we saw any negation in the addresses. If so, we
492      * skip it for ip-only */
493     bool src_contains_negation;
494     bool dst_contains_negation;
495 
496     /* used to hold flags that are used during init */
497     uint32_t init_flags;
498     /* coccinelle: SignatureInitData:init_flags:SIG_FLAG_INIT_ */
499 
500     /* used at init to determine max dsize */
501     SigMatch *dsize_sm;
502 
503     /* the fast pattern added from this signature */
504     SigMatch *mpm_sm;
505     /* used to speed up init of prefilter */
506     SigMatch *prefilter_sm;
507 
508     /* SigMatch list used for adding content and friends. E.g. file_data; */
509     int list;
510     bool list_set;
511 
512     DetectEngineTransforms transforms;
513 
514     /** score to influence rule grouping. A higher value leads to a higher
515      *  likelihood of a rulegroup with this sig ending up as a contained
516      *  group. */
517     int whitelist;
518 
519     /** address settings for this signature */
520     const DetectAddressHead *src, *dst;
521 
522     int prefilter_list;
523 
524     uint32_t smlists_array_size;
525     /* holds all sm lists */
526     struct SigMatch_ **smlists;
527     /* holds all sm lists' tails */
528     struct SigMatch_ **smlists_tail;
529 } SignatureInitData;
530 
531 /** \brief Signature container */
532 typedef struct Signature_ {
533     uint32_t flags;
534     /* coccinelle: Signature:flags:SIG_FLAG_ */
535 
536     AppProto alproto;
537 
538     uint16_t dsize_low;
539     uint16_t dsize_high;
540 
541     SignatureMask mask;
542     SigIntId num; /**< signature number, internal id */
543 
544     /** inline -- action */
545     uint8_t action;
546     uint8_t file_flags;
547 
548     /** addresses, ports and proto this sig matches on */
549     DetectProto proto;
550 
551     /** classification id **/
552     uint16_t class_id;
553 
554     /** ipv4 match arrays */
555     uint16_t addr_dst_match4_cnt;
556     uint16_t addr_src_match4_cnt;
557     uint16_t addr_dst_match6_cnt;
558     uint16_t addr_src_match6_cnt;
559     DetectMatchAddressIPv4 *addr_dst_match4;
560     DetectMatchAddressIPv4 *addr_src_match4;
561     /** ipv6 match arrays */
562     DetectMatchAddressIPv6 *addr_dst_match6;
563     DetectMatchAddressIPv6 *addr_src_match6;
564 
565     uint32_t id;  /**< sid, set by the 'sid' rule keyword */
566     uint32_t gid; /**< generator id */
567     uint32_t rev;
568     int prio;
569 
570     /** port settings for this signature */
571     DetectPort *sp, *dp;
572 
573 #ifdef PROFILING
574     uint16_t profiling_id;
575 #endif
576 
577     /** netblocks and hosts specified at the sid, in CIDR format */
578     IPOnlyCIDRItem *CidrSrc, *CidrDst;
579 
580     DetectEngineAppInspectionEngine *app_inspect;
581     DetectEnginePktInspectionEngine *pkt_inspect;
582 
583     /* Matching structures for the built-ins. The others are in
584      * their inspect engines. */
585     SigMatchData *sm_arrays[DETECT_SM_LIST_MAX];
586 
587     /* memory is still owned by the sm_lists/sm_arrays entry */
588     const struct DetectFilestoreData_ *filestore_ctx;
589 
590     char *msg;
591 
592     /** classification message */
593     char *class_msg;
594     /** Reference */
595     DetectReference *references;
596     /** Metadata */
597     DetectMetadataHead *metadata;
598 
599     char *sig_str;
600 
601     SignatureInitData *init_data;
602 
603     /** ptr to the next sig in the list */
604     struct Signature_ *next;
605 } Signature;
606 
607 enum DetectBufferMpmType {
608     DETECT_BUFFER_MPM_TYPE_PKT,
609     DETECT_BUFFER_MPM_TYPE_APP,
610     /* must be last */
611     DETECT_BUFFER_MPM_TYPE_SIZE,
612 };
613 
614 /** \brief one time registration of keywords at start up */
615 typedef struct DetectBufferMpmRegistery_ {
616     const char *name;
617     char pname[32];             /**< name used in profiling */
618     int direction;              /**< SIG_FLAG_TOSERVER or SIG_FLAG_TOCLIENT */
619     int16_t sm_list;
620     int16_t sm_list_base;
621     int priority;
622     int id;                     /**< index into this array and result arrays */
623     enum DetectBufferMpmType type;
624     int sgh_mpm_context;
625 
626     int (*PrefilterRegisterWithListId)(struct DetectEngineCtx_ *de_ctx,
627             struct SigGroupHead_ *sgh, MpmCtx *mpm_ctx,
628             const struct DetectBufferMpmRegistery_ *mpm_reg, int list_id);
629     DetectEngineTransforms transforms;
630 
631     union {
632         /* app-layer matching: use if type == DETECT_BUFFER_MPM_TYPE_APP */
633         struct {
634             InspectionBufferGetDataPtr GetData;
635             AppProto alproto;
636             int tx_min_progress;
637         } app_v2;
638 
639         /* pkt matching: use if type == DETECT_BUFFER_MPM_TYPE_PKT */
640         struct {
641             int (*PrefilterRegisterWithListId)(struct DetectEngineCtx_ *de_ctx,
642                     struct SigGroupHead_ *sgh, MpmCtx *mpm_ctx,
643                     const struct DetectBufferMpmRegistery_ *mpm_reg, int list_id);
644             InspectionBufferGetPktDataPtr GetData;
645         } pkt_v1;
646     };
647 
648     struct DetectBufferMpmRegistery_ *next;
649 } DetectBufferMpmRegistery;
650 
651 typedef struct DetectReplaceList_ {
652     struct DetectContentData_ *cd;
653     uint8_t *found;
654     struct DetectReplaceList_ *next;
655 } DetectReplaceList;
656 
657 /** only execute flowvar storage if rule matched */
658 #define DETECT_VAR_TYPE_FLOW_POSTMATCH      1
659 #define DETECT_VAR_TYPE_PKT_POSTMATCH       2
660 
661 /** list for flowvar store candidates, to be stored from
662  *  post-match function */
663 typedef struct DetectVarList_ {
664     uint32_t idx;                       /**< flowvar name idx */
665     uint16_t len;                       /**< data len */
666     uint16_t key_len;
667     int type;                           /**< type of store candidate POSTMATCH or ALWAYS */
668     uint8_t *key;
669     uint8_t *buffer;                    /**< alloc'd buffer, may be freed by
670                                              post-match, post-non-match */
671     struct DetectVarList_ *next;
672 } DetectVarList;
673 
674 typedef struct DetectEngineIPOnlyThreadCtx_ {
675     uint8_t *sig_match_array; /* bit array of sig nums */
676     uint32_t sig_match_size;  /* size in bytes of the array */
677 } DetectEngineIPOnlyThreadCtx;
678 
679 /** \brief IP only rules matching ctx. */
680 typedef struct DetectEngineIPOnlyCtx_ {
681     /* lookup hashes */
682     HashListTable *ht16_src, *ht16_dst;
683     HashListTable *ht24_src, *ht24_dst;
684 
685     /* Lookup trees */
686     SCRadixTree *tree_ipv4src, *tree_ipv4dst;
687     SCRadixTree *tree_ipv6src, *tree_ipv6dst;
688 
689     /* Used to build the radix trees */
690     IPOnlyCIDRItem *ip_src, *ip_dst;
691 
692     /* counters */
693     uint32_t a_src_uniq16, a_src_total16;
694     uint32_t a_dst_uniq16, a_dst_total16;
695     uint32_t a_src_uniq24, a_src_total24;
696     uint32_t a_dst_uniq24, a_dst_total24;
697 
698     uint32_t max_idx;
699 
700     uint8_t *sig_init_array; /* bit array of sig nums */
701     uint32_t sig_init_size;  /* size in bytes of the array */
702 
703     /* number of sigs in this head */
704     uint32_t sig_cnt;
705     uint32_t *match_array;
706 } DetectEngineIPOnlyCtx;
707 
708 typedef struct DetectEngineLookupFlow_ {
709     DetectPort *tcp;
710     DetectPort *udp;
711     struct SigGroupHead_ *sgh[256];
712 } DetectEngineLookupFlow;
713 
714 #include "detect-threshold.h"
715 
716 /** \brief threshold ctx */
717 typedef struct ThresholdCtx_    {
718     SCMutex threshold_table_lock;                   /**< Mutex for hash table */
719 
720     /** to support rate_filter "by_rule" option */
721     DetectThresholdEntry **th_entry;
722     uint32_t th_size;
723 } ThresholdCtx;
724 
725 typedef struct SigString_ {
726     char *filename;
727     char *sig_str;
728     char *sig_error;
729     int line;
730     TAILQ_ENTRY(SigString_) next;
731 } SigString;
732 
733 /** \brief Signature loader statistics */
734 typedef struct SigFileLoaderStat_ {
735     TAILQ_HEAD(, SigString_) failed_sigs;
736     int bad_files;
737     int total_files;
738     int good_sigs_total;
739     int bad_sigs_total;
740 } SigFileLoaderStat;
741 
742 typedef struct DetectEngineThreadKeywordCtxItem_ {
743     void *(*InitFunc)(void *);
744     void (*FreeFunc)(void *);
745     void *data;
746     struct DetectEngineThreadKeywordCtxItem_ *next;
747     int id;
748     const char *name; /* keyword name, for error printing */
749 } DetectEngineThreadKeywordCtxItem;
750 
751 enum DetectEnginePrefilterSetting
752 {
753     DETECT_PREFILTER_MPM = 0,   /**< use only mpm / fast_pattern */
754     DETECT_PREFILTER_AUTO = 1,  /**< use mpm + keyword prefilters */
755 };
756 
757 enum DetectEngineType
758 {
759     DETECT_ENGINE_TYPE_NORMAL = 0,
760     DETECT_ENGINE_TYPE_DD_STUB = 1, /* delayed detect stub: can be reloaded */
761     DETECT_ENGINE_TYPE_MT_STUB = 2, /* multi-tenant stub: cannot be reloaded */
762     DETECT_ENGINE_TYPE_TENANT = 3,
763 };
764 
765 /* Flow states:
766  *  toserver
767  *  toclient
768  */
769 #define FLOW_STATES 2
770 
771 /** \brief main detection engine ctx */
772 typedef struct DetectEngineCtx_ {
773     uint8_t flags;
774     int failure_fatal;
775 
776     int tenant_id;
777 
778     Signature *sig_list;
779     uint32_t sig_cnt;
780 
781     /* version of the srep data */
782     uint32_t srep_version;
783 
784     /* reputation for netblocks */
785     SRepCIDRTree *srepCIDR_ctx;
786 
787     Signature **sig_array;
788     uint32_t sig_array_size; /* size in bytes */
789     uint32_t sig_array_len;  /* size in array members */
790 
791     uint32_t signum;
792 
793     /** Maximum value of all our sgh's non_mpm_store_cnt setting,
794      *  used to alloc det_ctx::non_mpm_id_array */
795     uint32_t non_pf_store_cnt_max;
796 
797     /* used by the signature ordering module */
798     struct SCSigOrderFunc_ *sc_sig_order_funcs;
799 
800     /* hash table used for holding the classification config info */
801     HashTable *class_conf_ht;
802     /* hash table used for holding the reference config info */
803     HashTable *reference_conf_ht;
804 
805     /* main sigs */
806     DetectEngineLookupFlow flow_gh[FLOW_STATES];
807 
808     uint32_t gh_unique, gh_reuse;
809 
810     /* init phase vars */
811     HashListTable *sgh_hash_table;
812 
813     HashListTable *mpm_hash_table;
814 
815     /* hash table used to cull out duplicate sigs */
816     HashListTable *dup_sig_hash_table;
817 
818     DetectEngineIPOnlyCtx io_ctx;
819     ThresholdCtx ths_ctx;
820 
821     uint16_t mpm_matcher; /**< mpm matcher this ctx uses */
822     uint16_t spm_matcher; /**< spm matcher this ctx uses */
823 
824     /* spm thread context prototype, built as spm matchers are constructed and
825      * later used to construct thread context for each thread. */
826     SpmGlobalThreadCtx *spm_global_thread_ctx;
827 
828     /* Config options */
829 
830     uint16_t max_uniq_toclient_groups;
831     uint16_t max_uniq_toserver_groups;
832 
833     /* specify the configuration for mpm context factory */
834     uint8_t sgh_mpm_ctx_cnf;
835 
836     /* max flowbit id that is used */
837     uint32_t max_fb_id;
838 
839     uint32_t max_fp_id;
840 
841     MpmCtxFactoryContainer *mpm_ctx_factory_container;
842 
843     /* maximum recursion depth for content inspection */
844     int inspection_recursion_limit;
845 
846     /* conf parameter that limits the length of the http request body inspected */
847     int hcbd_buffer_limit;
848     /* conf parameter that limits the length of the http response body inspected */
849     int hsbd_buffer_limit;
850 
851     /* array containing all sgh's in use so we can loop
852      * through it in Stage4. */
853     struct SigGroupHead_ **sgh_array;
854     uint32_t sgh_array_cnt;
855     uint32_t sgh_array_size;
856 
857     int32_t sgh_mpm_context_proto_tcp_packet;
858     int32_t sgh_mpm_context_proto_udp_packet;
859     int32_t sgh_mpm_context_proto_other_packet;
860     int32_t sgh_mpm_context_stream;
861 
862     /* the max local id used amongst all sigs */
863     int32_t byte_extract_max_local_id;
864 
865     /** version of the detect engine. The version is incremented on reloads */
866     uint32_t version;
867 
868     /** sgh for signatures that match against invalid packets. In those cases
869      *  we can't lookup by proto, address, port as we don't have these */
870     struct SigGroupHead_ *decoder_event_sgh;
871 
872     /* Maximum size of the buffer for decoded base64 data. */
873     uint32_t base64_decode_max_len;
874 
875     /** Store rule file and line so that parsers can use them in errors. */
876     char *rule_file;
877     int rule_line;
878     bool sigerror_silent;
879     bool sigerror_ok;
880     const char *sigerror;
881 
882     /** list of keywords that need thread local ctxs */
883     DetectEngineThreadKeywordCtxItem *keyword_list;
884     int keyword_id;
885 
886     struct {
887         uint32_t content_limit;
888         uint32_t content_inspect_min_size;
889         uint32_t content_inspect_window;
890     } filedata_config[ALPROTO_MAX];
891     bool filedata_config_initialized;
892 
893 #ifdef PROFILING
894     struct SCProfileDetectCtx_ *profile_ctx;
895     struct SCProfileKeywordDetectCtx_ *profile_keyword_ctx;
896     struct SCProfilePrefilterDetectCtx_ *profile_prefilter_ctx;
897     struct SCProfileKeywordDetectCtx_ **profile_keyword_ctx_per_list;
898     struct SCProfileSghDetectCtx_ *profile_sgh_ctx;
899     uint32_t profile_match_logging_threshold;
900 #endif
901     uint32_t prefilter_maxid;
902 
903     char config_prefix[64];
904 
905     enum DetectEngineType type;
906 
907     /** how many de_ctx' are referencing this */
908     uint32_t ref_cnt;
909     /** list in master: either active or freelist */
910     struct DetectEngineCtx_ *next;
911 
912     /** id of loader thread 'owning' this de_ctx */
913     int loader_id;
914 
915     /** are we using just mpm or also other prefilters */
916     enum DetectEnginePrefilterSetting prefilter_setting;
917 
918     HashListTable *dport_hash_table;
919 
920     DetectPort *tcp_whitelist;
921     DetectPort *udp_whitelist;
922 
923     /** table for storing the string representation with the parsers result */
924     HashListTable *address_table;
925 
926     /** table to store metadata keys and values */
927     HashTable *metadata_table;
928 
929     DetectBufferType **buffer_type_map;
930     uint32_t buffer_type_map_elements;
931 
932     /* hash table with rule-time buffer registration. Start time registration
933      * is in detect-engine.c::g_buffer_type_hash */
934     HashListTable *buffer_type_hash;
935     int buffer_type_id;
936 
937     /* list with app inspect engines. Both the start-time registered ones and
938      * the rule-time registered ones. */
939     DetectEngineAppInspectionEngine *app_inspect_engines;
940     DetectBufferMpmRegistery *app_mpms_list;
941     uint32_t app_mpms_list_cnt;
942     DetectEnginePktInspectionEngine *pkt_inspect_engines;
943     DetectBufferMpmRegistery *pkt_mpms_list;
944     uint32_t pkt_mpms_list_cnt;
945 
946     uint32_t prefilter_id;
947     HashListTable *prefilter_hash_table;
948 
949     /** time of last ruleset reload */
950     struct timeval last_reload;
951 
952     /** signatures stats */
953     SigFileLoaderStat sig_stat;
954 
955     /** per keyword flag indicating if a prefilter has been
956      *  set for it. If true, the setup function will have to
957      *  run. */
958     bool sm_types_prefilter[DETECT_TBLSIZE];
959     bool sm_types_silent_error[DETECT_TBLSIZE];
960 
961 } DetectEngineCtx;
962 
963 /* Engine groups profiles (low, medium, high, custom) */
964 enum {
965     ENGINE_PROFILE_UNKNOWN,
966     ENGINE_PROFILE_LOW,
967     ENGINE_PROFILE_MEDIUM,
968     ENGINE_PROFILE_HIGH,
969     ENGINE_PROFILE_CUSTOM,
970     ENGINE_PROFILE_MAX
971 };
972 
973 /* Siggroup mpm context profile */
974 enum {
975     ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL = 0,
976     ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE,
977     ENGINE_SGH_MPM_FACTORY_CONTEXT_AUTO,
978 #define ENGINE_SGH_MPM_FACTORY_CONTEXT_START_ID_RANGE (ENGINE_SGH_MPM_FACTORY_CONTEXT_AUTO + 1)
979 };
980 
981 typedef struct HttpReassembledBody_ {
982     const uint8_t *buffer;
983     uint8_t *decompressed_buffer;
984     uint32_t buffer_size;   /**< size of the buffer itself */
985     uint32_t buffer_len;    /**< data len in the buffer */
986     uint32_t decompressed_buffer_len;
987     uint64_t offset;        /**< data offset */
988 } HttpReassembledBody;
989 
990 #define DETECT_FILESTORE_MAX 15
991 
992 typedef struct SignatureNonPrefilterStore_ {
993     SigIntId id;
994     SignatureMask mask;
995     uint8_t alproto;
996 } SignatureNonPrefilterStore;
997 
998 /** array of TX inspect rule candidates */
999 typedef struct RuleMatchCandidateTx {
1000     SigIntId id;            /**< internal signature id */
1001     uint32_t *flags;        /**< inspect flags ptr */
1002     union {
1003         struct {
1004             bool stream_stored;
1005             uint8_t stream_result;
1006         };
1007         uint32_t stream_reset;
1008     };
1009 
1010     const Signature *s;     /**< ptr to sig */
1011 } RuleMatchCandidateTx;
1012 
1013 /**
1014   * Detection engine thread data.
1015   */
1016 typedef struct DetectEngineThreadCtx_ {
1017     /** \note multi-tenant hash lookup code from Detect() *depends*
1018      *        on this being the first member */
1019     uint32_t tenant_id;
1020 
1021     /** ticker that is incremented once per packet. */
1022     uint64_t ticker;
1023 
1024     /* the thread to which this detection engine thread belongs */
1025     ThreadVars *tv;
1026 
1027     /** Array of non-prefiltered sigs that need to be evaluated. Updated
1028      *  per packet based on the rule group and traffic properties. */
1029     SigIntId *non_pf_id_array;
1030     uint32_t non_pf_id_cnt; // size is cnt * sizeof(uint32_t)
1031 
1032     uint32_t mt_det_ctxs_cnt;
1033     struct DetectEngineThreadCtx_ **mt_det_ctxs;
1034     HashTable *mt_det_ctxs_hash;
1035 
1036     struct DetectEngineTenantMapping_ *tenant_array;
1037     uint32_t tenant_array_size;
1038 
1039     uint32_t (*TenantGetId)(const void *, const Packet *p);
1040 
1041     /* detection engine variables */
1042 
1043     uint64_t raw_stream_progress;
1044 
1045     /** offset into the payload of the last match by:
1046      *  content, pcre, etc */
1047     uint32_t buffer_offset;
1048     /* used by pcre match function alone */
1049     uint32_t pcre_match_start_offset;
1050 
1051     /* counter for the filestore array below -- up here for cache reasons. */
1052     uint16_t filestore_cnt;
1053 
1054     /** id for alert counter */
1055     uint16_t counter_alerts;
1056 #ifdef PROFILING
1057     uint16_t counter_mpm_list;
1058     uint16_t counter_nonmpm_list;
1059     uint16_t counter_fnonmpm_list;
1060     uint16_t counter_match_list;
1061 #endif
1062 
1063     int inspect_list; /**< list we're currently inspecting, DETECT_SM_LIST_* */
1064 
1065     struct {
1066         InspectionBuffer *buffers;
1067         uint32_t buffers_size;          /**< in number of elements */
1068         uint32_t to_clear_idx;
1069         uint32_t *to_clear_queue;
1070     } inspect;
1071 
1072     struct {
1073         /** inspection buffers for more complex case. As we can inspect multiple
1074          *  buffers in parallel, we need this extra wrapper struct */
1075         InspectionBufferMultipleForList *buffers;
1076         uint32_t buffers_size;                      /**< in number of elements */
1077         uint32_t to_clear_idx;
1078         uint32_t *to_clear_queue;
1079     } multi_inspect;
1080 
1081     /* used to discontinue any more matching */
1082     uint16_t discontinue_matching;
1083     uint16_t flags;
1084 
1085     /* bool: if tx_id is set, this is 1, otherwise 0 */
1086     uint16_t tx_id_set;
1087     /** ID of the transaction currently being inspected. */
1088     uint64_t tx_id;
1089     Packet *p;
1090 
1091     SC_ATOMIC_DECLARE(int, so_far_used_by_detect);
1092 
1093     /* holds the current recursion depth on content inspection */
1094     int inspection_recursion_counter;
1095 
1096     /** array of signature pointers we're going to inspect in the detection
1097      *  loop. */
1098     Signature **match_array;
1099     /** size of the array in items (mem size if * sizeof(Signature *)
1100      *  Only used during initialization. */
1101     uint32_t match_array_len;
1102     /** size in use */
1103     SigIntId match_array_cnt;
1104 
1105     RuleMatchCandidateTx *tx_candidates;
1106     uint32_t tx_candidates_size;
1107 
1108     SignatureNonPrefilterStore *non_pf_store_ptr;
1109     uint32_t non_pf_store_cnt;
1110 
1111     /** pointer to the current mpm ctx that is stored
1112      *  in a rule group head -- can be either a content
1113      *  or uricontent ctx. */
1114     MpmThreadCtx mtc;   /**< thread ctx for the mpm */
1115     MpmThreadCtx mtcu;  /**< thread ctx for uricontent mpm */
1116     MpmThreadCtx mtcs;  /**< thread ctx for stream mpm */
1117     PrefilterRuleStore pmq;
1118 
1119     /** SPM thread context used for scanning. This has been cloned from the
1120      * prototype held by DetectEngineCtx. */
1121     SpmThreadCtx *spm_thread_ctx;
1122 
1123     /** ip only rules ctx */
1124     DetectEngineIPOnlyThreadCtx io_ctx;
1125 
1126     /* byte_* values */
1127     uint64_t *byte_values;
1128 
1129     /* string to replace */
1130     DetectReplaceList *replist;
1131     /* vars to store in post match function */
1132     DetectVarList *varlist;
1133 
1134     /* Array in which the filestore keyword stores file id and tx id. If the
1135      * full signature matches, these are processed by a post-match filestore
1136      * function to finalize the store. */
1137     struct {
1138         uint32_t file_id;
1139         uint64_t tx_id;
1140     } filestore[DETECT_FILESTORE_MAX];
1141 
1142     DetectEngineCtx *de_ctx;
1143     /** store for keyword contexts that need a per thread storage. Per de_ctx. */
1144     void **keyword_ctxs_array;
1145     int keyword_ctxs_size;
1146     /** store for keyword contexts that need a per thread storage. Global. */
1147     int global_keyword_ctxs_size;
1148     void **global_keyword_ctxs_array;
1149 
1150     uint8_t *base64_decoded;
1151     int base64_decoded_len;
1152     int base64_decoded_len_max;
1153 
1154     AppLayerDecoderEvents *decoder_events;
1155     uint16_t events;
1156 
1157 #ifdef DEBUG
1158     uint64_t pkt_stream_add_cnt;
1159     uint64_t payload_mpm_cnt;
1160     uint64_t payload_mpm_size;
1161     uint64_t stream_mpm_cnt;
1162     uint64_t stream_mpm_size;
1163     uint64_t payload_persig_cnt;
1164     uint64_t payload_persig_size;
1165     uint64_t stream_persig_cnt;
1166     uint64_t stream_persig_size;
1167 #endif
1168 #ifdef PROFILING
1169     struct SCProfileData_ *rule_perf_data;
1170     int rule_perf_data_size;
1171     struct SCProfileKeywordData_ *keyword_perf_data;
1172     struct SCProfileKeywordData_ **keyword_perf_data_per_list;
1173     int keyword_perf_list; /**< list we're currently inspecting, DETECT_SM_LIST_* */
1174     struct SCProfileSghData_ *sgh_perf_data;
1175 
1176     struct SCProfilePrefilterData_ *prefilter_perf_data;
1177     int prefilter_perf_size;
1178 #endif
1179 } DetectEngineThreadCtx;
1180 
1181 /** \brief element in sigmatch type table.
1182  */
1183 typedef struct SigTableElmt_ {
1184     /** Packet match function pointer */
1185     int (*Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *);
1186 
1187     /** AppLayer TX match function pointer */
1188     int (*AppLayerTxMatch)(DetectEngineThreadCtx *, Flow *,
1189             uint8_t flags, void *alstate, void *txv,
1190             const Signature *, const SigMatchCtx *);
1191 
1192     /** File match function  pointer */
1193     int (*FileMatch)(DetectEngineThreadCtx *,
1194         Flow *,                     /**< *LOCKED* flow */
1195         uint8_t flags, File *, const Signature *, const SigMatchCtx *);
1196 
1197     /** InspectionBuffer transformation callback */
1198     void (*Transform)(InspectionBuffer *, void *context);
1199     bool (*TransformValidate)(const uint8_t *content, uint16_t content_len, void *context);
1200 
1201     /** keyword setup function pointer */
1202     int (*Setup)(DetectEngineCtx *, Signature *, const char *);
1203 
1204     bool (*SupportsPrefilter)(const Signature *s);
1205     int (*SetupPrefilter)(DetectEngineCtx *de_ctx, struct SigGroupHead_ *sgh);
1206 
1207     void (*Free)(DetectEngineCtx *, void *);
1208 #ifdef UNITTESTS
1209     void (*RegisterTests)(void);
1210 #endif
1211     uint16_t flags;
1212     /* coccinelle: SigTableElmt:flags:SIGMATCH_ */
1213 
1214     /** better keyword to replace the current one */
1215     uint16_t alternative;
1216 
1217     const char *name;     /**< keyword name alias */
1218     const char *alias;    /**< name alias */
1219     const char *desc;
1220     const char *url;
1221 
1222 } SigTableElmt;
1223 
1224 /* event code */
1225 enum {
1226 #ifdef UNITTESTS
1227     DET_CTX_EVENT_TEST,
1228 #endif
1229     FILE_DECODER_EVENT_NO_MEM,
1230     FILE_DECODER_EVENT_INVALID_SWF_LENGTH,
1231     FILE_DECODER_EVENT_INVALID_SWF_VERSION,
1232     FILE_DECODER_EVENT_Z_DATA_ERROR,
1233     FILE_DECODER_EVENT_Z_STREAM_ERROR,
1234     FILE_DECODER_EVENT_Z_BUF_ERROR,
1235     FILE_DECODER_EVENT_Z_UNKNOWN_ERROR,
1236     FILE_DECODER_EVENT_LZMA_DECODER_ERROR,
1237     FILE_DECODER_EVENT_LZMA_MEMLIMIT_ERROR,
1238     FILE_DECODER_EVENT_LZMA_OPTIONS_ERROR,
1239     FILE_DECODER_EVENT_LZMA_FORMAT_ERROR,
1240     FILE_DECODER_EVENT_LZMA_DATA_ERROR,
1241     FILE_DECODER_EVENT_LZMA_BUF_ERROR,
1242     FILE_DECODER_EVENT_LZMA_UNKNOWN_ERROR,
1243 
1244     DETECT_EVENT_TOO_MANY_BUFFERS,
1245 };
1246 
1247 #define SIG_GROUP_HEAD_HAVERAWSTREAM    BIT_U32(0)
1248 #ifdef HAVE_MAGIC
1249 #define SIG_GROUP_HEAD_HAVEFILEMAGIC    BIT_U32(20)
1250 #endif
1251 #define SIG_GROUP_HEAD_HAVEFILEMD5      BIT_U32(21)
1252 #define SIG_GROUP_HEAD_HAVEFILESIZE     BIT_U32(22)
1253 #define SIG_GROUP_HEAD_HAVEFILESHA1     BIT_U32(23)
1254 #define SIG_GROUP_HEAD_HAVEFILESHA256   BIT_U32(24)
1255 
1256 enum MpmBuiltinBuffers {
1257     MPMB_TCP_PKT_TS,
1258     MPMB_TCP_PKT_TC,
1259     MPMB_TCP_STREAM_TS,
1260     MPMB_TCP_STREAM_TC,
1261     MPMB_UDP_TS,
1262     MPMB_UDP_TC,
1263     MPMB_OTHERIP,
1264     MPMB_MAX,
1265 };
1266 
1267 typedef struct MpmStore_ {
1268     uint8_t *sid_array;
1269     uint32_t sid_array_size;
1270 
1271     int direction;
1272     enum MpmBuiltinBuffers buffer;
1273     int sm_list;
1274     int32_t sgh_mpm_context;
1275 
1276     MpmCtx *mpm_ctx;
1277 
1278 } MpmStore;
1279 
1280 typedef struct PrefilterEngineList_ {
1281     uint16_t id;
1282 
1283     /** App Proto this engine applies to: only used with Tx Engines */
1284     AppProto alproto;
1285     /** Minimal Tx progress we need before running the engine. Only used
1286      *  with Tx Engine */
1287     int tx_min_progress;
1288 
1289     /** Context for matching. Might be MpmCtx for MPM engines, other ctx'
1290      *  for other engines. */
1291     void *pectx;
1292 
1293     void (*Prefilter)(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx);
1294     void (*PrefilterTx)(DetectEngineThreadCtx *det_ctx, const void *pectx,
1295             Packet *p, Flow *f, void *tx,
1296             const uint64_t idx, const uint8_t flags);
1297 
1298     struct PrefilterEngineList_ *next;
1299 
1300     /** Free function for pectx data. If NULL the memory is not freed. */
1301     void (*Free)(void *pectx);
1302 
1303     const char *name;
1304     /* global id for this prefilter */
1305     uint32_t gid;
1306 } PrefilterEngineList;
1307 
1308 typedef struct PrefilterEngine_ {
1309     uint16_t local_id;
1310 
1311     /** App Proto this engine applies to: only used with Tx Engines */
1312     AppProto alproto;
1313     /** Minimal Tx progress we need before running the engine. Only used
1314      *  with Tx Engine */
1315     int tx_min_progress;
1316 
1317     /** Context for matching. Might be MpmCtx for MPM engines, other ctx'
1318      *  for other engines. */
1319     void *pectx;
1320 
1321     union {
1322         void (*Prefilter)(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx);
1323         void (*PrefilterTx)(DetectEngineThreadCtx *det_ctx, const void *pectx,
1324                 Packet *p, Flow *f, void *tx,
1325                 const uint64_t idx, const uint8_t flags);
1326     } cb;
1327 
1328     /* global id for this prefilter */
1329     uint32_t gid;
1330     bool is_last;
1331     bool is_last_for_progress;
1332 } PrefilterEngine;
1333 
1334 typedef struct SigGroupHeadInitData_ {
1335     MpmStore mpm_store[MPMB_MAX];
1336 
1337     uint8_t *sig_array; /**< bit array of sig nums (internal id's) */
1338     uint32_t sig_size; /**< size in bytes */
1339 
1340     uint8_t protos[256];    /**< proto(s) this sgh is for */
1341     uint32_t direction;     /**< set to SIG_FLAG_TOSERVER, SIG_FLAG_TOCLIENT or both */
1342     int whitelist;          /**< try to make this group a unique one */
1343 
1344     MpmCtx **app_mpms;
1345     MpmCtx **pkt_mpms;
1346 
1347     PrefilterEngineList *pkt_engines;
1348     PrefilterEngineList *payload_engines;
1349     PrefilterEngineList *tx_engines;
1350 
1351     /* port ptr */
1352     struct DetectPort_ *port;
1353 } SigGroupHeadInitData;
1354 
1355 /** \brief Container for matching data for a signature group */
1356 typedef struct SigGroupHead_ {
1357     uint32_t flags;
1358     /* coccinelle: SigGroupHead:flags:SIG_GROUP_HEAD_ */
1359 
1360     /* number of sigs in this head */
1361     SigIntId sig_cnt;
1362 
1363     /* non prefilter list excluding SYN rules */
1364     uint32_t non_pf_other_store_cnt;
1365     uint32_t non_pf_syn_store_cnt;
1366     SignatureNonPrefilterStore *non_pf_other_store_array; // size is non_mpm_store_cnt * sizeof(SignatureNonPrefilterStore)
1367     /* non mpm list including SYN rules */
1368     SignatureNonPrefilterStore *non_pf_syn_store_array; // size is non_mpm_syn_store_cnt * sizeof(SignatureNonPrefilterStore)
1369 
1370     /** the number of signatures in this sgh that have the filestore keyword
1371      *  set. */
1372     uint16_t filestore_cnt;
1373 
1374     uint32_t id; /**< unique id used to index sgh_array for stats */
1375 
1376     PrefilterEngine *pkt_engines;
1377     PrefilterEngine *payload_engines;
1378     PrefilterEngine *tx_engines;
1379 
1380     /** Array with sig ptrs... size is sig_cnt * sizeof(Signature *) */
1381     Signature **match_array;
1382 
1383     /* ptr to our init data we only use at... init :) */
1384     SigGroupHeadInitData *init;
1385 
1386 } SigGroupHead;
1387 
1388 /** sigmatch has no options, so the parser shouldn't expect any */
1389 #define SIGMATCH_NOOPT                  BIT_U16(0)
1390 /** sigmatch is compatible with a ip only rule */
1391 #define SIGMATCH_IPONLY_COMPAT          BIT_U16(1)
1392 /** sigmatch is compatible with a decode event only rule */
1393 #define SIGMATCH_DEONLY_COMPAT          BIT_U16(2)
1394 /**< Flag to indicate that the signature is not built-in */
1395 #define SIGMATCH_NOT_BUILT              BIT_U16(3)
1396 /** sigmatch may have options, so the parser should be ready to
1397  *  deal with both cases */
1398 #define SIGMATCH_OPTIONAL_OPT           BIT_U16(4)
1399 /** input may be wrapped in double quotes. They will be stripped before
1400  *  input data is passed to keyword parser */
1401 #define SIGMATCH_QUOTES_OPTIONAL        BIT_U16(5)
1402 /** input MUST be wrapped in double quotes. They will be stripped before
1403  *  input data is passed to keyword parser. Missing double quotes lead to
1404  *  error and signature invalidation. */
1405 #define SIGMATCH_QUOTES_MANDATORY       BIT_U16(6)
1406 /** negation parsing is handled by the rule parser. Signature::init_data::negated
1407  *  will be set to true or false prior to calling the keyword parser. Exclamation
1408  *  mark is stripped from the input to the keyword parser. */
1409 #define SIGMATCH_HANDLE_NEGATION        BIT_U16(7)
1410 /** keyword is a content modifier */
1411 #define SIGMATCH_INFO_CONTENT_MODIFIER  BIT_U16(8)
1412 /** keyword is a sticky buffer */
1413 #define SIGMATCH_INFO_STICKY_BUFFER     BIT_U16(9)
1414 /** keyword is deprecated: used to suggest an alternative */
1415 #define SIGMATCH_INFO_DEPRECATED        BIT_U16(10)
1416 /** strict parsing is enabled */
1417 #define SIGMATCH_STRICT_PARSING         BIT_U16(11)
1418 
1419 enum DetectEngineTenantSelectors
1420 {
1421     TENANT_SELECTOR_UNKNOWN = 0,    /**< not set */
1422     TENANT_SELECTOR_DIRECT,         /**< method provides direct tenant id */
1423     TENANT_SELECTOR_VLAN,           /**< map vlan to tenant id */
1424     TENANT_SELECTOR_LIVEDEV,        /**< map livedev to tenant id */
1425 };
1426 
1427 typedef struct DetectEngineTenantMapping_ {
1428     uint32_t tenant_id;
1429 
1430     /* traffic id that maps to the tenant id */
1431     uint32_t traffic_id;
1432 
1433     struct DetectEngineTenantMapping_ *next;
1434 } DetectEngineTenantMapping;
1435 
1436 typedef struct DetectEngineMasterCtx_ {
1437     SCMutex lock;
1438 
1439     /** enable multi tenant mode */
1440     int multi_tenant_enabled;
1441 
1442     /** version, incremented after each 'apply to threads' */
1443     uint32_t version;
1444 
1445     /** list of active detection engines. This list is used to generate the
1446      *  threads det_ctx's */
1447     DetectEngineCtx *list;
1448 
1449     /** free list, containing detection engines that will be removed but may
1450      *  still be referenced by det_ctx's. Freed as soon as all references are
1451      *  gone. */
1452     DetectEngineCtx *free_list;
1453 
1454     enum DetectEngineTenantSelectors tenant_selector;
1455 
1456     /** list of tenant mappings. Updated under lock. Used to generate lookup
1457      *  structures. */
1458     DetectEngineTenantMapping *tenant_mapping_list;
1459 
1460     /** list of keywords that need thread local ctxs,
1461      *  only updated by keyword registration at start up. Not
1462      *  covered by the lock. */
1463     DetectEngineThreadKeywordCtxItem *keyword_list;
1464     int keyword_id;
1465 } DetectEngineMasterCtx;
1466 
1467 /* Table with all SigMatch registrations */
1468 extern SigTableElmt sigmatch_table[DETECT_TBLSIZE];
1469 
1470 /** Remember to add the options in SignatureIsIPOnly() at detect.c otherwise it wont be part of a signature group */
1471 
1472 /* detection api */
1473 TmEcode Detect(ThreadVars *tv, Packet *p, void *data);
1474 
1475 SigMatch *SigMatchAlloc(void);
1476 Signature *SigFindSignatureBySidGid(DetectEngineCtx *, uint32_t, uint32_t);
1477 void SigMatchSignaturesBuildMatchArray(DetectEngineThreadCtx *,
1478                                        Packet *, SignatureMask,
1479                                        uint16_t);
1480 void SigMatchFree(DetectEngineCtx *, SigMatch *sm);
1481 
1482 void SigRegisterTests(void);
1483 void TmModuleDetectRegister (void);
1484 
1485 void SigAddressPrepareBidirectionals (DetectEngineCtx *);
1486 
1487 void DisableDetectFlowFileFlags(Flow *f);
1488 char *DetectLoadCompleteSigPath(const DetectEngineCtx *, const char *sig_file);
1489 int SigLoadSignatures (DetectEngineCtx *, char *, int);
1490 void SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx,
1491                        DetectEngineThreadCtx *det_ctx, Packet *p);
1492 
1493 int SignatureIsIPOnly(DetectEngineCtx *de_ctx, const Signature *s);
1494 const SigGroupHead *SigMatchSignaturesGetSgh(const DetectEngineCtx *de_ctx, const Packet *p);
1495 
1496 Signature *DetectGetTagSignature(void);
1497 
1498 
1499 int DetectUnregisterThreadCtxFuncs(DetectEngineCtx *, DetectEngineThreadCtx *,void *data, const char *name);
1500 int DetectRegisterThreadCtxFuncs(DetectEngineCtx *, const char *name, void *(*InitFunc)(void *), void *data, void (*FreeFunc)(void *), int);
1501 void *DetectThreadCtxGetKeywordThreadCtx(DetectEngineThreadCtx *, int);
1502 
1503 void RuleMatchCandidateTxArrayInit(DetectEngineThreadCtx *det_ctx, uint32_t size);
1504 void RuleMatchCandidateTxArrayFree(DetectEngineThreadCtx *det_ctx);
1505 
1506 int DetectFlowbitsAnalyze(DetectEngineCtx *de_ctx);
1507 
1508 int DetectMetadataHashInit(DetectEngineCtx *de_ctx);
1509 void DetectMetadataHashFree(DetectEngineCtx *de_ctx);
1510 
1511 /* events */
1512 void DetectEngineSetEvent(DetectEngineThreadCtx *det_ctx, uint8_t e);
1513 AppLayerDecoderEvents *DetectEngineGetEvents(DetectEngineThreadCtx *det_ctx);
1514 int DetectEngineGetEventInfo(const char *event_name, int *event_id,
1515                              AppLayerEventType *event_type);
1516 
1517 #include "detect-engine-build.h"
1518 #include "detect-engine-register.h"
1519 
1520 #endif /* __DETECT_H__ */
1521 
1522