• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OISF / suricata / 23374838686

21 Mar 2026 07:29AM UTC coverage: 59.341% (-20.0%) from 79.315%
23374838686

Pull #15075

github

web-flow
Merge 90b4e834f into 6587e363a
Pull Request #15075: Stack 8001 v16.4

38 of 70 new or added lines in 10 files covered. (54.29%)

34165 existing lines in 563 files now uncovered.

119621 of 201584 relevant lines covered (59.34%)

650666.92 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.09
/src/detect.h
1
/* Copyright (C) 2007-2025 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 SURICATA_DETECT_H
25
#define SURICATA_DETECT_H
26

27
#include "suricata-common.h"
28
#include "flow.h"
29

30
#include "detect-engine-proto.h"
31
#include "detect-reference.h"
32
#include "detect-metadata.h"
33
#include "detect-engine-register.h"
34
#include "detect-engine-inspect-buffer.h"
35

36
#include "util-prefilter.h"
37
#include "util-mpm.h"
38
#include "util-spm.h"
39
#include "util-hash.h"
40
#include "util-hashlist.h"
41
#include "util-radix4-tree.h"
42
#include "util-radix6-tree.h"
43
#include "util-file.h"
44
#include "reputation.h"
45

46
#define DETECT_MAX_RULE_SIZE 8192
6,173,115✔
47

48
#define DETECT_TRANSFORMS_MAX 16
208,866✔
49

50
/** default rule priority if not set through priority keyword or via
51
 *  classtype. */
52
#define DETECT_DEFAULT_PRIO 3
814,930✔
53

54
// tx_id value to use when there is no transaction
55
#define PACKET_ALERT_NOTX UINT64_MAX
78,624✔
56

57
/* forward declaration for sigorder logic in detect-engine-sigorder.[ch] */
58
struct SCSigOrderFunc_;
59

60
/* Forward declarations for structures from Rust. */
61
typedef struct SCDetectRequiresStatus SCDetectRequiresStatus;
62

63
// rule types documentation tag start: SignatureType
64
enum SignatureType {
65
    SIG_TYPE_NOT_SET = 0,
66
    SIG_TYPE_IPONLY,      // rule is handled by IPONLY engine
67
    SIG_TYPE_LIKE_IPONLY, // rule is handled by pkt engine, has action effect like ip-only
68
    /** Proto detect only signature.
69
     *  Inspected once per direction when protocol detection is done. */
70
    SIG_TYPE_PDONLY, // rule is handled by PDONLY engine
71
    SIG_TYPE_DEONLY,
72
    SIG_TYPE_PKT,
73
    SIG_TYPE_PKT_STREAM,
74
    SIG_TYPE_STREAM,
75

76
    SIG_TYPE_APPLAYER, // app-layer but not tx, e.g. appproto
77
    SIG_TYPE_APP_TX,   // rule is handled by TX engine
78

79
    SIG_TYPE_MAX,
80
};
81
// rule types documentation tag end: SignatureType
82

83
enum SignaturePropertyFlowAction {
84
    SIG_PROP_FLOW_ACTION_PACKET,
85
    SIG_PROP_FLOW_ACTION_FLOW,
86
    SIG_PROP_FLOW_ACTION_FLOW_IF_STATEFUL,
87
};
88

89
struct SignatureProperties {
90
    enum SignaturePropertyFlowAction flow_action;
91
};
92

93
extern const struct SignatureProperties signature_properties[SIG_TYPE_MAX];
94

95
/*
96
  The detection engine groups similar signatures/rules together. Internally a
97
  tree of different types of data is created on initialization. This is it's
98
  global layout:
99

100
   For TCP/UDP
101

102
   - Flow direction
103
   -- Protocol
104
   -=- Dst port
105

106
   For the other protocols
107

108
   - Flow direction
109
   -- Protocol
110
*/
111

112
/* holds the values for different possible lists in struct Signature.
113
 * These codes are access points to particular lists in the array
114
 * Signature->init_data->smlists[DETECT_SM_LIST_MAX]. */
115
enum DetectSigmatchListEnum {
116
    /* list for non-payload per packet matches, e.g. ttl, flow keyword */
117
    DETECT_SM_LIST_MATCH = 0,
118
    /* list for payload and stream match */
119
    DETECT_SM_LIST_PMATCH,
120

121
    /* base64_data keyword uses some hardcoded logic so consider
122
     * built-in
123
     * TODO convert to inspect engine */
124
    DETECT_SM_LIST_BASE64_DATA,
125

126
    /* list for post match actions: flowbit set, flowint increment, etc */
127
    DETECT_SM_LIST_POSTMATCH,
128

129
    DETECT_SM_LIST_TMATCH, /**< post-detection tagging */
130

131
    /* lists for alert thresholding and suppression */
132
    DETECT_SM_LIST_SUPPRESS,
133
    DETECT_SM_LIST_THRESHOLD,
134

135
    DETECT_SM_LIST_MAX,
136

137
    /* start of dynamically registered lists */
138
    DETECT_SM_LIST_DYNAMIC_START = DETECT_SM_LIST_MAX,
139
};
140

141
/* used for Signature->list, which indicates which list
142
 * we're adding keywords to in cases of sticky buffers like
143
 * file_data */
144
#define DETECT_SM_LIST_NOTSET INT_MAX
10,654,339✔
145

146
/*
147
 * DETECT ADDRESS
148
 */
149

150
/* a is ... than b */
151
enum {
152
    ADDRESS_ER = -1, /**< error e.g. compare ipv4 and ipv6 */
153
    ADDRESS_LT,      /**< smaller              [aaa] [bbb] */
154
    ADDRESS_LE,      /**< smaller with overlap [aa[bab]bb] */
155
    ADDRESS_EQ,      /**< exactly equal        [abababab]  */
156
    ADDRESS_ES,      /**< within               [bb[aaa]bb] and [[abab]bbb] and [bbb[abab]] */
157
    ADDRESS_EB,      /**< completely overlaps  [aa[bbb]aa] and [[baba]aaa] and [aaa[baba]] */
158
    ADDRESS_GE,      /**< bigger with overlap  [bb[aba]aa] */
159
    ADDRESS_GT,      /**< bigger               [bbb] [aaa] */
160
};
161

162
#define ADDRESS_FLAG_NOT            0x01 /**< address is negated */
188,375✔
163

164
/** \brief address structure for use in the detection engine.
165
 *
166
 *  Contains the address information and matching information.
167
 */
168
typedef struct DetectAddress_ {
169
    /** address data for this group */
170
    Address ip;
171
    Address ip2;
172

173
    /** flags affecting this address */
174
    uint8_t flags;
175

176
    /** ptr to the previous address in the list */
177
    struct DetectAddress_ *prev;
178
    /** ptr to the next address in the list */
179
    struct DetectAddress_ *next;
180
} DetectAddress;
181

182
/** Address grouping head. IPv4 and IPv6 are split out */
183
typedef struct DetectAddressHead_ {
184
    DetectAddress *ipv4_head;
185
    DetectAddress *ipv6_head;
186
} DetectAddressHead;
187

188

189
typedef struct DetectMatchAddressIPv4_ {
190
    uint32_t ip;    /**< address in host order, start of range */
191
    uint32_t ip2;   /**< address in host order, end of range */
192
} DetectMatchAddressIPv4;
193

194
typedef struct DetectMatchAddressIPv6_ {
195
    uint32_t ip[4];
196
    uint32_t ip2[4];
197
} DetectMatchAddressIPv6;
198

199
/*
200
 * DETECT PORT
201
 */
202

203
/* a is ... than b */
204
enum {
205
    PORT_ER = -1, /* error */
206
    PORT_LT,      /* smaller              [aaa] [bbb] */
207
    PORT_LE,      /* smaller with overlap [aa[bab]bb] */
208
    PORT_EQ,      /* exactly equal        [abababab]  */
209
    PORT_ES,      /* within               [bb[aaa]bb] and [[abab]bbb] and [bbb[abab]] */
210
    PORT_EB,      /* completely overlaps  [aa[bbb]aa] and [[baba]aaa] and [aaa[baba]] */
211
    PORT_GE,      /* bigger with overlap  [bb[aba]aa] */
212
    PORT_GT,      /* bigger               [bbb] [aaa] */
213
};
214

215
#define PORT_FLAG_NOT           0x02 /**< negated port */
4,421,169✔
216
#define PORT_SIGGROUPHEAD_COPY  0x04 /**< sgh is a ptr copy */
440,435✔
217

218
/** \brief Port structure for detection engine */
219
typedef struct DetectPort_ {
220
    uint16_t port;
221
    uint16_t port2;
222

223
    uint8_t flags;  /**< flags for this port */
224

225
    /* signatures that belong in this group
226
     *
227
     * If the PORT_SIGGROUPHEAD_COPY flag is set, we don't own this pointer
228
     * (memory is freed elsewhere).
229
     */
230
    struct SigGroupHead_ *sh;
231

232
    struct DetectPort_ *prev;
233
    struct DetectPort_ *next;
234
    struct DetectPort_ *last; /* Pointer to the last node in the list */
235
} DetectPort;
236

237
/* Signature flags */
238
/** \note: additions should be added to the rule analyzer as well */
239

240
#define SIG_FLAG_SRC_ANY                BIT_U32(0)  /**< source is any */
2,251,108✔
241
#define SIG_FLAG_DST_ANY                BIT_U32(1)  /**< destination is any */
2,264,133✔
242
#define SIG_FLAG_SP_ANY                 BIT_U32(2)  /**< source port is any */
2,197,941✔
243
#define SIG_FLAG_DP_ANY                 BIT_U32(3)  /**< destination port is any */
1,980,975✔
244

245
#define SIG_FLAG_FIREWALL BIT_U32(4) /**< sig is a firewall rule */
1,638,419✔
246

247
#define SIG_FLAG_DSIZE                  BIT_U32(5)  /**< signature has a dsize setting */
580,106✔
248
#define SIG_FLAG_APPLAYER               BIT_U32(6) /**< signature applies to app layer instead of packets */
3,299,682✔
249
#define SIG_FLAG_TXBOTHDIR              BIT_U32(7) /**< signature needs tx with both directions to match */
2,127,770✔
250

251
// vacancy
252

253
#define SIG_FLAG_REQUIRE_PACKET         BIT_U32(9)  /**< signature is requiring packet match */
2,719,954✔
254
#define SIG_FLAG_REQUIRE_STREAM         BIT_U32(10) /**< signature is requiring stream match */
1,001,317✔
255

256
#define SIG_FLAG_MPM_NEG                BIT_U32(11)
631,159✔
257

258
#define SIG_FLAG_FLUSH                  BIT_U32(12) /**< detection logic needs stream flush notification */
8,583✔
259

260
#define SIG_FLAG_REQUIRE_STREAM_ONLY                                                               \
261
    BIT_U32(13) /**< signature is requiring stream match. Stream match is not optional, so no      \
9,481✔
262
                   fallback to packet payload. */
263

264
// vacancies
265

266
#define SIG_FLAG_REQUIRE_FLOWVAR        BIT_U32(17) /**< signature can only match if a flowbit, flowvar or flowint is available. */
509,078✔
267

268
#define SIG_FLAG_FILESTORE              BIT_U32(18) /**< signature has filestore keyword */
2,352,085✔
269

270
#define SIG_FLAG_TOSERVER               BIT_U32(19)
208,971,163✔
271
#define SIG_FLAG_TOCLIENT               BIT_U32(20)
130,596,809✔
272

273
#define SIG_FLAG_TLSSTORE               BIT_U32(21)
325✔
274

275
#define SIG_FLAG_BYPASS                 BIT_U32(22)
29,015✔
276

277
#define SIG_FLAG_PREFILTER              BIT_U32(23) /**< sig is part of a prefilter engine */
1,066,437✔
278

279
// vacancy
280

281
/** Info for Source and Target identification */
282
#define SIG_FLAG_SRC_IS_TARGET          BIT_U32(25)
108,132✔
283
/** Info for Source and Target identification */
284
#define SIG_FLAG_DEST_IS_TARGET         BIT_U32(26)
108,850✔
285

286
#define SIG_FLAG_HAS_TARGET             (SIG_FLAG_DEST_IS_TARGET|SIG_FLAG_SRC_IS_TARGET)
107,884✔
287

288
/* signature init flags */
289
// available 0
290
#define SIG_FLAG_INIT_PACKET                BIT_U32(1)  /**< signature has matches against a packet (as opposed to app layer) */
372,912✔
291
#define SIG_FLAG_INIT_FLOW                  BIT_U32(2)  /**< signature has a flow setting */
1,369,825✔
292
#define SIG_FLAG_INIT_BIDIREC               BIT_U32(3)  /**< signature has bidirectional operator */
1,376,110✔
293
#define SIG_FLAG_INIT_FIRST_IPPROTO_SEEN                                                           \
294
    BIT_U32(4) /** < signature has seen the first ip_proto keyword */
12,531✔
295
#define SIG_FLAG_INIT_STATE_MATCH           BIT_U32(6)  /**< signature has matches that require stateful inspection */
419,726✔
296
#define SIG_FLAG_INIT_NEED_FLUSH            BIT_U32(7)
54,705✔
297
#define SIG_FLAG_INIT_PRIO_EXPLICIT                                                                \
298
    BIT_U32(8) /**< priority is explicitly set by the priority keyword */
161,087✔
299
#define SIG_FLAG_INIT_FILEDATA       BIT_U32(9)  /**< signature has filedata keyword */
1,832,279✔
300
#define SIG_FLAG_INIT_FORCE_TOCLIENT BIT_U32(10) /**< signature now takes keywords toclient */
7,425,033✔
301
#define SIG_FLAG_INIT_FORCE_TOSERVER BIT_U32(11) /**< signature now takes keywords toserver */
7,359,565✔
302
// Two following flags are meant to be mutually exclusive
303
#define SIG_FLAG_INIT_TXDIR_STREAMING_TOSERVER                                                     \
304
    BIT_U32(12) /**< transactional signature uses a streaming buffer to server */
77,877✔
305
#define SIG_FLAG_INIT_TXDIR_FAST_TOCLIENT                                                          \
306
    BIT_U32(13) /**< transactional signature uses a fast pattern to client */
77,537✔
307

308
/* signature mask flags */
309
/** \note: additions should be added to the rule analyzer as well */
310
#define SIG_MASK_REQUIRE_PAYLOAD            BIT_U8(0)
589,551✔
311
#define SIG_MASK_REQUIRE_FLOW               BIT_U8(1)
915,877✔
312
#define SIG_MASK_REQUIRE_FLAGS_INITDEINIT   BIT_U8(2)    /* SYN, FIN, RST */
46,904✔
313
#define SIG_MASK_REQUIRE_FLAGS_UNUSUAL      BIT_U8(3)    /* URG, ECN, CWR */
95,868✔
314
#define SIG_MASK_REQUIRE_NO_PAYLOAD         BIT_U8(4)
259,978✔
315
#define SIG_MASK_REQUIRE_REAL_PKT           BIT_U8(5)
871,177✔
316
// vacancy 1x
317
#define SIG_MASK_REQUIRE_ENGINE_EVENT       BIT_U8(7)
92,143✔
318

319
#define FILE_SIG_NEED_FILE          0x01
42,982✔
320
#define FILE_SIG_NEED_FILENAME      0x02
44,277✔
321
#define FILE_SIG_NEED_MAGIC         0x04    /**< need the start of the file */
512,297✔
322
#define FILE_SIG_NEED_FILECONTENT   0x08
873✔
323
#define FILE_SIG_NEED_MD5           0x10
511,761✔
324
#define FILE_SIG_NEED_SHA1          0x20
511,761✔
325
#define FILE_SIG_NEED_SHA256        0x40
511,761✔
326
#define FILE_SIG_NEED_SIZE          0x80
1,219✔
327

328
/* Detection Engine flags */
329
#define DE_QUIET 0x01 /**< DE is quiet (esp for unittests) */
212,705✔
330

331
typedef struct IPOnlyCIDRItem_ {
332
    /* address data for this item */
333
    uint8_t family;
334
    /* netmask in CIDR values (ex. /16 /18 /24..) */
335
    uint8_t netmask;
336
    /* If this host or net is negated for the signum */
337
    uint8_t negated;
338

339
    uint32_t ip[4];
340
    SigIntId signum; /**< our internal id */
341

342
    /* linked list, the header should be the biggest network */
343
    struct IPOnlyCIDRItem_ *next;
344

345
} IPOnlyCIDRItem;
346

347
/** \brief Used to start a pointer to SigMatch context
348
 * Should never be dereferenced without casting to something else.
349
 */
350
typedef struct SigMatchCtx_ {
351
    int foo;
352
} SigMatchCtx;
353

354
/** \brief a single match condition for a signature */
355
typedef struct SigMatch_ {
356
    uint16_t type; /**< match type */
357
    uint16_t idx; /**< position in the signature */
358
    SigMatchCtx *ctx; /**< plugin specific data */
359
    struct SigMatch_ *next;
360
    struct SigMatch_ *prev;
361
} SigMatch;
362

363
/** \brief Data needed for Match() */
364
typedef struct SigMatchData_ {
365
    uint16_t type;   /**< match type */
366
    bool is_last;    /**< Last element of the list */
367
    SigMatchCtx *ctx; /**< plugin specific data */
368
} SigMatchData;
369

370
struct DetectEngineThreadCtx_;// DetectEngineThreadCtx;
371

372
/* inspection buffers are kept per tx (in det_ctx), but some protocols
373
 * need a bit more. A single TX might have multiple buffers, e.g. files in
374
 * SMTP or DNS queries. Since all prefilters+transforms run before the
375
 * individual rules need the same buffers, we need a place to store the
376
 * transformed data. This array of arrays is that place. */
377

378
typedef struct InspectionBufferMultipleForList {
379
    InspectionBuffer *inspection_buffers;
380
    uint32_t size;      /**< size in number of elements */
381
    uint32_t max:31;    /**< max id in use in this run */
382
    uint32_t init:1;    /**< first time used this run. Used for clean logic */
383
} InspectionBufferMultipleForList;
384

385
typedef struct TransformData_ {
386
    int transform;
387
    void *options;
388
} TransformData;
389

390
typedef struct DetectEngineTransforms {
391
    TransformData transforms[DETECT_TRANSFORMS_MAX];
392
    int cnt;
393
} DetectEngineTransforms;
394

395
/** callback for getting the buffer we need to prefilter/inspect */
396
typedef InspectionBuffer *(*InspectionBufferGetDataPtr)(
397
        struct DetectEngineThreadCtx_ *det_ctx,
398
        const DetectEngineTransforms *transforms,
399
        Flow *f, const uint8_t flow_flags,
400
        void *txv, const int list_id);
401

402
typedef bool (*InspectionSingleBufferGetDataPtr)(
403
        const void *txv, const uint8_t flow_flags, const uint8_t **buf, uint32_t *buf_len);
404

405
typedef bool (*InspectionMultiBufferGetDataPtr)(struct DetectEngineThreadCtx_ *det_ctx,
406
        const void *txv, const uint8_t flow_flags, uint32_t local_id, const uint8_t **buf,
407
        uint32_t *buf_len);
408
struct DetectEngineAppInspectionEngine_;
409

410
typedef uint8_t (*InspectEngineFuncPtr)(struct DetectEngineCtx_ *de_ctx,
411
        struct DetectEngineThreadCtx_ *det_ctx,
412
        const struct DetectEngineAppInspectionEngine_ *engine, const struct Signature_ *s, Flow *f,
413
        uint8_t flags, void *alstate, void *txv, uint64_t tx_id);
414

415
typedef struct DetectEngineAppInspectionEngine_ {
416
    AppProto alproto;
417
    uint8_t dir;
418
    uint8_t id;     /**< per sig id used in state keeping */
419
    bool mpm;
420
    bool stream;
421
    /** will match on a NULL buffer (so an absent buffer) */
422
    bool match_on_null;
423
    uint16_t sm_list;
424
    uint16_t sm_list_base; /**< base buffer being transformed */
425
    int16_t progress;
426

427
    struct {
428
        union {
429
            InspectionBufferGetDataPtr GetData;
430
            InspectionSingleBufferGetDataPtr GetDataSingle;
431
            InspectionMultiBufferGetDataPtr GetMultiData;
432
        };
433
        InspectEngineFuncPtr Callback;
434
        /** pointer to the transforms in the 'DetectBuffer entry for this list */
435
        const DetectEngineTransforms *transforms;
436
    } v2;
437

438
    SigMatchData *smd;
439

440
    struct DetectEngineAppInspectionEngine_ *next;
441
} DetectEngineAppInspectionEngine;
442

443
typedef struct TransformIdData_ {
444
    const uint8_t *id_data;
445
    uint32_t id_data_len;
446
} TransformIdData;
447

448
typedef struct DetectBufferType_ {
449
    char name[64];
450
    char description[128];
451
    int id;
452
    int parent_id;
453
    bool mpm;
454
    bool packet; /**< compat to packet matches */
455
    bool frame;  /**< is about Frame inspection */
456
    bool supports_transforms;
457
    bool multi_instance; /**< buffer supports multiple buffer instances per tx */
458
    void (*SetupCallback)(
459
            const struct DetectEngineCtx_ *, struct Signature_ *, const struct DetectBufferType_ *);
460
    bool (*ValidateCallback)(
461
            const struct Signature_ *, const char **sigerror, const struct DetectBufferType_ *);
462
    DetectEngineTransforms transforms;
463
    TransformIdData xform_id[DETECT_TRANSFORMS_MAX];
464
} DetectBufferType;
465

466
struct DetectEnginePktInspectionEngine;
467

468
/**
469
 *  \param alert_flags[out] for setting PACKET_ALERT_FLAG_*
470
 */
471
typedef int (*InspectionBufferPktInspectFunc)(
472
        struct DetectEngineThreadCtx_ *,
473
        const struct DetectEnginePktInspectionEngine *engine,
474
        const struct Signature_ *s,
475
        Packet *p, uint8_t *alert_flags);
476

477
/** callback for getting the buffer we need to prefilter/inspect */
478
typedef InspectionBuffer *(*InspectionBufferGetPktDataPtr)(
479
        struct DetectEngineThreadCtx_ *det_ctx,
480
        const DetectEngineTransforms *transforms,
481
        Packet *p, const int list_id);
482

483
typedef struct DetectEnginePktInspectionEngine {
484
    SigMatchData *smd;
485
    bool mpm;
486
    uint16_t sm_list;
487
    uint16_t sm_list_base;
488
    struct {
489
        InspectionBufferGetPktDataPtr GetData;
490
        InspectionBufferPktInspectFunc Callback;
491
        /** pointer to the transforms in the 'DetectBuffer entry for this list */
492
        const DetectEngineTransforms *transforms;
493
    } v1;
494
    struct DetectEnginePktInspectionEngine *next;
495
} DetectEnginePktInspectionEngine;
496

497
struct Frame;
498
struct Frames;
499
struct DetectEngineFrameInspectionEngine;
500

501
/**
502
 *  \param alert_flags[out] for setting PACKET_ALERT_FLAG_*
503
 */
504
typedef int (*InspectionBufferFrameInspectFunc)(struct DetectEngineThreadCtx_ *,
505
        const struct DetectEngineFrameInspectionEngine *engine, const struct Signature_ *s,
506
        Packet *p, const struct Frames *frames, const struct Frame *frame);
507

508
typedef struct DetectEngineFrameInspectionEngine {
509
    AppProto alproto;
510
    uint8_t dir;
511
    uint8_t type;
512
    bool mpm;
513
    uint16_t sm_list;
514
    uint16_t sm_list_base;
515
    struct {
516
        InspectionBufferFrameInspectFunc Callback;
517
        /** pointer to the transforms in the 'DetectBuffer entry for this list */
518
        const DetectEngineTransforms *transforms;
519
    } v1;
520
    SigMatchData *smd;
521
    struct DetectEngineFrameInspectionEngine *next;
522
} DetectEngineFrameInspectionEngine;
523

524
typedef struct SignatureInitDataBuffer_ {
525
    uint32_t id;  /**< buffer id */
526
    bool sm_init; /**< initialized by sigmatch, which is likely something like `urilen:10; http.uri;
527
                     content:"abc";`. These need to be in the same list. Unset once `http.uri` is
528
                     set up. */
529
    bool multi_capable; /**< true if we can have multiple instances of this buffer, so e.g. for
530
                           http.uri. */
531
    bool only_tc;       /**< true if we can only used toclient. */
532
    bool only_ts;       /**< true if we can only used toserver. */
533
    /* sig match list */
534
    SigMatch *head;
535
    SigMatch *tail;
536
} SignatureInitDataBuffer;
537

538
enum SignatureHookPkt {
539
    SIGNATURE_HOOK_PKT_NOT_SET,
540
    SIGNATURE_HOOK_PKT_FLOW_START,
541
    SIGNATURE_HOOK_PKT_PRE_FLOW,
542
    SIGNATURE_HOOK_PKT_PRE_STREAM,
543
    SIGNATURE_HOOK_PKT_ALL, /**< match each packet */
544
};
545

546
enum SignatureHookType {
547
    SIGNATURE_HOOK_TYPE_NOT_SET,
548
    SIGNATURE_HOOK_TYPE_PKT,
549
    SIGNATURE_HOOK_TYPE_APP,
550
};
551

552
enum DetectTable {
553
    DETECT_TABLE_NOT_SET = 0,
554
    DETECT_TABLE_PACKET_PRE_FLOW,
555
    DETECT_TABLE_PACKET_PRE_STREAM,
556
    DETECT_TABLE_PACKET_FILTER,
557
    DETECT_TABLE_PACKET_TD,
558
    DETECT_TABLE_APP_FILTER,
559
    DETECT_TABLE_APP_TD,
560

561
#define DETECT_TABLE_PACKET_PRE_FLOW_FLAG   BIT_U8(DETECT_TABLE_PACKET_PRE_FLOW)
3✔
562
#define DETECT_TABLE_PACKET_PRE_STREAM_FLAG BIT_U8(DETECT_TABLE_PACKET_PRE_STREAM)
9✔
563
#define DETECT_TABLE_PACKET_FILTER_FLAG     BIT_U8(DETECT_TABLE_PACKET_FILTER)
9✔
564
#define DETECT_TABLE_PACKET_TD_FLAG         BIT_U8(DETECT_TABLE_PACKET_TD)
9✔
565
#define DETECT_TABLE_APP_FILTER_FLAG        BIT_U8(DETECT_TABLE_APP_FILTER)
6✔
566
#define DETECT_TABLE_APP_TD_FLAG            BIT_U8(DETECT_TABLE_APP_TD)
6✔
567
};
568

569
// dns:request_complete should add DetectBufferTypeGetByName("dns:request_complete");
570
// TODO to json
571
typedef struct SignatureHook_ {
572
    enum SignatureHookType type;
573
    int sm_list; /**< list id for the hook's generic list. e.g. for dns:request_complete:generic */
574
    union {
575
        struct {
576
            AppProto alproto;
577
            /** progress value of the app-layer hook specified in the rule. Sets the app_proto
578
             *  specific progress value. */
579
            int app_progress;
580
        } app;
581
        struct {
582
            enum SignatureHookPkt ph;
583
        } pkt;
584
    } t;
585
} SignatureHook;
586

587
#define SIG_ALPROTO_MAX 4
23,184✔
588

589
typedef struct SignatureInitData_ {
590
    SignatureHook hook;
591

592
    /** Number of sigmatches. Used for assigning SigMatch::idx */
593
    uint16_t sm_cnt;
594

595
    /** option was prefixed with '!'. Only set for sigmatches that
596
     *  have the SIGMATCH_HANDLE_NEGATION flag set. */
597
    bool negated;
598

599
    /* track if we saw any negation in the addresses. If so, we
600
     * skip it for ip-only */
601
    bool src_contains_negation;
602
    bool dst_contains_negation;
603

604
    /** see if any of the sigmatches supports an enabled prefilter */
605
    bool has_possible_prefilter;
606

607
    /* used to hold flags that are used during init */
608
    uint32_t init_flags;
609
    /* coccinelle: SignatureInitData:init_flags:SIG_FLAG_INIT_ */
610

611
    /* alproto mask if multiple protocols are possible */
612
    AppProto alprotos[SIG_ALPROTO_MAX];
613

614
    /* used at init to determine max dsize */
615
    SigMatch *dsize_sm;
616

617
    /** netblocks and hosts specified at the sid, in CIDR format */
618
    IPOnlyCIDRItem *cidr_src, *cidr_dst;
619

620
    /* list id for `mpm_sm`. Should always match `SigMatchListSMBelongsTo(s, mpm_sm)`. */
621
    int mpm_sm_list;
622
    /* the fast pattern added from this signature */
623
    SigMatch *mpm_sm;
624
    /* used to speed up init of prefilter */
625
    SigMatch *prefilter_sm;
626

627
    /* SigMatch list used for adding content and friends. E.g. file_data; */
628
    int list;
629
    bool list_set;
630

631
    DetectEngineTransforms transforms;
632

633
    /** score to influence rule grouping. A higher value leads to a higher
634
     *  likelihood of a rulegroup with this sig ending up as a contained
635
     *  group. */
636
    int score;
637

638
    /** address settings for this signature */
639
    const DetectAddressHead *src, *dst;
640

641
    /* holds built-in sm lists */
642
    struct SigMatch_ *smlists[DETECT_SM_LIST_MAX];
643
    /* holds built-in sm lists' tails */
644
    struct SigMatch_ *smlists_tail[DETECT_SM_LIST_MAX];
645

646
    /* Storage for buffers. */
647
    SignatureInitDataBuffer *buffers;
648
    uint32_t buffer_index;
649
    uint32_t buffers_size;
650
    SignatureInitDataBuffer *curbuf;
651

652
    /* highest list/buffer id which holds a DETECT_CONTENT */
653
    uint32_t max_content_list_id;
654

655
    /* inter-signature state dependency */
656
    bool is_rule_state_dependant;
657
    uint32_t *rule_state_dependant_sids_array;
658
    uint32_t rule_state_dependant_sids_size;
659
    uint32_t rule_state_dependant_sids_idx;
660
    uint32_t *rule_state_flowbits_ids_array;
661
    uint32_t rule_state_flowbits_ids_size;
662

663
    /* Signature is a "firewall" rule. */
664
    bool firewall_rule;
665
} SignatureInitData;
666

667
/** \brief Signature container */
668
typedef struct Signature_ {
669
    uint32_t flags;
670
    /* coccinelle: Signature:flags:SIG_FLAG_ */
671
    enum SignatureType type;
672

673
    AppProto alproto;
674

675
    uint16_t dsize_low;
676
    uint16_t dsize_high;
677
    uint8_t dsize_mode;
678

679
    SignatureMask mask;
680
    SigIntId iid; /**< signature internal id */
681

682
    /** inline -- action */
683
    uint8_t action;
684
    uint8_t file_flags;
685

686
    /** addresses, ports and proto this sig matches on */
687
    DetectProto proto;
688

689
    /* scope setting for the action: enum ActionScope */
690
    uint8_t action_scope;
691

692
    /** ipv4 match arrays */
693
    uint16_t addr_dst_match4_cnt;
694
    uint16_t addr_src_match4_cnt;
695
    uint16_t addr_dst_match6_cnt;
696
    uint16_t addr_src_match6_cnt;
697

698
    /** classification id **/
699
    uint16_t class_id;
700

701
    /** detect: pseudo table this rule is part of (enum DetectTable) */
702
    uint8_t detect_table;
703

704
    /** firewall: progress value for this signature */
705
    uint8_t app_progress_hook;
706

707
    DetectMatchAddressIPv4 *addr_dst_match4;
708
    DetectMatchAddressIPv4 *addr_src_match4;
709
    /** ipv6 match arrays */
710
    DetectMatchAddressIPv6 *addr_dst_match6;
711
    DetectMatchAddressIPv6 *addr_src_match6;
712

713
    uint32_t id;  /**< sid, set by the 'sid' rule keyword */
714
    uint32_t gid; /**< generator id */
715
    uint32_t rev;
716
    int prio;
717

718
    /** port settings for this signature */
719
    DetectPort *sp, *dp;
720

721
#ifdef PROFILE_RULES
722
    uint16_t profiling_id;
723
#endif
724

725
    DetectEngineAppInspectionEngine *app_inspect;
726
    DetectEnginePktInspectionEngine *pkt_inspect;
727
    DetectEngineFrameInspectionEngine *frame_inspect;
728

729
    /* Matching structures for the built-ins. The others are in
730
     * their inspect engines. */
731
    SigMatchData *sm_arrays[DETECT_SM_LIST_MAX];
732

733
    /* memory is still owned by the sm_lists/sm_arrays entry */
734
    const struct DetectFilestoreData_ *filestore_ctx;
735

736
    char *msg;
737

738
    /** classification message */
739
    char *class_msg;
740
    /** Reference */
741
    DetectReference *references;
742
    /** Metadata */
743
    DetectMetadataHead *metadata;
744

745
    char *sig_str;
746

747
    SignatureInitData *init_data;
748

749
    /** ptr to the next sig in the list */
750
    struct Signature_ *next;
751
} Signature;
752

753
enum DetectBufferMpmType {
754
    DETECT_BUFFER_MPM_TYPE_PKT,
755
    DETECT_BUFFER_MPM_TYPE_APP,
756
    DETECT_BUFFER_MPM_TYPE_FRAME,
757
    /* must be last */
758
    DETECT_BUFFER_MPM_TYPE_SIZE,
759
};
760

761
#define DETECT_PROFILE_NAME_LEN 32
534,168✔
762
/** \brief one time registration of keywords at start up */
763
typedef struct DetectBufferMpmRegistry_ {
764
    const char *name;
765
    char pname[DETECT_PROFILE_NAME_LEN]; /**< name used in profiling */
766
    int direction;              /**< SIG_FLAG_TOSERVER or SIG_FLAG_TOCLIENT */
767
    int16_t sm_list;
768
    int16_t sm_list_base;
769
    int priority;
770
    int id;                     /**< index into this array and result arrays */
771
    enum DetectBufferMpmType type;
772
    int sgh_mpm_context;
773

774
    int (*PrefilterRegisterWithListId)(struct DetectEngineCtx_ *de_ctx, struct SigGroupHead_ *sgh,
775
            MpmCtx *mpm_ctx, const struct DetectBufferMpmRegistry_ *mpm_reg, int list_id);
776
    DetectEngineTransforms transforms;
777

778
    union {
779
        /* app-layer matching: use if type == DETECT_BUFFER_MPM_TYPE_APP */
780
        struct {
781
            union {
782
                InspectionBufferGetDataPtr GetData;
783
                InspectionSingleBufferGetDataPtr GetDataSingle;
784
                InspectionMultiBufferGetDataPtr GetMultiData;
785
            };
786
            AppProto alproto;
787
            int tx_min_progress;
788
        } app_v2;
789

790
        /* pkt matching: use if type == DETECT_BUFFER_MPM_TYPE_PKT */
791
        struct {
792
            int (*PrefilterRegisterWithListId)(struct DetectEngineCtx_ *de_ctx,
793
                    struct SigGroupHead_ *sgh, MpmCtx *mpm_ctx,
794
                    const struct DetectBufferMpmRegistry_ *mpm_reg, int list_id);
795
            InspectionBufferGetPktDataPtr GetData;
796
        } pkt_v1;
797

798
        /* frame matching: use if type == DETECT_BUFFER_MPM_TYPE_FRAME */
799
        struct {
800
            AppProto alproto;
801
            uint8_t type;
802
        } frame_v1;
803
    };
804

805
    struct DetectBufferMpmRegistry_ *next;
806
} DetectBufferMpmRegistry;
807

808
/* helper structure to track pattern stats and assign pattern id's. */
809
typedef struct DetectPatternTracker {
810
    const struct DetectContentData_ *cd;
811
    int sm_list;
812
    uint32_t cnt;
813
    uint32_t mpm;
814
} DetectPatternTracker;
815

816
typedef struct DetectReplaceList_ {
817
    const struct DetectContentData_ *cd;
818
    uint8_t *found;
819
    struct DetectReplaceList_ *next;
820
} DetectReplaceList;
821

822
/** only execute flowvar storage if rule matched */
823
#define DETECT_VAR_TYPE_FLOW_POSTMATCH      1
113✔
824
#define DETECT_VAR_TYPE_PKT_POSTMATCH       2
80✔
825

826
/** list for flowvar store candidates, to be stored from
827
 *  post-match function */
828
typedef struct DetectVarList_ {
829
    uint16_t type; /**< type of store candidate POSTMATCH or ALWAYS */
830
    uint8_t pad[2];
831
    uint32_t idx;                       /**< flowvar name idx */
832
    uint16_t len;                       /**< data len */
833
    uint16_t key_len;
834
    uint8_t *key;
835
    uint8_t *buffer;                    /**< alloc'd buffer, may be freed by
836
                                             post-match, post-non-match */
837
    struct DetectVarList_ *next;
838
} DetectVarList;
839

840
typedef struct SCFPSupportSMList_ {
841
    int list_id;
842
    int priority;
843
    struct SCFPSupportSMList_ *next;
844
} SCFPSupportSMList;
845

846
/** \brief IP only rules matching ctx. */
847
typedef struct DetectEngineIPOnlyCtx_ {
848
    /* Lookup trees */
849
    SCRadix4Tree tree_ipv4src, tree_ipv4dst;
850
    SCRadix6Tree tree_ipv6src, tree_ipv6dst;
851

852
    /* Used to build the radix trees */
853
    IPOnlyCIDRItem *ip_src, *ip_dst;
854
    uint32_t max_idx;
855

856
    /* Used to map large signums to smaller values to compact the bitsets
857
     * stored in the radix trees */
858
    uint32_t *sig_mapping;
859
    uint32_t sig_mapping_size;
860
} DetectEngineIPOnlyCtx;
861

862
typedef struct DetectEngineLookupFlow_ {
863
    DetectPort *tcp;
864
    DetectPort *udp;
865
    struct SigGroupHead_ *sgh[256];
866
} DetectEngineLookupFlow;
867

868
typedef struct SigString_ {
869
    char *filename;
870
    char *sig_str;
871
    char *sig_error;
872
    int line;
873
    TAILQ_ENTRY(SigString_) next;
874
} SigString;
875

876
/** \brief Signature loader statistics */
877
typedef struct SigFileLoaderStat_ {
878
    TAILQ_HEAD(, SigString_) failed_sigs;
879
    int bad_files;
880
    int total_files;
881
    int good_sigs_total;
882
    int bad_sigs_total;
883
    int skipped_sigs_total;
884
} SigFileLoaderStat;
885

886
typedef struct DetectEngineThreadKeywordCtxItem_ {
887
    void *(*InitFunc)(void *);
888
    void (*FreeFunc)(void *);
889
    void *data;
890
    struct DetectEngineThreadKeywordCtxItem_ *next;
891
    int id;
892
    const char *name; /* keyword name, for error printing */
893
} DetectEngineThreadKeywordCtxItem;
894

895
enum DetectEnginePrefilterSetting
896
{
897
    DETECT_PREFILTER_MPM = 0,   /**< use only mpm / fast_pattern */
898
    DETECT_PREFILTER_AUTO = 1,  /**< use mpm + keyword prefilters */
899
};
900

901
enum DetectEngineType
902
{
903
    DETECT_ENGINE_TYPE_NORMAL = 0,
904
    DETECT_ENGINE_TYPE_DD_STUB = 1, /* delayed detect stub: can be reloaded */
905
    DETECT_ENGINE_TYPE_MT_STUB = 2, /* multi-tenant stub: cannot be reloaded */
906
    DETECT_ENGINE_TYPE_TENANT = 3,
907
};
908

909
/* Flow states:
910
 *  toserver
911
 *  toclient
912
 */
913
#define FLOW_STATES 2
106,398✔
914

915
typedef struct {
916
    uint32_t content_limit;
917
    uint32_t content_inspect_min_size;
918
} DetectFileDataCfg;
919

920
typedef uint8_t (*DetectPacketHookFunc)(ThreadVars *tv, DetectEngineThreadCtx *det_ctx, Packet *p);
921

922
/**
923
 * \brief Function type for rate filter callback.
924
 *
925
 * This function should return the new action to be applied. If no change to the
926
 * action is to be made, the callback should return the current action provided
927
 * in the new_action parameter.
928
 */
929
typedef uint8_t (*SCDetectRateFilterFunc)(const Packet *p, uint32_t sid, uint32_t gid, uint32_t rev,
930
        uint8_t original_action, uint8_t new_action, void *arg);
931

932
/** \brief main detection engine ctx */
933
typedef struct DetectEngineCtx_ {
934
    bool failure_fatal;
935
    uint8_t flags;       /**< only DE_QUIET */
936
    uint8_t mpm_matcher; /**< mpm matcher this ctx uses */
937
    MpmConfig *mpm_cfg;
938
    uint8_t spm_matcher; /**< spm matcher this ctx uses */
939

940
    uint32_t tenant_id;
941

942
    Signature *sig_list;
943
    uint32_t sig_cnt;
944

945
    /* version of the srep data */
946
    uint32_t srep_version;
947

948
    /* reputation for netblocks */
949
    SRepCIDRTree *srepCIDR_ctx;
950

951
    Signature **sig_array;
952
    uint32_t sig_array_len;  /* size in array members */
953

954
    uint32_t signum;
955

956
    /* used by the signature ordering module */
957
    struct SCSigOrderFunc_ *sc_sig_order_funcs;
958

959
    /* main sigs */
960
    DetectEngineLookupFlow flow_gh[FLOW_STATES];
961

962
    /* init phase vars */
963
    HashListTable *sgh_hash_table;
964

965
    HashListTable *mpm_hash_table;
966
    HashListTable *pattern_hash_table;
967

968
    /* hash table used to cull out duplicate sigs */
969
    HashListTable *dup_sig_hash_table;
970

971
    DetectEngineIPOnlyCtx io_ctx;
972

973
    /* maximum recursion depth for content inspection */
974
    int inspection_recursion_limit;
975

976
    /* maximum number of times a tx will get logged for rules not using app-layer keywords */
977
    uint8_t guess_applayer_log_limit;
978

979
    /* force app-layer tx finding for alerts with signatures not having app-layer keywords */
980
    bool guess_applayer;
981

982
    /* registration id for per thread ctx for the filemagic/file.magic keywords */
983
    int filemagic_thread_ctx_id;
984

985
    /* spm thread context prototype, built as spm matchers are constructed and
986
     * later used to construct thread context for each thread. */
987
    SpmGlobalThreadCtx *spm_global_thread_ctx;
988

989
    /* Config options */
990

991
    uint16_t max_uniq_toclient_groups;
992
    uint16_t max_uniq_toserver_groups;
993

994
    /* max flowbit id that is used */
995
    uint32_t max_fb_id;
996

997
    MpmCtxFactoryContainer *mpm_ctx_factory_container;
998

999
    /* array containing all sgh's in use so we can loop
1000
     * through it in Stage4. */
1001
    struct SigGroupHead_ **sgh_array;
1002
    uint32_t sgh_array_cnt;
1003
    uint32_t sgh_array_size;
1004

1005
    int32_t sgh_mpm_context_proto_tcp_packet;
1006
    int32_t sgh_mpm_context_proto_udp_packet;
1007
    int32_t sgh_mpm_context_proto_other_packet;
1008
    int32_t sgh_mpm_context_stream;
1009

1010
    /* the max local id used amongst all sigs */
1011
    int32_t byte_extract_max_local_id;
1012

1013
    /** version of the detect engine. The version is incremented on reloads */
1014
    uint32_t version;
1015

1016
    /** sgh for signatures that match against invalid packets. In those cases
1017
     *  we can't lookup by proto, address, port as we don't have these */
1018
    struct SigGroupHead_ *decoder_event_sgh;
1019

1020
    /* Maximum size of the buffer for decoded base64 data. */
1021
    uint16_t base64_decode_max_len;
1022

1023
    /** Store rule file and line so that parsers can use them in errors. */
1024
    int rule_line;
1025
    const char *rule_file;
1026
    const char *sigerror;
1027
    bool sigerror_silent;
1028
    bool sigerror_ok;
1029

1030
    /** The rule errored out due to missing requirements. */
1031
    bool sigerror_requires;
1032

1033
    /* specify the configuration for mpm context factory */
1034
    uint8_t sgh_mpm_ctx_cnf;
1035

1036
    int keyword_id;
1037
    /** hash list of keywords that need thread local ctxs */
1038
    HashListTable *keyword_hash;
1039

1040
    DetectFileDataCfg *filedata_config;
1041

1042
#ifdef PROFILE_RULES
1043
    struct SCProfileDetectCtx_ *profile_ctx;
1044
#endif
1045
#ifdef PROFILING
1046
    struct SCProfileKeywordDetectCtx_ *profile_keyword_ctx;
1047
    struct SCProfilePrefilterDetectCtx_ *profile_prefilter_ctx;
1048
    struct SCProfileKeywordDetectCtx_ **profile_keyword_ctx_per_list;
1049
    struct SCProfileSghDetectCtx_ *profile_sgh_ctx;
1050
    uint32_t profile_match_logging_threshold;
1051
#endif
1052
    char config_prefix[64];
1053

1054
    enum DetectEngineType type;
1055

1056
    /** how many de_ctx' are referencing this */
1057
    uint32_t ref_cnt;
1058
    /** list in master: either active or freelist */
1059
    struct DetectEngineCtx_ *next;
1060

1061
    /** id of loader thread 'owning' this de_ctx */
1062
    int loader_id;
1063

1064
    /** are we using just mpm or also other prefilters */
1065
    enum DetectEnginePrefilterSetting prefilter_setting;
1066

1067
    HashListTable *dport_hash_table;
1068

1069
    DetectPort *tcp_priorityports;
1070
    DetectPort *udp_priorityports;
1071

1072
    /** table for storing the string representation with the parsers result */
1073
    HashListTable *address_table;
1074

1075
    /** table to store metadata keys and values */
1076
    HashTable *metadata_table;
1077

1078
    /* hash tables with rule-time buffer registration. Start time registration
1079
     * is in detect-engine.c::g_buffer_type_hash */
1080
    HashListTable *buffer_type_hash_name;
1081
    HashListTable *buffer_type_hash_id;
1082
    uint32_t buffer_type_id;
1083

1084
    uint32_t app_mpms_list_cnt;
1085
    DetectBufferMpmRegistry *app_mpms_list;
1086
    /* list with app inspect engines. Both the start-time registered ones and
1087
     * the rule-time registered ones. */
1088
    DetectEngineAppInspectionEngine *app_inspect_engines;
1089
    DetectEnginePktInspectionEngine *pkt_inspect_engines;
1090
    DetectBufferMpmRegistry *pkt_mpms_list;
1091
    uint32_t pkt_mpms_list_cnt;
1092
    DetectEngineFrameInspectionEngine *frame_inspect_engines;
1093
    DetectBufferMpmRegistry *frame_mpms_list;
1094
    uint32_t frame_mpms_list_cnt;
1095

1096
    uint32_t prefilter_id;
1097
    HashListTable *prefilter_hash_table;
1098

1099
    /** time of last ruleset reload */
1100
    struct timeval last_reload;
1101

1102
    /** signatures stats */
1103
    SigFileLoaderStat sig_stat;
1104

1105
    /* list of Fast Pattern registrations. Initially filled using a copy of
1106
     * `g_fp_support_smlist_list`, then extended at rule loading time if needed */
1107
    SCFPSupportSMList *fp_support_smlist_list;
1108

1109
    /** per keyword flag indicating if a prefilter has been
1110
     *  set for it. If true, the setup function will have to
1111
     *  run. */
1112
    bool *sm_types_prefilter;
1113
    bool *sm_types_silent_error;
1114

1115
    /* classification config parsing */
1116

1117
    /* hash table used for holding the classification config info */
1118
    HashTable *class_conf_ht;
1119
    pcre2_code *class_conf_regex;
1120
    pcre2_match_data *class_conf_regex_match;
1121

1122
    /* reference config parsing */
1123

1124
    /* hash table used for holding the reference config info */
1125
    HashTable *reference_conf_ht;
1126
    pcre2_code *reference_conf_regex;
1127
    pcre2_match_data *reference_conf_regex_match;
1128

1129
    /* --engine-analysis */
1130
    struct EngineAnalysisCtx_ *ea;
1131

1132
    /* path to the tenant yaml for this engine */
1133
    char *tenant_path;
1134

1135
    /* Track rule requirements for reporting after loading rules. */
1136
    SCDetectRequiresStatus *requirements;
1137

1138
    /* number of signatures using filestore, limited as u16 */
1139
    uint16_t filestore_cnt;
1140

1141
    /* name store for non-prefilter engines. Used in profiling but
1142
     * part of the API, so hash is always used. */
1143
    HashTable *non_pf_engine_names;
1144

1145
    const char *firewall_rule_file_exclusive;
1146

1147
    /* user provided rate filter callbacks. */
1148
    SCDetectRateFilterFunc RateFilterCallback;
1149

1150
    /* use provided data to be passed to rate_filter_callback. */
1151
    void *rate_filter_callback_arg;
1152

1153
    /* Hook for pre_stream engine if it is used. */
1154
    DetectPacketHookFunc PreStreamHook;
1155
    /** TCP pre_stream hook rule groups. One per direction. */
1156
    struct SigGroupHead_ *pre_stream_sgh[2];
1157

1158
    /* Hook for pre_flow engine if it is used. */
1159
    DetectPacketHookFunc PreFlowHook;
1160
    /** pre_flow hook rule groups. Before flow we don't know a direction yet. */
1161
    struct SigGroupHead_ *pre_flow_sgh;
1162
} DetectEngineCtx;
1163

1164
/**
1165
 * \brief Register a callback when a rate_filter has been applied to
1166
 *     an alert.
1167
 *
1168
 * This callback is added to the current detection engine and will be
1169
 * copied to all future detection engines over rule reloads.
1170
 */
1171
void SCDetectEngineRegisterRateFilterCallback(SCDetectRateFilterFunc cb, void *arg);
1172

1173
/* Engine groups profiles (low, medium, high, custom) */
1174
enum {
1175
    ENGINE_PROFILE_UNKNOWN,
1176
    ENGINE_PROFILE_LOW,
1177
    ENGINE_PROFILE_MEDIUM,
1178
    ENGINE_PROFILE_HIGH,
1179
    ENGINE_PROFILE_CUSTOM,
1180
};
1181

1182
/* Siggroup mpm context profile */
1183
enum {
1184
    ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL = 0,
1185
    ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE,
1186
    ENGINE_SGH_MPM_FACTORY_CONTEXT_AUTO,
1187
#define ENGINE_SGH_MPM_FACTORY_CONTEXT_START_ID_RANGE (ENGINE_SGH_MPM_FACTORY_CONTEXT_AUTO + 1)
35,469✔
1188
};
1189

1190
#define DETECT_FILESTORE_MAX 15
699✔
1191

1192
typedef struct SignatureNonPrefilterStore_ {
1193
    SigIntId id;
1194
    SignatureMask mask;
1195
    AppProto alproto;
1196
} SignatureNonPrefilterStore;
1197

1198
/** array of TX inspect rule candidates */
1199
typedef struct RuleMatchCandidateTx {
1200
    SigIntId id;            /**< internal signature id */
1201
    uint32_t *flags;        /**< inspect flags ptr */
1202
    union {
1203
        struct {
1204
            bool stream_stored;
1205
            uint8_t stream_result;
1206
        };
1207
        uint32_t stream_reset;
1208
    };
1209

1210
    const Signature *s;     /**< ptr to sig */
1211
} RuleMatchCandidateTx;
1212

1213
/** Stores a single u32 for a rule match of the type `sm_type`. Used by
1214
 *  flowbits prefilter to register DETECT_FLOWBITS,<flowbit id> for post
1215
 *  match handling. */
1216
typedef struct PostRuleMatchWorkQueueItem {
1217
    int sm_type;    /**< sigmatch type e.g. DETECT_FLOWBITS */
1218
    uint32_t value; /**< value to be interpreted by the sm_type
1219
                     *   implementation. E.g. flowbit id. */
1220
#ifdef DEBUG
1221
    SigIntId id;
1222
#endif
1223
} PostRuleMatchWorkQueueItem;
1224

1225
/** Array of PostRuleMatchWorkQueueItem's. */
1226
typedef struct PostRuleMatchWorkQueue {
1227
    PostRuleMatchWorkQueueItem *q; /**< array pointer */
1228
    uint32_t len;                  /**< number of array elements in use. */
1229
    uint32_t size;                 /**< allocation size in number of elements. */
1230
} PostRuleMatchWorkQueue;
1231

UNCOV
1232
#define SIG_JSON_CONTENT_ARRAY_LEN 16
×
UNCOV
1233
#define SIG_JSON_CONTENT_ITEM_LEN  1024
×
UNCOV
1234
#define SIG_JSON_CONTENT_KEY_LEN   32
×
1235

1236
/** structure to store the json content with info on sig that triggered it */
1237
typedef struct SigJsonContent {
1238
    void *id; /**< pointer to the sig that triggered this json content */
1239
    char json_content[SIG_JSON_CONTENT_ITEM_LEN];
1240
} SigJsonContent;
1241

1242
/**
1243
  * Detection engine thread data.
1244
  */
1245
typedef struct DetectEngineThreadCtx_ {
1246
    /** \note multi-tenant hash lookup code from Detect() *depends*
1247
     *        on this being the first member */
1248
    uint32_t tenant_id;
1249

1250
    SC_ATOMIC_DECLARE(int, so_far_used_by_detect);
1251

1252
    /* the thread to which this detection engine thread belongs */
1253
    ThreadVars *tv;
1254

1255
    uint32_t mt_det_ctxs_cnt;
1256
    struct DetectEngineThreadCtx_ **mt_det_ctxs;
1257
    HashTable *mt_det_ctxs_hash;
1258

1259
    struct DetectEngineTenantMapping_ *tenant_array;
1260
    uint32_t tenant_array_size;
1261

1262
    uint32_t (*TenantGetId)(const void *, const Packet *p);
1263

1264
    /* detection engine variables */
1265

1266
    uint64_t raw_stream_progress;
1267

1268
    /** offset into the payload of the end of the last match by: content, pcre, etc */
1269
    uint32_t buffer_offset;
1270

1271
    /** used by pcre match function alone: normally in sync with buffer_offset, but
1272
     *  points to 1 byte after the start of the last pcre match if a pcre match happened. */
1273
    uint32_t pcre_match_start_offset;
1274

1275
    /** SPM thread context used for scanning. This has been cloned from the
1276
     * prototype held by DetectEngineCtx. */
1277
    SpmThreadCtx *spm_thread_ctx;
1278

1279
    /* byte_* values */
1280
    uint64_t *byte_values;
1281

1282
    SigJsonContent *json_content;
1283
    uint8_t json_content_capacity;
1284
    uint8_t json_content_len;
1285

1286
    /* counter for the filestore array below -- up here for cache reasons. */
1287
    uint16_t filestore_cnt;
1288

1289
    /** id for alert counter */
1290
    StatsCounterId counter_alerts;
1291
    /** id for discarded alerts counter */
1292
    StatsCounterId counter_alerts_overflow;
1293
    /** id for suppressed alerts counter */
1294
    StatsCounterId counter_alerts_suppressed;
1295
#ifdef PROFILING
1296
    StatsCounterAvgId counter_mpm_list;
1297
    StatsCounterAvgId counter_match_list;
1298
#endif
1299

1300
    struct {
1301
        InspectionBuffer *buffers;
1302
        uint32_t buffers_size;          /**< in number of elements */
1303
        uint32_t to_clear_idx;
1304
        uint32_t *to_clear_queue;
1305
    } inspect;
1306

1307
    struct {
1308
        /** inspection buffers for more complex case. As we can inspect multiple
1309
         *  buffers in parallel, we need this extra wrapper struct */
1310
        InspectionBufferMultipleForList *buffers;
1311
        uint32_t buffers_size;                      /**< in number of elements */
1312
        uint32_t to_clear_idx;
1313
        uint32_t *to_clear_queue;
1314
    } multi_inspect;
1315

1316
    /* true if tx_id is set */
1317
    bool tx_id_set;
1318
    /** ID of the transaction currently being inspected. */
1319
    uint64_t tx_id;
1320
    int64_t frame_id;
1321
    uint64_t frame_inspect_progress; /**< used to set Frame::inspect_progress after all inspection
1322
                                        on a frame is complete. */
1323
    Packet *p;
1324

1325
    uint8_t *base64_decoded;
1326
    int base64_decoded_len;
1327

1328
    uint16_t alert_queue_size;
1329
    uint16_t alert_queue_capacity;
1330
    PacketAlert *alert_queue;
1331

1332
    /** array of signature pointers we're going to inspect in the detection
1333
     *  loop. */
1334
    Signature **match_array;
1335
    /** temporary array of signature pointers we're going to inspect in the
1336
     *   detection loop. */
1337
    const Signature **replace;
1338
    /** size of the array in items (mem size if * sizeof(Signature *)
1339
     *  Only used during initialization. */
1340
    uint32_t match_array_len;
1341
    /** size in use */
1342
    SigIntId match_array_cnt;
1343

1344
    RuleMatchCandidateTx *tx_candidates;
1345
    uint32_t tx_candidates_size;
1346

1347
    MpmThreadCtx mtc; /**< thread ctx for the mpm */
1348
    /* work queue for post-rule matching affecting prefilter */
1349
    PostRuleMatchWorkQueue post_rule_work_queue;
1350

1351
    PrefilterRuleStore pmq;
1352

1353
    /* string to replace */
1354
    DetectReplaceList *replist;
1355
    /* vars to store in post match function */
1356
    DetectVarList *varlist;
1357

1358
    /* Array in which the filestore keyword stores file id and tx id. If the
1359
     * full signature matches, these are processed by a post-match filestore
1360
     * function to finalize the store. */
1361
    struct {
1362
        uint32_t file_id;
1363
        uint64_t tx_id;
1364
    } filestore[DETECT_FILESTORE_MAX];
1365

1366
    DetectEngineCtx *de_ctx;
1367
    /** store for keyword contexts that need a per thread storage. Per de_ctx. */
1368
    void **keyword_ctxs_array;
1369
    int keyword_ctxs_size;
1370
    /** store for keyword contexts that need a per thread storage. Global. */
1371
    int global_keyword_ctxs_size;
1372
    void **global_keyword_ctxs_array;
1373

1374
    AppLayerDecoderEvents *decoder_events;
1375
    uint16_t events;
1376

1377
    /** stats id for lua rule errors */
1378
    StatsCounterId lua_rule_errors;
1379

1380
    /** stats id for lua blocked function counts */
1381
    StatsCounterId lua_blocked_function_errors;
1382

1383
    /** stats if for lua instruction limit errors */
1384
    StatsCounterId lua_instruction_limit_errors;
1385

1386
    /** stat of lua memory limit errors. */
1387
    StatsCounterId lua_memory_limit_errors;
1388

1389
#ifdef DEBUG
1390
    uint64_t pkt_stream_add_cnt;
1391
    uint64_t payload_mpm_cnt;
1392
    uint64_t payload_mpm_size;
1393
    uint64_t stream_mpm_cnt;
1394
    uint64_t stream_mpm_size;
1395
    uint64_t payload_persig_cnt;
1396
    uint64_t payload_persig_size;
1397
    uint64_t stream_persig_cnt;
1398
    uint64_t stream_persig_size;
1399
#endif
1400
#ifdef PROFILE_RULES
1401
    struct SCProfileData_ *rule_perf_data;
1402
    int rule_perf_data_size;
1403
    uint32_t rule_perf_last_sync;
1404
#endif
1405
#ifdef PROFILING
1406
    struct SCProfileKeywordData_ *keyword_perf_data;
1407
    struct SCProfileKeywordData_ **keyword_perf_data_per_list;
1408
    int keyword_perf_list; /**< list we're currently inspecting, DETECT_SM_LIST_* */
1409
    struct SCProfileSghData_ *sgh_perf_data;
1410

1411
    struct SCProfilePrefilterData_ *prefilter_perf_data;
1412
    /** bytes inspected by current prefilter callback call */
1413
    uint64_t prefilter_bytes;
1414
    /** number of times we inspected a buffer */
1415
    uint64_t prefilter_bytes_called;
1416
#endif
1417
} DetectEngineThreadCtx;
1418

1419
/** \brief element in sigmatch type table.
1420
 */
1421
typedef struct SigTableElmt_ {
1422
    /** Packet match function pointer */
1423
    int (*Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *);
1424

1425
    /** AppLayer TX match function pointer */
1426
    int (*AppLayerTxMatch)(DetectEngineThreadCtx *, Flow *,
1427
            uint8_t flags, void *alstate, void *txv,
1428
            const Signature *, const SigMatchCtx *);
1429

1430
    /** File match function pointer */
1431
    int (*FileMatch)(DetectEngineThreadCtx *,
1432
        Flow *,                     /**< *LOCKED* flow */
1433
        uint8_t flags, File *, const Signature *, const SigMatchCtx *);
1434

1435
    /** InspectionBuffer transformation callback */
1436
    void (*Transform)(DetectEngineThreadCtx *, InspectionBuffer *, void *context);
1437
    bool (*TransformValidate)(const uint8_t *content, uint16_t content_len, void *context);
1438

1439
    /** Transform identity callback */
1440
    void (*TransformId)(const uint8_t **data, uint32_t *length, void *context);
1441

1442
    /** keyword setup function pointer */
1443
    int (*Setup)(DetectEngineCtx *, Signature *, const char *);
1444

1445
    bool (*SupportsPrefilter)(const Signature *s);
1446
    int (*SetupPrefilter)(DetectEngineCtx *de_ctx, struct SigGroupHead_ *sgh);
1447

1448
    void (*Free)(DetectEngineCtx *, void *);
1449
#ifdef UNITTESTS
1450
    void (*RegisterTests)(void);
1451
#endif
1452
    uint32_t flags;
1453
    /* coccinelle: SigTableElmt:flags:SIGMATCH_ */
1454

1455
    /** bitfield of tables supported by this rule: used by DETECT_TABLE_*_FLAG flags. */
1456
    uint8_t tables;
1457

1458
    /** better keyword to replace the current one */
1459
    uint16_t alternative;
1460

1461
    const char *name;     /**< keyword name alias */
1462
    const char *alias;    /**< name alias */
1463
    const char *desc;
1464
    const char *url;
1465

1466
    // Cleanup function for freeing rust allocated name or such
1467
    void (*Cleanup)(struct SigTableElmt_ *);
1468
} SigTableElmt;
1469

1470
/* event code */
1471
enum {
1472
    FILE_DECODER_EVENT_NO_MEM,
1473
    FILE_DECODER_EVENT_INVALID_SWF_LENGTH,
1474
    FILE_DECODER_EVENT_INVALID_SWF_VERSION,
1475
    FILE_DECODER_EVENT_Z_DATA_ERROR,
1476
    FILE_DECODER_EVENT_Z_STREAM_ERROR,
1477
    FILE_DECODER_EVENT_Z_BUF_ERROR,
1478
    FILE_DECODER_EVENT_Z_UNKNOWN_ERROR,
1479
    FILE_DECODER_EVENT_LZMA_IO_ERROR,
1480
    FILE_DECODER_EVENT_LZMA_HEADER_TOO_SHORT_ERROR,
1481
    FILE_DECODER_EVENT_LZMA_DECODER_ERROR,
1482
    FILE_DECODER_EVENT_LZMA_MEMLIMIT_ERROR,
1483
    FILE_DECODER_EVENT_LZMA_XZ_ERROR,
1484
    FILE_DECODER_EVENT_LZMA_UNKNOWN_ERROR,
1485

1486
    DETECT_EVENT_TOO_MANY_BUFFERS,
1487
    DETECT_EVENT_POST_MATCH_QUEUE_FAILED,
1488
};
1489

1490
#define SIG_GROUP_HEAD_HAVERAWSTREAM BIT_U16(0)
65,843✔
1491
#ifdef HAVE_MAGIC
1492
#define SIG_GROUP_HEAD_HAVEFILEMAGIC BIT_U16(1)
56,406✔
1493
#endif
1494
#define SIG_GROUP_HEAD_HAVEFILEMD5    BIT_U16(2)
55,442✔
1495
// vacancy
1496
#define SIG_GROUP_HEAD_HAVEFILESHA1   BIT_U16(4)
55,442✔
1497
#define SIG_GROUP_HEAD_HAVEFILESHA256 BIT_U16(5)
55,442✔
1498

1499
enum MpmBuiltinBuffers {
1500
    MPMB_TCP_PKT_TS,
1501
    MPMB_TCP_PKT_TC,
1502
    MPMB_TCP_STREAM_TS,
1503
    MPMB_TCP_STREAM_TC,
1504
    MPMB_UDP_TS,
1505
    MPMB_UDP_TC,
1506
    MPMB_OTHERIP,
1507
    MPMB_MAX,
1508
};
1509

1510
typedef struct MpmStore_ {
1511
    uint8_t *sid_array;
1512
    uint32_t sid_array_size;
1513

1514
    int direction;
1515
    enum MpmBuiltinBuffers buffer;
1516
    int sm_list;
1517
    int32_t sgh_mpm_context;
1518
    AppProto alproto;
1519
    MpmCtx *mpm_ctx;
1520

1521
} MpmStore;
1522

1523
typedef void (*PrefilterPktFn)(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx);
1524
typedef void (*PrefilterFrameFn)(DetectEngineThreadCtx *det_ctx, const void *pectx, Packet *p,
1525
        const struct Frames *frames, const struct Frame *frame);
1526

1527
typedef struct AppLayerTxData AppLayerTxData;
1528
typedef void (*PrefilterTxFn)(DetectEngineThreadCtx *det_ctx, const void *pectx, Packet *p, Flow *f,
1529
        void *tx, const uint64_t tx_id, const AppLayerTxData *tx_data, const uint8_t flags);
1530

1531
typedef struct PrefilterEngineList_ {
1532
    uint16_t id;
1533

1534
    /** App Proto this engine applies to: only used with Tx Engines */
1535
    AppProto alproto;
1536
    /** Minimal Tx progress we need before running the engine. Only used
1537
     *  with Tx Engine. Set to -1 for all states. */
1538
    int8_t tx_min_progress;
1539

1540
    uint8_t frame_type;
1541

1542
    SignatureMask pkt_mask; /**< mask for pkt engines */
1543

1544
    enum SignatureHookPkt pkt_hook;
1545

1546
    /** Context for matching. Might be MpmCtx for MPM engines, other ctx'
1547
     *  for other engines. */
1548
    void *pectx;
1549

1550
    PrefilterPktFn Prefilter;
1551
    PrefilterTxFn PrefilterTx;
1552
    PrefilterFrameFn PrefilterFrame;
1553
    void (*PrefilterPostRule)(
1554
            DetectEngineThreadCtx *det_ctx, const void *pectx, Packet *p, Flow *f);
1555

1556
    struct PrefilterEngineList_ *next;
1557

1558
    /** Free function for pectx data. If NULL the memory is not freed. */
1559
    void (*Free)(void *pectx);
1560

1561
    const char *name;
1562
    /* global id for this prefilter */
1563
    uint32_t gid;
1564
} PrefilterEngineList;
1565

1566
typedef struct PrefilterEngine_ {
1567
    uint16_t local_id;
1568

1569
    /** App Proto this engine applies to: only used with Tx Engines */
1570
    AppProto alproto;
1571

1572
    union {
1573
        struct {
1574
            SignatureMask mask; /**< mask for pkt engines */
1575
            uint8_t hook;       /**< enum SignatureHookPkt */
1576
        } pkt;
1577
        /** Minimal Tx progress we need before running the engine. Only used
1578
         *  with Tx Engine. Set to -1 for all states. */
1579
        int8_t tx_min_progress;
1580
        uint8_t frame_type;
1581
    } ctx;
1582

1583
    bool is_last;
1584
    bool is_last_for_progress;
1585

1586
    /** Context for matching. Might be MpmCtx for MPM engines, other ctx'
1587
     *  for other engines. */
1588
    void *pectx;
1589

1590
    union {
1591
        PrefilterPktFn Prefilter;
1592
        PrefilterTxFn PrefilterTx;
1593
        PrefilterFrameFn PrefilterFrame;
1594
        void (*PrefilterPostRule)(
1595
                DetectEngineThreadCtx *det_ctx, const void *pectx, Packet *p, Flow *f);
1596
    } cb;
1597

1598
    /* global id for this prefilter */
1599
    uint32_t gid;
1600
} PrefilterEngine;
1601

1602
typedef struct SigGroupHeadInitData_ {
1603
    MpmStore mpm_store[MPMB_MAX];
1604

1605
    uint8_t *sig_array; /**< bit array of sig nums (internal id's) */
1606
    uint32_t sig_size; /**< size in bytes */
1607

1608
    uint8_t protos[256];    /**< proto(s) this sgh is for */
1609
    uint32_t direction;     /**< set to SIG_FLAG_TOSERVER, SIG_FLAG_TOCLIENT or both */
1610
    int score;              /**< try to make this group a unique one */
1611
    uint32_t max_sig_id;    /**< max signature idx for this sgh */
1612

1613
    MpmCtx **app_mpms;
1614
    MpmCtx **pkt_mpms;
1615
    MpmCtx **frame_mpms;
1616

1617
    PrefilterEngineList *pkt_engines;
1618
    PrefilterEngineList *payload_engines;
1619
    PrefilterEngineList *tx_engines;
1620
    PrefilterEngineList *frame_engines;
1621
    PrefilterEngineList *post_rule_match_engines;
1622

1623
    /** number of sigs in this group */
1624
    SigIntId sig_cnt;
1625

1626
    /** Array with sig ptrs... size is sig_cnt * sizeof(Signature *) */
1627
    Signature **match_array;
1628
} SigGroupHeadInitData;
1629

1630
/** \brief Container for matching data for a signature group */
1631
typedef struct SigGroupHead_ {
1632
    uint16_t flags;
1633
    /* coccinelle: SigGroupHead:flags:SIG_GROUP_HEAD_ */
1634

1635
    /** the number of signatures in this sgh that have the filestore keyword
1636
     *  set. */
1637
    uint16_t filestore_cnt;
1638

1639
    uint32_t id; /**< unique id used to index sgh_array for stats */
1640

1641
    PrefilterEngine *pkt_engines;
1642
    PrefilterEngine *payload_engines;
1643
    PrefilterEngine *tx_engines;
1644
    PrefilterEngine *frame_engines;
1645
    PrefilterEngine *post_rule_match_engines; /**< engines to run after rules modified a state */
1646

1647
    /* ptr to our init data we only use at... init :) */
1648
    SigGroupHeadInitData *init;
1649

1650
} SigGroupHead;
1651

1652
/** sigmatch has no options, so the parser shouldn't expect any */
1653
#define SIGMATCH_NOOPT BIT_U32(0)
8,132,494✔
1654
/** sigmatch is compatible with a ip only rule */
1655
#define SIGMATCH_IPONLY_COMPAT          BIT_U16(1)
150,353✔
1656
/** sigmatch is compatible with a decode event only rule */
1657
#define SIGMATCH_DEONLY_COMPAT          BIT_U16(2)
81,185✔
1658

1659
// vacancy
1660

1661
/** sigmatch may have options, so the parser should be ready to
1662
 *  deal with both cases */
1663
#define SIGMATCH_OPTIONAL_OPT BIT_U32(4)
7,308,881✔
1664
/** input may be wrapped in double quotes. They will be stripped before
1665
 *  input data is passed to keyword parser */
1666
#define SIGMATCH_QUOTES_OPTIONAL BIT_U32(5)
6,490,923✔
1667
/** input MUST be wrapped in double quotes. They will be stripped before
1668
 *  input data is passed to keyword parser. Missing double quotes lead to
1669
 *  error and signature invalidation. */
1670
#define SIGMATCH_QUOTES_MANDATORY BIT_U32(6)
12,992,595✔
1671
/** negation parsing is handled by the rule parser. Signature::init_data::negated
1672
 *  will be set to true or false prior to calling the keyword parser. Exclamation
1673
 *  mark is stripped from the input to the keyword parser. */
1674
#define SIGMATCH_HANDLE_NEGATION BIT_U32(7)
6,501,910✔
1675
/** keyword is a content modifier */
1676
#define SIGMATCH_INFO_CONTENT_MODIFIER BIT_U32(8)
39✔
1677
/** keyword is a sticky buffer */
1678
#define SIGMATCH_INFO_STICKY_BUFFER BIT_U32(9)
261✔
1679
/** keyword is deprecated: used to suggest an alternative */
1680
#define SIGMATCH_INFO_DEPRECATED BIT_U32(10)
7,300,901✔
1681
/** strict parsing is enabled */
1682
#define SIGMATCH_STRICT_PARSING BIT_U32(11)
32,657✔
1683
/** keyword supported by firewall rules */
1684
#define SIGMATCH_SUPPORT_FIREWALL BIT_U32(12)
48✔
1685
/** keyword supporting setting an optional direction */
1686
#define SIGMATCH_SUPPORT_DIR BIT_U32(13)
6,440,442✔
1687
/** keyword is a multi buffer */
1688
#define SIGMATCH_INFO_MULTI_BUFFER BIT_U32(14)
72✔
1689
/** keyword is a unsigned 8-bit integer */
1690
#define SIGMATCH_INFO_UINT8 BIT_U32(15)
33✔
1691
/** keyword is a unsigned 16-bit integer */
1692
#define SIGMATCH_INFO_UINT16 BIT_U32(16)
33✔
1693
/** keyword is a unsigned 32-bit integer */
1694
#define SIGMATCH_INFO_UINT32 BIT_U32(17)
30✔
1695
/** keyword is a unsigned 64-bit integer */
1696
#define SIGMATCH_INFO_UINT64 BIT_U32(18)
15✔
1697
/** keyword is a multi uint */
1698
#define SIGMATCH_INFO_MULTI_UINT BIT_U32(19)
18✔
1699
/** keyword is an uint with enumeration stringer */
1700
#define SIGMATCH_INFO_ENUM_UINT BIT_U32(20)
9✔
1701
/** keyword is an uint with bitflags */
1702
#define SIGMATCH_INFO_BITFLAGS_UINT BIT_U32(21)
9✔
1703

1704
enum DetectEngineTenantSelectors
1705
{
1706
    TENANT_SELECTOR_UNKNOWN = 0,    /**< not set */
1707
    TENANT_SELECTOR_DIRECT,         /**< method provides direct tenant id */
1708
    TENANT_SELECTOR_VLAN,           /**< map vlan to tenant id */
1709
    TENANT_SELECTOR_LIVEDEV,        /**< map livedev to tenant id */
1710
};
1711

1712
typedef struct DetectEngineTenantMapping_ {
1713
    uint32_t tenant_id;
1714

1715
    /* traffic id that maps to the tenant id */
1716
    uint32_t traffic_id;
1717

1718
    struct DetectEngineTenantMapping_ *next;
1719
} DetectEngineTenantMapping;
1720

1721
typedef struct DetectEngineMasterCtx_ {
1722
    SCMutex lock;
1723

1724
    /** enable multi tenant mode */
1725
    int multi_tenant_enabled;
1726

1727
    /** version, incremented after each 'apply to threads' */
1728
    uint32_t version;
1729

1730
    /** list of active detection engines. This list is used to generate the
1731
     *  threads det_ctx's */
1732
    DetectEngineCtx *list;
1733

1734
    /** free list, containing detection engines that will be removed but may
1735
     *  still be referenced by det_ctx's. Freed as soon as all references are
1736
     *  gone. */
1737
    DetectEngineCtx *free_list;
1738

1739
    enum DetectEngineTenantSelectors tenant_selector;
1740

1741
    /** list of tenant mappings. Updated under lock. Used to generate lookup
1742
     *  structures. */
1743
    DetectEngineTenantMapping *tenant_mapping_list;
1744

1745
    /** list of keywords that need thread local ctxs,
1746
     *  only updated by keyword registration at start up. Not
1747
     *  covered by the lock. */
1748
    DetectEngineThreadKeywordCtxItem *keyword_list;
1749
    int keyword_id;
1750
} DetectEngineMasterCtx;
1751

1752
/* Table with all SigMatch registrations */
1753
extern SigTableElmt *sigmatch_table;
1754

1755
/** Remember to add the options in SignatureIsIPOnly() at detect.c otherwise it wont be part of a signature group */
1756

1757
#define DETECT_ENGINE_MPM_CACHE_OP_PRUNE BIT_U32(0)
35,438✔
1758
#define DETECT_ENGINE_MPM_CACHE_OP_SAVE  BIT_U32(1)
35,438✔
1759

1760
/* detection api */
1761
TmEcode Detect(ThreadVars *tv, Packet *p, void *data);
1762
uint8_t DetectPreFlow(ThreadVars *tv, DetectEngineThreadCtx *det_ctx, Packet *p);
1763
uint8_t DetectPreStream(ThreadVars *tv, DetectEngineThreadCtx *det_ctx, Packet *p);
1764

1765
SigMatch *SigMatchAlloc(void);
1766
Signature *SigFindSignatureBySidGid(DetectEngineCtx *, uint32_t, uint32_t);
1767
void SigMatchFree(DetectEngineCtx *, SigMatch *sm);
1768

1769
void SigRegisterTests(void);
1770

1771
void DisableDetectFlowFileFlags(Flow *f);
1772
char *DetectLoadCompleteSigPath(const DetectEngineCtx *, const char *sig_file);
1773
int SigLoadSignatures(DetectEngineCtx *, char *, bool);
1774
void SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx,
1775
                       DetectEngineThreadCtx *det_ctx, Packet *p);
1776

1777
int SignatureIsIPOnly(DetectEngineCtx *de_ctx, const Signature *s);
1778
const SigGroupHead *SigMatchSignaturesGetSgh(const DetectEngineCtx *de_ctx, const Packet *p);
1779

1780
int DetectUnregisterThreadCtxFuncs(DetectEngineCtx *, void *data, const char *name);
1781
int DetectRegisterThreadCtxFuncs(DetectEngineCtx *, const char *name, void *(*InitFunc)(void *), void *data, void (*FreeFunc)(void *), int);
1782
void *DetectThreadCtxGetKeywordThreadCtx(DetectEngineThreadCtx *, int);
1783
void *DetectGetInnerTx(void *tx_ptr, AppProto alproto, AppProto engine_alproto, uint8_t flow_flags);
1784

1785
void RuleMatchCandidateTxArrayInit(DetectEngineThreadCtx *det_ctx, uint32_t size);
1786
void RuleMatchCandidateTxArrayFree(DetectEngineThreadCtx *det_ctx);
1787

1788
int DetectFlowbitsAnalyze(DetectEngineCtx *de_ctx);
1789

1790
int DetectMetadataHashInit(DetectEngineCtx *de_ctx);
1791
void DetectMetadataHashFree(DetectEngineCtx *de_ctx);
1792

1793
/* events */
1794
void DetectEngineSetEvent(DetectEngineThreadCtx *det_ctx, uint8_t e);
1795

1796
void DumpPatterns(DetectEngineCtx *de_ctx);
1797

1798
#endif /* SURICATA_DETECT_H */
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc