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