return 0;
}
+static uint64_t HTPGetTxMpmIDs(void *vtx)
+{
+ htp_tx_t *tx = (htp_tx_t *)vtx;
+ HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
+ return tx_ud ? tx_ud->mpm_ids : 0;
+}
+
+static int HTPSetTxMpmIDs(void *vtx, uint64_t mpm_ids)
+{
+ htp_tx_t *tx = (htp_tx_t *)vtx;
+ HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
+ if (tx_ud == NULL) {
+ tx_ud = HTPMalloc(sizeof(*tx_ud));
+ if (unlikely(tx_ud == NULL))
+ return -ENOMEM;
+ memset(tx_ud, 0, sizeof(*tx_ud));
+ htp_tx_set_user_data(tx, tx_ud);
+ }
+ tx_ud->mpm_ids = mpm_ids;
+ return 0;
+}
+
static int HTPRegisterPatternsForProtocolDetection(void)
{
char *methods[] = { "GET", "PUT", "POST", "HEAD", "TRACE", "OPTIONS",
AppLayerParserRegisterDetectStateFuncs(IPPROTO_TCP, ALPROTO_HTTP,
HTPStateHasTxDetectState,
HTPGetTxDetectState, HTPSetTxDetectState);
+ AppLayerParserRegisterMpmIDsFuncs(IPPROTO_TCP, ALPROTO_HTTP,
+ HTPGetTxMpmIDs, HTPSetTxMpmIDs);
AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_HTTP, STREAM_TOSERVER,
HTPHandleRequestData);
/** Now the Body Chunks will be stored per transaction, at
* the tx user data */
typedef struct HtpTxUserData_ {
+ /** flags to track which mpm has run */
+ uint64_t mpm_ids;
+
/* Body of the request (if any) */
uint8_t request_body_init;
uint8_t response_body_init;
} HtpTxUserData;
typedef struct HtpState_ {
-
/* Connection parser structure for each connection */
htp_connp_t *connp;
/* Connection structure for each connection */
DetectEngineState *(*GetTxDetectState)(void *tx);
int (*SetTxDetectState)(void *alstate, void *tx, DetectEngineState *);
+ uint64_t (*GetTxMpmIDs)(void *tx);
+ int (*SetTxMpmIDs)(void *tx, uint64_t);
+
/* each app-layer has its own value */
uint32_t stream_depth;
SCReturn;
}
+void AppLayerParserRegisterMpmIDsFuncs(uint8_t ipproto, AppProto alproto,
+ uint64_t(*GetTxMpmIDs)(void *tx),
+ int (*SetTxMpmIDs)(void *tx, uint64_t))
+{
+ SCEnter();
+
+ alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetTxMpmIDs = GetTxMpmIDs;
+ alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].SetTxMpmIDs = SetTxMpmIDs;
+
+ SCReturn;
+}
+
/***** Get and transaction functions *****/
void *AppLayerParserGetProtocolParserLocalStorage(uint8_t ipproto, AppProto alproto)
SCReturnInt(r);
}
+uint64_t AppLayerParserGetTxMpmIDs(uint8_t ipproto, AppProto alproto, void *tx)
+{
+ if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetTxMpmIDs != NULL) {
+ return alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetTxMpmIDs(tx);
+ }
+
+ return 0ULL;
+}
+
+int AppLayerParserSetTxMpmIDs(uint8_t ipproto, AppProto alproto, void *tx, uint64_t mpm_ids)
+{
+ int r = 0;
+ if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].SetTxMpmIDs != NULL) {
+ r = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].SetTxMpmIDs(tx, mpm_ids);
+ }
+ SCReturnInt(r);
+}
+
/***** General *****/
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto,
void AppLayerParserRegisterGetStreamDepth(uint8_t ipproto,
AppProto alproto,
uint32_t (*GetStreamDepth)(void));
+void AppLayerParserRegisterMpmIDsFuncs(uint8_t ipproto, AppProto alproto,
+ uint64_t (*GetTxMpmIDs)(void *tx),
+ int (*SetTxMpmIDs)(void *tx, uint64_t));
/***** Get and transaction functions *****/
DetectEngineState *AppLayerParserGetTxDetectState(uint8_t ipproto, AppProto alproto, void *tx);
int AppLayerParserSetTxDetectState(uint8_t ipproto, AppProto alproto, void *alstate, void *tx, DetectEngineState *s);
+uint64_t AppLayerParserGetTxMpmIDs(uint8_t ipproto, AppProto alproto, void *tx);
+int AppLayerParserSetTxMpmIDs(uint8_t ipproto, AppProto alproto, void *tx, uint64_t);
+
/***** General *****/
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *tctx, Flow *f, AppProto alproto,
return 0;
}
+static uint64_t SSHGetTxMpmIDs(void *vtx)
+{
+ SshState *ssh_state = (SshState *)vtx;
+ return ssh_state->mpm_ids;
+}
+
+static int SSHSetTxMpmIDs(void *vtx, uint64_t mpm_ids)
+{
+ SshState *ssh_state = (SshState *)vtx;
+ ssh_state->mpm_ids = mpm_ids;
+ return 0;
+}
+
static int SSHGetAlstateProgressCompletionStatus(uint8_t direction)
{
return SSH_STATE_FINISHED;
AppLayerParserRegisterGetStateProgressFunc(IPPROTO_TCP, ALPROTO_SSH, SSHGetAlstateProgress);
AppLayerParserRegisterLoggerFuncs(IPPROTO_TCP, ALPROTO_SSH, SSHGetTxLogged, SSHSetTxLogged);
+ AppLayerParserRegisterMpmIDsFuncs(IPPROTO_TCP, ALPROTO_SSH,
+ SSHGetTxMpmIDs, SSHSetTxMpmIDs);
AppLayerParserRegisterGetStateProgressCompletionStatus(ALPROTO_SSH,
SSHGetAlstateProgressCompletionStatus);
/* specifies which loggers are done logging */
uint32_t logged;
+ /* bit flags of mpms that have already run */
+ uint64_t mpm_ids;
+
DetectEngineState *de_state;
} SshState;
return TLS_STATE_IN_PROGRESS;
}
+static uint64_t SSLGetTxMpmIDs(void *vtx)
+{
+ SSLState *ssl_state = (SSLState *)vtx;
+ return ssl_state->mpm_ids;
+}
+
+static int SSLSetTxMpmIDs(void *vtx, uint64_t mpm_ids)
+{
+ SSLState *ssl_state = (SSLState *)vtx;
+ ssl_state->mpm_ids = mpm_ids;
+ return 0;
+}
+
static int TLSDecodeHandshakeHello(SSLState *ssl_state, uint8_t *input,
uint32_t input_len)
{
AppLayerParserRegisterGetStateProgressFunc(IPPROTO_TCP, ALPROTO_TLS, SSLGetAlstateProgress);
AppLayerParserRegisterLoggerFuncs(IPPROTO_TCP, ALPROTO_TLS, SSLGetTxLogged, SSLSetTxLogged);
+ AppLayerParserRegisterMpmIDsFuncs(IPPROTO_TCP, ALPROTO_TLS,
+ SSLGetTxMpmIDs, SSLSetTxMpmIDs);
AppLayerParserRegisterGetStateProgressCompletionStatus(ALPROTO_TLS,
SSLGetAlstateProgressCompletionStatus);
/* specifies which loggers are done logging */
uint32_t logged;
+ /* MPM/prefilter Id's */
+ uint64_t mpm_ids;
+
/* there might be a better place to store this*/
uint16_t hb_record_len;
if (tx == NULL)
continue;
+ uint64_t mpm_ids = AppLayerParserGetTxMpmIDs(ipproto, alproto, tx);
const int tx_progress = AppLayerParserGetStateProgress(ipproto, alproto, tx, flags);
SCLogDebug("tx %p progress %d", tx, tx_progress);
goto next;
if (engine->tx_min_progress > tx_progress)
goto next;
+ if (tx_progress > engine->tx_min_progress) {
+ if (mpm_ids & (1<<(engine->gid))) {
+ goto next;
+ }
+ }
PROFILING_PREFILTER_START(p);
engine->cb.PrefilterTx(det_ctx, engine->pectx,
p, p->flow, tx, idx, flags);
PROFILING_PREFILTER_END(p, engine->gid);
+
+ if (tx_progress > engine->tx_min_progress) {
+ mpm_ids |= (1<<(engine->gid));
+ }
next:
if (engine->is_last)
break;
engine++;
} while (1);
+
+ if (mpm_ids != 0) {
+ //SCLogNotice("tx %p Mpm IDs: %"PRIx64, tx, mpm_ids);
+ AppLayerParserSetTxMpmIDs(ipproto, alproto, tx, mpm_ids);
+ }
}
}