Go to the documentation of this file.
56 #define PARSE_REGEX "^([a-z]+)(?:,\\s*(.*))?"
59 #define MAX_TOKENS 100
69 static bool PrefilterFlowbitIsPrefilterable(
const Signature *s);
95 static bool DetectFlowbitIsPostmatch(uint8_t cmd)
116 static inline int DetectFlowbitValidateDo(
117 Signature *s, uint8_t cmd, uint8_t cmd2, uint32_t idx,
bool err)
119 bool postmatch = DetectFlowbitIsPostmatch(cmd);
128 if ((fd->
idx == idx) && (fd->
cmd == cmd)) {
130 SCLogError(
"invalid flowbit command combination in the same signature: isset and "
135 "inconsequential flowbit command combination in the same signature: %s and %s",
148 struct DetectFlowbitInvalidCmdMap_ {
154 struct DetectFlowbitInvalidCmdMap_ icmds_map[] = {
168 for (uint8_t i = 0; i <
ARRAY_SIZE(icmds_map); i++) {
169 if (fd->
cmd == icmds_map[i].cmd1) {
170 ret = DetectFlowbitValidateDo(
171 s, icmds_map[i].cmd2, icmds_map[i].cmd1, fd->
idx, icmds_map[i].err);
175 }
else if (fd->
cmd == icmds_map[i].cmd2) {
176 ret = DetectFlowbitValidateDo(
177 s, icmds_map[i].cmd1, icmds_map[i].cmd2, fd->
idx, icmds_map[i].err);
191 char *saveptr = NULL;
194 while ((token = strtok_r(arrptr,
"|", &saveptr))) {
196 while(isspace((
unsigned char)*token))
200 char *end = token + strlen(token) - 1;
201 while(end > token && isspace((
unsigned char)*end))
205 if (strchr(token,
' ') != NULL) {
206 SCLogError(
"Spaces are not allowed in flowbit names.");
212 "maximum allowed: %d.",
311 return DetectFlowbitMatchIsset(p,fd);
313 return DetectFlowbitMatchIsnotset(p,fd);
315 int r = DetectFlowbitMatchSet(p, fd);
318 SCLogDebug(
"flowbit set, appending to work queue");
324 return DetectFlowbitMatchUnset(p,fd);
326 int r = DetectFlowbitMatchToggle(p, fd);
328 SCLogDebug(
"flowbit set (by toggle), appending to work queue");
341 static int DetectFlowbitParse(
const char *
str,
char *cmd,
int cmd_len,
char *
name,
346 pcre2_match_data *match = NULL;
349 if (count != 2 && count != 3) {
350 SCLogError(
"\"%s\" is not a valid setting for flowbits.",
str);
355 rc = pcre2_substring_copy_bynumber(match, 1, (PCRE2_UCHAR8 *)cmd, &pcre2len);
357 SCLogError(
"pcre2_substring_copy_bynumber failed");
363 rc = pcre2_substring_copy_bynumber(match, 2, (PCRE2_UCHAR8 *)
name, &pcre2len);
365 SCLogError(
"pcre2_substring_copy_bynumber failed");
370 while (strlen(
name) > 0 && isblank(
name[strlen(
name) - 1])) {
374 if (strchr(
name,
'|') == NULL) {
376 for (
size_t i = 0; i < strlen(
name); i++) {
377 if (isblank(
name[i])) {
378 SCLogError(
"spaces not allowed in flowbit names");
385 pcre2_match_data_free(match);
390 pcre2_match_data_free(match);
399 char fb_cmd_str[16] =
"", fb_name[256] =
"";
401 if (!DetectFlowbitParse(rawstr, fb_cmd_str,
sizeof(fb_cmd_str), fb_name,
406 if (strcmp(fb_cmd_str,
"noalert") == 0) {
407 if (strlen(fb_name) != 0)
411 }
else if (strcmp(fb_cmd_str,
"isset") == 0) {
413 }
else if (strcmp(fb_cmd_str,
"isnotset") == 0) {
415 }
else if (strcmp(fb_cmd_str,
"set") == 0) {
417 }
else if (strcmp(fb_cmd_str,
"unset") == 0) {
419 }
else if (strcmp(fb_cmd_str,
"toggle") == 0) {
422 SCLogError(
"ERROR: flowbits action \"%s\" is not supported.", fb_cmd_str);
433 if (strlen(fb_name) == 0)
441 if (strchr(fb_name,
'|') != NULL) {
442 int retval = FlowbitOrAddData(
de_ctx, cd, fb_name);
451 cd->
idx = varname_id;
456 SCLogDebug(
"idx %" PRIu32
", cmd %s, name %s",
457 cd->
idx, fb_cmd_str, strlen(fb_name) ? fb_name :
"(none)");
460 if (DetectFlowbitValidate(s, cd) != 0) {
549 struct FBAnalyze *array, uint32_t elements);
551 static void FBAnalyzerArrayFree(
struct FBAnalyze *array,
const uint32_t array_size)
554 for (uint32_t i = 0; i < array_size; i++) {
555 SCFree(array[i].set_sids);
556 SCFree(array[i].unset_sids);
557 SCFree(array[i].isset_sids);
558 SCFree(array[i].isnotset_sids);
559 SCFree(array[i].toggle_sids);
565 static void FBAnalyzerFree(
struct FBAnalyzer *fba)
567 if (fba && fba->
array) {
575 static bool CheckExpand(
const uint32_t sids_idx, uint32_t **sids, uint32_t *sids_size)
577 if (sids_idx >= *sids_size) {
578 const uint32_t old_size = *sids_size;
579 const uint32_t new_size =
MAX(2 * old_size,
MAX_SIDS);
581 void *ptr =
SCRealloc(*sids, new_size *
sizeof(uint32_t));
584 *sids_size = new_size;
683 SCLogError(
"Unable to allocate flowbit analyze array");
690 (uint64_t)(array_size *
sizeof(
struct FBAnalyze)));
696 int r = DetectFlowbitsAnalyzeSignature(s, &fba);
698 FBAnalyzerFree(&fba);
704 for (uint32_t i = 0; i < array_size; i++) {
709 bool to_state =
false;
717 "set. Checked in %u and %u other sigs",
723 SCLogDebug(
"flowbit %s/%u: isset in state, set not in state", varname, i);
732 SCLogDebug(
"flowbit %s/%u: isset not in state, set in state", varname, i);
736 SCLogDebug(
"ALL flowbit %s/%u: sets %u toggles %u unsets %u isnotsets %u issets %u", varname, i,
740 SCLogDebug(
"STATE flowbit %s/%u: sets %u toggles %u unsets %u isnotsets %u issets %u", varname, i,
745 SCLogDebug(
"SET flowbit %s/%u: SID %u", varname, i,
751 SCLogDebug(
"GET flowbit %s/%u: SID %u", varname, i, s->
id);
761 SCCalloc(sids_array_size,
sizeof(uint32_t));
763 SCLogError(
"Failed to allocate memory for rule_state_dependant_ids");
770 SCLogError(
"Failed to allocate memory for rule_state_variable_idx");
774 SCLogDebug(
"alloc'ed array for rule dependency and fbs idx array, sid %u, "
775 "sizes are %u and %u",
779 uint32_t new_array_size =
782 new_array_size *
sizeof(uint32_t));
783 if (tmp_ptr == NULL) {
784 SCLogError(
"Failed to allocate memory for rule_state_variable_idx");
789 SCLogDebug(
"realloc'ed array for rule dependency, sid %u, new size is %u",
793 new_fb_array_size *
sizeof(uint32_t));
796 SCLogError(
"Failed to reallocate memory for rule_state_variable_idx");
800 "realloc'ed array for flowbits ids, new size is %u", new_fb_array_size);
818 SCLogDebug(
"made SID %u stateful because it depends on "
819 "stateful rules that set flowbit %s", s->
id, varname);
825 DetectFlowbitsAnalyzeDump(
de_ctx, array, array_size);
828 FBAnalyzerFree(&fba);
831 FBAnalyzerFree(&fba);
836 static struct FBAnalyzer DetectFlowbitsAnalyzeForGroup(
848 SCLogError(
"Unable to allocate flowbit analyze array");
852 "fb analyzer array size: %" PRIu64, (uint64_t)(array_size *
sizeof(
struct FBAnalyze)));
857 for (uint32_t i = 0; i < sgh->init->sig_cnt; i++) {
858 const Signature *s = sgh->init->match_array[i];
861 int r = DetectFlowbitsAnalyzeSignature(s, &fba);
863 FBAnalyzerFree(&fba);
869 for (uint32_t i = 0; i < array_size; i++) {
874 bool to_state =
false;
877 SCLogDebug(
"flowbit %s/%u: isset in state, set not in state", varname, i);
885 SCLogDebug(
"flowbit %s/%u: isset not in state, set in state", varname, i);
889 SCLogDebug(
"ALL flowbit %s/%u: sets %u toggles %u unsets %u isnotsets %u issets %u",
894 SCLogDebug(
"STATE flowbit %s/%u: sets %u toggles %u unsets %u isnotsets %u issets %u",
901 SCLogDebug(
"SET flowbit %s/%u: SID %u", varname, i,
906 SCLogDebug(
"GET flowbit %s/%u: SID %u", varname, i, s->
id);
910 SCLogDebug(
"made SID %u stateful because it depends on "
911 "stateful rules that set flowbit %s",
922 struct FBAnalyze *array, uint32_t elements)
924 SCJsonBuilder *js = SCJbNewObject();
928 SCJbOpenArray(js,
"flowbits");
929 for (uint32_t x = 0; x < elements; x++) {
937 SCJbSetString(js,
"name", varname);
938 SCJbSetUint(js,
"internal_id", x);
947 SCJbOpenArray(js,
"sets");
950 SCJbAppendUint(js, s->
id);
956 SCJbOpenArray(js,
"isset");
959 SCJbAppendUint(js, s->
id);
965 SCJbOpenArray(js,
"isnotset");
968 SCJbAppendUint(js, s->
id);
974 SCJbOpenArray(js,
"unset");
977 SCJbAppendUint(js, s->
id);
983 SCJbOpenArray(js,
"toggle");
986 SCJbAppendUint(js, s->
id);
995 const char *filename =
"flowbits.json";
997 char log_path[PATH_MAX] =
"";
998 snprintf(log_path,
sizeof(log_path),
"%s/%s", log_dir, filename);
1001 FILE *fp = fopen(log_path,
"w");
1003 fwrite(SCJbPtr(js), SCJbLen(js), 1, fp);
1012 static bool PrefilterFlowbitIsPrefilterable(
const Signature *s)
1022 SCLogDebug(
"sid:%u: FLOWBITS ISSET can prefilter", s->
id);
1047 else if (a->
id < b->
id)
1062 static void PrefilterFlowbitFree(
void *vctx)
1067 PFB_RB_REMOVE(&
ctx->fb_tree, rec);
1080 if (p->
flow == NULL) {
1089 memset(&lookup, 0,
sizeof(lookup));
1090 lookup.
id = gv->idx;
1097 SCLogDebug(
"flowbit %u found in the tree: %u", lookup.
id, b->
id);
1110 static void PrefilterFlowbitPostRuleMatch(
1116 if (p->
flow == NULL) {
1126 memset(&lookup, 0,
sizeof(lookup));
1133 SCLogDebug(
"flowbit %u found in the tree: %u. Adding %u sids", lookup.
id, b->
id,
1148 #define BLOCK_SIZE 8
1150 static int AddBitAndSid(
1154 memset(&x, 0,
sizeof(x));
1163 add->
id = flowbit_id;
1174 SCLogDebug(
"not found, so added (res %p)", res);
1204 if (AddBitAndSid(
ctx, s, fb->
idx) < 0) {
1210 if (AddBitAndSid(
ctx, s, fb->
or_list[i]) < 0) {
1218 static uint32_t NextMultiple(
const uint32_t v,
const uint32_t
m)
1220 return v + (
m - v %
m);
1244 SCLogDebug(
"flowbit: %u => rejected sid %u (iid:%u). No prefilter or prefilter not "
1245 "flowbits (%p, %s, %d)",
1255 if (fs_fb->
idx != fb->
idx) {
1257 "flowbit: %u => rejected sid %u (iid:%u). Sig prefilters on different bit %u",
1258 fb->
idx, s->
id, sig_iid, fs_fb->
idx);
1264 if (add->
rule_id[x] == sig_iid) {
1283 SCLogDebug(
"flowbit: %u => accepted sid %u (iid:%u)", fb->
idx, s->
id, sig_iid);
1300 memset(&x, 0,
sizeof(x));
1316 if (AddIssetSidsForBit(
de_ctx, fba, fb, add) != 1) {
1323 SCLogDebug(
"not found, so added (res %p)", res);
1328 int r = AddIssetSidsForBit(
de_ctx, fba, fb, pfb);
1331 }
else if (r == 0) {
1353 SCLogDebug(
"sgh %p: setting up prefilter", sgh);
1357 struct FBAnalyzer fb_analysis = DetectFlowbitsAnalyzeForGroup(
de_ctx, sgh);
1358 if (fb_analysis.
array == NULL)
1361 for (uint32_t i = 0; i < sgh->
init->
sig_cnt; i++) {
1379 "DETECT_SM_LIST_POSTMATCH: sid %u DETECT_FLOWBITS set %u", s->
id, fb->
idx);
1381 SCLogDebug(
"DETECT_SM_LIST_POSTMATCH: sid %u DETECT_FLOWBITS toggle %u", s->
id,
1390 SCLogDebug(
"flowbit %u not supported: unset in use", fb->
idx);
1394 if (set_ctx == NULL) {
1395 set_ctx =
SCCalloc(1,
sizeof(*set_ctx));
1396 if (set_ctx == NULL)
1400 SCLogDebug(
"setting up sets/toggles for sid %u", s->
id);
1401 if (AddBitSetToggle(
de_ctx, &fb_analysis, set_ctx, fb, s) == 1) {
1416 SCLogDebug(
"no prefilter or prefilter not flowbits");
1423 SCLogDebug(
"flowbit %u not supported: toggle or unset in use", fb->
idx);
1431 if (isset_ctx == NULL) {
1432 isset_ctx =
SCCalloc(1,
sizeof(*isset_ctx));
1433 if (isset_ctx == NULL)
1436 if (AddBitsAndSid(
de_ctx, isset_ctx, fb, s) < 0) {
1442 static const char *g_prefilter_flowbits_isset =
"flowbits:isset";
1443 if (isset_ctx != NULL) {
1446 isset_ctx, PrefilterFlowbitFree, g_prefilter_flowbits_isset);
1450 static const char *g_prefilter_flowbits_set =
"flowbits:set";
1452 PrefilterFlowbitFree, g_prefilter_flowbits_set);
1453 SCLogDebug(
"set/toggle: added prefilter engine");
1456 PrefilterFlowbitFree(set_ctx);
1458 SCLogDebug(
"set/toggle: NO prefilter engine added");
1460 }
else if (set_ctx != NULL) {
1461 PrefilterFlowbitFree(set_ctx);
1463 FBAnalyzerFree(&fb_analysis);
1468 PrefilterFlowbitFree(set_ctx);
1471 PrefilterFlowbitFree(isset_ctx);
1473 FBAnalyzerFree(&fb_analysis);
1479 static int FlowBitsTestParse01(
void)
1481 char command[16] =
"",
name[16] =
"";
1484 FAIL_IF(!DetectFlowbitParse(
"noalert", command,
sizeof(command),
name,
1486 FAIL_IF(strcmp(command,
"noalert") != 0);
1489 FAIL_IF(!DetectFlowbitParse(
"set,flowbit", command,
sizeof(command),
name,
1491 FAIL_IF(strcmp(command,
"set") != 0);
1495 FAIL_IF(!DetectFlowbitParse(
"set, flowbit", command,
sizeof(command),
name,
1497 FAIL_IF(strcmp(command,
"set") != 0);
1501 FAIL_IF(!DetectFlowbitParse(
"set,flowbit ", command,
sizeof(command),
name,
1503 FAIL_IF(strcmp(command,
"set") != 0);
1507 FAIL_IF(!DetectFlowbitParse(
"set, flowbit ", command,
sizeof(command),
name,
1509 FAIL_IF(strcmp(command,
"set") != 0);
1513 FAIL_IF(DetectFlowbitParse(
"set,namewith space", command,
sizeof(command),
1526 static int FlowBitsTestSig01(
void)
1536 s =
de_ctx->
sig_list =
SigInit(
de_ctx,
"alert ip any any -> any any (msg:\"Noalert\"; flowbits:noalert,wrongusage; content:\"GET \"; sid:1;)");
1551 static int FlowBitsTestSig02(
void)
1557 memset(&th_v, 0,
sizeof(th_v));
1564 s =
de_ctx->
sig_list =
SigInit(
de_ctx,
"alert ip any any -> any any (msg:\"isset rule need an option\"; flowbits:isset; content:\"GET \"; sid:1;)");
1567 s =
de_ctx->
sig_list =
SigInit(
de_ctx,
"alert ip any any -> any any (msg:\"isnotset rule need an option\"; flowbits:isnotset; content:\"GET \"; sid:2;)");
1570 s =
de_ctx->
sig_list =
SigInit(
de_ctx,
"alert ip any any -> any any (msg:\"set rule need an option\"; flowbits:set; content:\"GET \"; sid:3;)");
1573 s =
de_ctx->
sig_list =
SigInit(
de_ctx,
"alert ip any any -> any any (msg:\"unset rule need an option\"; flowbits:unset; content:\"GET \"; sid:4;)");
1576 s =
de_ctx->
sig_list =
SigInit(
de_ctx,
"alert ip any any -> any any (msg:\"toggle rule need an option\"; flowbits:toggle; content:\"GET \"; sid:5;)");
1579 s =
de_ctx->
sig_list =
SigInit(
de_ctx,
"alert ip any any -> any any (msg:\"!set is not an option\"; flowbits:!set,myerr; content:\"GET \"; sid:6;)");
1595 static int FlowBitsTestSig03(
void)
1605 s =
de_ctx->
sig_list =
SigInit(
de_ctx,
"alert ip any any -> any any (msg:\"Unknown cmd\"; flowbits:wrongcmd; content:\"GET \"; sid:1;)");
1620 static int FlowBitsTestSig04(
void)
1630 s =
de_ctx->
sig_list =
SigInit(
de_ctx,
"alert ip any any -> any any (msg:\"isset option\"; flowbits:isset,fbt; content:\"GET \"; sid:1;)");
1648 static int FlowBitsTestSig05(
void)
1658 s =
de_ctx->
sig_list =
SigInit(
de_ctx,
"alert ip any any -> any any (msg:\"Noalert\"; flowbits:noalert; content:\"GET \"; sid:1;)");
1674 static int FlowBitsTestSig06(
void)
1676 uint8_t *buf = (uint8_t *)
1677 "GET /one/ HTTP/1.1\r\n"
1678 "Host: one.example.org\r\n"
1680 uint16_t buflen = strlen((
char *)buf);
1692 memset(&th_v, 0,
sizeof(th_v));
1694 memset(&f, 0,
sizeof(
Flow));
1705 p->
proto = IPPROTO_TCP;
1726 for ( ; gv != NULL; gv = gv->
next) {
1749 static int FlowBitsTestSig07(
void)
1751 uint8_t *buf = (uint8_t *)
1752 "GET /one/ HTTP/1.1\r\n"
1753 "Host: one.example.org\r\n"
1755 uint16_t buflen = strlen((
char *)buf);
1767 memset(&th_v, 0,
sizeof(th_v));
1769 memset(&f, 0,
sizeof(
Flow));
1780 p->
proto = IPPROTO_TCP;
1790 s = s->
next =
SigInit(
de_ctx,
"alert ip any any -> any any (msg:\"Flowbit unset\"; flowbits:unset,myflow2; sid:11;)");
1803 for ( ; gv != NULL; gv = gv->
next) {
1825 static int FlowBitsTestSig08(
void)
1827 uint8_t *buf = (uint8_t *)
1828 "GET /one/ HTTP/1.1\r\n"
1829 "Host: one.example.org\r\n"
1831 uint16_t buflen = strlen((
char *)buf);
1844 memset(&th_v, 0,
sizeof(th_v));
1846 memset(&f, 0,
sizeof(
Flow));
1857 p->
proto = IPPROTO_TCP;
1867 s = s->
next =
SigInit(
de_ctx,
"alert ip any any -> any any (msg:\"Flowbit unset\"; flowbits:toggle,myflow2; sid:11;)");
1880 for ( ; gv != NULL; gv = gv->
next) {
uint16_t cnts[DETECT_FLOWBITS_CMD_MAX]
uint32_t rule_state_dependant_sids_idx
uint32_t isnotset_sids_idx
SCMutex g_flowbits_dump_write_m
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
struct SigMatch_ * smlists[DETECT_SM_LIST_MAX]
#define DETECT_FLOWBITS_CMD_MAX
SigTableElmt * sigmatch_table
void PostRuleMatchWorkQueueAppend(DetectEngineThreadCtx *det_ctx, const Signature *s, const int type, const uint32_t value)
void(* Free)(DetectEngineCtx *, void *)
#define DETECT_TABLE_PACKET_FILTER_FLAG
Container for matching data for a signature group.
void FlowBitsRegisterTests(void)
this function registers unit tests for FlowBits
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
uint64_t PcapPacketCntGet(const Packet *p)
bool is_rule_state_dependant
struct HtpBodyChunk_ * next
#define DETECT_FLOWBITS_CMD_ISNOTSET
int PrefilterAppendEngine(DetectEngineCtx *de_ctx, SigGroupHead *sgh, PrefilterPktFn PrefilterFunc, SignatureMask mask, enum SignatureHookPkt hook, void *pectx, void(*FreeFunc)(void *pectx), const char *name)
SCEnumCharMap flowbit_cmds[]
bool FlowBitToggle(Flow *f, uint32_t idx)
int DetectFlowbitsAnalyze(DetectEngineCtx *de_ctx)
main detection engine ctx
@ SIGNATURE_HOOK_PKT_NOT_SET
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
#define FLOW_PKT_TOSERVER
const char * VarNameStoreSetupLookup(const uint32_t id, const enum VarTypes type)
#define DETECT_TABLE_APP_TD_FLAG
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
#define SCMUTEX_INITIALIZER
int DetectParsePcreExec(DetectParseRegex *parse_regex, pcre2_match_data **match, const char *str, int start_offset, int options)
#define DETECT_FLOWBITS_CMD_TOGGLE
#define DETECT_FLOWBITS_CMD_ISSET
uint32_t VarNameStoreRegister(const char *name, const enum VarTypes type)
#define SIGMATCH_SUPPORT_FIREWALL
struct PrefilterEngineFlowbits __attribute__
#define DETECT_TABLE_APP_FILTER_FLAG
RB_HEAD(PFB, PrefilterFlowbit)
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
int FlowBitSet(Flow *f, uint32_t idx)
add a flowbit to the flow
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
#define DETECT_TABLE_PACKET_TD_FLAG
int(* SetupPrefilter)(DetectEngineCtx *de_ctx, struct SigGroupHead_ *sgh)
void FlowBitUnset(Flow *f, uint32_t idx)
@ DETECT_SM_LIST_POSTMATCH
#define FLOW_INITIALIZE(f)
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
struct GenericVar_ * next
#define PASS
Pass the test.
#define SCMutexUnlock(mut)
#define SIG_MASK_REQUIRE_FLOW
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
#define RB_FOREACH_SAFE(x, name, head, y)
SigMatch * SCSigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
Per thread variable structure.
uint32_t rule_state_flowbits_ids_size
TmEcode DetectEngineThreadCtxInit(ThreadVars *tv, void *initdata, void **data)
initialize thread specific detection engine context
void VarNameStoreUnregister(const uint32_t id, const enum VarTypes type)
void PacketFree(Packet *p)
Return a malloced packet.
#define SCLogWarning(...)
Macro used to log WARNING messages.
Signature * SigInit(DetectEngineCtx *de_ctx, const char *sigstr)
Parses a signature and adds it to the Detection Engine Context.
SigGroupHeadInitData * init
void DetectFlowbitFree(DetectEngineCtx *, void *)
void DetectFlowbitsRegister(void)
const char * SCConfigGetLogDirectory(void)
RB_GENERATE(PFB, PrefilterFlowbit, rb, PrefilterFlowbitCompare)
SignatureInitData * init_data
uint32_t * rule_state_dependant_sids_array
Data structures and function prototypes for keeping state for the detection engine.
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
uint32_t rule_state_dependant_sids_size
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
void StatsThreadInit(StatsThreadContext *stats)
uint32_t toggle_sids_size
#define SCRealloc(ptr, sz)
#define SIG_FLAG_INIT_STATE_MATCH
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
const char * SCMapEnumValueToName(int enum_value, SCEnumCharMap *table)
Maps an enum value to a string name, from the supplied table.
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
uint16_t state_cnts[DETECT_FLOWBITS_CMD_MAX]
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data)
PostRuleMatchWorkQueueItem * q
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
int PrefilterAppendPostRuleEngine(DetectEngineCtx *de_ctx, SigGroupHead *sgh, void(*PrefilterPostRuleFunc)(DetectEngineThreadCtx *det_ctx, const void *pectx, Packet *p, Flow *f), void *pectx, void(*FreeFunc)(void *pectx), const char *name)
int FlowBitIsset(Flow *f, uint32_t idx)
#define SCLogError(...)
Macro used to log ERROR messages.
#define DETECT_TABLE_PACKET_PRE_STREAM_FLAG
bool(* SupportsPrefilter)(const Signature *s)
#define DETECT_FLOWBITS_CMD_UNSET
a single match condition for a signature
uint32_t isnotset_sids_size
DetectEngineCtx * DetectEngineCtxInit(void)
int DetectFlowbitMatch(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
uint32_t * rule_state_flowbits_ids_array
void StatsThreadCleanup(StatsThreadContext *stats)
#define SIGMATCH_IPONLY_COMPAT
#define FLOW_PKT_TOSERVER_FIRST
bool rule_engine_analysis_set
#define DEBUG_VALIDATE_BUG_ON(exp)
#define SIG_FLAG_PREFILTER
bool post_rule_match_prefilter
RB_PROTOTYPE(PFB, PrefilterFlowbit, rb, PrefilterFlowbitCompare)
PostRuleMatchWorkQueue post_rule_work_queue
int FlowBitIsnotset(Flow *f, uint32_t idx)
#define DETECT_FLOWBITS_CMD_SET
void(* RegisterTests)(void)