47#define PARSE_REGEX "^\\s*([A-z_]+)\\s*(?:,\\s*([A-z_]+))?\\s*(?:,\\s*([A-z_]+))?\\s*$"
55static void DetectFlowRegisterTests(
void);
60static bool PrefilterFlowIsPrefilterable(
const Signature *s);
93static inline int FlowMatch(
const uint32_t pflags,
const uint8_t pflowflags,
const uint16_t dflags,
94 const uint16_t match_cnt)
120 return (match_cnt == cnt) ? 1 : 0;
154 SCLogDebug(
"returning %" PRId32
" fd->match_cnt %" PRId32
" fd->flags 0x%02X p->flowflags 0x%02X",
173 char *args[3] = {NULL,NULL,NULL};
176 char str1[16] =
"", str2[16] =
"", str3[16] =
"";
177 pcre2_match_data *match = NULL;
180 if (ret < 1 || ret > 4) {
181 SCLogError(
"parse error, ret %" PRId32
", string %s", ret, flowstr);
186 pcre2len =
sizeof(str1);
189 SCLogError(
"pcre2_substring_copy_bynumber failed");
192 args[0] = (
char *)str1;
195 pcre2len =
sizeof(str2);
196 res = pcre2_substring_copy_bynumber(match, 2, (PCRE2_UCHAR8 *)str2, &pcre2len);
198 SCLogError(
"pcre2_substring_copy_bynumber failed");
201 args[1] = (
char *)str2;
204 pcre2len =
sizeof(str3);
205 res = pcre2_substring_copy_bynumber(match, 3, (PCRE2_UCHAR8 *)str3, &pcre2len);
207 SCLogError(
"pcre2_substring_copy_bynumber failed");
210 args[2] = (
char *)str3;
220 for (
int i = 0; i < (ret - 1); i++) {
223 if (strcasecmp(args[i],
"established") == 0) {
225 SCLogError(
"DETECT_FLOW_FLAG_ESTABLISHED flag is already set");
228 SCLogError(
"cannot set DETECT_FLOW_FLAG_ESTABLISHED, "
229 "DETECT_FLOW_FLAG_NOT_ESTABLISHED already set");
232 SCLogError(
"DETECT_FLOW_FLAG_STATELESS already set");
237 }
else if (strcasecmp(args[i],
"not_established") == 0) {
239 SCLogError(
"DETECT_FLOW_FLAG_NOT_ESTABLISHED flag is already set");
242 SCLogError(
"cannot set DETECT_FLOW_FLAG_NOT_ESTABLISHED, "
243 "DETECT_FLOW_FLAG_ESTABLISHED already set");
248 }
else if (strcasecmp(args[i],
"stateless") == 0) {
250 SCLogError(
"DETECT_FLOW_FLAG_STATELESS flag is already set");
253 SCLogError(
"cannot set DETECT_FLOW_FLAG_STATELESS, "
254 "DETECT_FLOW_FLAG_ESTABLISHED already set");
259 }
else if (strcasecmp(args[i],
"to_client") == 0 || strcasecmp(args[i],
"from_server") == 0) {
261 SCLogError(
"cannot set DETECT_FLOW_FLAG_TOCLIENT flag is already set");
264 SCLogError(
"cannot set to_client, DETECT_FLOW_FLAG_TOSERVER already set");
269 }
else if (strcasecmp(args[i],
"to_server") == 0 || strcasecmp(args[i],
"from_client") == 0){
271 SCLogError(
"cannot set DETECT_FLOW_FLAG_TOSERVER flag is already set");
274 SCLogError(
"cannot set to_server, DETECT_FLOW_FLAG_TO_CLIENT flag already set");
279 }
else if (strcasecmp(args[i],
"no_frag") == 0) {
281 SCLogError(
"cannot set no_frag flag is already set");
284 SCLogError(
"cannot set no_frag flag, only_frag already set");
289 }
else if (strcasecmp(args[i],
"only_frag") == 0) {
291 SCLogError(
"cannot set only_frag flag is already set");
294 SCLogError(
"cannot set only_frag flag, no_frag already set");
302 }
else if (strcasecmp(args[i],
"only_stream") == 0) {
304 SCLogError(
"cannot set only_stream flag is already set");
308 "cannot set only_stream flag, DETECT_FLOW_FLAG_NOSTREAM already set");
312 }
else if (strcasecmp(args[i],
"no_stream") == 0) {
314 SCLogError(
"cannot set no_stream flag is already set");
318 "cannot set no_stream flag, DETECT_FLOW_FLAG_ONLYSTREAM already set");
323 SCLogError(
"invalid flow option \"%s\"", args[i]);
328 pcre2_match_data_free(match);
333 pcre2_match_data_free(match);
343#define SIG_FLAG_BOTH (SIG_FLAG_TOSERVER|SIG_FLAG_TOCLIENT)
354 s->
flags &= ~SIG_FLAG_TOCLIENT;
362 s->
flags &= ~SIG_FLAG_TOSERVER;
384 uint16_t parse_flags = 0;
388 SCLogError(
"A signature may have only one flow option.");
396 bool appendsm =
true;
401 "rule %u means to use both directions, cannot specify a flow direction", s->
id);
405 SCLogError(
"rule %u has flow to_server but a hook to_client", s->
id);
412 "rule %u means to use both directions, cannot specify a flow direction", s->
id);
416 SCLogError(
"rule %u has flow to_client but a hook to_server", s->
id);
478 if (!PrefilterPacketHeaderExtraMatch(
ctx, p))
483 PrefilterAddSids(&det_ctx->
pmq,
ctx->sigs_array,
ctx->sigs_cnt);
509 PrefilterPacketFlowCompare, PrefilterPacketFlowMatch);
512static bool PrefilterFlowIsPrefilterable(
const Signature *s)
531static int DetectFlowTestParse01 (
void)
533 uint16_t parsed_flags = 0;
534 DetectFlowData *fd = DetectFlowParse(NULL,
"established", &parsed_flags);
544static int DetectFlowTestParse02 (
void)
546 uint16_t parsed_flags = 0;
547 DetectFlowData *fd = DetectFlowParse(NULL,
"established", &parsed_flags);
557static int DetectFlowTestParse03 (
void)
559 uint16_t parsed_flags = 0;
560 DetectFlowData *fd = DetectFlowParse(NULL,
"stateless", &parsed_flags);
570static int DetectFlowTestParse04 (
void)
572 uint16_t parsed_flags = 0;
573 DetectFlowData *fd = DetectFlowParse(NULL,
"to_client", &parsed_flags);
583static int DetectFlowTestParse05 (
void)
585 uint16_t parsed_flags = 0;
586 DetectFlowData *fd = DetectFlowParse(NULL,
"to_server", &parsed_flags);
596static int DetectFlowTestParse06 (
void)
598 uint16_t parsed_flags = 0;
599 DetectFlowData *fd = DetectFlowParse(NULL,
"from_server", &parsed_flags);
609static int DetectFlowTestParse07 (
void)
611 uint16_t parsed_flags = 0;
612 DetectFlowData *fd = DetectFlowParse(NULL,
"from_client", &parsed_flags);
622static int DetectFlowTestParse08 (
void)
624 uint16_t parsed_flags = 0;
625 DetectFlowData *fd = DetectFlowParse(NULL,
"established,to_client", &parsed_flags);
635static int DetectFlowTestParse09 (
void)
637 uint16_t parsed_flags = 0;
638 DetectFlowData *fd = DetectFlowParse(NULL,
"to_client,stateless", &parsed_flags);
650static int DetectFlowTestParse10 (
void)
652 uint16_t parsed_flags = 0;
653 DetectFlowData *fd = DetectFlowParse(NULL,
"from_server,stateless", &parsed_flags);
665static int DetectFlowTestParse11 (
void)
667 uint16_t parsed_flags = 0;
668 DetectFlowData *fd = DetectFlowParse(NULL,
" from_server , stateless ", &parsed_flags);
681static int DetectFlowTestParseNocase01 (
void)
683 uint16_t parsed_flags = 0;
684 DetectFlowData *fd = DetectFlowParse(NULL,
"ESTABLISHED", &parsed_flags);
693static int DetectFlowTestParseNocase02 (
void)
695 uint16_t parsed_flags = 0;
696 DetectFlowData *fd = DetectFlowParse(NULL,
"ESTABLISHED", &parsed_flags);
707static int DetectFlowTestParseNocase03 (
void)
709 uint16_t parsed_flags = 0;
710 DetectFlowData *fd = DetectFlowParse(NULL,
"STATELESS", &parsed_flags);
720static int DetectFlowTestParseNocase04 (
void)
722 uint16_t parsed_flags = 0;
723 DetectFlowData *fd = DetectFlowParse(NULL,
"TO_CLIENT", &parsed_flags);
733static int DetectFlowTestParseNocase05 (
void)
735 uint16_t parsed_flags = 0;
736 DetectFlowData *fd = DetectFlowParse(NULL,
"TO_SERVER", &parsed_flags);
746static int DetectFlowTestParseNocase06 (
void)
748 uint16_t parsed_flags = 0;
749 DetectFlowData *fd = DetectFlowParse(NULL,
"FROM_SERVER", &parsed_flags);
759static int DetectFlowTestParseNocase07 (
void)
761 uint16_t parsed_flags = 0;
762 DetectFlowData *fd = DetectFlowParse(NULL,
"FROM_CLIENT", &parsed_flags);
772static int DetectFlowTestParseNocase08 (
void)
774 uint16_t parsed_flags = 0;
775 DetectFlowData *fd = DetectFlowParse(NULL,
"ESTABLISHED,TO_CLIENT", &parsed_flags);
787static int DetectFlowTestParseNocase09 (
void)
789 uint16_t parsed_flags = 0;
790 DetectFlowData *fd = DetectFlowParse(NULL,
"TO_CLIENT,STATELESS", &parsed_flags);
802static int DetectFlowTestParseNocase10 (
void)
804 uint16_t parsed_flags = 0;
805 DetectFlowData *fd = DetectFlowParse(NULL,
"FROM_SERVER,STATELESS", &parsed_flags);
817static int DetectFlowTestParseNocase11 (
void)
819 uint16_t parsed_flags = 0;
820 DetectFlowData *fd = DetectFlowParse(NULL,
" FROM_SERVER , STATELESS ", &parsed_flags);
832static int DetectFlowTestParse12 (
void)
834 uint16_t parsed_flags = 0;
835 DetectFlowData *fd = DetectFlowParse(NULL,
"from_server:stateless", &parsed_flags);
843static int DetectFlowTestParse13 (
void)
845 uint16_t parsed_flags = 0;
846 DetectFlowData *fd = DetectFlowParse(NULL,
"invalidoptiontest", &parsed_flags);
854static int DetectFlowTestParse14 (
void)
856 uint16_t parsed_flags = 0;
865static int DetectFlowTestParse15 (
void)
867 uint16_t parsed_flags = 0;
868 DetectFlowData *fd = DetectFlowParse(NULL,
"established,stateless", &parsed_flags);
876static int DetectFlowTestParse16 (
void)
878 uint16_t parsed_flags = 0;
879 DetectFlowData *fd = DetectFlowParse(NULL,
"to_client,to_server", &parsed_flags);
888static int DetectFlowTestParse17 (
void)
890 uint16_t parsed_flags = 0;
891 DetectFlowData *fd = DetectFlowParse(NULL,
"to_client,from_server", &parsed_flags);
899static int DetectFlowTestParse18 (
void)
901 uint16_t parsed_flags = 0;
903 DetectFlowParse(NULL,
"from_server,established,only_stream", &parsed_flags);
915static int DetectFlowTestParseNocase18 (
void)
917 uint16_t parsed_flags = 0;
919 DetectFlowParse(NULL,
"FROM_SERVER,ESTABLISHED,ONLY_STREAM", &parsed_flags);
932static int DetectFlowTestParse19 (
void)
934 uint16_t parsed_flags = 0;
936 DetectFlowParse(NULL,
"from_server,established,only_stream,a", &parsed_flags);
944static int DetectFlowTestParse20 (
void)
946 uint16_t parsed_flags = 0;
947 DetectFlowData *fd = DetectFlowParse(NULL,
"from_server,established,no_stream", &parsed_flags);
959static int DetectFlowTestParseNocase20 (
void)
961 uint16_t parsed_flags = 0;
962 DetectFlowData *fd = DetectFlowParse(NULL,
"FROM_SERVER,ESTABLISHED,NO_STREAM", &parsed_flags);
974static int DetectFlowTestParse21 (
void)
976 uint16_t parsed_flags = 0;
977 DetectFlowData *fd = DetectFlowParse(NULL,
"from_server,a,no_stream", &parsed_flags);
985static int DetectFlowTestParse22(
void)
987 uint16_t parsed_flags = 0;
988 DetectFlowData *fd = DetectFlowParse(NULL,
"established,not_established", &parsed_flags);
990 fd = DetectFlowParse(NULL,
"not_established,established", &parsed_flags);
995static int DetectFlowSigTest01(
void)
997 uint8_t *buf = (uint8_t *)
"supernovaduper";
998 uint16_t buflen = strlen((
char *)buf);
1002 memset(&th_v, 0,
sizeof(th_v));
1007 const char *sig1 =
"alert tcp any any -> any any (msg:\"dummy\"; "
1008 "content:\"nova\"; flow:no_stream; sid:1;)";
1035static int DetectFlowTestParseNotEstablished(
void)
1037 uint16_t parsed_flags = 0;
1038 DetectFlowData *fd = DetectFlowParse(NULL,
"not_established", &parsed_flags);
1048static int DetectFlowTestParseNoFrag(
void)
1050 uint16_t parsed_flags = 0;
1051 DetectFlowData *fd = DetectFlowParse(NULL,
"no_frag", &parsed_flags);
1061static int DetectFlowTestParseOnlyFrag(
void)
1063 uint16_t parsed_flags = 0;
1064 DetectFlowData *fd = DetectFlowParse(NULL,
"only_frag", &parsed_flags);
1074static int DetectFlowTestParseNoFragOnlyFrag(
void)
1076 uint16_t parsed_flags = 0;
1077 DetectFlowData *fd = DetectFlowParse(NULL,
"no_frag,only_frag", &parsed_flags);
1085static int DetectFlowTestNoFragMatch(
void)
1087 uint16_t parsed_flags = 0;
1088 uint32_t pflags = 0;
1089 DetectFlowData *fd = DetectFlowParse(NULL,
"no_frag", &parsed_flags);
1102static int DetectFlowTestOnlyFragMatch(
void)
1104 uint16_t parsed_flags = 0;
1105 uint32_t pflags = 0;
1106 DetectFlowData *fd = DetectFlowParse(NULL,
"only_frag", &parsed_flags);
1119static void DetectFlowRegisterTests(
void)
1132 UtRegisterTest(
"DetectFlowTestParseNocase01", DetectFlowTestParseNocase01);
1133 UtRegisterTest(
"DetectFlowTestParseNocase02", DetectFlowTestParseNocase02);
1134 UtRegisterTest(
"DetectFlowTestParseNocase03", DetectFlowTestParseNocase03);
1135 UtRegisterTest(
"DetectFlowTestParseNocase04", DetectFlowTestParseNocase04);
1136 UtRegisterTest(
"DetectFlowTestParseNocase05", DetectFlowTestParseNocase05);
1137 UtRegisterTest(
"DetectFlowTestParseNocase06", DetectFlowTestParseNocase06);
1138 UtRegisterTest(
"DetectFlowTestParseNocase07", DetectFlowTestParseNocase07);
1139 UtRegisterTest(
"DetectFlowTestParseNocase08", DetectFlowTestParseNocase08);
1140 UtRegisterTest(
"DetectFlowTestParseNocase09", DetectFlowTestParseNocase09);
1141 UtRegisterTest(
"DetectFlowTestParseNocase10", DetectFlowTestParseNocase10);
1142 UtRegisterTest(
"DetectFlowTestParseNocase11", DetectFlowTestParseNocase11);
1150 UtRegisterTest(
"DetectFlowTestParseNocase18", DetectFlowTestParseNocase18);
1153 UtRegisterTest(
"DetectFlowTestParseNocase20", DetectFlowTestParseNocase20);
1157 DetectFlowTestParseNotEstablished);
1158 UtRegisterTest(
"DetectFlowTestParseNoFrag", DetectFlowTestParseNoFrag);
1160 DetectFlowTestParseOnlyFrag);
1162 DetectFlowTestParseNoFragOnlyFrag);
1163 UtRegisterTest(
"DetectFlowTestNoFragMatch", DetectFlowTestNoFragMatch);
1164 UtRegisterTest(
"DetectFlowTestOnlyFragMatch", DetectFlowTestOnlyFragMatch);
#define PKT_REBUILT_FRAGMENT
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
int PrefilterSetupPacketHeader(DetectEngineCtx *de_ctx, SigGroupHead *sgh, int sm_type, SignatureMask mask, void(*Set)(PrefilterPacketHeaderValue *v, void *), bool(*Compare)(PrefilterPacketHeaderValue v, void *), void(*Match)(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx))
DetectEngineCtx * DetectEngineCtxInit(void)
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
TmEcode DetectEngineThreadCtxInit(ThreadVars *tv, void *initdata, void **data)
initialize thread specific detection engine context
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data)
void DetectFlowFree(DetectEngineCtx *, void *)
this function will free memory associated with DetectFlowData
int DetectFlowSetupImplicit(Signature *s, uint32_t flags)
void DetectFlowRegister(void)
Registration function for flow: keyword.
int DetectFlowMatch(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
This function is used to match flow flags set on a packet with those passed via flow:
#define PARSE_REGEX
Regex for parsing our flow options.
#define DETECT_FLOW_FLAG_NOSTREAM
#define DETECT_FLOW_FLAG_ESTABLISHED
#define DETECT_FLOW_FLAG_STATELESS
#define DETECT_FLOW_FLAG_ONLYSTREAM
#define DETECT_FLOW_FLAG_TOSERVER
#define DETECT_FLOW_FLAG_ONLY_FRAG
#define DETECT_FLOW_FLAG_NOT_ESTABLISHED
#define DETECT_FLOW_FLAG_TOCLIENT
#define DETECT_FLOW_FLAG_NO_FRAG
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
int DetectParsePcreExec(DetectParseRegex *parse_regex, pcre2_match_data **match, const char *str, int start_offset, int options)
int SC_Pcre2SubstringCopy(pcre2_match_data *match_data, uint32_t number, PCRE2_UCHAR *buffer, PCRE2_SIZE *bufflen)
Signature * SigInit(DetectEngineCtx *de_ctx, const char *sigstr)
Parses a signature and adds it to the Detection Engine Context.
SigMatch * SCSigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
SigTableElmt * sigmatch_table
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
#define DETECT_TABLE_APP_TD_FLAG
#define DETECT_TABLE_PACKET_TD_FLAG
#define SIG_FLAG_REQUIRE_PACKET
#define SIG_FLAG_TOCLIENT
#define DETECT_TABLE_APP_FILTER_FLAG
#define SIGMATCH_SUPPORT_FIREWALL
#define SIG_FLAG_INIT_FLOW
#define DETECT_TABLE_PACKET_PRE_STREAM_FLAG
#define DETECT_TABLE_PACKET_FILTER_FLAG
#define SIG_FLAG_TOSERVER
#define SIG_FLAG_REQUIRE_STREAM_ONLY
#define SIG_FLAG_TXBOTHDIR
#define SIG_FLAG_REQUIRE_STREAM
#define FLOW_PKT_TOSERVER
#define FLOW_PKT_ESTABLISHED
#define FLOW_PKT_TOCLIENT
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
#define PASS
Pass the test.
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
Structure to hold thread specific data for all decode modules.
main detection engine ctx
Container for matching data for a signature group.
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
a single match condition for a signature
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
int(* SetupPrefilter)(DetectEngineCtx *de_ctx, struct SigGroupHead_ *sgh)
void(* Free)(DetectEngineCtx *, void *)
void(* RegisterTests)(void)
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
bool(* SupportsPrefilter)(const Signature *s)
struct SigMatch_ * smlists[DETECT_SM_LIST_MAX]
SignatureInitData * init_data
Per thread variable structure.
#define SCLogError(...)
Macro used to log ERROR messages.
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself.