diff --git a/src/detect-engine-state.c b/src/detect-engine-state.c index e25accf3fd..687e3b397b 100644 --- a/src/detect-engine-state.c +++ b/src/detect-engine-state.c @@ -715,7 +715,7 @@ static int DoInspectItem(ThreadVars *tv, SCLogDebug("MATCH: tx %u packet %u", (uint)inspect_tx_id, (uint)p->pcap_cnt); } - DetectFlowvarProcessList(det_ctx, f); + DetectVarProcessList(det_ctx, f, p); return 1; } diff --git a/src/detect-flowvar.c b/src/detect-flowvar.c index c5f838bb6c..b0c30d4099 100644 --- a/src/detect-flowvar.c +++ b/src/detect-flowvar.c @@ -33,6 +33,7 @@ #include "threads.h" #include "flow.h" #include "flow-var.h" +#include "pkt-var.h" #include "detect-flowvar.h" #include "util-spm.h" @@ -194,10 +195,10 @@ error: /** \brief Store flowvar in det_ctx so we can exec it post-match */ -int DetectFlowvarStoreMatch(DetectEngineThreadCtx *det_ctx, uint32_t idx, +int DetectVarStoreMatch(DetectEngineThreadCtx *det_ctx, uint32_t idx, uint8_t *buffer, uint16_t len, int type) { - DetectFlowvarList *fs = det_ctx->flowvarlist; + DetectVarList *fs = det_ctx->varlist; /* first check if we have had a previous match for this idx */ for ( ; fs != NULL; fs = fs->next) { @@ -216,8 +217,8 @@ int DetectFlowvarStoreMatch(DetectEngineThreadCtx *det_ctx, uint32_t idx, fs->idx = idx; - fs->next = det_ctx->flowvarlist; - det_ctx->flowvarlist = fs; + fs->next = det_ctx->varlist; + det_ctx->varlist = fs; } fs->len = len; @@ -266,29 +267,33 @@ static int DetectFlowvarPostMatch(ThreadVars *tv, DetectEngineThreadCtx *det_ctx, Packet *p, const Signature *s, const SigMatchCtx *ctx) { - DetectFlowvarList *fs, *prev; + DetectVarList *fs, *prev; const DetectFlowvarData *fd; - if (det_ctx->flowvarlist == NULL || p->flow == NULL) + if (det_ctx->varlist == NULL) return 1; fd = (const DetectFlowvarData *)ctx; prev = NULL; - fs = det_ctx->flowvarlist; + fs = det_ctx->varlist; while (fs != NULL) { if (fd->idx == fs->idx) { SCLogDebug("adding to the flow %u:", fs->idx); //PrintRawDataFp(stdout, fs->buffer, fs->len); - FlowVarAddStrNoLock(p->flow, fs->idx, fs->buffer, fs->len); - /* memory at fs->buffer is now the responsibility of - * the flowvar code. */ + if (fs->type == DETECT_VAR_TYPE_FLOW_POSTMATCH && p && p->flow) { + FlowVarAddStrNoLock(p->flow, fs->idx, fs->buffer, fs->len); + /* memory at fs->buffer is now the responsibility of + * the flowvar code. */ + } else if (fs->type == DETECT_VAR_TYPE_PKT_POSTMATCH && p) { + PktVarAdd(p, fs->idx, fs->buffer, fs->len); + } - if (fs == det_ctx->flowvarlist) { - det_ctx->flowvarlist = fs->next; + if (fs == det_ctx->varlist) { + det_ctx->varlist = fs->next; SCFree(fs); - fs = det_ctx->flowvarlist; + fs = det_ctx->varlist; } else { prev->next = fs->next; SCFree(fs); @@ -307,14 +312,14 @@ static int DetectFlowvarPostMatch(ThreadVars *tv, * - enforce storage for type ALWAYS (vars set from lua) * Only called from DetectFlowvarProcessList() when flowvarlist is not NULL . */ -void DetectFlowvarProcessListInternal(DetectFlowvarList *fs, Flow *f) +void DetectVarProcessListInternal(DetectVarList *fs, Flow *f, Packet *p) { - DetectFlowvarList *next; + DetectVarList *next; do { next = fs->next; - if (fs->type == DETECT_FLOWVAR_TYPE_ALWAYS) { + if (fs->type == DETECT_VAR_TYPE_ALWAYS) { SCLogDebug("adding to the flow %u:", fs->idx); //PrintRawDataFp(stdout, fs->buffer, fs->len); diff --git a/src/detect-flowvar.h b/src/detect-flowvar.h index 32222372b4..59edfc80bc 100644 --- a/src/detect-flowvar.h +++ b/src/detect-flowvar.h @@ -36,18 +36,18 @@ typedef struct DetectFlowvarData_ { void DetectFlowvarRegister (void); int DetectFlowvarPostMatchSetup(Signature *s, uint32_t idx); -int DetectFlowvarStoreMatch(DetectEngineThreadCtx *, uint32_t, uint8_t *, uint16_t, int); +int DetectVarStoreMatch(DetectEngineThreadCtx *, uint32_t, uint8_t *, uint16_t, int); /* For use only by DetectFlowvarProcessList() */ -void DetectFlowvarProcessListInternal(DetectFlowvarList *fs, Flow *f); -static inline void DetectFlowvarProcessList(DetectEngineThreadCtx *det_ctx, Flow *f) +void DetectVarProcessListInternal(DetectVarList *fs, Flow *f, Packet *p); +static inline void DetectVarProcessList(DetectEngineThreadCtx *det_ctx, Flow *f, Packet *p) { - DetectFlowvarList *fs = det_ctx->flowvarlist; + DetectVarList *fs = det_ctx->varlist; - SCLogDebug("flow %p det_ctx->flowvarlist %p", f, fs); - if (f && fs != NULL) { - det_ctx->flowvarlist = NULL; - DetectFlowvarProcessListInternal(fs, f); + SCLogDebug("flow %p det_ctx->varlist %p", f, fs); + if ((f || p) && fs != NULL) { + det_ctx->varlist = NULL; + DetectVarProcessListInternal(fs, f, p); } } diff --git a/src/detect-pcre.c b/src/detect-pcre.c index 1fe8af2758..0d0a46756e 100644 --- a/src/detect-pcre.c +++ b/src/detect-pcre.c @@ -219,21 +219,28 @@ int DetectPcrePayloadMatch(DetectEngineThreadCtx *det_ctx, const Signature *s, if (ret > 1 && pe->idx != 0) { uint8_t x; for (x = 0; x < pe->idx; x++) { - SCLogDebug("capturing"); + SCLogDebug("capturing %u", x); const char *str_ptr; ret = pcre_get_substring((char *)ptr, ov, MAX_SUBSTRINGS, x+1, &str_ptr); if (unlikely(ret == 0)) continue; - if (pe->captypes[x] == VAR_TYPE_PKT_VAR && p != NULL) { - PktVarAdd(p, pe->capids[x], (uint8_t *)str_ptr, ret); + SCLogDebug("data %p/%u, type %u id %u p %p", + str_ptr, ret, pe->captypes[x], pe->capids[x], p); + + if (pe->captypes[x] == VAR_TYPE_PKT_VAR) { + /* store max 64k. Errors are ignored */ + capture_len = (ret < 0xffff) ? (uint16_t)ret : 0xffff; + (void)DetectVarStoreMatch(det_ctx, pe->capids[x], + (uint8_t *)str_ptr, capture_len, + DETECT_VAR_TYPE_PKT_POSTMATCH); } else if (pe->captypes[x] == VAR_TYPE_FLOW_VAR && f != NULL) { /* store max 64k. Errors are ignored */ capture_len = (ret < 0xffff) ? (uint16_t)ret : 0xffff; - (void)DetectFlowvarStoreMatch(det_ctx, pe->capids[x], + (void)DetectVarStoreMatch(det_ctx, pe->capids[x], (uint8_t *)str_ptr, capture_len, - DETECT_FLOWVAR_TYPE_POSTMATCH); + DETECT_VAR_TYPE_FLOW_POSTMATCH); } } } @@ -717,10 +724,8 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst uint8_t x; for (x = 0; x < pd->idx; x++) { - if (pd->captypes[x] == VAR_TYPE_FLOW_VAR) { - if (DetectFlowvarPostMatchSetup(s, pd->capids[x]) < 0) - goto error_nofree; - } + if (DetectFlowvarPostMatchSetup(s, pd->capids[x]) < 0) + goto error_nofree; } if (!(pd->flags & DETECT_PCRE_RELATIVE)) diff --git a/src/detect.c b/src/detect.c index 3797a2272c..9207b537c0 100644 --- a/src/detect.c +++ b/src/detect.c @@ -549,21 +549,19 @@ int SigMatchSignaturesRunPostMatch(ThreadVars *tv, const Signature *s) { /* run the packet match functions */ - if (s->sm_arrays[DETECT_SM_LIST_POSTMATCH] != NULL) { + SigMatchData *smd = s->sm_arrays[DETECT_SM_LIST_POSTMATCH]; + if (smd != NULL) { KEYWORD_PROFILING_SET_LIST(det_ctx, DETECT_SM_LIST_POSTMATCH); - SigMatchData *smd = s->sm_arrays[DETECT_SM_LIST_POSTMATCH]; SCLogDebug("running match functions, sm %p", smd); - if (smd != NULL) { - while (1) { - KEYWORD_PROFILING_START; - (void)sigmatch_table[smd->type].Match(tv, det_ctx, p, s, smd->ctx); - KEYWORD_PROFILING_END(det_ctx, smd->type, 1); - if (smd->is_last) - break; - smd++; - } + while (1) { + KEYWORD_PROFILING_START; + (void)sigmatch_table[smd->type].Match(tv, det_ctx, p, s, smd->ctx); + KEYWORD_PROFILING_END(det_ctx, smd->type, 1); + if (smd->is_last) + break; + smd++; } } @@ -1472,7 +1470,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh } alerts++; next: - DetectFlowvarProcessList(det_ctx, pflow); + DetectVarProcessList(det_ctx, pflow, p); DetectReplaceFree(det_ctx); RULE_PROFILING_END(det_ctx, s, smatch, p); diff --git a/src/detect.h b/src/detect.h index fd609f056b..2394ab442e 100644 --- a/src/detect.h +++ b/src/detect.h @@ -490,20 +490,21 @@ typedef struct DetectReplaceList_ { } DetectReplaceList; /** only execute flowvar storage if rule matched */ -#define DETECT_FLOWVAR_TYPE_POSTMATCH 1 +#define DETECT_VAR_TYPE_FLOW_POSTMATCH 1 +#define DETECT_VAR_TYPE_PKT_POSTMATCH 2 /** execute flowvar storage even if rule doesn't match (for lua) */ -#define DETECT_FLOWVAR_TYPE_ALWAYS 2 +#define DETECT_VAR_TYPE_ALWAYS 3 /** list for flowvar store candidates, to be stored from * post-match function */ -typedef struct DetectFlowvarList_ { +typedef struct DetectVarList_ { uint32_t idx; /**< flowvar name idx */ uint16_t len; /**< data len */ int type; /**< type of store candidate POSTMATCH or ALWAYS */ uint8_t *buffer; /**< alloc'd buffer, may be freed by post-match, post-non-match */ - struct DetectFlowvarList_ *next; -} DetectFlowvarList; + struct DetectVarList_ *next; +} DetectVarList; typedef struct DetectEngineIPOnlyThreadCtx_ { uint8_t *sig_match_array; /* bit array of sig nums */ @@ -877,8 +878,8 @@ typedef struct DetectEngineThreadCtx_ { /* string to replace */ DetectReplaceList *replist; - /* flowvars to store in post match function */ - DetectFlowvarList *flowvarlist; + /* vars to store in post match function */ + DetectVarList *varlist; /* Array in which the filestore keyword stores file id and tx id. If the * full signature matches, these are processed by a post-match filestore