diff --git a/src/detect-parse.c b/src/detect-parse.c index 4f86b452a96b..7673a80e62e3 100644 --- a/src/detect-parse.c +++ b/src/detect-parse.c @@ -1186,12 +1186,61 @@ static const char *SignatureHookTypeToString(enum SignatureHookType t) return "not_set"; case SIGNATURE_HOOK_TYPE_APP: return "app"; - // case SIGNATURE_HOOK_TYPE_PKT: - // return "pkt"; + case SIGNATURE_HOOK_TYPE_PKT: + return "pkt"; } return "unknown"; } +static enum SignatureHookPkt HookPktFromString(const char *str) +{ + if (strcmp(str, "flow_start") == 0) { + return SIGNATURE_HOOK_PKT_FLOW_START; + } + return SIGNATURE_HOOK_PKT_NOT_SET; +} + +static const char *HookPktToString(const enum SignatureHookPkt ph) +{ + switch (ph) { + case SIGNATURE_HOOK_PKT_NOT_SET: + return "not set"; + case SIGNATURE_HOOK_PKT_FLOW_START: + return "flow_start"; + } + return "error"; +} + +static SignatureHook SetPktHook(const char *hook_str) +{ + SignatureHook h = { + .type = SIGNATURE_HOOK_TYPE_PKT, + .t.pkt.ph = HookPktFromString(hook_str), + }; + return h; +} + +/** + * \param proto_hook string of protocol and hook, e.g. dns:request_complete + */ +static int SigParseProtoHookPkt(Signature *s, const char *proto_hook, const char *p, const char *h) +{ + if (strcmp(h, "flow_start") == 0) { + s->init_data->hook = SetPktHook(h); + if (s->init_data->hook.t.pkt.ph == SIGNATURE_HOOK_PKT_NOT_SET) { + return -1; + } + } else { + SCLogError("unknown pkt hook %s", h); + } + // s->init_data->hook.sm_list = list; + + SCLogNotice("protocol:%s hook:%s: type:%s parsed hook:%s", p, h, + SignatureHookTypeToString(s->init_data->hook.type), + HookPktToString(s->init_data->hook.t.pkt.ph)); + return 0; +} + static SignatureHook SetAppHook(const AppProto alproto, int progress) { SignatureHook h = { @@ -1307,6 +1356,13 @@ static int SigParseProto(Signature *s, const char *protostr) p, p); SCReturnInt(-1); } + } else if (h != NULL) { + SCLogNotice("non-app-layer rule with %s:%s", p, h); + + if (SigParseProtoHookPkt(s, protostr, p, h) < 0) { + SCLogError("protocol \"%s\" does not support hook \"%s\"", p, h); + SCReturnInt(-1); + } } /* if any of these flags are set they are set in a mutually exclusive @@ -2477,6 +2533,14 @@ static Signature *SigInitHelper(DetectEngineCtx *de_ctx, const char *sigstr, } } + if (sig->init_data->hook.type == SIGNATURE_HOOK_TYPE_PKT) { + if (sig->init_data->hook.t.pkt.ph == SIGNATURE_HOOK_PKT_FLOW_START) { + if ((sig->flags & SIG_FLAG_TOSERVER) != 0) { + sig->init_data->init_flags |= SIG_FLAG_INIT_FLOW; + } + } + } + if (!(sig->init_data->init_flags & SIG_FLAG_INIT_FLOW)) { if ((sig->flags & (SIG_FLAG_TOSERVER|SIG_FLAG_TOCLIENT)) == 0) { sig->flags |= SIG_FLAG_TOSERVER; diff --git a/src/detect.h b/src/detect.h index 052928fc998b..24b008adb2b0 100644 --- a/src/detect.h +++ b/src/detect.h @@ -540,9 +540,14 @@ typedef struct SignatureInitDataBuffer_ { SigMatch *tail; } SignatureInitDataBuffer; +enum SignatureHookPkt { + SIGNATURE_HOOK_PKT_NOT_SET, + SIGNATURE_HOOK_PKT_FLOW_START, +}; + enum SignatureHookType { SIGNATURE_HOOK_TYPE_NOT_SET, - // SIGNATURE_HOOK_TYPE_PKT, + SIGNATURE_HOOK_TYPE_PKT, SIGNATURE_HOOK_TYPE_APP, }; @@ -558,6 +563,9 @@ typedef struct SignatureHook_ { * specific progress value. */ int app_progress; } app; + struct { + enum SignatureHookPkt ph; + } pkt; } t; } SignatureHook;