goto end;
}
- htp_tx_t *tx = list_get(http_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = AppLayerGetTx(ALPROTO_HTTP, http_state, 0);
if (tx == NULL) {
goto end;
}
goto end;
}
- htp_tx_t *tx = list_get(http_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = AppLayerGetTx(ALPROTO_HTTP, http_state, 0);
if (tx == NULL) {
goto end;
}
goto end;
}
- htp_tx_t *tx = list_get(http_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = AppLayerGetTx(ALPROTO_HTTP, http_state, 0);
if (tx == NULL) {
goto end;
}
goto end;
}
- htp_tx_t *tx = list_get(http_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = AppLayerGetTx(ALPROTO_HTTP, http_state, 0);
if (tx == NULL) {
goto end;
}
goto end;
}
- htp_tx_t *tx = list_get(http_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = AppLayerGetTx(ALPROTO_HTTP, http_state, 0);
if (tx == NULL) {
goto end;
}
goto end;
}
- htp_tx_t *tx = list_get(http_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = AppLayerGetTx(ALPROTO_HTTP, http_state, 0);
if (tx == NULL) {
goto end;
}
goto end;
}
- htp_tx_t *tx = list_get(http_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = AppLayerGetTx(ALPROTO_HTTP, http_state, 0);
if (tx == NULL) {
goto end;
}
goto end;
}
- htp_tx_t *tx = list_get(http_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = AppLayerGetTx(ALPROTO_HTTP, http_state, 0);
if (tx == NULL) {
goto end;
}
{ NULL, -1 },
};
+static void *HTPStateGetTx(void *alstate, uint64_t tx_id);
+static int HTPStateGetAlstateProgress(void *tx, uint8_t direction);
+static uint64_t HTPStateGetTxCnt(void *alstate);
+static int HTPStateGetAlstateProgressCompletionStatus(uint8_t direction);
+
#ifdef DEBUG
/**
* \internal
if (s->connp != NULL) {
SCLogDebug("freeing HTP state");
- size_t i;
+ uint64_t tx_id;
+ uint64_t total_txs = HTPStateGetTxCnt(state);
/* free the list of body chunks */
if (s->connp->conn != NULL) {
- for (i = 0; i < list_size(s->connp->conn->transactions); i++) {
- htp_tx_t *tx = (htp_tx_t *)list_get(s->connp->conn->transactions, i);
+ for (tx_id = 0; tx_id < total_txs; tx_id++) {
+ htp_tx_t *tx = HTPStateGetTx(s, tx_id);
if (tx != NULL) {
HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(tx);
if (htud != NULL) {
SCReturn;
}
-/**
- * \brief Update the transaction id based on the http state
- */
-void HTPStateUpdateTransactionId(void *state, uint16_t *id) {
- SCEnter();
-
- HtpState *s = (HtpState *)state;
-
- SCLogDebug("original id %"PRIu16", s->transaction_cnt %"PRIu16,
- *id, (s->transaction_cnt));
-
- if ((s->transaction_cnt) > (*id)) {
- SCLogDebug("original id %"PRIu16", updating with s->transaction_cnt %"PRIu16,
- *id, (s->transaction_cnt));
-
- (*id) = (s->transaction_cnt);
-
- SCLogDebug("updated id %"PRIu16, *id);
- }
-
- SCReturn;
-}
-
/**
* \brief HTP transaction cleanup callback
*
SCReturnInt(ret);
}
-/**
- * \brief get the highest loggable transaction id
- */
-int HtpTransactionGetLoggableId(Flow *f)
-{
- SCEnter();
-
- AppLayerParserStateStore *parser_state_store =
- (AppLayerParserStateStore *)f->alparser;
-
- if (parser_state_store == NULL) {
- SCLogDebug("no state store");
- goto error;
- }
-
- int id = 0;
-
- HtpState *http_state = f->alstate;
- if (http_state == NULL || http_state->connp == NULL ||
- http_state->connp->conn == NULL) {
- SCLogDebug("no (void) http state");
- goto error;
- }
-
- if (parser_state_store->id_flags & APP_LAYER_TRANSACTION_EOF) {
- SCLogDebug("eof, return current transaction as well");
- id = (int)(list_size(http_state->connp->conn->transactions));
- } else {
- id = (int)(parser_state_store->avail_id - 1);
- }
-
- SCReturnInt(id);
-
-error:
- SCReturnInt(-1);
-}
-
#ifdef HAVE_HTP_URI_NORMALIZE_HOOK
/**
* \brief Normalize the query part of the URI as if it's part of the URI.
SCReturnInt(HOOK_ERROR);
}
- SCLogDebug("transaction_cnt %"PRIu16", list_size %"PRIuMAX,
- hstate->transaction_cnt,
- (uintmax_t)list_size(hstate->connp->conn->transactions));
+ SCLogDebug("transaction_cnt %"PRIu64", list_size %"PRIu64,
+ hstate->transaction_cnt, HTPStateGetTxCnt(hstate));
SCLogDebug("HTTP request completed");
}
/* remove obsolete transactions */
- size_t idx;
+ uint64_t idx;
for (idx = 0; idx < hstate->transaction_done; idx++) {
SCLogDebug("idx %"PRIuMAX, (uintmax_t)idx);
- htp_tx_t *tx = list_get(hstate->connp->conn->transactions, idx);
+ htp_tx_t *tx = HTPStateGetTx(hstate, idx);
if (tx == NULL)
continue;
}
}
+static int HTPStateGetAlstateProgress(void *tx, uint8_t direction)
+{
+ return ((htp_tx_t *)tx)->progress[direction];
+}
+
+static uint64_t HTPStateGetTxCnt(void *alstate)
+{
+ return (uint64_t)list_size(((htp_tx_t *)alstate)->connp->conn->transactions);
+}
+
+static void *HTPStateGetTx(void *alstate, uint64_t tx_id)
+{
+ return list_get(((htp_tx_t *)alstate)->connp->conn->transactions, tx_id);
+}
+
+static int HTPStateGetAlstateProgressCompletionStatus(uint8_t direction)
+{
+ return (direction == 0) ? TX_PROGRESS_WAIT : TX_PROGRESS_DONE;
+}
+
static void HTPStateTruncate(void *state, uint8_t flags) {
FileContainer *fc = HTPStateGetFiles(state, flags);
if (fc != NULL) {
AlpProtoAdd(&alp_proto_ctx, proto_name, IPPROTO_TCP, ALPROTO_HTTP, "CONNECT|09|", 8, 0, STREAM_TOSERVER);
AppLayerRegisterStateFuncs(ALPROTO_HTTP, HTPStateAlloc, HTPStateFree);
- AppLayerRegisterTransactionIdFuncs(ALPROTO_HTTP, HTPStateUpdateTransactionId, HTPStateTransactionFree);
+ AppLayerRegisterTransactionIdFuncs(ALPROTO_HTTP, NULL, HTPStateTransactionFree);
AppLayerRegisterGetFilesFunc(ALPROTO_HTTP, HTPStateGetFiles);
+ AppLayerRegisterGetAlstateProgressFunc(ALPROTO_HTTP, HTPStateGetAlstateProgress);
+ AppLayerRegisterGetTxCnt(ALPROTO_HTTP, HTPStateGetTxCnt);
+ AppLayerRegisterGetTx(ALPROTO_HTTP, HTPStateGetTx);
+ AppLayerRegisterGetAlstateProgressCompletionStatus(ALPROTO_HTTP,
+ HTPStateGetAlstateProgressCompletionStatus);
AppLayerDecoderEventsModuleRegister(ALPROTO_HTTP, http_decoder_event_table);
goto end;
}
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
htp_header_t *h = NULL;
table_iterator_reset(tx->request_headers);
goto end;
}
- htp_tx_t *tx = list_get(http_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = HTPStateGetTx(http_state, 0);
htp_header_t *h = NULL;
table_iterator_reset(tx->request_headers);
goto end;
}
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
htp_header_t *h = NULL;
table_iterator_reset(tx->request_headers);
goto end;
}
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
htp_header_t *h = NULL;
table_iterator_reset(tx->request_headers);
goto end;
}
- htp_tx_t *tx = list_get(http_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = HTPStateGetTx(http_state, 0);
htp_header_t *h = NULL;
table_iterator_reset(tx->request_headers);
goto end;
}
- htp_tx_t *tx = list_get(http_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = HTPStateGetTx(http_state, 0);
htp_header_t *h = NULL;
table_iterator_reset(tx->request_headers);
uint8_t ref[] = "/awstats.pl?/migratemigrate = |";
size_t reflen = sizeof(ref) - 1;
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
if (tx != NULL && tx->request_uri_normalized != NULL) {
if (reflen != bstr_size(tx->request_uri_normalized)) {
printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX,
goto end;
}
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
if (tx != NULL && tx->request_uri_normalized != NULL) {
//printf("uri %s\n", bstr_tocstr(tx->request_uri_normalized));
PrintRawDataFp(stdout, (uint8_t *)bstr_ptr(tx->request_uri_normalized),
goto end;
}
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
if (tx != NULL && tx->request_uri_normalized != NULL) {
//printf("uri %s\n", bstr_tocstr(tx->request_uri_normalized));
PrintRawDataFp(stdout, (uint8_t *)bstr_ptr(tx->request_uri_normalized),
goto end;
}
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
htp_header_t *h = NULL;
table_iterator_reset(tx->request_headers);
table_iterator_next(tx->request_headers, (void **) & h);
goto end;
}
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
if (tx != NULL && tx->request_uri_normalized != NULL) {
if (4 != bstr_size(tx->request_uri_normalized)) {
printf("normalized uri len should be 2, is %"PRIuMAX,
goto end;
}
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
if (tx != NULL && tx->request_uri_normalized != NULL) {
if (7 != bstr_size(tx->request_uri_normalized)) {
printf("normalized uri len should be 5, is %"PRIuMAX,
goto end;
}
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
htp_header_t *h = NULL;
table_iterator_reset(tx->request_headers);
table_iterator_next(tx->request_headers, (void **) & h);
uint8_t ref1[] = "/abc%2fdef";
size_t reflen = sizeof(ref1) - 1;
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
if (tx != NULL && tx->request_uri_normalized != NULL) {
if (reflen != bstr_size(tx->request_uri_normalized)) {
printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX,
uint8_t ref2[] = "/abc/def?ghi%2Fjkl";
reflen = sizeof(ref2) - 1;
- tx = list_get(htp_state->connp->conn->transactions, 1);
+ tx = HTPStateGetTx(htp_state, 1);
if (tx != NULL && tx->request_uri_normalized != NULL) {
if (reflen != bstr_size(tx->request_uri_normalized)) {
printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX,
uint8_t ref3[] = "/abc/def?ghi%2Fjkl";
reflen = sizeof(ref2) - 1;
- tx = list_get(htp_state->connp->conn->transactions, 2);
+ tx = HTPStateGetTx(htp_state, 2);
if (tx != NULL && tx->request_uri_normalized != NULL) {
if (reflen != bstr_size(tx->request_uri_normalized)) {
printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX,
uint8_t ref1[] = "/abc/def";
size_t reflen = sizeof(ref1) - 1;
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
if (tx != NULL && tx->request_uri_normalized != NULL) {
if (reflen != bstr_size(tx->request_uri_normalized)) {
printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX,
uint8_t ref2[] = "/abc/def?ghi/jkl";
reflen = sizeof(ref2) - 1;
- tx = list_get(htp_state->connp->conn->transactions, 1);
+ tx = HTPStateGetTx(htp_state, 1);
if (tx != NULL && tx->request_uri_normalized != NULL) {
if (reflen != bstr_size(tx->request_uri_normalized)) {
printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX,
uint8_t ref3[] = "/abc/def?ghi%2Fjkl";
reflen = sizeof(ref3) - 1;
- tx = list_get(htp_state->connp->conn->transactions, 2);
+ tx = HTPStateGetTx(htp_state, 2);
if (tx != NULL && tx->request_uri_normalized != NULL) {
if (reflen != bstr_size(tx->request_uri_normalized)) {
printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX" (3): ",
uint8_t ref1[] = "/abc/def";
size_t reflen = sizeof(ref1) - 1;
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
if (tx != NULL && tx->request_uri_normalized != NULL) {
if (reflen != bstr_size(tx->request_uri_normalized)) {
printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX,
uint8_t ref2[] = "/abc/def?ghi/jkl";
reflen = sizeof(ref2) - 1;
- tx = list_get(htp_state->connp->conn->transactions, 1);
+ tx = HTPStateGetTx(htp_state, 1);
if (tx != NULL && tx->request_uri_normalized != NULL) {
if (reflen != bstr_size(tx->request_uri_normalized)) {
printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX,
uint8_t ref1[] = "/abc/def?a=http://www.abc.com/";
size_t reflen = sizeof(ref1) - 1;
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
if (tx != NULL && tx->request_uri_normalized != NULL) {
if (reflen != bstr_size(tx->request_uri_normalized)) {
printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX,
uint8_t ref1[] = "/index?id=\\\"<script>alert(document.cookie)</script>";
size_t reflen = sizeof(ref1) - 1;
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = HTPStateGetTx(htp_state, 0);
if (tx != NULL && tx->request_uri_normalized != NULL) {
if (reflen != bstr_size(tx->request_uri_normalized)) {
printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX,
htp_connp_t *connp; /**< Connection parser structure for
each connection */
Flow *f; /**< Needed to retrieve the original flow when usin HTPLib callbacks */
- uint16_t flags;
- uint16_t transaction_cnt;
- uint16_t transaction_done;
- uint16_t store_tx_id;
+ uint64_t transaction_cnt;
+ uint64_t transaction_done;
+ uint64_t store_tx_id;
FileContainer *files_ts;
FileContainer *files_tc;
struct HTPCfgRec_ *cfg;
+ uint16_t flags;
} HtpState;
/** part of the engine needs the request body (e.g. http_client_body keyword) */
return e;
}
+int AppLayerGetAlstateProgress(uint16_t alproto, void *state, uint8_t direction)
+{
+ return al_proto_table[alproto].StateGetAlstateProgress(state, direction);
+}
+
+uint64_t AppLayerGetTxCnt(uint16_t alproto, void *alstate)
+{
+ return al_proto_table[alproto].StateGetTxCnt(alstate);
+}
+
+void *AppLayerGetTx(uint16_t alproto, void *alstate, uint64_t tx_id)
+{
+ return al_proto_table[alproto].StateGetTx(alstate, tx_id);
+}
+
+int AppLayerGetAlstateProgressCompletionStatus(uint16_t alproto, uint8_t direction)
+{
+ return al_proto_table[alproto].StateGetAlstateProgressCompletionStatus(direction);
+}
+
+int AppLayerAlprotoSupportsTxs(uint16_t alproto)
+{
+ return (al_proto_table[alproto].StateTransactionFree != NULL);
+}
+
static void AlpResultElmtPoolCleanup(void *e)
{
AppLayerParserResultElmt *re = (AppLayerParserResultElmt *)e;
al_proto_table[proto].StateGetFiles = StateGetFiles;
}
+void AppLayerRegisterGetAlstateProgressFunc(uint16_t alproto,
+ int (*StateGetAlstateProgress)(void *alstate, uint8_t direction))
+{
+ al_proto_table[alproto].StateGetAlstateProgress = StateGetAlstateProgress;
+}
+
+void AppLayerRegisterGetTxCnt(uint16_t alproto,
+ uint64_t (*StateGetTxCnt)(void *alstate))
+{
+ al_proto_table[alproto].StateGetTxCnt = StateGetTxCnt;
+}
+
+void AppLayerRegisterGetTx(uint16_t alproto,
+ void *(StateGetTx)(void *alstate, uint64_t tx_id))
+{
+ al_proto_table[alproto].StateGetTx = StateGetTx;
+}
+
+void AppLayerRegisterGetAlstateProgressCompletionStatus(uint16_t alproto,
+ int (*StateGetAlstateProgressCompletionStatus)(uint8_t direction))
+{
+ al_proto_table[alproto].StateGetAlstateProgressCompletionStatus =
+ StateGetAlstateProgressCompletionStatus;
+}
+
/** \brief Indicate to the app layer parser that a logger is active
* for this protocol.
*/
memset(s, 0, sizeof(AppLayerParserStateStore));
- /* when we start, we're working with transaction id 1 */
- s->avail_id = 1;
-
return s;
}
SCReturnInt(retval);
}
-/** \brief remove obsolete (inspected and logged) transactions */
-static int AppLayerTransactionsCleanup(AppLayerProto *p, AppLayerParserStateStore *parser_state_store, void *app_layer_state) {
- SCEnter();
-
- uint16_t obsolete = 0;
+/**
+ * \brief remove obsolete (inspected and logged) transactions
+ */
+static int AppLayerTransactionsCleanup(AppLayerProto *p, AppLayerParserStateStore *parser_state_store, void *app_layer_state)
+{
+ uint64_t low;
- if (p->StateTransactionFree == NULL) {
- SCLogDebug("no StateTransactionFree function");
+ if (p->StateTransactionFree == NULL)
goto end;
- }
if (p->logger == TRUE) {
- uint16_t low = (parser_state_store->logged_id < parser_state_store->inspect_id) ?
- parser_state_store->logged_id : parser_state_store->inspect_id;
-
- obsolete = low - parser_state_store->base_id;
-
- SCLogDebug("low %"PRIu16" (logged %"PRIu16", inspect %"PRIu16"), base_id %"PRIu16", obsolete %"PRIu16", avail_id %"PRIu16,
- low, parser_state_store->logged_id, parser_state_store->inspect_id, parser_state_store->base_id, obsolete, parser_state_store->avail_id);
+ if (parser_state_store->inspect_id[0] < parser_state_store->inspect_id[1])
+ low = parser_state_store->inspect_id[0];
+ else
+ low = parser_state_store->inspect_id[1];
+ if (parser_state_store->log_id < low) {
+ low = parser_state_store->log_id;
+ }
} else {
- obsolete = parser_state_store->inspect_id - parser_state_store->base_id;
+ if (parser_state_store->inspect_id[0] < parser_state_store->inspect_id[1])
+ low = parser_state_store->inspect_id[0];
+ else
+ low = parser_state_store->inspect_id[1];
}
- SCLogDebug("obsolete transactions: %"PRIu16, obsolete);
-
- /* call the callback on the obsolete transactions */
- while ((obsolete--)) {
- p->StateTransactionFree(app_layer_state, parser_state_store->base_id);
- parser_state_store->base_id++;
- }
-
- SCLogDebug("base_id %"PRIu16, parser_state_store->base_id);
+ p->StateTransactionFree(app_layer_state, low);
end:
- SCReturnInt(0);
+ return 0;
}
#ifdef DEBUG
}
}
- /* update the transaction id */
- if (p->StateUpdateTransactionId != NULL) {
- p->StateUpdateTransactionId(app_layer_state, &parser_state_store->avail_id);
+ /* next, see if we can get rid of transactions now */
+ AppLayerTransactionsCleanup(p, parser_state_store, app_layer_state);
- /* next, see if we can get rid of transactions now */
- AppLayerTransactionsCleanup(p, parser_state_store, app_layer_state);
- }
if (parser_state->flags & APP_LAYER_PARSER_EOF) {
SCLogDebug("eof, flag Transaction id's");
parser_state_store->id_flags |= APP_LAYER_TRANSACTION_EOF;
SCReturnInt(-1);
}
-/** \brief get the base transaction id */
-int AppLayerTransactionGetBaseId(Flow *f) {
- SCEnter();
-
- DEBUG_ASSERT_FLOW_LOCKED(f);
-
- AppLayerParserStateStore *parser_state_store =
- (AppLayerParserStateStore *)f->alparser;
-
- if (parser_state_store == NULL) {
- SCLogDebug("no state store");
- goto error;
- }
-
- SCReturnInt((int)parser_state_store->base_id);
-
-error:
- SCReturnInt(-1);
-}
-
-/** \brief get the base transaction id
- *
- * \retval txid or -1 on error
- */
-int AppLayerTransactionGetInspectId(Flow *f) {
- SCEnter();
-
- DEBUG_ASSERT_FLOW_LOCKED(f);
-
- AppLayerParserStateStore *parser_state_store =
- (AppLayerParserStateStore *)f->alparser;
-
- if (parser_state_store == NULL) {
- SCLogDebug("no state store");
- goto error;
- }
-
- SCReturnInt((int)parser_state_store->inspect_id);
-
-error:
- SCReturnInt(-1);
-}
-
-uint16_t AppLayerTransactionGetAvailId(Flow *f) {
- SCEnter();
-
- DEBUG_ASSERT_FLOW_LOCKED(f);
-
- AppLayerParserStateStore *parser_state_store =
- (AppLayerParserStateStore *)f->alparser;
-
- if (parser_state_store == NULL) {
- SCLogDebug("no state store");
- SCReturnUInt(0);
- }
-
- SCReturnUInt(parser_state_store->avail_id);
-}
-
-/** \brief get the highest loggable transaction id */
-int AppLayerTransactionGetLoggableId(Flow *f) {
- SCEnter();
-
- DEBUG_ASSERT_FLOW_LOCKED(f);
-
- AppLayerParserStateStore *parser_state_store =
- (AppLayerParserStateStore *)f->alparser;
-
- if (parser_state_store == NULL) {
- SCLogDebug("no state store");
- goto error;
- }
-
- int id = 0;
-
- if (parser_state_store->id_flags & APP_LAYER_TRANSACTION_EOF) {
- SCLogDebug("eof, return current transaction as well");
- id = (int)(parser_state_store->avail_id);
- } else {
- id = (int)(parser_state_store->avail_id - 1);
- }
-
- SCReturnInt(id);
-
-error:
- SCReturnInt(-1);
-}
-
-/** \brief get the highest loggable transaction id */
-void AppLayerTransactionUpdateLoggedId(Flow *f) {
- SCEnter();
-
+void AppLayerTransactionUpdateLogId(Flow *f)
+{
DEBUG_ASSERT_FLOW_LOCKED(f);
+ ((AppLayerParserStateStore *)f->alparser)->log_id++;
- AppLayerParserStateStore *parser_state_store =
- (AppLayerParserStateStore *)f->alparser;
-
- if (parser_state_store == NULL) {
- SCLogDebug("no state store");
- goto error;
- }
-
- parser_state_store->logged_id++;
- SCReturn;
-
-error:
- SCReturn;
+ return;
}
-/** \brief get the highest loggable transaction id */
-int AppLayerTransactionGetLoggedId(Flow *f) {
- SCEnter();
+uint64_t AppLayerTransactionGetLogId(Flow *f)
+{
DEBUG_ASSERT_FLOW_LOCKED(f);
- AppLayerParserStateStore *parser_state_store =
- (AppLayerParserStateStore *)f->alparser;
-
- if (parser_state_store == NULL) {
- SCLogDebug("no state store");
- goto error;
- }
-
- SCReturnInt((int)parser_state_store->logged_id);
-
-error:
- SCReturnInt(-1);
+ return ((AppLayerParserStateStore *)f->alparser)->log_id;
}
-/**
- * \brief get the version of the state in a direction
- *
- * \param f LOCKED flow
- * \param direction STREAM_TOSERVER or STREAM_TOCLIENT
- */
-uint16_t AppLayerGetStateVersion(Flow *f) {
+uint16_t AppLayerGetStateVersion(Flow *f)
+{
SCEnter();
DEBUG_ASSERT_FLOW_LOCKED(f);
SCReturnUInt(version);
}
-/**
- * \param f LOCKED flow
- * \param direction STREAM_TOSERVER or STREAM_TOCLIENT
- *
- * \retval 2 current transaction done, new available
- * \retval 1 current transaction done, no new (yet)
- * \retval 0 current transaction is not done yet
- */
-int AppLayerTransactionUpdateInspectId(Flow *f, char direction)
+uint64_t AppLayerTransactionGetInspectId(Flow *f, uint8_t flags)
{
- SCEnter();
-
DEBUG_ASSERT_FLOW_LOCKED(f);
- int r = 0;
- AppLayerParserStateStore *parser_state_store = NULL;
-
- parser_state_store = (AppLayerParserStateStore *)f->alparser;
- if (parser_state_store != NULL) {
- /* update inspect_id and see if it there are other transactions
- * as well */
-
- SCLogDebug("avail_id %"PRIu16", inspect_id %"PRIu16,
- parser_state_store->avail_id, parser_state_store->inspect_id);
+ return ((AppLayerParserStateStore *)f->alparser)->
+ inspect_id[flags & STREAM_TOSERVER ? 0 : 1];
+}
- if (direction == STREAM_TOSERVER) {
- SCLogDebug("toserver");
- parser_state_store->id_flags |= APP_LAYER_TRANSACTION_TOSERVER;
- } else {
- SCLogDebug("toclient");
- parser_state_store->id_flags |= APP_LAYER_TRANSACTION_TOCLIENT;
- }
+void AppLayerTransactionUpdateInspectId(Flow *f, uint8_t flags)
+{
+ DEBUG_ASSERT_FLOW_LOCKED(f);
- if ((parser_state_store->inspect_id+1) < parser_state_store->avail_id &&
- (parser_state_store->id_flags & APP_LAYER_TRANSACTION_TOCLIENT) &&
- (parser_state_store->id_flags & APP_LAYER_TRANSACTION_TOSERVER))
- {
- parser_state_store->id_flags &=~ APP_LAYER_TRANSACTION_TOCLIENT;
- parser_state_store->id_flags &=~ APP_LAYER_TRANSACTION_TOSERVER;
+ uint8_t direction = (flags & STREAM_TOSERVER) ? 0 : 1;
- parser_state_store->inspect_id = parser_state_store->avail_id - 1;
- if (parser_state_store->inspect_id < parser_state_store->avail_id) {
- /* done and more transactions available */
- r = 2;
+ uint64_t total_txs = AppLayerGetTxCnt(f->alproto, f->alstate);
+ uint64_t idx = AppLayerTransactionGetInspectId(f, flags);
+ int state_done_progress = AppLayerGetAlstateProgressCompletionStatus(f->alproto, direction);
+ void *tx;
+ int tx_updated_by = 0;
+ int state_progress;
- SCLogDebug("inspect_id %"PRIu16", avail_id %"PRIu16,
- parser_state_store->inspect_id,
- parser_state_store->avail_id);
- } else {
- /* done but no more transactions available */
- r = 1;
+ for (; idx < total_txs; idx++, tx_updated_by++) {
+ tx = AppLayerGetTx(f->alproto, f->alstate, idx);
+ if (tx == NULL)
+ continue;
+ state_progress = AppLayerGetAlstateProgress(f->alproto, tx, direction);
+ if (state_progress >= state_done_progress)
+ continue;
+ else
+ break;
+ }
- SCLogDebug("inspect_id %"PRIu16", avail_id %"PRIu16,
- parser_state_store->inspect_id,
- parser_state_store->avail_id);
- }
- }
+ ((AppLayerParserStateStore *)f->alparser)->inspect_id[direction] = idx;
+ if (tx_updated_by > 0) {
+ DetectEngineStateReset(f->de_state, flags);
}
- SCReturnInt(r);
+ return;
}
void AppLayerListSupportedProtocols(void)
void (*Truncate)(void *, uint8_t);
FileContainer *(*StateGetFiles)(void *, uint8_t);
+ int (*StateGetAlstateProgress)(void *alstate, uint8_t direction);
+ uint64_t (*StateGetTxCnt)(void *alstate);
+ void *(*StateGetTx)(void *alstate, uint64_t tx_id);
+ int (*StateGetAlstateProgressCompletionStatus)(uint8_t direction);
} AppLayerProto;
/** flags for the result elmts */
/** flags related to the id's */
uint8_t id_flags;
- /** the highest id of inspected state's (i.e. http transactions), updated by
- * the stateful detection engine code */
- uint16_t inspect_id;
- /** the highest id of logged state's (i.e. http transactions), updated by
- * a logging module throught the app layer API */
- uint16_t logged_id;
- /** the higest id of available state's, updated by the app layer parser */
- uint16_t avail_id;
- /** the base id signifies the id number of the oldest id we have in our
- * state. As transactions may be cleaned up before the entire state is
- * freed, id's may "disappear". */
- uint16_t base_id;
-
+ /* Indicates the current transaction that is being indicated. We have
+ * a var per direction. */
+ uint64_t inspect_id[2];
+ /* Indicates the current transaction being logged. Unlike inspect_id,
+ * we don't need a var per direction since we don't log a transaction
+ * unless we have the entire transaction. */
+ uint64_t log_id;
uint16_t version; /**< state version, incremented for each update,
* can wrap around */
uint16_t AppLayerGetProtoByName(const char *);
const char *AppLayerGetProtoString(int proto);
void AppLayerRegisterTruncateFunc(uint16_t proto, void (*Truncate)(void *, uint8_t));
+void AppLayerRegisterGetAlstateProgressFunc(uint16_t alproto,
+ int (*StateGetAlstateProgress)(void *alstate, uint8_t direction));
+void AppLayerRegisterGetTxCnt(uint16_t alproto,
+ uint64_t (*StateGetTxCnt)(void *alstate));
+void AppLayerRegisterGetTx(uint16_t alproto,
+ void *(*StateGetTx)(void *alstate, uint64_t tx_id));
+void AppLayerRegisterGetAlstateProgressCompletionStatus(uint16_t alproto,
+ int (*StateProgressCompletionStatus)(uint8_t direction));
int AppLayerParse(void *, Flow *, uint8_t,
uint8_t, uint8_t *, uint32_t);
uint32_t, uint32_t *);
-/* transaction handling */
-int AppLayerTransactionUpdateInspectId(Flow *, char);
-void AppLayerTransactionUpdateLoggedId(Flow *);
-int AppLayerTransactionGetLoggableId(Flow *f);
-int AppLayerTransactionGetLoggedId(Flow *f);
-int AppLayerTransactionGetBaseId(Flow *f);
-int AppLayerTransactionGetInspectId(Flow *f);
-uint16_t AppLayerTransactionGetAvailId(Flow *f);
+/***** transaction handling *****/
+
+/**
+ * \brief Update the current log id. Does one step increments currently.
+ *
+ * \param f Flow.
+ */
+void AppLayerTransactionUpdateLogId(Flow *f);
+
+/**
+ * \brief Get the current log id.
+ *
+ * \param f Flow.
+ */
+uint64_t AppLayerTransactionGetLogId(Flow *f);
+
+/**
+ * \brief Updates the inspection id for the alstate.
+ *
+ * \param f Pointer to the flow(LOCKED).
+ * \param direction Direction. 0 - toserver, 1 - toclient.
+ */
+void AppLayerTransactionUpdateInspectId(Flow *f, uint8_t direction);
+
+/**
+ * \brief Get the current tx id to be inspected.
+ *
+ * \param f Flow.
+ * \param flags Flags.
+ *
+ * \retval A positive integer value.
+ */
+uint64_t AppLayerTransactionGetInspectId(Flow *f, uint8_t flags);
+
+
void AppLayerSetEOF(Flow *);
-/* cleanup */
+
+
+/***** cleanup *****/
+
void AppLayerParserCleanupState(Flow *);
void AppLayerFreeProbingParsers(AppLayerProbingParser *);
void AppLayerFreeProbingParsersInfo(AppLayerProbingParserInfo *);
void AppLayerPrintProbingParsers(AppLayerProbingParser *);
-uint16_t AppLayerGetStateVersion(Flow *f);
void AppLayerListSupportedProtocols(void);
-FileContainer *AppLayerGetFilesFromFlow(Flow *, uint8_t);
AppLayerDecoderEvents *AppLayerGetDecoderEventsForFlow(Flow *);
+/***** Alproto param retrieval ******/
+
+/**
+ * \brief get the version of the state in a direction
+ *
+ * \param f Flow(LOCKED).
+ * \param direction STREAM_TOSERVER or STREAM_TOCLIENT
+ */
+uint16_t AppLayerGetStateVersion(Flow *f);
+
+FileContainer *AppLayerGetFilesFromFlow(Flow *, uint8_t);
+
+/**
+ * \brief Get the state progress.
+ *
+ * This is a generic wrapper to each ALPROTO. The value returned
+ * needs to be interpreted by the caller, based on the ALPROTO_*
+ * the caller supplies.
+ *
+ * The state can be anything based on what the ALPROTO handler
+ * expects. We have given a return value of int, although a range
+ * of -128 to 127 (int8_t) should be more than sufficient.
+ *
+ * \param alproto The app protocol.
+ * \param state App state.
+ * \param dir Directin. 0 - ts, 1 - tc.
+ *
+ * \retval An integer value indicating the current progress of "state".
+ */
+int AppLayerGetAlstateProgress(uint16_t alproto, void *state, uint8_t direction);
+
+/**
+ * \brief Get the no of txs.
+ *
+ * \param alproto The app protocol.
+ * \param alstate App state.
+ *
+ * \retval A positive integer value indicating the no of txs.
+ */
+uint64_t AppLayerGetTxCnt(uint16_t alproto, void *alstate);
+
+/**
+ * \brief Get a tx referenced by the id.
+ *
+ * \param alproto The app protocol
+ * \param alstate App state.
+ * \param tx_id The transaction id.
+ *
+ * \retval Tx instance.
+ */
+void *AppLayerGetTx(uint16_t alproto, void *alstate, uint64_t tx_id);
+
+/**
+ * \brief Get the state value for the following alproto, that corresponds to
+ * COMPLETE or DONE.
+ *
+ * \param alproto The app protocol.
+ * \param direction The direction. 0 - ts, 1 - tc.
+ *
+ * \retval An integer value indicating the state value.
+ */
+int AppLayerGetAlstateProgressCompletionStatus(uint16_t alproto, uint8_t direction);
+
+/**
+ * \brief Informs if the alproto supports transactions or not.
+ *
+ * \param alproto The app protocol.
+ * \param direction The direction. 0 - ts, 1 - tc.
+ *
+ * \retval 1 If true; 0 If false.
+ */
+int AppLayerAlprotoSupportsTxs(uint16_t alproto);
+
void AppLayerTriggerRawStreamReassembly(Flow *);
#endif /* __APP_LAYER_PARSER_H__ */
return result;
}
+/* Disabled because of bug_753. Would be enabled, once we rewrite
+ * dce parser */
+#if 0
+
/**
* \test Test a valid dce_iface entry with a bind, bind_ack and 3 request/responses.
*/
return result;
}
+#endif
+
/**
* \test Test a valid dce_iface entry for a bind and bind_ack
*/
UtRegisterTest("DetectDceIfaceTestParse10", DetectDceIfaceTestParse10, 1);
UtRegisterTest("DetectDceIfaceTestParse11", DetectDceIfaceTestParse11, 1);
UtRegisterTest("DetectDceIfaceTestParse12", DetectDceIfaceTestParse12, 1);
+ /* Disabled because of bug_753. Would be enabled, once we rewrite
+ * dce parser */
+#if 0
UtRegisterTest("DetectDceIfaceTestParse13", DetectDceIfaceTestParse13, 1);
+#endif
UtRegisterTest("DetectDceIfaceTestParse14", DetectDceIfaceTestParse14, 1);
UtRegisterTest("DetectDceIfaceTestParse15", DetectDceIfaceTestParse15, 1);
#endif
return result;
}
+/* Disabled because of bug_753. Would be enabled, once we rewrite
+ * dce parser */
+#if 0
+
/**
* \test Test a valid dce_opnum(with multiple values) with a bind, bind_ack,
* and multiple request/responses with a match test after each frag parsing.
UTHFreePackets(&p, 1);
return result;
}
+#endif
+
+
#endif
void DetectDceOpnumRegisterTests(void)
{
UtRegisterTest("DetectDceOpnumTestParse07", DetectDceOpnumTestParse07, 1);
UtRegisterTest("DetectDceOpnumTestParse08", DetectDceOpnumTestParse08, 1);
UtRegisterTest("DetectDceOpnumTestParse09", DetectDceOpnumTestParse09, 1);
+ /* Disabled because of bug_753. Would be enabled, once we rewrite
+ * dce parser */
+#if 0
UtRegisterTest("DetectDceOpnumTestParse10", DetectDceOpnumTestParse10, 1);
UtRegisterTest("DetectDceOpnumTestParse11", DetectDceOpnumTestParse11, 1);
UtRegisterTest("DetectDceOpnumTestParse12", DetectDceOpnumTestParse12, 1);
UtRegisterTest("DetectDceOpnumTestParse13", DetectDceOpnumTestParse13, 1);
+#endif
#endif
return;
#endif
}
+/* Disabled because of bug_753. Would be enabled, once we rewrite
+ * dce parser */
+#if 0
/**
* \test Test the working of detection engien with respect to dce keywords.
return result;
}
+#endif
+
/**
* \test Test the working of byte_test endianness.
*/
UtRegisterTest("DcePayloadTest10", DcePayloadTest10, 1);
UtRegisterTest("DcePayloadTest11", DcePayloadTest11, 1);
UtRegisterTest("DcePayloadTest12", DcePayloadTest12, 1);
+ /* Disabled because of bug_753. Would be enabled, once we rewrite
+ * dce parser */
+#if 0
UtRegisterTest("DcePayloadTest13", DcePayloadTest13, 1);
UtRegisterTest("DcePayloadTest14", DcePayloadTest14, 1);
+#endif
UtRegisterTest("DcePayloadTest15", DcePayloadTest15, 1);
UtRegisterTest("DcePayloadTest16", DcePayloadTest16, 1);
UtRegisterTest("DcePayloadTest17", DcePayloadTest17, 1);
}
if (file->txid < det_ctx->tx_id) {
- SCLogDebug("file->txid < det_ctx->tx_id == %u < %u", file->txid, det_ctx->tx_id);
+ SCLogDebug("file->txid < det_ctx->tx_id == %"PRIu64" < %"PRIu64, file->txid, det_ctx->tx_id);
continue;
}
if (file->txid > det_ctx->tx_id) {
- SCLogDebug("file->txid > det_ctx->tx_id == %u > %u", file->txid, det_ctx->tx_id);
+ SCLogDebug("file->txid > det_ctx->tx_id == %"PRIu64" > %"PRIu64, file->txid, det_ctx->tx_id);
break;
}
*
* \note flow should be locked when this function's called.
*/
-int DetectFileInspectHttp(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Signature *s, Flow *f, uint8_t flags, void *alstate, int tx_id) {
- int r = 0;
+int DetectFileInspectHttp(ThreadVars *tv,
+ DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
+ Signature *s, Flow *f, uint8_t flags, void *alstate,
+ void *tx, uint64_t tx_id)
+{
+ int r = DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
FileContainer *ffc;
HtpState *htp_state = (HtpState *)alstate;
int match = DetectFileInspect(tv, det_ctx, f, s, flags, ffc);
if (match == 1) {
- r = 1;
+ r = DETECT_ENGINE_INSPECT_SIG_MATCH;
} else if (match == 2) {
if (r != 1) {
SCLogDebug("sid %u can't match on this transaction", s->id);
- r = 2;
+ r = DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
}
} else if (match == 3) {
if (r != 1) {
SCLogDebug("sid %u can't match on this transaction (filestore sig)", s->id);
- r = 3;
+ r = DETECT_ENGINE_INSPECT_SIG_CANT_MATCH_FILESTORE;
}
}
#ifndef __DETECT_ENGINE_FILE_H__
#define __DETECT_ENGINE_FILE_H__
-int DetectFileInspectHttp(ThreadVars *tv, DetectEngineCtx *de_ctx,
- DetectEngineThreadCtx *det_ctx, Signature *s,
- Flow *f, uint8_t flags, void *alstate, int tx_id);
-
+int DetectFileInspectHttp(ThreadVars *tv,
+ DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
+ Signature *s, Flow *f, uint8_t flags, void *alstate,
+ void *tx, uint64_t tx_id);
#endif /* __DETECT_ENGINE_FILE_H__ */
return 0;
}
-static uint8_t *DetectEngineHCBDGetBufferForTX(int tx_id,
+/**
+ */
+static uint8_t *DetectEngineHCBDGetBufferForTX(htp_tx_t *tx, uint64_t tx_id,
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Flow *f, HtpState *htp_state,
if (det_ctx->hcbd_buffers_list_len == 0) {
if (HCBDCreateSpace(det_ctx, 1) < 0)
- goto end;
+ goto end; /* let's consider it as stage not done for now */
index = 0;
if (det_ctx->hcbd_buffers_list_len == 0) {
}
} else {
if (HCBDCreateSpace(det_ctx, (tx_id - det_ctx->hcbd_start_tx_id) + 1) < 0)
- goto end;
+ goto end; /* let's consider it as stage not done for now */
if (det_ctx->hcbd_buffers_list_len == 0) {
det_ctx->hcbd_start_tx_id = tx_id;
index = (tx_id - det_ctx->hcbd_start_tx_id);
}
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, tx_id);
- if (tx == NULL) {
- SCLogDebug("no tx");
- goto end;
- }
-
HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx);
if (htud == NULL) {
SCLogDebug("no htud");
* when they come */
if (htud->request_body.content_len == 0) {
if ((htud->request_body.content_len_so_far > 0) &&
- tx->progress != TX_PROGRESS_REQ_BODY) {
+ tx->progress[0] != TX_PROGRESS_REQ_BODY) {
/* final length of the body */
htud->tsflags |= HTP_REQ_BODY_COMPLETE;
}
int DetectEngineRunHttpClientBodyMpm(DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx, Flow *f,
- HtpState *htp_state, uint8_t flags)
+ HtpState *htp_state, uint8_t flags,
+ void *tx, uint64_t idx)
{
uint32_t cnt = 0;
-
- if (htp_state == NULL) {
- SCLogDebug("no HTTP state");
- goto end;
- }
-
- FLOWLOCK_WRLOCK(f);
-
- if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
- SCLogDebug("HTP state has no conn(p)");
- goto end;
- }
-
- /* get the transaction id */
- int idx = AppLayerTransactionGetInspectId(f);
- /* error! get out of here */
- if (idx == -1)
+ uint32_t buffer_len = 0;
+ uint8_t *buffer = DetectEngineHCBDGetBufferForTX(tx, idx,
+ de_ctx, det_ctx,
+ f, htp_state,
+ flags,
+ &buffer_len);
+ if (buffer_len == 0)
goto end;
- int size = (int)list_size(htp_state->connp->conn->transactions);
- for (; idx < size; idx++) {
- uint32_t buffer_len = 0;
- uint8_t *buffer = DetectEngineHCBDGetBufferForTX(idx,
- de_ctx, det_ctx,
- f, htp_state,
- flags,
- &buffer_len);
- if (buffer_len == 0)
- continue;
-
- cnt += HttpClientBodyPatternSearch(det_ctx, buffer, buffer_len, flags);
- }
+ cnt = HttpClientBodyPatternSearch(det_ctx, buffer, buffer_len, flags);
end:
- FLOWLOCK_UNLOCK(f);
return cnt;
}
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Signature *s, Flow *f, uint8_t flags,
- void *alstate, int tx_id)
+ void *alstate, void *tx, uint64_t tx_id)
{
HtpState *htp_state = (HtpState *)alstate;
-
uint32_t buffer_len = 0;
- uint8_t *buffer = DetectEngineHCBDGetBufferForTX(tx_id,
+ uint8_t *buffer = DetectEngineHCBDGetBufferForTX(tx, tx_id,
de_ctx, det_ctx,
f, htp_state,
flags,
&buffer_len);
if (buffer_len == 0)
- return 0;
+ goto end;
det_ctx->buffer_offset = 0;
det_ctx->discontinue_matching = 0;
buffer_len,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_HCBD, NULL);
if (r == 1)
- return 1;
+ return DETECT_ENGINE_INSPECT_SIG_MATCH;
- return 0;
+
+ end:
+ if (AppLayerGetAlstateProgress(ALPROTO_HTTP, tx, 0) > TX_PROGRESS_REQ_BODY)
+ return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
+ else
+ return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
}
void DetectEngineCleanHCBDBuffers(DetectEngineThreadCtx *det_ctx)
#include "app-layer-htp.h"
-int DetectEngineRunHttpClientBodyMpm(DetectEngineCtx *,
- DetectEngineThreadCtx *, Flow *f,
- HtpState *, uint8_t);
+int DetectEngineRunHttpClientBodyMpm(DetectEngineCtx *de_ctx,
+ DetectEngineThreadCtx *det_ctx, Flow *f,
+ HtpState *htp_state, uint8_t flags,
+ void *tx, uint64_t idx);
int DetectEngineInspectHttpClientBody(ThreadVars *tv,
- DetectEngineCtx *,
- DetectEngineThreadCtx *,
- Signature *, Flow *,
- uint8_t, void *, int);
+ DetectEngineCtx *de_ctx,
+ DetectEngineThreadCtx *det_ctx,
+ Signature *s, Flow *f, uint8_t flags,
+ void *alstate,
+ void *tx, uint64_t tx_id);
void DetectEngineCleanHCBDBuffers(DetectEngineThreadCtx *);
void DetectEngineHttpClientBodyRegisterTests(void);
#include "app-layer-protos.h"
int DetectEngineRunHttpCookieMpm(DetectEngineThreadCtx *det_ctx, Flow *f,
- HtpState *htp_state, uint8_t flags)
+ HtpState *htp_state, uint8_t flags,
+ void *txv, uint64_t idx)
{
- htp_tx_t *tx = NULL;
uint32_t cnt = 0;
- int idx;
-
- /* we need to lock because the buffers are not actually true buffers
- * but are ones that point to a buffer given by libhtp */
- FLOWLOCK_RDLOCK(f);
-
- if (htp_state == NULL) {
- SCLogDebug("no HTTP state");
- goto end;
- }
-
- if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
- SCLogDebug("HTP state has no conn(p)");
- goto end;
- }
-
- idx = AppLayerTransactionGetInspectId(f);
- if (idx == -1) {
+ htp_tx_t *tx = (htp_tx_t *)txv;
+ if (tx->request_headers == NULL)
goto end;
- }
- int size = (int)list_size(htp_state->connp->conn->transactions);
- for (; idx < size; idx++) {
-
- tx = list_get(htp_state->connp->conn->transactions, idx);
- if (tx == NULL)
- continue;
-
- htp_header_t *h = NULL;
- if (flags & STREAM_TOSERVER) {
- h = (htp_header_t *)table_getc(tx->request_headers,
- "Cookie");
- if (h == NULL) {
- SCLogDebug("HTTP cookie header not present in this request");
- continue;
- }
- } else {
- h = (htp_header_t *)table_getc(tx->response_headers,
- "Set-Cookie");
- if (h == NULL) {
- SCLogDebug("HTTP Set-Cookie header not present in this request");
- continue;
- }
+ htp_header_t *h = NULL;
+ if (flags & STREAM_TOSERVER) {
+ h = (htp_header_t *)table_getc(tx->request_headers,
+ "Cookie");
+ if (h == NULL) {
+ SCLogDebug("HTTP cookie header not present in this request");
+ goto end;
+ }
+ } else {
+ h = (htp_header_t *)table_getc(tx->response_headers,
+ "Set-Cookie");
+ if (h == NULL) {
+ SCLogDebug("HTTP Set-Cookie header not present in this request");
+ goto end;
}
-
- cnt += HttpCookiePatternSearch(det_ctx,
- (uint8_t *)bstr_ptr(h->value),
- bstr_len(h->value), flags);
}
+ cnt = HttpCookiePatternSearch(det_ctx,
+ (uint8_t *)bstr_ptr(h->value),
+ bstr_len(h->value), flags);
end:
- FLOWLOCK_UNLOCK(f);
return cnt;
}
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Signature *s, Flow *f, uint8_t flags,
- void *alstate, int tx_id)
+ void *alstate,
+ void *txv, uint64_t tx_id)
{
- HtpState *htp_state = (HtpState *)alstate;
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, tx_id);
- if (tx == NULL)
- return 0;
-
+ htp_tx_t *tx = (htp_tx_t *)txv;
htp_header_t *h = NULL;
if (flags & STREAM_TOSERVER) {
h = (htp_header_t *)table_getc(tx->request_headers,
"Cookie");
if (h == NULL) {
SCLogDebug("HTTP cookie header not present in this request");
- return 0;
+ goto end;
}
} else {
h = (htp_header_t *)table_getc(tx->response_headers,
"Set-Cookie");
if (h == NULL) {
SCLogDebug("HTTP Set-Cookie header not present in this request");
- return 0;
+ goto end;
}
}
bstr_len(h->value),
DETECT_ENGINE_CONTENT_INSPECTION_MODE_HCD, NULL);
if (r == 1)
- return 1;
+ return DETECT_ENGINE_INSPECT_SIG_MATCH;
- return 0;
+ end:
+ if (flags & STREAM_TOSERVER) {
+ if (AppLayerGetAlstateProgress(ALPROTO_HTTP, tx, 0) > TX_PROGRESS_REQ_HEADERS)
+ return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
+ } else {
+ if (AppLayerGetAlstateProgress(ALPROTO_HTTP, tx, 1) > TX_PROGRESS_RES_HEADERS)
+ return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
+ }
+ return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
}
/***********************************Unittests**********************************/
#include "app-layer-htp.h"
int DetectEngineInspectHttpCookie(ThreadVars *tv,
- DetectEngineCtx *, DetectEngineThreadCtx *,
- Signature *, Flow *, uint8_t, void *, int);
-int DetectEngineRunHttpCookieMpm(DetectEngineThreadCtx *, Flow *, HtpState *, uint8_t);
+ DetectEngineCtx *de_ctx,
+ DetectEngineThreadCtx *det_ctx,
+ Signature *s, Flow *f, uint8_t flags,
+ void *alstate,
+ void *tx, uint64_t tx_id);
+int DetectEngineRunHttpCookieMpm(DetectEngineThreadCtx *det_ctx, Flow *f,
+ HtpState *htp_state, uint8_t flags,
+ void *tx, uint64_t idx);
void DetectEngineHttpCookieRegisterTests(void);
#endif /* __DETECT_ENGINE_HCD_H__ */
}
-static uint8_t *DetectEngineHHDGetBufferForTX(int tx_id,
+static uint8_t *DetectEngineHHDGetBufferForTX(htp_tx_t *tx, uint64_t tx_id,
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Flow *f, HtpState *htp_state,
index = (tx_id - det_ctx->hhd_start_tx_id);
}
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, tx_id);
- if (tx == NULL) {
- SCLogDebug("no tx");
- goto end;
- }
-
table_t *headers;
if (flags & STREAM_TOSERVER) {
headers = tx->request_headers;
}
int DetectEngineRunHttpHeaderMpm(DetectEngineThreadCtx *det_ctx, Flow *f,
- HtpState *htp_state, uint8_t flags)
+ HtpState *htp_state, uint8_t flags,
+ void *tx, uint64_t idx)
{
uint32_t cnt = 0;
-
- if (htp_state == NULL) {
- SCLogDebug("no HTTP state");
- goto end;
- }
-
- FLOWLOCK_WRLOCK(f);
-
- if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
- SCLogDebug("HTP state has no conn(p)");
- goto end;
- }
-
- /* get the transaction id */
- int idx = AppLayerTransactionGetInspectId(f);
- /* error! get out of here */
- if (idx == -1)
+ uint32_t buffer_len = 0;
+ uint8_t *buffer = DetectEngineHHDGetBufferForTX(tx, idx,
+ NULL, det_ctx,
+ f, htp_state,
+ flags,
+ &buffer_len);
+ if (buffer_len == 0)
goto end;
- int size = (int)list_size(htp_state->connp->conn->transactions);
- for (; idx < size; idx++) {
- uint32_t buffer_len = 0;
- uint8_t *buffer = DetectEngineHHDGetBufferForTX(idx,
- NULL, det_ctx,
- f, htp_state,
- flags,
- &buffer_len);
- if (buffer_len == 0)
- continue;
-
- cnt += HttpHeaderPatternSearch(det_ctx, buffer, buffer_len, flags);
- }
+ cnt = HttpHeaderPatternSearch(det_ctx, buffer, buffer_len, flags);
end:
- FLOWLOCK_UNLOCK(f);
return cnt;
}
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Signature *s, Flow *f, uint8_t flags,
- void *alstate, int tx_id)
+ void *alstate,
+ void *tx, uint64_t tx_id)
{
HtpState *htp_state = (HtpState *)alstate;
uint32_t buffer_len = 0;
- uint8_t *buffer = DetectEngineHHDGetBufferForTX(tx_id,
+ uint8_t *buffer = DetectEngineHHDGetBufferForTX(tx, tx_id,
de_ctx, det_ctx,
f, htp_state,
flags,
&buffer_len);
if (buffer_len == 0)
- return 0;
+ goto end;
det_ctx->buffer_offset = 0;
det_ctx->discontinue_matching = 0;
buffer_len,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_HHD, NULL);
if (r == 1)
- return 1;
+ return DETECT_ENGINE_INSPECT_SIG_MATCH;
- return 0;
+ end:
+ if (flags & STREAM_TOSERVER) {
+ if (AppLayerGetAlstateProgress(ALPROTO_HTTP, tx, 0) > TX_PROGRESS_REQ_HEADERS)
+ return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
+ } else {
+ if (AppLayerGetAlstateProgress(ALPROTO_HTTP, tx, 1) > TX_PROGRESS_RES_HEADERS)
+ return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
+ }
+ return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
}
void DetectEngineCleanHHDBuffers(DetectEngineThreadCtx *det_ctx)
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Signature *s, Flow *f, uint8_t flags,
- void *alstate, int tx_id);
+ void *alstate,
+ void *tx, uint64_t tx_id);
int DetectEngineRunHttpHeaderMpm(DetectEngineThreadCtx *det_ctx, Flow *f,
- HtpState *htp_state, uint8_t flags);
+ HtpState *htp_state, uint8_t flags,
+ void *tx, uint64_t idx);
void DetectEngineCleanHHDBuffers(DetectEngineThreadCtx *det_ctx);
void DetectEngineHttpHeaderRegisterTests(void);
#include "detect-engine-hhhd.h"
int DetectEngineRunHttpHHMpm(DetectEngineThreadCtx *det_ctx, Flow *f,
- HtpState *htp_state, uint8_t flags)
+ HtpState *htp_state, uint8_t flags,
+ void *txv, uint64_t idx)
{
- htp_tx_t *tx = NULL;
uint32_t cnt = 0;
- int idx;
-
- /* we need to lock because the buffers are not actually true buffers
- * but are ones that point to a buffer given by libhtp */
- FLOWLOCK_RDLOCK(f);
-
- if (htp_state == NULL) {
- SCLogDebug("no HTTP state");
- goto end;
- }
-
- if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
- SCLogDebug("HTP state has no conn(p)");
+ htp_tx_t *tx = (htp_tx_t *)txv;
+ if (tx->parsed_uri == NULL || tx->parsed_uri->hostname == NULL)
goto end;
- }
-
- idx = AppLayerTransactionGetInspectId(f);
- if (idx == -1) {
+ uint8_t *hname = (uint8_t *)bstr_ptr(tx->parsed_uri->hostname);
+ if (hname == NULL)
goto end;
- }
-
- int size = (int)list_size(htp_state->connp->conn->transactions);
- for (; idx < size; idx++) {
-
- tx = list_get(htp_state->connp->conn->transactions, idx);
- if (tx == NULL || tx->parsed_uri == NULL || tx->parsed_uri->hostname == NULL)
- continue;
- uint8_t *hname = (uint8_t *)bstr_ptr(tx->parsed_uri->hostname);
- if (hname == NULL)
- continue;
- uint32_t hname_len = bstr_len(tx->parsed_uri->hostname);
+ uint32_t hname_len = bstr_len(tx->parsed_uri->hostname);
- cnt += HttpHHPatternSearch(det_ctx, hname, hname_len, flags);
- }
+ cnt += HttpHHPatternSearch(det_ctx, hname, hname_len, flags);
end:
- FLOWLOCK_UNLOCK(f);
return cnt;
}
* \retval 1 Match.
*/
int DetectEngineInspectHttpHH(ThreadVars *tv,
- DetectEngineCtx *de_ctx,
- DetectEngineThreadCtx *det_ctx,
- Signature *s, Flow *f, uint8_t flags,
- void *alstate, int tx_id)
+ DetectEngineCtx *de_ctx,
+ DetectEngineThreadCtx *det_ctx,
+ Signature *s, Flow *f, uint8_t flags,
+ void *alstate,
+ void *txv, uint64_t tx_id)
{
- HtpState *htp_state = (HtpState *)alstate;
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, tx_id);
- if (tx == NULL || tx->parsed_uri == NULL || tx->parsed_uri->hostname == NULL)
- return 0;
+ htp_tx_t *tx = (htp_tx_t *)txv;
+ if (tx->parsed_uri == NULL || tx->parsed_uri->hostname == NULL)
+ goto end;
uint8_t *hname = (uint8_t *)bstr_ptr(tx->parsed_uri->hostname);
if (hname == NULL)
- return 0;
+ goto end;
uint32_t hname_len = bstr_len(tx->parsed_uri->hostname);
det_ctx->buffer_offset = 0;
hname, hname_len,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_HHHD, NULL);
if (r == 1)
- return 1;
+ return DETECT_ENGINE_INSPECT_SIG_MATCH;
- return 0;
+ end:
+ if (AppLayerGetAlstateProgress(ALPROTO_HTTP, tx, 0) > TX_PROGRESS_REQ_HEADERS)
+ return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
+ else
+ return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
}
/***********************************Unittests**********************************/
#include "app-layer-htp.h"
int DetectEngineInspectHttpHH(ThreadVars *tv,
- DetectEngineCtx *, DetectEngineThreadCtx *,
- Signature *, Flow *, uint8_t, void *, int);
-int DetectEngineRunHttpHHMpm(DetectEngineThreadCtx *, Flow *, HtpState *, uint8_t);
+ DetectEngineCtx *de_ctx,
+ DetectEngineThreadCtx *det_ctx,
+ Signature *s, Flow *f, uint8_t flags,
+ void *alstate,
+ void *tx, uint64_t tx_id);
+int DetectEngineRunHttpHHMpm(DetectEngineThreadCtx *det_ctx, Flow *f,
+ HtpState *htp_state, uint8_t flags,
+ void *tx, uint64_t idx);
void DetectEngineHttpHHRegisterTests(void);
#endif /* __DETECT_ENGINE_HHHD_H__ */
#include "app-layer-protos.h"
int DetectEngineRunHttpMethodMpm(DetectEngineThreadCtx *det_ctx, Flow *f,
- HtpState *htp_state, uint8_t flags)
+ HtpState *htp_state, uint8_t flags,
+ void *txv, uint64_t idx)
{
- htp_tx_t *tx = NULL;
uint32_t cnt = 0;
- int idx;
-
- /* we need to lock because the buffers are not actually true buffers
- * but are ones that point to a buffer given by libhtp */
- FLOWLOCK_RDLOCK(f);
-
- if (htp_state == NULL) {
- SCLogDebug("no HTTP state");
- goto end;
- }
-
- if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
- SCLogDebug("HTP state has no conn(p)");
+ htp_tx_t *tx = (htp_tx_t *)txv;
+ if (tx->request_method == NULL)
goto end;
- }
-
- idx = AppLayerTransactionGetInspectId(f);
- if (idx == -1) {
- goto end;
- }
-
- int size = (int)list_size(htp_state->connp->conn->transactions);
- for (; idx < size; idx++) {
-
- tx = list_get(htp_state->connp->conn->transactions, idx);
- if (tx == NULL || tx->request_method == NULL)
- continue;
-
- cnt += HttpMethodPatternSearch(det_ctx,
- (uint8_t *)bstr_ptr(tx->request_method),
- bstr_len(tx->request_method),
- flags);
- }
+ cnt = HttpMethodPatternSearch(det_ctx,
+ (uint8_t *)bstr_ptr(tx->request_method),
+ bstr_len(tx->request_method),
+ flags);
end:
- FLOWLOCK_UNLOCK(f);
return cnt;
}
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Signature *s, Flow *f, uint8_t flags,
- void *alstate, int tx_id)
+ void *alstate,
+ void *txv, uint64_t tx_id)
{
- HtpState *htp_state = (HtpState *)alstate;
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, tx_id);
- if (tx == NULL || tx->request_method == NULL)
- return 0;
+ htp_tx_t *tx = (htp_tx_t *)txv;
+ if (tx->request_method == NULL) {
+ if (AppLayerGetAlstateProgress(ALPROTO_HTTP, tx, 0) > TX_PROGRESS_REQ_LINE)
+ return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
+ else
+ return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
+ }
det_ctx->buffer_offset = 0;
det_ctx->discontinue_matching = 0;
bstr_len(tx->request_method),
DETECT_ENGINE_CONTENT_INSPECTION_MODE_HMD, NULL);
if (r == 1)
- return 1;
-
- return 0;
+ return DETECT_ENGINE_INSPECT_SIG_MATCH;
+ else
+ return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
}
/***********************************Unittests**********************************/
#include "app-layer-htp.h"
int DetectEngineInspectHttpMethod(ThreadVars *tv,
- DetectEngineCtx *, DetectEngineThreadCtx *,
- Signature *, Flow *, uint8_t, void *, int);
-int DetectEngineRunHttpMethodMpm(DetectEngineThreadCtx *, Flow *, HtpState *, uint8_t);
+ DetectEngineCtx *de_ctx,
+ DetectEngineThreadCtx *det_ctx,
+ Signature *s, Flow *f, uint8_t flags,
+ void *alstate,
+ void *tx, uint64_t tx_id);
+int DetectEngineRunHttpMethodMpm(DetectEngineThreadCtx *det_ctx, Flow *f,
+ HtpState *htp_state, uint8_t flags,
+ void *tx, uint64_t idx);
void DetectEngineHttpMethodRegisterTests(void);
#endif /* __DETECT_ENGINE_HMD_H__ */
int DetectEngineRunHttpRawHeaderMpm(DetectEngineThreadCtx *det_ctx, Flow *f,
- HtpState *htp_state, uint8_t flags)
+ HtpState *htp_state, uint8_t flags,
+ void *txv, uint64_t idx)
{
SCEnter();
- htp_tx_t *tx = NULL;
- uint32_t cnt = 0;
- int idx;
-
- /* we need to lock because the buffers are not actually true buffers
- * but are ones that point to a buffer given by libhtp */
- FLOWLOCK_RDLOCK(f);
-
- if (htp_state == NULL) {
- SCLogDebug("no HTTP state");
- goto end;
- }
-
- if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
- SCLogDebug("HTP state has no conn(p)");
- goto end;
- }
-
- idx = AppLayerTransactionGetInspectId(f);
- if (idx == -1) {
- goto end;
- }
- int size = (int)list_size(htp_state->connp->conn->transactions);
- for (; idx < size; idx++) {
-
- tx = list_get(htp_state->connp->conn->transactions, idx);
- if (tx == NULL)
- continue;
- bstr *raw_headers = htp_tx_get_request_headers_raw(tx);
+ uint32_t cnt = 0;
+ bstr *raw_headers;
+ htp_tx_t *tx = (htp_tx_t *)txv;
+ if (flags & STREAM_TOSERVER) {
+ raw_headers = htp_tx_get_request_headers_raw(tx);
if (raw_headers != NULL) {
- cnt += HttpRawHeaderPatternSearch(det_ctx,
- (uint8_t *)bstr_ptr(raw_headers),
- bstr_len(raw_headers), flags);
+ cnt = HttpRawHeaderPatternSearch(det_ctx,
+ (uint8_t *)bstr_ptr(raw_headers),
+ bstr_len(raw_headers), flags);
} else {
SCLogDebug("no raw headers");
}
+ } else {
#ifdef HAVE_HTP_TX_GET_RESPONSE_HEADERS_RAW
raw_headers = htp_tx_get_response_headers_raw(tx);
if (raw_headers != NULL) {
#endif /* HAVE_HTP_TX_GET_RESPONSE_HEADERS_RAW */
}
-end:
- FLOWLOCK_UNLOCK(f);
SCReturnInt(cnt);
}
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Signature *s, Flow *f, uint8_t flags,
- void *alstate, int tx_id)
+ void *alstate,
+ void *txv, uint64_t tx_id)
{
- HtpState *htp_state = (HtpState *)alstate;
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, tx_id);
- if (tx == NULL)
- return 0;
-
+ htp_tx_t *tx = (htp_tx_t *)txv;
bstr *raw_headers = NULL;
if (flags & STREAM_TOSERVER) {
raw_headers = htp_tx_get_request_headers_raw(tx);
}
#endif /* HAVE_HTP_TX_GET_RESPONSE_HEADERS_RAW */
if (raw_headers == NULL)
- return 0;
+ goto end;
det_ctx->buffer_offset = 0;
det_ctx->discontinue_matching = 0;
bstr_len(raw_headers),
DETECT_ENGINE_CONTENT_INSPECTION_MODE_HRHD, NULL);
if (r == 1)
- return 1;
+ return DETECT_ENGINE_INSPECT_SIG_MATCH;
- return 0;
+ end:
+ if (flags & STREAM_TOSERVER) {
+ if (AppLayerGetAlstateProgress(ALPROTO_HTTP, tx, 0) > TX_PROGRESS_REQ_HEADERS)
+ return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
+ } else {
+ if (AppLayerGetAlstateProgress(ALPROTO_HTTP, tx, 1) > TX_PROGRESS_RES_HEADERS)
+ return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
+ }
+ return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
}
/***********************************Unittests**********************************/
#include "app-layer-htp.h"
-int DetectEngineInspectHttpRawHeader(ThreadVars *tv, DetectEngineCtx *,
- DetectEngineThreadCtx *, Signature *,
- Flow *, uint8_t, void *, int);
-int DetectEngineRunHttpRawHeaderMpm(DetectEngineThreadCtx *, Flow *, HtpState *,
- uint8_t);
+int DetectEngineInspectHttpRawHeader(ThreadVars *tv,
+ DetectEngineCtx *de_ctx,
+ DetectEngineThreadCtx *det_ctx,
+ Signature *s, Flow *f, uint8_t flags,
+ void *alstate,
+ void *tx, uint64_t tx_id);
+int DetectEngineRunHttpRawHeaderMpm(DetectEngineThreadCtx *det_ctx, Flow *f,
+ HtpState *htp_state, uint8_t flags,
+ void *tx, uint64_t idx);
void DetectEngineHttpRawHeaderRegisterTests(void);
#endif /* __DETECT_ENGINE_HHD_H__ */
#include "detect-engine-hrhhd.h"
int DetectEngineRunHttpHRHMpm(DetectEngineThreadCtx *det_ctx, Flow *f,
- HtpState *htp_state, uint8_t flags)
+ HtpState *htp_state, uint8_t flags,
+ void *txv, uint64_t idx)
{
- htp_tx_t *tx = NULL;
uint32_t cnt = 0;
- int idx;
+ htp_tx_t *tx = (htp_tx_t *)txv;
+ uint8_t *hname = NULL;
+ uint32_t hname_len = 0;
- /* we need to lock because the buffers are not actually true buffers
- * but are ones that point to a buffer given by libhtp */
- FLOWLOCK_RDLOCK(f);
-
- if (htp_state == NULL) {
- SCLogDebug("no HTTP state");
- goto end;
- }
-
- if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
- SCLogDebug("HTP state has no conn(p)");
- goto end;
- }
-
- idx = AppLayerTransactionGetInspectId(f);
- if (idx == -1) {
- goto end;
- }
-
- int size = (int)list_size(htp_state->connp->conn->transactions);
- for (; idx < size; idx++) {
-
- uint8_t *hname;
- uint32_t hname_len;
-
- tx = list_get(htp_state->connp->conn->transactions, idx);
- if (tx == NULL)
- continue;
-
- if (tx->parsed_uri_incomplete == NULL || tx->parsed_uri_incomplete->hostname == NULL) {
- htp_header_t *h = NULL;
- h = (htp_header_t *)table_getc(tx->request_headers, "Host");
- if (h == NULL) {
- SCLogDebug("HTTP host header not present in this request");
- continue;
- }
+ if (tx->parsed_uri_incomplete == NULL || tx->parsed_uri_incomplete->hostname == NULL) {
+ if (tx->request_headers == NULL)
+ goto end;
+ htp_header_t *h = NULL;
+ h = (htp_header_t *)table_getc(tx->request_headers, "Host");
+ if (h != NULL) {
+ SCLogDebug("HTTP host header not present in this request");
hname = (uint8_t *)bstr_ptr(h->value);
hname_len = bstr_len(h->value);
} else {
- hname = (uint8_t *)bstr_ptr(tx->parsed_uri_incomplete->hostname);
- if (hname == NULL)
- continue;
- hname_len = bstr_len(tx->parsed_uri_incomplete->hostname);
+ goto end;
}
-
- cnt += HttpHRHPatternSearch(det_ctx, hname, hname_len, flags);
+ } else {
+ hname = (uint8_t *)bstr_ptr(tx->parsed_uri_incomplete->hostname);
+ if (hname != NULL)
+ hname_len = bstr_len(tx->parsed_uri_incomplete->hostname);
+ else
+ goto end;
}
+ cnt = HttpHRHPatternSearch(det_ctx, hname, hname_len, flags);
+
end:
- FLOWLOCK_UNLOCK(f);
return cnt;
}
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Signature *s, Flow *f, uint8_t flags,
- void *alstate, int tx_id)
+ void *alstate,
+ void *txv, uint64_t tx_id)
{
- HtpState *htp_state = (HtpState *)alstate;
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, tx_id);
uint8_t *hname;
uint32_t hname_len;
-
- if (tx == NULL)
- return 0;
+ htp_tx_t *tx = (htp_tx_t *)txv;
if (tx->parsed_uri_incomplete == NULL || tx->parsed_uri_incomplete->hostname == NULL) {
htp_header_t *h = NULL;
h = (htp_header_t *)table_getc(tx->request_headers, "Host");
if (h == NULL) {
SCLogDebug("HTTP host header not present in this request");
- return 0;
+ goto end;
}
hname = (uint8_t *)bstr_ptr(h->value);
hname_len = bstr_len(h->value);
} else {
hname = (uint8_t *)bstr_ptr(tx->parsed_uri_incomplete->hostname);
if (hname == NULL)
- return 0;
+ goto end;
hname_len = bstr_len(tx->parsed_uri_incomplete->hostname);
}
hname, hname_len,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_HRHHD, NULL);
if (r == 1)
- return 1;
+ return DETECT_ENGINE_INSPECT_SIG_MATCH;
- return 0;
+ end:
+ if (AppLayerGetAlstateProgress(ALPROTO_HTTP, tx, 0) > TX_PROGRESS_REQ_HEADERS)
+ return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
+ else
+ return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
}
/***********************************Unittests**********************************/
#include "app-layer-htp.h"
int DetectEngineInspectHttpHRH(ThreadVars *tv,
- DetectEngineCtx *, DetectEngineThreadCtx *,
- Signature *, Flow *, uint8_t, void *, int);
-int DetectEngineRunHttpHRHMpm(DetectEngineThreadCtx *, Flow *, HtpState *, uint8_t);
+ DetectEngineCtx *de_ctx,
+ DetectEngineThreadCtx *det_ctx,
+ Signature *s, Flow *f, uint8_t flags,
+ void *alstate,
+ void *tx, uint64_t tx_id);
+int DetectEngineRunHttpHRHMpm(DetectEngineThreadCtx *det_ctx, Flow *f,
+ HtpState *htp_state, uint8_t flags,
+ void *tx, uint64_t idx);
void DetectEngineHttpHRHRegisterTests(void);
#endif /* __DETECT_ENGINE_HRHHD_H__ */
* \retval cnt Number of matches reported by the mpm algo.
*/
int DetectEngineRunHttpRawUriMpm(DetectEngineThreadCtx *det_ctx, Flow *f,
- HtpState *htp_state, uint8_t flags)
+ HtpState *htp_state, uint8_t flags,
+ void *txv, uint64_t idx)
{
SCEnter();
+ htp_tx_t *tx = (htp_tx_t *)txv;
uint32_t cnt = 0;
-
- if (htp_state == NULL) {
- SCLogDebug("no HTTP state");
- SCReturnInt(0);
- }
-
- /* locking the flow, we will inspect the htp state */
- FLOWLOCK_RDLOCK(f);
-
- if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
- SCLogDebug("HTP state has no conn(p)");
+ if (tx->request_uri == NULL)
goto end;
- }
-
- int idx = AppLayerTransactionGetInspectId(f);
- if (idx == -1) {
- goto end;
- }
- htp_tx_t *tx = NULL;
-
- int size = (int)list_size(htp_state->connp->conn->transactions);
- for ( ; idx < size; idx++)
- {
- tx = list_get(htp_state->connp->conn->transactions, idx);
- if (tx == NULL || tx->request_uri == NULL)
- continue;
-
- cnt += HttpRawUriPatternSearch(det_ctx,
- (uint8_t *)bstr_ptr(tx->request_uri),
- bstr_len(tx->request_uri), flags);
- }
+ cnt = HttpRawUriPatternSearch(det_ctx,
+ (uint8_t *)bstr_ptr(tx->request_uri),
+ bstr_len(tx->request_uri), flags);
end:
- FLOWLOCK_UNLOCK(f);
SCReturnInt(cnt);
}
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Signature *s, Flow *f, uint8_t flags,
- void *alstate, int tx_id)
+ void *alstate,
+ void *txv, uint64_t tx_id)
{
- HtpState *htp_state = (HtpState *)alstate;
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, tx_id);
- if (tx == NULL || tx->request_uri == NULL)
- return 0;
+ htp_tx_t *tx = (htp_tx_t *)txv;
+ if (tx->request_uri == NULL) {
+ if (AppLayerGetAlstateProgress(ALPROTO_HTTP, tx, 0) > TX_PROGRESS_REQ_LINE)
+ return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
+ else
+ return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
+ }
det_ctx->discontinue_matching = 0;
det_ctx->buffer_offset = 0;
bstr_len(tx->request_uri),
DETECT_ENGINE_CONTENT_INSPECTION_MODE_HRUD, NULL);
if (r == 1)
- return 1;
-
- return 0;
+ return DETECT_ENGINE_INSPECT_SIG_MATCH;
+ else
+ return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
}
/***********************************Unittests**********************************/
#include "app-layer-htp.h"
-int DetectEngineRunHttpRawUriMpm(DetectEngineThreadCtx *,
- Flow *f, HtpState *, uint8_t);
+int DetectEngineRunHttpRawUriMpm(DetectEngineThreadCtx *det_ctx, Flow *f,
+ HtpState *htp_state, uint8_t flags,
+ void *tx, uint64_t idx);
int DetectEngineInspectHttpRawUri(ThreadVars *tv,
- DetectEngineCtx *, DetectEngineThreadCtx *,
- Signature *, Flow *, uint8_t, void *, int);
+ DetectEngineCtx *de_ctx,
+ DetectEngineThreadCtx *det_ctx,
+ Signature *s, Flow *f, uint8_t flags,
+ void *alstate,
+ void *tx, uint64_t tx_id);
void DetectEngineHttpRawUriRegisterTests(void);
#endif /* __DETECT_ENGINE_HRUD_H__ */
}
-static uint8_t *DetectEngineHSBDGetBufferForTX(int tx_id,
+static uint8_t *DetectEngineHSBDGetBufferForTX(htp_tx_t *tx, uint64_t tx_id,
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Flow *f, HtpState *htp_state,
index = (tx_id - det_ctx->hsbd_start_tx_id);
}
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, tx_id);
- if (tx == NULL) {
- SCLogDebug("no tx");
- goto end;
- }
-
HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx);
if (htud == NULL) {
SCLogDebug("no htud");
* when they come */
if (htud->response_body.content_len == 0) {
if ((htud->response_body.content_len_so_far > 0) &&
- tx->progress != TX_PROGRESS_RES_BODY) {
+ tx->progress[1] != TX_PROGRESS_RES_BODY) {
/* final length of the body */
htud->tcflags |= HTP_RES_BODY_COMPLETE;
}
int DetectEngineRunHttpServerBodyMpm(DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx, Flow *f,
- HtpState *htp_state, uint8_t flags)
+ HtpState *htp_state, uint8_t flags,
+ void *tx, uint64_t idx)
{
uint32_t cnt = 0;
-
- if (htp_state == NULL) {
- SCLogDebug("no HTTP state");
- goto end;
- }
-
- FLOWLOCK_WRLOCK(f);
-
- if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
- SCLogDebug("HTP state has no conn(p)");
- goto end;
- }
-
- /* get the transaction id */
- int idx = AppLayerTransactionGetInspectId(f);
- /* error! get out of here */
- if (idx == -1)
+ uint32_t buffer_len = 0;
+ uint8_t *buffer = DetectEngineHSBDGetBufferForTX(tx, idx,
+ de_ctx, det_ctx,
+ f, htp_state,
+ flags,
+ &buffer_len);
+ if (buffer_len == 0)
goto end;
- int size = (int)list_size(htp_state->connp->conn->transactions);
- for (; idx < size; idx++) {
- uint32_t buffer_len = 0;
- uint8_t *buffer = DetectEngineHSBDGetBufferForTX(idx,
- de_ctx, det_ctx,
- f, htp_state,
- flags,
- &buffer_len);
- if (buffer_len == 0)
- continue;
-
- cnt += HttpServerBodyPatternSearch(det_ctx,buffer, buffer_len, flags);
- }
+ cnt = HttpServerBodyPatternSearch(det_ctx, buffer, buffer_len, flags);
end:
- FLOWLOCK_UNLOCK(f);
return cnt;
}
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Signature *s, Flow *f, uint8_t flags,
- void *alstate, int tx_id)
+ void *alstate,
+ void *tx, uint64_t tx_id)
{
HtpState *htp_state = (HtpState *)alstate;
uint32_t buffer_len = 0;
- uint8_t *buffer = DetectEngineHSBDGetBufferForTX(tx_id,
+ uint8_t *buffer = DetectEngineHSBDGetBufferForTX(tx, tx_id,
de_ctx, det_ctx,
f, htp_state,
flags,
&buffer_len);
if (buffer_len == 0)
- return 0;
+ goto end;
det_ctx->buffer_offset = 0;
det_ctx->discontinue_matching = 0;
buffer_len,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_HSBD, NULL);
if (r == 1)
- return 1;
+ return DETECT_ENGINE_INSPECT_SIG_MATCH;
- return 0;
+ end:
+ if (AppLayerGetAlstateProgress(ALPROTO_HTTP, tx, 0) > TX_PROGRESS_RES_BODY)
+ return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
+ else
+ return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
}
void DetectEngineCleanHSBDBuffers(DetectEngineThreadCtx *det_ctx)
int DetectEngineRunHttpServerBodyMpm(DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx, Flow *f,
- HtpState *htp_state, uint8_t flags);
+ HtpState *htp_state, uint8_t flags,
+ void *tx, uint64_t idx);
int DetectEngineInspectHttpServerBody(ThreadVars *tv,
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Signature *s, Flow *f, uint8_t flags,
- void *alstate, int tx_id);
+ void *alstate,
+ void *tx, uint64_t tx_id);
void DetectEngineCleanHSBDBuffers(DetectEngineThreadCtx *det_ctx);
void DetectEngineHttpServerBodyRegisterTests(void);
* \retval cnt Number of matches reported by the mpm algo.
*/
int DetectEngineRunHttpStatCodeMpm(DetectEngineThreadCtx *det_ctx, Flow *f,
- HtpState *htp_state, uint8_t flags)
+ HtpState *htp_state, uint8_t flags,
+ void *txv, uint64_t idx)
{
SCEnter();
uint32_t cnt = 0;
-
- if (htp_state == NULL) {
- SCLogDebug("no HTTP state");
- SCReturnInt(0);
- }
-
- /* locking the flow, we will inspect the htp state */
- FLOWLOCK_RDLOCK(f);
-
- if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
- SCLogDebug("HTP state has no conn(p)");
- goto end;
- }
-
- int idx = AppLayerTransactionGetInspectId(f);
- if (idx == -1) {
+ htp_tx_t *tx = (htp_tx_t *)txv;
+ if (tx->response_status == NULL)
goto end;
- }
- htp_tx_t *tx = NULL;
-
- int size = (int)list_size(htp_state->connp->conn->transactions);
- for ( ; idx < size; idx++)
- {
- tx = list_get(htp_state->connp->conn->transactions, idx);
- if (tx == NULL || tx->response_status == NULL)
- continue;
- cnt += HttpStatCodePatternSearch(det_ctx,
- (uint8_t *)bstr_ptr(tx->response_status),
- bstr_len(tx->response_status), flags);
- }
+ cnt = HttpStatCodePatternSearch(det_ctx,
+ (uint8_t *)bstr_ptr(tx->response_status),
+ bstr_len(tx->response_status), flags);
end:
- FLOWLOCK_UNLOCK(f);
SCReturnInt(cnt);
}
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Signature *s, Flow *f, uint8_t flags,
- void *alstate, int tx_id)
+ void *alstate,
+ void *txv, uint64_t tx_id)
{
- HtpState *htp_state = (HtpState *)alstate;
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, tx_id);
- if (tx == NULL || tx->response_status == NULL)
- return 0;
+ htp_tx_t *tx = (htp_tx_t *)txv;
+ if (tx->response_status == NULL) {
+ if (AppLayerGetAlstateProgress(ALPROTO_HTTP, tx, 0) > TX_PROGRESS_RES_LINE)
+ return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
+ else
+ return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
+ }
det_ctx->discontinue_matching = 0;
det_ctx->buffer_offset = 0;
bstr_len(tx->response_status),
DETECT_ENGINE_CONTENT_INSPECTION_MODE_HSCD, NULL);
if (r == 1)
- return 1;
-
- return 0;
+ return DETECT_ENGINE_INSPECT_SIG_MATCH;
+ else
+ return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
}
/***********************************Unittests**********************************/
#include "app-layer-htp.h"
-int DetectEngineRunHttpStatCodeMpm(DetectEngineThreadCtx *,
- Flow *f, HtpState *, uint8_t);
+int DetectEngineRunHttpStatCodeMpm(DetectEngineThreadCtx *det_ctx, Flow *f,
+ HtpState *htp_state, uint8_t flags,
+ void *tx, uint64_t idx);
int DetectEngineInspectHttpStatCode(ThreadVars *tv,
- DetectEngineCtx *, DetectEngineThreadCtx *,
- Signature *, Flow *, uint8_t, void *, int);
+ DetectEngineCtx *de_ctx,
+ DetectEngineThreadCtx *det_ctx,
+ Signature *s, Flow *f, uint8_t flags,
+ void *alstate,
+ void *tx, uint64_t tx_id);
void DetectEngineHttpStatCodeRegisterTests(void);
#endif /* __DETECT_ENGINE_HSCD_H__ */
* \retval cnt Number of matches reported by the mpm algo.
*/
int DetectEngineRunHttpStatMsgMpm(DetectEngineThreadCtx *det_ctx, Flow *f,
- HtpState *htp_state, uint8_t flags)
+ HtpState *htp_state, uint8_t flags,
+ void *txv, uint64_t idx)
{
SCEnter();
uint32_t cnt = 0;
-
- if (htp_state == NULL) {
- SCLogDebug("no HTTP state");
- SCReturnInt(0);
- }
-
- /* locking the flow, we will inspect the htp state */
- FLOWLOCK_RDLOCK(f);
-
- if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
- SCLogDebug("HTP state has no conn(p)");
- goto end;
- }
-
- int idx = AppLayerTransactionGetInspectId(f);
- if (idx == -1) {
+ htp_tx_t *tx = (htp_tx_t *)txv;
+ if (tx->response_message == NULL)
goto end;
- }
- htp_tx_t *tx = NULL;
-
- int size = (int)list_size(htp_state->connp->conn->transactions);
- for ( ; idx < size; idx++)
- {
- tx = list_get(htp_state->connp->conn->transactions, idx);
- if (tx == NULL || tx->response_message == NULL)
- continue;
- cnt += HttpStatMsgPatternSearch(det_ctx,
- (uint8_t *)bstr_ptr(tx->response_message),
- bstr_len(tx->response_message), flags);
- }
+ cnt = HttpStatMsgPatternSearch(det_ctx,
+ (uint8_t *)bstr_ptr(tx->response_message),
+ bstr_len(tx->response_message), flags);
end:
- FLOWLOCK_UNLOCK(f);
SCReturnInt(cnt);
}
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Signature *s, Flow *f, uint8_t flags,
- void *alstate, int tx_id)
+ void *alstate,
+ void *txv, uint64_t tx_id)
{
- HtpState *htp_state = (HtpState *)alstate;
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, tx_id);
- if (tx == NULL || tx->response_message == NULL)
- return 0;
+ htp_tx_t *tx = (htp_tx_t *)txv;
+ if (tx->response_message == NULL) {
+ if (AppLayerGetAlstateProgress(ALPROTO_HTTP, tx, 0) > TX_PROGRESS_RES_LINE)
+ return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
+ else
+ return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
+ }
det_ctx->discontinue_matching = 0;
det_ctx->buffer_offset = 0;
bstr_len(tx->response_message),
DETECT_ENGINE_CONTENT_INSPECTION_MODE_HSMD, NULL);
if (r == 1)
- return 1;
-
- return 0;
+ return DETECT_ENGINE_INSPECT_SIG_MATCH;
+ else
+ return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
}
/***********************************Unittests**********************************/
#include "app-layer-htp.h"
-int DetectEngineRunHttpStatMsgMpm(DetectEngineThreadCtx *,
- Flow *f, HtpState *, uint8_t);
+int DetectEngineRunHttpStatMsgMpm(DetectEngineThreadCtx *det_ctx, Flow *f,
+ HtpState *htp_state, uint8_t flags,
+ void *tx, uint64_t idx);
int DetectEngineInspectHttpStatMsg(ThreadVars *tv,
- DetectEngineCtx *, DetectEngineThreadCtx *,
- Signature *, Flow *, uint8_t, void *, int tx_id);
+ DetectEngineCtx *de_ctx,
+ DetectEngineThreadCtx *det_ctx,
+ Signature *s, Flow *f, uint8_t flags,
+ void *alstate,
+ void *tx, uint64_t tx_id);
void DetectEngineHttpStatMsgRegisterTests(void);
#endif /* __DETECT_ENGINE_HSMD_H__ */
#include "detect-engine-hua.h"
int DetectEngineRunHttpUAMpm(DetectEngineThreadCtx *det_ctx, Flow *f,
- HtpState *htp_state, uint8_t flags)
+ HtpState *htp_state, uint8_t flags,
+ void *txv, uint64_t idx)
{
- htp_tx_t *tx = NULL;
uint32_t cnt = 0;
- int idx;
-
- /* we need to lock because the buffers are not actually true buffers
- * but are ones that point to a buffer given by libhtp */
- FLOWLOCK_RDLOCK(f);
-
- if (htp_state == NULL) {
- SCLogDebug("no HTTP state");
+ htp_tx_t *tx = (htp_tx_t *)txv;
+ if (tx->request_headers == NULL)
goto end;
- }
- if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
- SCLogDebug("HTP state has no conn(p)");
- goto end;
- }
-
- idx = AppLayerTransactionGetInspectId(f);
- if (idx == -1) {
+ htp_header_t *h = (htp_header_t *)table_getc(tx->request_headers,
+ "User-Agent");
+ if (h == NULL) {
+ SCLogDebug("HTTP user agent header not present in this request");
goto end;
}
-
- int size = (int)list_size(htp_state->connp->conn->transactions);
- for (; idx < size; idx++) {
-
- tx = list_get(htp_state->connp->conn->transactions, idx);
- if (tx == NULL)
- continue;
-
- htp_header_t *h = (htp_header_t *)table_getc(tx->request_headers,
- "User-Agent");
- if (h == NULL) {
- SCLogDebug("HTTP user agent header not present in this request");
- continue;
- }
-
- cnt += HttpUAPatternSearch(det_ctx,
- (uint8_t *)bstr_ptr(h->value),
- bstr_len(h->value), flags);
- }
+ cnt = HttpUAPatternSearch(det_ctx,
+ (uint8_t *)bstr_ptr(h->value),
+ bstr_len(h->value), flags);
end:
- FLOWLOCK_UNLOCK(f);
return cnt;
}
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Signature *s, Flow *f, uint8_t flags,
- void *alstate, int tx_id)
+ void *alstate,
+ void *txv, uint64_t tx_id)
{
- HtpState *htp_state = (HtpState *)alstate;
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, tx_id);
- if (tx == NULL)
- return 0;
-
+ htp_tx_t *tx = (htp_tx_t *)txv;
htp_header_t *h = (htp_header_t *)table_getc(tx->request_headers,
"User-Agent");
if (h == NULL) {
SCLogDebug("HTTP user agent header not present in this request");
- return 0;
+ goto end;
}
det_ctx->buffer_offset = 0;
bstr_len(h->value),
DETECT_ENGINE_CONTENT_INSPECTION_MODE_HUAD, NULL);
if (r == 1)
- return 1;
+ return DETECT_ENGINE_INSPECT_SIG_MATCH;
- return 0;
+ end:
+ if (AppLayerGetAlstateProgress(ALPROTO_HTTP, tx, 0) > TX_PROGRESS_REQ_HEADERS)
+ return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
+ else
+ return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
}
/***********************************Unittests**********************************/
#include "app-layer-htp.h"
int DetectEngineInspectHttpUA(ThreadVars *tv,
- DetectEngineCtx *, DetectEngineThreadCtx *,
- Signature *, Flow *, uint8_t, void *, int);
-int DetectEngineRunHttpUAMpm(DetectEngineThreadCtx *, Flow *, HtpState *, uint8_t);
+ DetectEngineCtx *de_ctx,
+ DetectEngineThreadCtx *det_ctx,
+ Signature *s, Flow *f, uint8_t flags,
+ void *alstate,
+ void *tx, uint64_t tx_id);
+int DetectEngineRunHttpUAMpm(DetectEngineThreadCtx *det_ctx, Flow *f,
+ HtpState *htp_state, uint8_t flags,
+ void *tx, uint64_t idx);
void DetectEngineHttpUARegisterTests(void);
#endif /* __DETECT_ENGINE_HUA_H__ */
-/* Copyright (C) 2007-2011 Open Information Security Foundation
+/* Copyright (C) 2007-2013 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* \file
*
* \author Victor Julien <victor@inliniac.net>
+ * \author Anoop Saldanha <anoopsaldanha@gmail.com>
*
- * \brief State based signature handling
- *
+ * \brief State based signature handling.
*/
#include "suricata-common.h"
#include "detect-engine.h"
#include "detect-parse.h"
#include "detect-engine-state.h"
-
-#include "detect-engine-uri.h"
-#include "detect-engine-hcbd.h"
-#include "detect-engine-hsbd.h"
-#include "detect-engine-hhd.h"
-#include "detect-engine-hrhd.h"
-#include "detect-engine-hmd.h"
-#include "detect-engine-hcd.h"
-#include "detect-engine-hrud.h"
-#include "detect-engine-hsmd.h"
-#include "detect-engine-hscd.h"
-#include "detect-engine-hua.h"
-#include "detect-engine-hhhd.h"
-#include "detect-engine-hrhhd.h"
#include "detect-engine-dcepayload.h"
-#include "detect-engine-file.h"
#include "stream-tcp.h"
#include "stream-tcp-private.h"
/** convert enum to string */
#define CASE_CODE(E) case E: return #E
-/* prototype */
-static void DeStateResetFileInspection(Flow *f, uint16_t alproto, void *alstate);
-
-
-int DeStateStoreFilestoreSigsCantMatch(SigGroupHead *sgh,
- DetectEngineState *de_state, uint8_t direction)
-{
- if (direction & STREAM_TOSERVER) {
- if (de_state->toserver_filestore_cnt == sgh->filestore_cnt) {
- SCReturnInt(1);
- }
- } else if (direction & STREAM_TOCLIENT) {
- if (de_state->toclient_filestore_cnt == sgh->filestore_cnt) {
- SCReturnInt(1);
- }
- }
-
- SCReturnInt(0);
-}
+/******** static internal helpers *********/
-/** \brief get string for match enum */
-const char *DeStateMatchResultToString(DeStateMatchResult res)
+static DeStateStore *DeStateStoreAlloc(void)
{
- switch (res) {
- CASE_CODE (DE_STATE_MATCH_NOSTATE);
- CASE_CODE (DE_STATE_MATCH_FULL);
- CASE_CODE (DE_STATE_MATCH_PARTIAL);
- CASE_CODE (DE_STATE_MATCH_NEW);
- CASE_CODE (DE_STATE_MATCH_NOMATCH);
- }
-
- return NULL;
-}
-
-/**
- * \brief Alloc a DeStateStore object
- * \retval d alloc'd object
- */
-DeStateStore *DeStateStoreAlloc(void) {
- SCEnter();
-
DeStateStore *d = SCMalloc(sizeof(DeStateStore));
- if (unlikely(d == NULL)) {
- SCReturnPtr(NULL, "DeStateStore");
- }
- memset(d, 0x00, sizeof(DeStateStore));
+ if (unlikely(d == NULL))
+ return NULL;
+ memset(d, 0, sizeof(DeStateStore));
- SCReturnPtr(d, "DeStateStore");
+ return d;
}
-/**
- * \brief free a DeStateStore object (recursively)
- * \param store DeStateStore object to free
- */
-void DeStateStoreFree(DeStateStore *store) {
- SCEnter();
-
- if (store == NULL) {
- SCReturn;
- }
-
- if (store->next != NULL) {
- DeStateStoreFree(store->next);
- }
-
- SCFree(store);
- SCReturn;
-}
-
-/**
- * \brief Alloc a DetectEngineState object
- * \param d alloc'd object
- */
-DetectEngineState *DetectEngineStateAlloc(void) {
- SCEnter();
-
- DetectEngineState *d = SCMalloc(sizeof(DetectEngineState));
- if (unlikely(d == NULL)) {
- SCReturnPtr(NULL, "DetectEngineState");
- }
- memset(d, 0x00, sizeof(DetectEngineState));
-
- SCReturnPtr(d, "DetectEngineState");
-}
-
-/**
- * \brief Free a DetectEngineState object
- * You must lock the flow mutex for de_state
- * (f->de_state_m)
- * \param state DetectEngineState object to free
- */
-void DetectEngineStateFree(DetectEngineState *state) {
- DeStateStore *iter = NULL;
- DeStateStore *aux = NULL;
-
- if (state == NULL)
- return;
-
- iter = state->head;
- while (iter != NULL) {
- aux = iter;
- iter = iter->next;
- SCFree(aux);
- }
-
- state->head = NULL;
- state->tail = NULL;
-
- state->cnt = 0;
-
- SCFree(state);
-}
-
-/**
- * \brief reset a DetectEngineState state
- * \param state LOCKED state
- */
-void DetectEngineStateReset(DetectEngineState *state) {
- SCEnter();
-
- DeStateStore *iter = NULL;
- DeStateStore *aux = NULL;
-
- if (state == NULL)
- return;
-
- iter = state->head;
- while (iter != NULL) {
- aux = iter;
- iter = iter->next;
- SCFree(aux);
- }
-
- state->head = NULL;
- state->tail = NULL;
-
- state->cnt = 0;
-
- SCReturn;
-}
-
-/**
- * \brief update the transaction id
- *
- * \param f unlocked flow
- * \param direction STREAM_TOCLIENT / STREAM_TOSERVER
- *
- * \retval 2 current transaction done, new available
- * \retval 1 current transaction done, no new (yet)
- * \retval 0 current transaction is not done yet
- */
-int DeStateUpdateInspectTransactionId(Flow *f, char direction) {
- SCEnter();
-
- int r = 0;
-
- FLOWLOCK_WRLOCK(f);
- r = AppLayerTransactionUpdateInspectId(f, direction);
- FLOWLOCK_UNLOCK(f);
-
- SCReturnInt(r);
-}
-
-/**
- * \brief Append a signature to the detect engine state
- *
- * \param state the detect engine state
- * \param s signature
- * \param sm sigmatch
- * \param uri did uri already match (if any)
- * \param dce did dce already match (if any)
- * \param hcbd did http client body already match (if any)
- *
- * \todo Need to use an array to transfer all these args. Pushing so
- * many args is slow.
- */
static void DeStateSignatureAppend(DetectEngineState *state, Signature *s,
- SigMatch *sm, uint32_t match_flags) {
- DeStateStore *store = state->tail;
+ SigMatch *sm, uint32_t inspect_flags,
+ uint8_t direction)
+{
+ int jump = 0;
+ int i = 0;
+ DetectEngineStateDirection *dir_state = &state->dir_state[direction & STREAM_TOSERVER ? 0 : 1];
+ DeStateStore *store = dir_state->head;
if (store == NULL) {
store = DeStateStoreAlloc();
if (store != NULL) {
- state->head = store;
- state->tail = store;
+ dir_state->head = store;
+ dir_state->tail = store;
}
} else {
- if ((state->cnt % DE_STATE_CHUNK_SIZE) == 0) {
+ jump = dir_state->cnt / DE_STATE_CHUNK_SIZE;
+ for (i = 0; i < jump; i++) {
+ store = store->next;
+ }
+ if (store == NULL) {
store = DeStateStoreAlloc();
if (store != NULL) {
- state->tail->next = store;
- state->tail = store;
+ dir_state->tail->next = store;
+ dir_state->tail = store;
}
}
}
- if (store == NULL) {
+ if (store == NULL)
return;
- }
- SigIntId idx = state->cnt % DE_STATE_CHUNK_SIZE;
+ SigIntId idx = dir_state->cnt++ % DE_STATE_CHUNK_SIZE;
store->store[idx].sid = s->num;
- store->store[idx].flags = 0;
- store->store[idx].flags |= match_flags;
+ store->store[idx].flags = inspect_flags;
store->store[idx].nm = sm;
- state->cnt++;
- SCLogDebug("store %p idx %"PRIuMAX" cnt %"PRIuMAX" sig id %"PRIuMAX"",
- store, (uintmax_t)idx, (uintmax_t)state->cnt,
- (uintmax_t)store->store[idx].sid);
+ return;
+}
+
+static void DeStateStoreStateVersion(DetectEngineState *de_state,
+ uint16_t alversion, uint8_t direction)
+{
+ de_state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].alversion = alversion;
return;
}
+static void DeStateStoreFileNoMatchCnt(DetectEngineState *de_state, uint16_t file_no_match, uint8_t direction)
+{
+ de_state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].filestore_cnt += file_no_match;
+ return;
+}
-/*
- on first detection run:
+static int DeStateStoreFilestoreSigsCantMatch(SigGroupHead *sgh, DetectEngineState *de_state, uint8_t direction)
+{
+ if (de_state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].filestore_cnt == sgh->filestore_cnt)
+ return 1;
+ else
+ return 0;
+}
- for each
- (1) app layer signature
- (2a) at least one app layer sm match OR
- (2b) content/uri match AND other app layer sigmatches present
+static void DeStateResetFileInspection(Flow *f, uint16_t alproto, void *alstate, uint8_t direction)
+{
+ if (f == NULL || alproto != ALPROTO_HTTP || alstate == NULL || f->de_state == NULL)
+ return;
- Cases:
- multiple app layer sm's
- content + uricontent
- content + app layer sm
- uricontent + app layer sm
-*/
+ FLOWLOCK_WRLOCK(f);
+ HtpState *htp_state = (HtpState *)alstate;
-uint16_t DeStateGetStateVersion(DetectEngineState *de_state, uint8_t direction) {
if (direction & STREAM_TOSERVER) {
- SCReturnUInt(de_state->toserver_version);
+ if (htp_state->flags & HTP_FLAG_NEW_FILE_TX_TS) {
+ SCLogDebug("new file in the TS direction");
+ htp_state->flags &= ~HTP_FLAG_NEW_FILE_TX_TS;
+ f->de_state->dir_state[0].flags |= DETECT_ENGINE_STATE_FLAG_FILE_TS_NEW;
+ }
} else {
- SCReturnUInt(de_state->toclient_version);
+ if (htp_state->flags & HTP_FLAG_NEW_FILE_TX_TC) {
+ SCLogDebug("new file in the TC direction");
+ htp_state->flags &= ~HTP_FLAG_NEW_FILE_TX_TC;
+ f->de_state->dir_state[1].flags |= DETECT_ENGINE_STATE_FLAG_FILE_TC_NEW;
+ }
}
+
+ FLOWLOCK_UNLOCK(f);
}
-void DeStateStoreStateVersion(DetectEngineState *de_state, uint8_t direction,
- uint16_t alversion)
+
+
+DetectEngineState *DetectEngineStateAlloc(void)
{
- if (direction & STREAM_TOSERVER) {
- SCLogDebug("STREAM_TOSERVER updated to %"PRIu16, alversion);
- de_state->toserver_version = alversion;
- } else {
- SCLogDebug("STREAM_TOCLIENT updated to %"PRIu16, alversion);
- de_state->toclient_version = alversion;
- }
+ DetectEngineState *d = SCMalloc(sizeof(DetectEngineState));
+ if (unlikely(d == NULL))
+ return NULL;
+ memset(d, 0, sizeof(DetectEngineState));
+
+ return d;
}
-/**
- * \brief Increment de_state filestore_cnt in the proper direction.
- *
- * \param de_state flow's locked de_state
- * \param direction flags containing direction
- * \param file_no_match number of sigs that are identified as "can't match"
- * with filestore.
- */
-void DeStateStoreFileNoMatch(DetectEngineState *de_state, uint8_t direction,
- uint16_t file_no_match)
+void DetectEngineStateFree(DetectEngineState *state)
{
- if (direction & STREAM_TOSERVER) {
- SCLogDebug("STREAM_TOSERVER added %"PRIu16, file_no_match);
- de_state->toserver_filestore_cnt += file_no_match;
- } else {
- SCLogDebug("STREAM_TOCLIENT added %"PRIu16, file_no_match);
- de_state->toclient_filestore_cnt += file_no_match;
+ DeStateStore *store;
+ DeStateStore *store_next;
+ int i = 0;
+
+ for (i = 0; i < 2; i++) {
+ store = state->dir_state[i].head;
+ while (store != NULL) {
+ store_next = store->next;
+ SCFree(store);
+ store = store_next;
+ }
}
-}
+ SCFree(state);
-/**
- * \brief Check if a flow already contains a flow detect state
- *
- * \retval 2 has state, but it's not updated
- * \retval 1 has state
- * \retval 0 has no state
- */
-int DeStateFlowHasState(Flow *f, uint8_t flags, uint16_t alversion) {
- SCEnter();
+ return;
+}
+int DeStateFlowHasInspectableState(Flow *f, uint16_t alversion, uint8_t flags)
+{
int r = 0;
- SCMutexLock(&f->de_state_m);
- if (f->de_state == NULL || f->de_state->cnt == 0) {
- r = 0;
- } else if (DeStateGetStateVersion(f->de_state, flags) == alversion)
+ SCMutexLock(&f->de_state_m);
+ if (f->de_state == NULL || f->de_state->dir_state[flags & STREAM_TOSERVER ? 0 : 1].cnt == 0) {
+ if (AppLayerAlprotoSupportsTxs(f->alproto)) {
+ if (AppLayerTransactionGetInspectId(f, flags) >= AppLayerGetTxCnt(f->alproto, f->alstate))
+ r = 2;
+ else
+ r = 0;
+ }
+ } else if (!(flags & STREAM_EOF) &&
+ f->de_state->dir_state[flags & STREAM_TOSERVER ? 0 : 1].alversion == alversion) {
r = 2;
- else
+ } else {
r = 1;
-
+ }
SCMutexUnlock(&f->de_state_m);
- SCReturnInt(r);
+
+ return r;
}
-/** \brief Match app layer sig list against state. Set up state for non matches
- * and partial matches.
- * \retval 1 match
- * \retval 0 no or partial match
- */
int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
- DetectEngineThreadCtx *det_ctx, Signature *s, Flow *f, uint8_t flags,
- void *alstate, uint16_t alproto, uint16_t alversion)
+ DetectEngineThreadCtx *det_ctx,
+ Signature *s, Flow *f, uint8_t flags,
+ void *alstate, uint16_t alproto, uint16_t alversion)
{
- SCEnter();
+ DetectEngineAppInspectionEngine *engine = NULL;
+ SigMatch *sm = NULL;
+ uint16_t file_no_match = 0;
+ uint32_t inspect_flags = 0;
+
+ HtpState *htp_state = NULL;
+ SMBState *smb_state = NULL;
- SigMatch *sm = s->sm_lists[DETECT_SM_LIST_AMATCH];
+ void *tx = NULL;
+ uint64_t tx_id = 0;
+ uint64_t total_txs = 0;
int match = 0;
- int r = 0;
- uint32_t inspect_flags = 0;
- uint32_t match_flags = 0;
- uint16_t file_no_match = 0;
+ int store_de_state = 0;
+ uint8_t direction = (flags & STREAM_TOSERVER) ? 0 : 1;
- if (alstate == NULL) {
- SCReturnInt(0);
- }
+ int alert_cnt = 0;
- SCLogDebug("s->id %"PRIu32, s->id);
+ if (alstate == NULL)
+ goto end;
- /* Check the uricontent, http client body, http header keywords here */
- if (alproto == ALPROTO_HTTP) {
+ if (AppLayerAlprotoSupportsTxs(alproto)) {
FLOWLOCK_WRLOCK(f);
- HtpState *htp_state = (HtpState *)alstate;
+ htp_state = (HtpState *)alstate;
if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
- SCLogDebug("HTP state has no conn(p)");
FLOWLOCK_UNLOCK(f);
- SCReturnInt(0);
+ goto end;
}
- int tx_id = AppLayerTransactionGetInspectId(f);
- if (tx_id == -1) {
- FLOWLOCK_UNLOCK(f);
- SCReturnInt(0);
- }
-
- int total_txs = (int)list_size(htp_state->connp->conn->transactions);
- for ( ; tx_id < total_txs; tx_id++) {
- DetectEngineAppInspectionEngine *engine =
- app_inspection_engine[ALPROTO_HTTP][(flags & STREAM_TOSERVER) ? 0 : 1];
+ tx_id = AppLayerTransactionGetInspectId(f, flags);
+ total_txs = AppLayerGetTxCnt(alproto, htp_state);
+ if (((total_txs - tx_id) > 1) && f->de_state != NULL)
+ DetectEngineStateReset(f->de_state, flags);
+ for (; tx_id < total_txs; tx_id++) {
+ tx = AppLayerGetTx(alproto, alstate, tx_id);
+ if (tx == NULL)
+ continue;
+ engine = app_inspection_engine[alproto][direction];
+ inspect_flags = 0;
while (engine != NULL) {
if (s->sm_lists[engine->sm_list] != NULL) {
- inspect_flags |= engine->inspect_flags;
- int r = engine->Callback(tv, de_ctx, det_ctx, s, f,
- flags, alstate, tx_id);
- if (r == 1) {
- match_flags |= engine->match_flags;
- } else if (r == 2) {
- match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
- } else if (r == 3) {
- match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
+ match = engine->Callback(tv, de_ctx, det_ctx, s, f,
+ flags, alstate,
+ tx, tx_id);
+ if (match == 1) {
+ inspect_flags |= engine->inspect_flags;
+ engine = engine->next;
+ continue;
+ } else if (match == 2) {
+ inspect_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
+ inspect_flags |= engine->inspect_flags;
+ } else if (match == 3) {
+ inspect_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
+ inspect_flags |= engine->inspect_flags;
file_no_match++;
}
+ break;
}
engine = engine->next;
}
- if (inspect_flags == match_flags)
- break;
- }
+ /* all the engines seem to be exhausted at this point. If we
+ * didn't have a match in one of the engines we would have
+ * broken off and engine wouldn't be NULL. Hence the alert. */
+ if (engine == NULL)
+ alert_cnt++;
+
+ if (tx_id == (total_txs - 1)) {
+ void *tx = AppLayerGetTx(alproto, alstate, tx_id);
+ if (tx == NULL)
+ continue;
+ if (AppLayerGetAlstateProgress(alproto, tx, direction) <
+ AppLayerGetAlstateProgressCompletionStatus(alproto, direction)) {
+ store_de_state = 1;
+ if (engine == NULL || inspect_flags & DE_STATE_FLAG_SIG_CANT_MATCH)
+ inspect_flags |= DE_STATE_FLAG_FULL_INSPECT;
+ }
+ }
+ } /* for */
FLOWLOCK_UNLOCK(f);
- } else if (alproto == ALPROTO_DCERPC || alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) {
- if (s->sm_lists[DETECT_SM_LIST_DMATCH] != NULL) {
- inspect_flags |= DE_STATE_FLAG_DCE_INSPECT;
-
- SCLogDebug("inspecting dce payload");
-
- if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) {
- SMBState *smb_state = (SMBState *)alstate;
-
- if (smb_state->dcerpc_present &&
- DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f,
- flags, &smb_state->dcerpc) == 1) {
- SCLogDebug("dce payload matched");
- match_flags |= DE_STATE_FLAG_DCE_MATCH;
- } else {
- SCLogDebug("dce payload inspected but no match");
- }
- } else {
- if (DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f,
- flags, alstate) == 1) {
- SCLogDebug("dce payload matched");
- match_flags |= DE_STATE_FLAG_DCE_MATCH;
- } else {
- SCLogDebug("dce payload inspected but no match");
- }
+ } else if (s->sm_lists[DETECT_SM_LIST_DMATCH] != NULL &&
+ (alproto == ALPROTO_DCERPC || alproto == ALPROTO_SMB ||
+ alproto == ALPROTO_SMB2))
+ {
+ if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) {
+ smb_state = (SMBState *)alstate;
+ if (smb_state->dcerpc_present &&
+ DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f,
+ flags, &smb_state->dcerpc) == 1) {
+ alert_cnt++;
+ }
+ } else {
+ if (DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f,
+ flags, alstate) == 1) {
+ alert_cnt++;
}
}
}
- if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) {
- for ( ; sm != NULL; sm = sm->next) {
- SCLogDebug("sm %p, sm->next %p", sm, sm->next);
-
- if (sigmatch_table[sm->type].AppLayerMatch != NULL &&
- (alproto == s->alproto ||
- alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2))
- {
- if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) {
- SMBState *smb_state = (SMBState *)alstate;
-
- if (smb_state->dcerpc_present) {
- match = sigmatch_table[sm->type].
- AppLayerMatch(tv, det_ctx, f, flags, &smb_state->dcerpc,
- s, sm);
- }
- } else {
+ sm = s->sm_lists[DETECT_SM_LIST_AMATCH];
+ for (; sm != NULL; sm = sm->next) {
+ if (sigmatch_table[sm->type].AppLayerMatch != NULL &&
+ (alproto == s->alproto || alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2))
+ {
+ if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) {
+ smb_state = (SMBState *)alstate;
+ if (smb_state->dcerpc_present) {
match = sigmatch_table[sm->type].
- AppLayerMatch(tv, det_ctx, f, flags, alstate, s, sm);
- }
-
- if (match == 0) {
- break;
- } else if (sm->next == NULL) {
- sm = NULL; /* set to NULL as we have a match */
-
- if (inspect_flags == 0 || (inspect_flags == match_flags)) {
- match_flags |= DE_STATE_FLAG_FULL_MATCH;
- r = 1;
- }
- break;
+ AppLayerMatch(tv, det_ctx, f, flags, &smb_state->dcerpc, s, sm);
}
+ } else {
+ match = sigmatch_table[sm->type].
+ AppLayerMatch(tv, det_ctx, f, flags, alstate, s, sm);
}
+
+ if (match == 0)
+ break;
+ else if (match == 2)
+ inspect_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
}
- } else {
- if (inspect_flags != 0 && (inspect_flags == match_flags)) {
- match_flags |= DE_STATE_FLAG_FULL_MATCH;
- r = 1;
+ }
+ if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) {
+ store_de_state = 1;
+ if (sm == NULL || inspect_flags & DE_STATE_FLAG_SIG_CANT_MATCH) {
+ if (sm == NULL)
+ alert_cnt = 1;
+ inspect_flags |= DE_STATE_FLAG_FULL_INSPECT;
}
}
- SCLogDebug("detection done, store results: sm %p, inspect_flags %04X, "
- "match_flags %04X", sm, inspect_flags, match_flags);
+ if (!store_de_state && file_no_match == 0)
+ goto end;
SCMutexLock(&f->de_state_m);
- /* match or no match, we store the state anyway
- * "sm" here is either NULL (complete match) or
- * the last SigMatch that didn't match */
if (f->de_state == NULL) {
f->de_state = DetectEngineStateAlloc();
- }
- if (f->de_state != NULL) {
- /* \todo shift to an array to transfer these match values*/
- DeStateSignatureAppend(f->de_state, s, sm, match_flags);
- DeStateStoreStateVersion(f->de_state, flags, alversion);
- DeStateStoreFileNoMatch(f->de_state, flags, file_no_match);
-
- if (DeStateStoreFilestoreSigsCantMatch(det_ctx->sgh, f->de_state, flags) == 1) {
- SCLogDebug("disabling file storage for transaction %u", det_ctx->tx_id);
-
- FLOWLOCK_WRLOCK(f);
- FileDisableStoringForTransaction(f, flags & (STREAM_TOCLIENT|STREAM_TOSERVER),
- det_ctx->tx_id);
- FLOWLOCK_UNLOCK(f);
-
- f->de_state->flags |= DE_STATE_FILE_STORE_DISABLED;
+ if (f->de_state == NULL) {
+ SCMutexUnlock(&f->de_state_m);
+ goto end;
}
}
+ if (store_de_state) {
+ DeStateSignatureAppend(f->de_state, s, sm, inspect_flags, flags);
+ DeStateStoreStateVersion(f->de_state, alversion, flags);
+ }
+ DeStateStoreFileNoMatchCnt(f->de_state, file_no_match, flags);
+ if (DeStateStoreFilestoreSigsCantMatch(det_ctx->sgh, f->de_state, flags) == 1) {
+ FLOWLOCK_WRLOCK(f);
+ FileDisableStoringForTransaction(f, flags & (STREAM_TOCLIENT | STREAM_TOSERVER),
+ det_ctx->tx_id);
+ FLOWLOCK_UNLOCK(f);
+ f->de_state->dir_state[flags & STREAM_TOSERVER ? 0 : 1].flags |= DETECT_ENGINE_STATE_FLAG_FILE_STORE_DISABLED;
+ }
SCMutexUnlock(&f->de_state_m);
- SCReturnInt(r);
+ end:
+ return alert_cnt;
}
-/** \brief Continue DeState detection of the signatures stored in the state.
- *
- * \retval 0 all is good
- */
-int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
- Flow *f, uint8_t flags, void *alstate, uint16_t alproto, uint16_t alversion)
+void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
+ DetectEngineThreadCtx *det_ctx,
+ Packet *p, Flow *f, uint8_t flags, void *alstate,
+ uint16_t alproto, uint16_t alversion)
{
- SCEnter();
- SigIntId cnt = 0;
- SigIntId store_cnt = 0;
- DeStateStore *store = NULL;
- uint32_t inspect_flags = 0;
- uint32_t match_flags = 0;
- int match = 0;
+ SCMutexLock(&f->de_state_m);
+
+ DetectEngineAppInspectionEngine *engine = NULL;
+ SigMatch *sm = NULL;
uint16_t file_no_match = 0;
+ uint32_t inspect_flags = 0;
- if (f == NULL || alstate == NULL || alproto == ALPROTO_UNKNOWN) {
- return 0;
- }
+ HtpState *htp_state = NULL;
+ SMBState *smb_state = NULL;
- SCMutexLock(&f->de_state_m);
+ SigIntId store_cnt = 0;
+ SigIntId state_cnt = 0;
+ int match = 0;
+ uint8_t alert = 0;
- if (f->de_state == NULL || f->de_state->cnt == 0)
- goto end;
+ DetectEngineStateDirection *dir_state = &f->de_state->dir_state[flags & STREAM_TOSERVER ? 0 : 1];
+ DeStateStore *store = dir_state->head;
+ uint64_t inspect_tx_id = 0;
+ uint64_t total_txs = 0;
+ uint8_t alproto_supports_txs = 0;
- DeStateResetFileInspection(f, alproto, alstate);
+ DeStateResetFileInspection(f, alproto, alstate, flags);
- /* loop through the stores */
- for (store = f->de_state->head; store != NULL; store = store->next)
- {
- /* loop through the sigs in the stores */
+ if (AppLayerAlprotoSupportsTxs(alproto)) {
+ inspect_tx_id = AppLayerTransactionGetInspectId(f, flags);
+ total_txs = AppLayerGetTxCnt(alproto, alstate);
+ alproto_supports_txs = 1;
+ }
+
+ for (; store != NULL; store = store->next) {
for (store_cnt = 0;
- store_cnt < DE_STATE_CHUNK_SIZE && cnt < f->de_state->cnt;
- store_cnt++, cnt++)
+ store_cnt < DE_STATE_CHUNK_SIZE && state_cnt < dir_state->cnt;
+ store_cnt++, state_cnt++)
{
DeStateStoreItem *item = &store->store[store_cnt];
-
- inspect_flags = 0;
- match_flags = 0;
- match = 0;
-
- SCLogDebug("internal id of signature to inspect: %"PRIuMAX,
- (uintmax_t)item->sid);
-
Signature *s = de_ctx->sig_array[item->sid];
- SCLogDebug("id of signature to inspect: %"PRIuMAX,
- (uintmax_t)s->id);
-
- /* if we already fully matched previously, detect that here */
- if (item->flags & DE_STATE_FLAG_FULL_MATCH) {
- /* check first if we have received new files in the livetime of
- * this de_state (this tx). */
- if (item->flags & (DE_STATE_FLAG_FILE_TC_INSPECT|DE_STATE_FLAG_FILE_TS_INSPECT)) {
- if ((flags & STREAM_TOCLIENT) && (f->de_state->flags & DE_STATE_FILE_TC_NEW)) {
+
+ if (item->flags & DE_STATE_FLAG_FULL_INSPECT) {
+ if (item->flags & (DE_STATE_FLAG_FILE_TC_INSPECT |
+ DE_STATE_FLAG_FILE_TS_INSPECT)) {
+ if ((flags & STREAM_TOCLIENT) &&
+ (dir_state->flags & DETECT_ENGINE_STATE_FLAG_FILE_TC_NEW))
+ {
item->flags &= ~DE_STATE_FLAG_FILE_TC_INSPECT;
- item->flags &= ~DE_STATE_FLAG_FULL_MATCH;
+ item->flags &= ~DE_STATE_FLAG_FULL_INSPECT;
}
- if ((flags & STREAM_TOSERVER) && (f->de_state->flags & DE_STATE_FILE_TS_NEW)) {
+ if ((flags & STREAM_TOSERVER) &&
+ (dir_state->flags & DETECT_ENGINE_STATE_FLAG_FILE_TS_NEW))
+ {
item->flags &= ~DE_STATE_FLAG_FILE_TS_INSPECT;
- item->flags &= ~DE_STATE_FLAG_FULL_MATCH;
+ item->flags &= ~DE_STATE_FLAG_FULL_INSPECT;
}
}
- if (item->flags & DE_STATE_FLAG_FULL_MATCH) {
- det_ctx->de_state_sig_array[item->sid] = DE_STATE_MATCH_FULL;
- SCLogDebug("full match state");
+ if (item->flags & DE_STATE_FLAG_FULL_INSPECT) {
+ if (alproto_supports_txs) {
+ if ((total_txs - inspect_tx_id) <= 1)
+ det_ctx->de_state_sig_array[item->sid] = DE_STATE_MATCH_NO_NEW_STATE;
+ } else {
+ det_ctx->de_state_sig_array[item->sid] = DE_STATE_MATCH_NO_NEW_STATE;
+ }
continue;
}
}
- /* if we know for sure we can't ever match, detect that here */
if (item->flags & DE_STATE_FLAG_SIG_CANT_MATCH) {
if ((flags & STREAM_TOSERVER) &&
- (item->flags & DE_STATE_FLAG_FILE_TS_INSPECT) &&
- (f->de_state->flags & DE_STATE_FILE_TS_NEW)) {
-
- /* new file, fall through */
+ (item->flags & DE_STATE_FLAG_FILE_TS_INSPECT) &&
+ (dir_state->flags & DETECT_ENGINE_STATE_FLAG_FILE_TS_NEW))
+ {
item->flags &= ~DE_STATE_FLAG_FILE_TS_INSPECT;
item->flags &= ~DE_STATE_FLAG_SIG_CANT_MATCH;
-
} else if ((flags & STREAM_TOCLIENT) &&
- (item->flags & DE_STATE_FLAG_FILE_TC_INSPECT) &&
- (f->de_state->flags & DE_STATE_FILE_TC_NEW)) {
-
- /* new file, fall through */
+ (item->flags & DE_STATE_FLAG_FILE_TC_INSPECT) &&
+ (dir_state->flags & DETECT_ENGINE_STATE_FLAG_FILE_TC_NEW))
+ {
item->flags &= ~DE_STATE_FLAG_FILE_TC_INSPECT;
item->flags &= ~DE_STATE_FLAG_SIG_CANT_MATCH;
-
} else {
- det_ctx->de_state_sig_array[item->sid] = DE_STATE_MATCH_NOMATCH;
+ if (alproto_supports_txs) {
+ if ((total_txs - inspect_tx_id) <= 1)
+ det_ctx->de_state_sig_array[item->sid] = DE_STATE_MATCH_NO_NEW_STATE;
+ } else {
+ det_ctx->de_state_sig_array[item->sid] = DE_STATE_MATCH_NO_NEW_STATE;
+ }
continue;
}
}
- /* only inspect in the right direction here */
- if ((flags & STREAM_TOSERVER) && !(s->flags & SIG_FLAG_TOSERVER))
- continue;
- else if ((flags & STREAM_TOCLIENT) && !(s->flags & SIG_FLAG_TOCLIENT))
- continue;
+ alert = 0;
+ inspect_flags = 0;
+ match = 0;
RULE_PROFILING_START;
- /* let's continue detection */
-
- /* first, check uricontent */
- if (alproto == ALPROTO_HTTP) {
+ if (alproto_supports_txs) {
FLOWLOCK_WRLOCK(f);
- HtpState *htp_state = (HtpState *)alstate;
+ htp_state = (HtpState *)alstate;
if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
- SCLogDebug("HTP state has no conn(p)");
FLOWLOCK_UNLOCK(f);
goto end;
}
- int tx_id = AppLayerTransactionGetInspectId(f);
- if (tx_id == -1) {
+ engine = app_inspection_engine[alproto][(flags & STREAM_TOSERVER) ? 0 : 1];
+ void *inspect_tx = AppLayerGetTx(alproto, alstate, inspect_tx_id);
+ if (inspect_tx == NULL) {
FLOWLOCK_UNLOCK(f);
goto end;
}
-
- int total_txs = (int)list_size(htp_state->connp->conn->transactions);
- for ( ; tx_id < total_txs; tx_id++) {
- DetectEngineAppInspectionEngine *engine =
- app_inspection_engine[ALPROTO_HTTP][(flags & STREAM_TOSERVER) ? 0 : 1];
- while (engine != NULL) {
- if (s->sm_lists[engine->sm_list] != NULL && !(item->flags & engine->match_flags)) {
+ while (engine != NULL) {
+ if (!(item->flags & engine->inspect_flags) &&
+ s->sm_lists[engine->sm_list] != NULL)
+ {
+ match = engine->Callback(tv, de_ctx, det_ctx, s, f,
+ flags, alstate, inspect_tx, inspect_tx_id);
+ if (match == 1) {
inspect_flags |= engine->inspect_flags;
- int r = engine->Callback(tv, de_ctx, det_ctx, s, f,
- flags, alstate, tx_id);
- if (r == 1) {
- match_flags |= engine->match_flags;
- } else if (r == 2) {
- match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
- } else if (r == 3) {
- match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
- file_no_match++;
- }
+ engine = engine->next;
+ continue;
+ } else if (match == 2) {
+ inspect_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
+ inspect_flags |= engine->inspect_flags;
+ } else if (match == 3) {
+ inspect_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
+ inspect_flags |= engine->inspect_flags;
+ file_no_match++;
}
- engine = engine->next;
- }
- if (inspect_flags == match_flags)
break;
+ }
+ engine = engine->next;
+ }
+ if (engine == NULL || inspect_flags & DE_STATE_FLAG_SIG_CANT_MATCH) {
+ if (engine == NULL)
+ alert = 1;
+ inspect_flags |= DE_STATE_FLAG_FULL_INSPECT;
}
FLOWLOCK_UNLOCK(f);
+ }
- } else if (alproto == ALPROTO_DCERPC || alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) {
- if (s->sm_lists[DETECT_SM_LIST_DMATCH] != NULL) {
- if (!(item->flags & DE_STATE_FLAG_DCE_MATCH)) {
- SCLogDebug("inspecting dce payload");
- inspect_flags |= DE_STATE_FLAG_DCE_INSPECT;
-
+ for (sm = item->nm; sm != NULL; sm = sm->next) {
+ if (sigmatch_table[sm->type].AppLayerMatch != NULL &&
+ (alproto == s->alproto || alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2))
+ {
if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) {
- SMBState *smb_state = (SMBState *)alstate;
- //DCERPCState dcerpc_state;
- //dcerpc_state.dcerpc = smb_state->dcerpc;
- if (smb_state->dcerpc_present &&
- DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f,
- flags, &smb_state->dcerpc) == 1) {
- SCLogDebug("dce payload matched");
- match_flags |= DE_STATE_FLAG_DCE_MATCH;
- } else {
- SCLogDebug("dce payload inspected but no match");
+ smb_state = (SMBState *)alstate;
+ if (smb_state->dcerpc_present) {
+ match = sigmatch_table[sm->type].
+ AppLayerMatch(tv, det_ctx, f, flags, &smb_state->dcerpc, s, sm);
}
} else {
- if (DetectEngineInspectDcePayload(de_ctx, det_ctx, s, f,
- flags, alstate) == 1) {
- SCLogDebug("dce payload matched");
- match_flags |= DE_STATE_FLAG_DCE_MATCH;
- } else {
- SCLogDebug("dce payload inspected but no match");
- }
+ match = sigmatch_table[sm->type].
+ AppLayerMatch(tv, det_ctx, f, flags, alstate, s, sm);
}
- } else {
- SCLogDebug("dce payload already inspected");
+ if (match == 0)
+ break;
+ else if (match == 2)
+ inspect_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
}
- }
+ }
+ RULE_PROFILING_END(det_ctx, s, match);
+ if (s->sm_lists[DETECT_SM_LIST_AMATCH] != NULL) {
+ if (sm == NULL || inspect_flags & DE_STATE_FLAG_SIG_CANT_MATCH) {
+ if (sm == NULL)
+ alert = 1;
+ inspect_flags |= DE_STATE_FLAG_FULL_INSPECT;
+ }
+ det_ctx->de_state_sig_array[item->sid] = DE_STATE_MATCH_NO_NEW_STATE;
}
- /* next, check the other sig matches */
- if (item->nm != NULL) {
- SigMatch *sm;
- for (sm = item->nm; sm != NULL; sm = sm->next) {
- if (alproto == ALPROTO_SMB || alproto == ALPROTO_SMB2) {
- SMBState *smb_state = (SMBState *)alstate;
- //DCERPCState dcerpc_state;
- //dcerpc_state.dcerpc = smb_state->dcerpc;
- if (smb_state->dcerpc_present) {
- match = sigmatch_table[sm->type].
- AppLayerMatch(tv, det_ctx, f, flags, &smb_state->dcerpc,
- s, sm);
- }
- } else {
- match = sigmatch_table[sm->type].
- AppLayerMatch(tv, det_ctx, f, flags, alstate,
- s, sm);
- }
- /* no match, break out */
- if (match == 0) {
- item->nm = sm;
- det_ctx->de_state_sig_array[item->sid] = DE_STATE_MATCH_PARTIAL;
- SCLogDebug("state set to %s", DeStateMatchResultToString(DE_STATE_MATCH_PARTIAL));
- break;
+ item->flags |= inspect_flags;
+ if ((total_txs - inspect_tx_id) <= 1)
+ det_ctx->de_state_sig_array[item->sid] = DE_STATE_MATCH_NO_NEW_STATE;
- /* match, and no more sm's */
- } else if (sm->next == NULL) {
- /* mark the sig as matched */
- item->nm = NULL;
+ if (alert) {
+ SigMatchSignaturesRunPostMatch(tv, de_ctx, det_ctx, p, s);
- SCLogDebug("inspect_flags %04x match_flags %04x", inspect_flags, match_flags);
- if (inspect_flags == 0 || (inspect_flags == match_flags)) {
- det_ctx->de_state_sig_array[item->sid] = DE_STATE_MATCH_NEW;
- SCLogDebug("state set to %s", DeStateMatchResultToString(DE_STATE_MATCH_NEW));
- match_flags |= DE_STATE_FLAG_FULL_MATCH;
- } else {
- det_ctx->de_state_sig_array[item->sid] = DE_STATE_MATCH_PARTIAL;
- SCLogDebug("state set to %s", DeStateMatchResultToString(DE_STATE_MATCH_PARTIAL));
- }
- }
- }
- } else {
- SCLogDebug("inspect_flags %04x match_flags %04x", inspect_flags, match_flags);
- if (inspect_flags != 0 && (inspect_flags == match_flags)) {
- det_ctx->de_state_sig_array[item->sid] = DE_STATE_MATCH_NEW;
- SCLogDebug("state set to %s", DeStateMatchResultToString(DE_STATE_MATCH_NEW));
- match_flags |= DE_STATE_FLAG_FULL_MATCH;
+ if (!(s->flags & SIG_FLAG_NOALERT)) {
+ PacketAlertAppend(det_ctx, s, p, 0);
} else {
- det_ctx->de_state_sig_array[item->sid] = DE_STATE_MATCH_PARTIAL;
- SCLogDebug("state set to %s", DeStateMatchResultToString(DE_STATE_MATCH_PARTIAL));
+ p->action |= s->action;
}
}
-
- item->flags |= match_flags;
-
- SCLogDebug("signature %"PRIu32" match state %s",
- s->id, DeStateMatchResultToString(det_ctx->de_state_sig_array[item->sid]));
-
- RULE_PROFILING_END(det_ctx, s, match);
-
}
}
- DeStateStoreStateVersion(f->de_state, flags, alversion);
- DeStateStoreFileNoMatch(f->de_state, flags, file_no_match);
+ DeStateStoreStateVersion(f->de_state, alversion, flags);
+ DeStateStoreFileNoMatchCnt(f->de_state, file_no_match, flags);
- if (!(f->de_state->flags & DE_STATE_FILE_STORE_DISABLED)) {
+ if (!(dir_state->flags & DETECT_ENGINE_STATE_FLAG_FILE_STORE_DISABLED)) {
if (DeStateStoreFilestoreSigsCantMatch(det_ctx->sgh, f->de_state, flags) == 1) {
SCLogDebug("disabling file storage for transaction");
FLOWLOCK_WRLOCK(f);
FileDisableStoringForTransaction(f, flags & (STREAM_TOCLIENT|STREAM_TOSERVER),
- det_ctx->tx_id);
+ det_ctx->tx_id);
FLOWLOCK_UNLOCK(f);
- f->de_state->flags |= DE_STATE_FILE_STORE_DISABLED;
+ dir_state->flags |= DETECT_ENGINE_STATE_FLAG_FILE_STORE_DISABLED;
}
}
end:
- if (f->de_state != NULL) {
- if (flags & STREAM_TOCLIENT)
- f->de_state->flags &= ~DE_STATE_FILE_TC_NEW;
- else
- f->de_state->flags &= ~DE_STATE_FILE_TS_NEW;
- }
+ if (f->de_state != NULL)
+ dir_state->flags &= ~DETECT_ENGINE_STATE_FLAG_FILE_TC_NEW;
SCMutexUnlock(&f->de_state_m);
- SCReturnInt(0);
+ return;
}
-/**
- * \brief Restart detection as we're going to inspect a new transaction
- */
-int DeStateRestartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
- Flow *f, uint8_t flags, void *alstate, uint16_t alproto)
+void DeStateUpdateInspectTransactionId(Flow *f, uint8_t direction)
{
- SCEnter();
-
- /* first clear the existing state as it belongs
- * to the previous transaction */
- SCMutexLock(&f->de_state_m);
- if (f->de_state != NULL) {
- DetectEngineStateReset(f->de_state);
- }
- SCMutexUnlock(&f->de_state_m);
+ FLOWLOCK_WRLOCK(f);
+ AppLayerTransactionUpdateInspectId(f, direction);
+ FLOWLOCK_UNLOCK(f);
- SCReturnInt(0);
+ SCReturn;
}
-/**
- * \brief Act on HTTP new file in same tx flag.
- *
- * \param f flow with *LOCKED* de_state
- */
-static void DeStateResetFileInspection(Flow *f, uint16_t alproto, void *alstate) {
- if (f == NULL || alproto != ALPROTO_HTTP || alstate == NULL || f->de_state == NULL) {
- SCReturn;
+
+void DetectEngineStateReset(DetectEngineState *state, uint8_t direction)
+{
+ if (state != NULL) {
+ if (direction & STREAM_TOSERVER) {
+ state->dir_state[0].cnt = 0;
+ state->dir_state[0].filestore_cnt = 0;
+ state->dir_state[0].flags = 0;
+ }
+ if (direction & STREAM_TOCLIENT) {
+ state->dir_state[1].cnt = 0;
+ state->dir_state[1].filestore_cnt = 0;
+ state->dir_state[1].flags = 0;
+ }
}
- FLOWLOCK_WRLOCK(f);
- HtpState *htp_state = (HtpState *)alstate;
+ return;
+}
- if (htp_state->flags & HTP_FLAG_NEW_FILE_TX_TC) {
- SCLogDebug("new file in the TC direction");
- htp_state->flags &= ~HTP_FLAG_NEW_FILE_TX_TC;
- f->de_state->flags |= DE_STATE_FILE_TC_NEW;
- } else if (htp_state->flags & HTP_FLAG_NEW_FILE_TX_TS) {
- SCLogDebug("new file in the TS direction");
- htp_state->flags &= ~HTP_FLAG_NEW_FILE_TX_TS;
- f->de_state->flags |= DE_STATE_FILE_TS_NEW;
+/** \brief get string for match enum */
+const char *DeStateMatchResultToString(DeStateMatchResult res)
+{
+ switch (res) {
+ CASE_CODE (DE_STATE_MATCH_NO_NEW_STATE);
+ CASE_CODE (DE_STATE_MATCH_HAS_NEW_STATE);
}
- FLOWLOCK_UNLOCK(f);
+ return NULL;
}
+/*********Unittests*********/
+
#ifdef UNITTESTS
#include "flow-util.h"
-static int DeStateTest01(void) {
+static int DeStateTest01(void)
+{
SCLogDebug("sizeof(DetectEngineState)\t\t%"PRIuMAX,
(uintmax_t)sizeof(DetectEngineState));
SCLogDebug("sizeof(DeStateStore)\t\t\t%"PRIuMAX,
(uintmax_t)sizeof(DeStateStore));
SCLogDebug("sizeof(DeStateStoreItem)\t\t%"PRIuMAX"",
(uintmax_t)sizeof(DeStateStoreItem));
+
return 1;
}
-static int DeStateTest02(void) {
+static int DeStateTest02(void)
+{
int result = 0;
DetectEngineState *state = DetectEngineStateAlloc();
Signature s;
memset(&s, 0x00, sizeof(s));
+ uint8_t direction = STREAM_TOSERVER;
+
s.num = 0;
- DeStateSignatureAppend(state, &s, NULL, 0);
+ DeStateSignatureAppend(state, &s, NULL, 0, direction);
s.num = 11;
- DeStateSignatureAppend(state, &s, NULL, 0);
+ DeStateSignatureAppend(state, &s, NULL, 0, direction);
s.num = 22;
- DeStateSignatureAppend(state, &s, NULL, 0);
+ DeStateSignatureAppend(state, &s, NULL, 0, direction);
s.num = 33;
- DeStateSignatureAppend(state, &s, NULL, 0);
+ DeStateSignatureAppend(state, &s, NULL, 0, direction);
s.num = 44;
- DeStateSignatureAppend(state, &s, NULL, 0);
+ DeStateSignatureAppend(state, &s, NULL, 0, direction);
s.num = 55;
- DeStateSignatureAppend(state, &s, NULL, 0);
+ DeStateSignatureAppend(state, &s, NULL, 0, direction);
s.num = 66;
- DeStateSignatureAppend(state, &s, NULL, 0);
+ DeStateSignatureAppend(state, &s, NULL, 0, direction);
s.num = 77;
- DeStateSignatureAppend(state, &s, NULL, 0);
+ DeStateSignatureAppend(state, &s, NULL, 0, direction);
s.num = 88;
- DeStateSignatureAppend(state, &s, NULL, 0);
+ DeStateSignatureAppend(state, &s, NULL, 0, direction);
s.num = 99;
- DeStateSignatureAppend(state, &s, NULL, 0);
+ DeStateSignatureAppend(state, &s, NULL, 0, direction);
s.num = 100;
- DeStateSignatureAppend(state, &s, NULL, 0);
+ DeStateSignatureAppend(state, &s, NULL, 0, direction);
s.num = 111;
- DeStateSignatureAppend(state, &s, NULL, 0);
+ DeStateSignatureAppend(state, &s, NULL, 0, direction);
s.num = 122;
- DeStateSignatureAppend(state, &s, NULL, 0);
+ DeStateSignatureAppend(state, &s, NULL, 0, direction);
s.num = 133;
- DeStateSignatureAppend(state, &s, NULL, 0);
+ DeStateSignatureAppend(state, &s, NULL, 0, direction);
s.num = 144;
- DeStateSignatureAppend(state, &s, NULL, 0);
+ DeStateSignatureAppend(state, &s, NULL, 0, direction);
s.num = 155;
- DeStateSignatureAppend(state, &s, NULL, 0);
+ DeStateSignatureAppend(state, &s, NULL, 0, direction);
s.num = 166;
- DeStateSignatureAppend(state, &s, NULL, 0);
+ DeStateSignatureAppend(state, &s, NULL, 0, direction);
- if (state->head == NULL) {
+ if (state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head == NULL) {
goto end;
}
- if (state->head->store[1].sid != 11) {
+ if (state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[1].sid != 11) {
goto end;
}
- if (state->head->next == NULL) {
+ if (state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next == NULL) {
goto end;
}
- if (state->head->store[14].sid != 144) {
+ if (state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[14].sid != 144) {
goto end;
}
- if (state->head->next->store[0].sid != 155) {
+ if (state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next->store[0].sid != 155) {
goto end;
}
- if (state->head->next->store[1].sid != 166) {
+ if (state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next->store[1].sid != 166) {
goto end;
}
return result;
}
-static int DeStateTest03(void) {
+static int DeStateTest03(void)
+{
int result = 0;
DetectEngineState *state = DetectEngineStateAlloc();
Signature s;
memset(&s, 0x00, sizeof(s));
+ uint8_t direction = STREAM_TOSERVER;
+
s.num = 11;
- DeStateSignatureAppend(state, &s, NULL, 0);
+ DeStateSignatureAppend(state, &s, NULL, 0, direction);
s.num = 22;
- DeStateSignatureAppend(state, &s, NULL, DE_STATE_FLAG_URI_MATCH);
+ DeStateSignatureAppend(state, &s, NULL, DE_STATE_FLAG_URI_INSPECT, direction);
- if (state->head == NULL) {
+ if (state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head == NULL) {
goto end;
}
- if (state->head->store[0].sid != 11) {
+ if (state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[0].sid != 11) {
goto end;
}
- if (state->head->store[0].flags & DE_STATE_FLAG_URI_MATCH) {
+ if (state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[0].flags & DE_STATE_FLAG_URI_INSPECT) {
goto end;
}
- if (state->head->store[1].sid != 22) {
+ if (state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[1].sid != 22) {
goto end;
}
- if (!(state->head->store[1].flags & DE_STATE_FLAG_URI_MATCH)) {
+ if (!(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[1].flags & DE_STATE_FLAG_URI_INSPECT)) {
goto end;
}
return result;
}
-static int DeStateSigTest01(void) {
+static int DeStateSigTest01(void)
+{
int result = 0;
Signature *s = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
#endif
-void DeStateRegisterTests(void) {
+void DeStateRegisterTests(void)
+{
#ifdef UNITTESTS
UtRegisterTest("DeStateTest01", DeStateTest01, 1);
UtRegisterTest("DeStateTest02", DeStateTest02, 1);
UtRegisterTest("DeStateSigTest06", DeStateSigTest06, 1);
UtRegisterTest("DeStateSigTest07", DeStateSigTest07, 1);
#endif
+
+ return;
}
/**
-/* Copyright (C) 2007-2011 Open Information Security Foundation
+/* Copyright (C) 2007-2013 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* state for the detection engine.
*
* \author Victor Julien <victor@inliniac.net>
+ * \author Anoop Saldanha <anoopsaldanha@gmail.com>
*/
/* On DeState and locking.
#ifndef __DETECT_ENGINE_STATE_H__
#define __DETECT_ENGINE_STATE_H__
+#define DETECT_ENGINE_INSPECT_SIG_NO_MATCH 0
+#define DETECT_ENGINE_INSPECT_SIG_MATCH 1
+#define DETECT_ENGINE_INSPECT_SIG_CANT_MATCH 2
+#define DETECT_ENGINE_INSPECT_SIG_CANT_MATCH_FILESTORE 3
+
/** number of DeStateStoreItem's in one DeStateStore object */
#define DE_STATE_CHUNK_SIZE 15
-/* per stored sig flags */
-#define DE_STATE_FLAG_PAYLOAD_MATCH 1 /**< payload part of the sig matched */
-#define DE_STATE_FLAG_URI_MATCH 1 << 1 /**< uri part of the sig matched */
-#define DE_STATE_FLAG_DCE_MATCH 1 << 2 /**< dce payload inspection part matched */
-#define DE_STATE_FLAG_HCBD_MATCH 1 << 3 /**< hcbd payload inspection part matched */
-#define DE_STATE_FLAG_HSBD_MATCH 1 << 4 /**< hcbd payload inspection part matched */
-#define DE_STATE_FLAG_HHD_MATCH 1 << 5 /**< hhd payload inspection part matched */
-#define DE_STATE_FLAG_HRHD_MATCH 1 << 6 /**< hrhd payload inspection part matched */
-#define DE_STATE_FLAG_HMD_MATCH 1 << 7 /**< hmd payload inspection part matched */
-#define DE_STATE_FLAG_HCD_MATCH 1 << 8 /**< hcd payload inspection part matched */
-#define DE_STATE_FLAG_HRUD_MATCH 1 << 9 /**< hrud payload inspection part matched */
-#define DE_STATE_FLAG_FILE_TC_MATCH 1 << 10
-#define DE_STATE_FLAG_FILE_TS_MATCH 1 << 11
-#define DE_STATE_FLAG_FULL_MATCH 1 << 12 /**< sig already fully matched */
-#define DE_STATE_FLAG_SIG_CANT_MATCH 1 << 13 /**< signature has no chance of matching */
-#define DE_STATE_FLAG_HSMD_MATCH 1 << 14 /**< hsmd payload inspection part matched */
-#define DE_STATE_FLAG_HSCD_MATCH 1 << 15 /**< hscd payload inspection part matched */
-#define DE_STATE_FLAG_HUAD_MATCH 1 << 16 /**< huad payload inspection part matched */
-#define DE_STATE_FLAG_HHHD_MATCH 1 << 17 /**< hhhd payload inspection part matched */
-#define DE_STATE_FLAG_HRHHD_MATCH 1 << 18 /**< hrhhd payload inspection part matched */
-
-#define DE_STATE_FLAG_URI_INSPECT DE_STATE_FLAG_URI_MATCH /**< uri part of the sig inspected */
-#define DE_STATE_FLAG_DCE_INSPECT DE_STATE_FLAG_DCE_MATCH /**< dce payload inspection part inspected */
-#define DE_STATE_FLAG_HCBD_INSPECT DE_STATE_FLAG_HCBD_MATCH /**< hcbd payload inspection part inspected */
-#define DE_STATE_FLAG_HSBD_INSPECT DE_STATE_FLAG_HSBD_MATCH /**< hsbd payload inspection part inspected */
-#define DE_STATE_FLAG_HHD_INSPECT DE_STATE_FLAG_HHD_MATCH /**< hhd payload inspection part inspected */
-#define DE_STATE_FLAG_HRHD_INSPECT DE_STATE_FLAG_HRHD_MATCH /**< hrhd payload inspection part inspected */
-#define DE_STATE_FLAG_HMD_INSPECT DE_STATE_FLAG_HMD_MATCH /**< hmd payload inspection part inspected */
-#define DE_STATE_FLAG_HCD_INSPECT DE_STATE_FLAG_HCD_MATCH /**< hcd payload inspection part inspected */
-#define DE_STATE_FLAG_HRUD_INSPECT DE_STATE_FLAG_HRUD_MATCH /**< hrud payload inspection part inspected */
-#define DE_STATE_FLAG_FILE_TC_INSPECT DE_STATE_FLAG_FILE_TC_MATCH
-#define DE_STATE_FLAG_FILE_TS_INSPECT DE_STATE_FLAG_FILE_TS_MATCH
-#define DE_STATE_FLAG_HSMD_INSPECT DE_STATE_FLAG_HSMD_MATCH /**< hsmd payload inspection part inspected */
-#define DE_STATE_FLAG_HSCD_INSPECT DE_STATE_FLAG_HSCD_MATCH /**< hscd payload inspection part inspected */
-#define DE_STATE_FLAG_HUAD_INSPECT DE_STATE_FLAG_HUAD_MATCH /**< huad payload inspection part inspected */
-#define DE_STATE_FLAG_HHHD_INSPECT DE_STATE_FLAG_HHHD_MATCH /**< hhhd payload inspection part inspected */
-#define DE_STATE_FLAG_HRHHD_INSPECT DE_STATE_FLAG_HRHHD_MATCH /**< hrhhd payload inspection part inspected */
+/* per sig flags */
+#define DE_STATE_FLAG_URI_INSPECT (1)
+#define DE_STATE_FLAG_HRUD_INSPECT (1 << 1)
+#define DE_STATE_FLAG_HCBD_INSPECT (1 << 2)
+#define DE_STATE_FLAG_HSBD_INSPECT (1 << 3)
+#define DE_STATE_FLAG_HHD_INSPECT (1 << 4)
+#define DE_STATE_FLAG_HRHD_INSPECT (1 << 5)
+#define DE_STATE_FLAG_HHHD_INSPECT (1 << 6)
+#define DE_STATE_FLAG_HRHHD_INSPECT (1 << 7)
+#define DE_STATE_FLAG_HUAD_INSPECT (1 << 8)
+#define DE_STATE_FLAG_HMD_INSPECT (1 << 9)
+#define DE_STATE_FLAG_HCD_INSPECT (1 << 10)
+#define DE_STATE_FLAG_HSMD_INSPECT (1 << 11)
+#define DE_STATE_FLAG_HSCD_INSPECT (1 << 12)
+#define DE_STATE_FLAG_FILE_TC_INSPECT (1 << 13)
+#define DE_STATE_FLAG_FILE_TS_INSPECT (1 << 14)
+#define DE_STATE_FLAG_FULL_INSPECT (1 << 15)
+#define DE_STATE_FLAG_SIG_CANT_MATCH (1 << 16)
/* state flags */
-#define DE_STATE_FILE_STORE_DISABLED 0x0001
-#define DE_STATE_FILE_TC_NEW 0x0002
-#define DE_STATE_FILE_TS_NEW 0x0004
+#define DETECT_ENGINE_STATE_FLAG_FILE_STORE_DISABLED 0x0001
+#define DETECT_ENGINE_STATE_FLAG_FILE_TC_NEW 0x0002
+#define DETECT_ENGINE_STATE_FLAG_FILE_TS_NEW 0x0004
-/** per signature detection engine state */
+/* We have 2 possible state values to be used by ContinueDetection() while
+ * trying to figure if we have fresh state to install or not.
+ *
+ * For tx based alprotos, we don't need to indicate the below values on a
+ * per sig basis, but for non-tx based alprotos we do, since we might have
+ * new alstate coming in, and some sigs might have already matchced in
+ * de_state and ContinueDetection needs to inform the detection filter that
+ * it no longer needs to inspect this sig, since ContinueDetection would
+ * handle it.
+ *
+ * Wrt tx based alprotos, if we have a new tx available apart from the one
+ * currently being inspected(and also added to de_state), we continue with
+ * the HAS_NEW_STATE flag, while if we don't have a new tx, we set
+ * NO_NEW_STATE, to avoid getting the sig reinspected for the already
+ * inspected tx. */
typedef enum {
- DE_STATE_MATCH_NOSTATE = 0, /**< no state for this sig*/
- DE_STATE_MATCH_FULL, /**< sig already fully matched */
- DE_STATE_MATCH_PARTIAL, /**< partial state match */
- DE_STATE_MATCH_NEW, /**< new (full) match this run */
- DE_STATE_MATCH_NOMATCH, /**< not a match */
+ DE_STATE_MATCH_HAS_NEW_STATE = 0,
+ DE_STATE_MATCH_NO_NEW_STATE,
} DeStateMatchResult;
-/** \brief State storage for a single signature */
typedef struct DeStateStoreItem_ {
- SigIntId sid; /**< Signature internal id to store the state for (16 or
- * 32 bit depending on how SigIntId is defined). */
- uint32_t flags; /**< flags */
- SigMatch *nm; /**< next sig match to try, or null if done */
+ SigMatch *nm;
+ uint32_t flags;
+ SigIntId sid;
} DeStateStoreItem;
-/** \brief State store "chunk" for x number of signature */
typedef struct DeStateStore_ {
- DeStateStoreItem store[DE_STATE_CHUNK_SIZE]; /**< array of storage objects */
- struct DeStateStore_ *next; /**< ptr to the next array */
+ DeStateStoreItem store[DE_STATE_CHUNK_SIZE];
+ struct DeStateStore_ *next;
} DeStateStore;
-/** \brief State store main object */
+typedef struct DetectEngineStateDirection_ {
+ DeStateStore *head;
+ DeStateStore *tail;
+ SigIntId cnt;
+ uint16_t filestore_cnt;
+ uint8_t alversion;
+ uint8_t flags;
+} DetectEngineStateDirection;
+
typedef struct DetectEngineState_ {
- DeStateStore *head; /**< signature state storage */
- DeStateStore *tail; /**< tail item of the storage list */
- SigIntId cnt; /**< number of sigs in the storage */
- uint16_t toclient_version; /**< app layer state "version" inspected
- * last in to client direction */
- uint16_t toserver_version; /**< app layer state "version" inspected
- * last in to server direction */
- uint16_t toclient_filestore_cnt;/**< number of sigs with filestore that
- * cannot match in to client direction. */
- uint16_t toserver_filestore_cnt;/**< number of sigs with filestore that
- * cannot match in to server direction. */
- uint16_t flags;
+ DetectEngineStateDirection dir_state[2];
} DetectEngineState;
-void DeStateRegisterTests(void);
+/**
+ * \brief Alloc a DetectEngineState object.
+ *
+ * \retval Alloc'd instance of DetectEngineState.
+ */
+DetectEngineState *DetectEngineStateAlloc(void);
-DeStateStore *DeStateStoreAlloc(void);
-void DeStateStoreFree(DeStateStore *);
-void DetectEngineStateReset(DetectEngineState *state);
+/**
+ * \brief Frees a DetectEngineState object.
+ *
+ * \param state DetectEngineState instance to free.
+ */
+void DetectEngineStateFree(DetectEngineState *state);
-DetectEngineState *DetectEngineStateAlloc(void);
-void DetectEngineStateFree(DetectEngineState *);
+/**
+ * \brief Check if a flow already contains(newly updated as well) de state.
+ *
+ * \param f Pointer to the flow.
+ * \param alversino The alversion to check against de_state's.
+ * \param direction Direction to check. 0 - ts, 1 - tc.
+ *
+ * \retval 1 Has state.
+ * \retval 0 Has no state.
+ */
+int DeStateFlowHasInspectableState(Flow *f, uint16_t alversion, uint8_t direction);
+
+/**
+ * \brief Match app layer sig list against app state and store relevant match
+ * information.
+ *
+ * \param tv Pointer to the threadvars.
+ * \param de_ctx DetectEngineCtx instance.
+ * \param det_ctx DetectEngineThreadCtx instance.
+ * \param s Pointer to the signature.
+ * \param f Pointer to the flow.
+ * \param flags Flags.
+ * \param alstate App state.
+ * \param alproto App protocol.
+ * \param alversion Current app layer version.
+ *
+ * \retval >= 0 An integer value indicating the no of matches.
+ */
+int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
+ DetectEngineThreadCtx *det_ctx,
+ Signature *s, Flow *f, uint8_t flags,
+ void *alstate, uint16_t alproto,
+ uint16_t alversion);
-int DeStateFlowHasState(Flow *, uint8_t, uint16_t);
+/**
+ * \brief Continue DeState detection of the signatures stored in the state.
+ *
+ * \param tv Pointer to the threadvars.
+ * \param de_ctx DetectEngineCtx instance.
+ * \param det_ctx DetectEngineThreadCtx instance.
+ * \param f Pointer to the flow.
+ * \param flags Flags.
+ * \param alstate App state.
+ * \param alproto App protocol.
+ * \param alversion Current app layer version.
+ */
+void DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
+ DetectEngineThreadCtx *det_ctx,
+ Packet *p, Flow *f, uint8_t flags, void *alstate,
+ uint16_t alproto, uint16_t alversion);
-int DeStateDetectStartDetection(ThreadVars *, DetectEngineCtx *,
- DetectEngineThreadCtx *, Signature *, Flow *, uint8_t, void *,
- uint16_t, uint16_t);
+/**
+ * \brief Update the inspect id.
+ *
+ * \param f Flow(unlocked).
+ * \param direction 0 for to server, 1 for toclient.
+ */
+void DeStateUpdateInspectTransactionId(Flow *f, uint8_t direction);
-int DeStateDetectContinueDetection(ThreadVars *, DetectEngineCtx *,
- DetectEngineThreadCtx *, Flow *, uint8_t, void *, uint16_t,
- uint16_t);
+/**
+ * \brief Reset a DetectEngineState state.
+ *
+ * \param state Pointer to the state(LOCKED).
+ * \param direction Direction flags - STREAM_TOSERVER or STREAM_TOCLIENT.
+ */
+void DetectEngineStateReset(DetectEngineState *state, uint8_t direction);
-const char *DeStateMatchResultToString(DeStateMatchResult);
-int DeStateUpdateInspectTransactionId(Flow *, char);
+void DeStateRegisterTests(void);
#endif /* __DETECT_ENGINE_STATE_H__ */
#include "app-layer-htp.h"
#include "app-layer-protos.h"
-/** \brief Do the content inspection & validation for a signature
+/**
+ * \brief Do the content inspection & validation for a signature
*
- * \param de_ctx Detection engine context
- * \param det_ctx Detection engine thread context
- * \param s Signature to inspect
- * \param sm SigMatch to inspect
- * \param f Flow
- * \param flags app layer flags
- * \param state App layer state
+ * \param de_ctx Detection engine context
+ * \param det_ctx Detection engine thread context
+ * \param s Signature to inspect
+ * \param sm SigMatch to inspect
+ * \param f Flow
+ * \param flags app layer flags
+ * \param state App layer state
*
- * \retval 0 no match
- * \retval 1 match
+ * \retval 0 no match.
+ * \retval 1 match.
+ * \retval 2 Sig can't match.
*/
int DetectEngineInspectPacketUris(ThreadVars *tv,
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
Signature *s, Flow *f, uint8_t flags,
- void *alstate, int tx_id)
+ void *alstate,
+ void *txv, uint64_t tx_id)
{
- HtpState *htp_state = (HtpState *)alstate;
+ htp_tx_t *tx = (htp_tx_t *)txv;
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, tx_id);
- if (tx == NULL || tx->request_uri_normalized == NULL)
- return 0;
+ if (tx->request_uri_normalized == NULL) {
+ if (AppLayerGetAlstateProgress(ALPROTO_HTTP, tx, 0) > TX_PROGRESS_REQ_LINE)
+ return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
+ else
+ return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
+ }
det_ctx->discontinue_matching = 0;
det_ctx->buffer_offset = 0;
det_ctx->inspection_recursion_counter = 0;
- //PrintRawDataFp(stdout, (uint8_t *)bstr_ptr(tx->request_uri_normalized),
- // bstr_len(tx->request_uri_normalized));
+#if 0
+ PrintRawDataFp(stdout, (uint8_t *)bstr_ptr(tx->request_uri_normalized),
+ bstr_len(tx->request_uri_normalized));
+#endif
/* Inspect all the uricontents fetched on each
* transaction at the app layer */
bstr_len(tx->request_uri_normalized),
DETECT_ENGINE_CONTENT_INSPECTION_MODE_URI, NULL);
if (r == 1) {
- return 1;
+ return DETECT_ENGINE_INSPECT_SIG_MATCH;
+ } else {
+ return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
}
-
- return 0;
}
/***********************************Unittests**********************************/
goto end;
}
- DetectEngineStateReset(f.de_state);
+ DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT);
r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
if (r != 0) {
goto end;
}
- DetectEngineStateReset(f.de_state);
+ DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT);
r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
if (r != 0) {
goto end;
}
- DetectEngineStateReset(f.de_state);
+ DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT);
r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
if (r != 0) {
goto end;
}
- DetectEngineStateReset(f.de_state);
+ DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT);
r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
if (r != 0) {
goto end;
}
- DetectEngineStateReset(f.de_state);
+ DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT);
r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
if (r != 0) {
goto end;
}
- DetectEngineStateReset(f.de_state);
+ DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT);
r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
if (r != 0) {
goto end;
}
- DetectEngineStateReset(f.de_state);
+ DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT);
r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
if (r != 0) {
goto end;
}
- DetectEngineStateReset(f.de_state);
+ DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT);
r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
if (r != 0) {
goto end;
}
- DetectEngineStateReset(f.de_state);
+ DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT);
r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
if (r != 0) {
goto end;
}
- DetectEngineStateReset(f.de_state);
+ DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT);
r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
if (r != 0) {
goto end;
}
- DetectEngineStateReset(f.de_state);
+ DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT);
r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
if (r != 0) {
goto end;
}
- DetectEngineStateReset(f.de_state);
+ DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT);
r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
if (r != 0) {
goto end;
}
- DetectEngineStateReset(f.de_state);
+ DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT);
r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
if (r != 0) {
goto end;
}
- DetectEngineStateReset(f.de_state);
+ DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT);
r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
if (r != 0) {
goto end;
}
- DetectEngineStateReset(f.de_state);
+ DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT);
r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
if (r != 0) {
}
p->alerts.cnt = 0;
- DetectEngineStateReset(f.de_state);
+ DetectEngineStateReset(f.de_state, STREAM_TOSERVER | STREAM_TOCLIENT);
p->payload = http_buf2;
p->payload_len = http_buf2_len;
#define __DETECT_ENGINE_URICONTENT_H__
int DetectEngineInspectPacketUris(ThreadVars *tv,
- DetectEngineCtx *, DetectEngineThreadCtx *,
- Signature *, Flow *, uint8_t, void *, int);
+ DetectEngineCtx *de_ctx,
+ DetectEngineThreadCtx *det_ctx,
+ Signature *s, Flow *f, uint8_t flags,
+ void *alstate,
+ void *tx, uint64_t tx_id);
void UriRegisterTests(void);
#endif /* __DETECT_ENGINE_URICONTENT_H__ */
DetectEngineThreadCtx *det_ctx,
Signature *sig, Flow *f,
uint8_t flags, void *alstate,
- int32_t tx_id);
+ void *tx, uint64_t tx_id);
};
{ ALPROTO_HTTP,
DETECT_SM_LIST_UMATCH,
DE_STATE_FLAG_URI_INSPECT,
- DE_STATE_FLAG_URI_MATCH,
+ DE_STATE_FLAG_URI_INSPECT,
0,
DetectEngineInspectPacketUris },
{ ALPROTO_HTTP,
DETECT_SM_LIST_HCBDMATCH,
DE_STATE_FLAG_HCBD_INSPECT,
- DE_STATE_FLAG_HCBD_MATCH,
+ DE_STATE_FLAG_HCBD_INSPECT,
0,
DetectEngineInspectHttpClientBody },
{ ALPROTO_HTTP,
DETECT_SM_LIST_HHDMATCH,
DE_STATE_FLAG_HHD_INSPECT,
- DE_STATE_FLAG_HHD_MATCH,
+ DE_STATE_FLAG_HHD_INSPECT,
0,
DetectEngineInspectHttpHeader },
{ ALPROTO_HTTP,
DETECT_SM_LIST_HRHDMATCH,
DE_STATE_FLAG_HRHD_INSPECT,
- DE_STATE_FLAG_HRHD_MATCH,
+ DE_STATE_FLAG_HRHD_INSPECT,
0,
DetectEngineInspectHttpRawHeader },
{ ALPROTO_HTTP,
DETECT_SM_LIST_HMDMATCH,
DE_STATE_FLAG_HMD_INSPECT,
- DE_STATE_FLAG_HMD_MATCH,
+ DE_STATE_FLAG_HMD_INSPECT,
0,
DetectEngineInspectHttpMethod },
{ ALPROTO_HTTP,
DETECT_SM_LIST_HCDMATCH,
DE_STATE_FLAG_HCD_INSPECT,
- DE_STATE_FLAG_HCD_MATCH,
+ DE_STATE_FLAG_HCD_INSPECT,
0,
DetectEngineInspectHttpCookie },
{ ALPROTO_HTTP,
DETECT_SM_LIST_HRUDMATCH,
DE_STATE_FLAG_HRUD_INSPECT,
- DE_STATE_FLAG_HRUD_MATCH,
+ DE_STATE_FLAG_HRUD_INSPECT,
0,
DetectEngineInspectHttpRawUri },
{ ALPROTO_HTTP,
DETECT_SM_LIST_FILEMATCH,
DE_STATE_FLAG_FILE_TS_INSPECT,
- DE_STATE_FLAG_FILE_TS_MATCH,
+ DE_STATE_FLAG_FILE_TS_INSPECT,
0,
DetectFileInspectHttp },
{ ALPROTO_HTTP,
DETECT_SM_LIST_HUADMATCH,
DE_STATE_FLAG_HUAD_INSPECT,
- DE_STATE_FLAG_HUAD_MATCH,
+ DE_STATE_FLAG_HUAD_INSPECT,
0,
DetectEngineInspectHttpUA },
{ ALPROTO_HTTP,
DETECT_SM_LIST_HHHDMATCH,
DE_STATE_FLAG_HHHD_INSPECT,
- DE_STATE_FLAG_HHHD_MATCH,
+ DE_STATE_FLAG_HHHD_INSPECT,
0,
DetectEngineInspectHttpHH },
{ ALPROTO_HTTP,
DETECT_SM_LIST_HRHHDMATCH,
DE_STATE_FLAG_HRHHD_INSPECT,
- DE_STATE_FLAG_HRHHD_MATCH,
+ DE_STATE_FLAG_HRHHD_INSPECT,
0,
DetectEngineInspectHttpHRH },
};
{ ALPROTO_HTTP,
DETECT_SM_LIST_HSBDMATCH,
DE_STATE_FLAG_HSBD_INSPECT,
- DE_STATE_FLAG_HSBD_MATCH,
+ DE_STATE_FLAG_HSBD_INSPECT,
1,
DetectEngineInspectHttpServerBody },
{ ALPROTO_HTTP,
DETECT_SM_LIST_HHDMATCH,
DE_STATE_FLAG_HHD_INSPECT,
- DE_STATE_FLAG_HHD_MATCH,
+ DE_STATE_FLAG_HHD_INSPECT,
1,
DetectEngineInspectHttpHeader },
{ ALPROTO_HTTP,
DETECT_SM_LIST_HRHDMATCH,
DE_STATE_FLAG_HRHD_INSPECT,
- DE_STATE_FLAG_HRHD_MATCH,
+ DE_STATE_FLAG_HRHD_INSPECT,
1,
DetectEngineInspectHttpRawHeader },
{ ALPROTO_HTTP,
DETECT_SM_LIST_HCDMATCH,
DE_STATE_FLAG_HCD_INSPECT,
- DE_STATE_FLAG_HCD_MATCH,
+ DE_STATE_FLAG_HCD_INSPECT,
1,
DetectEngineInspectHttpCookie },
{ ALPROTO_HTTP,
DETECT_SM_LIST_FILEMATCH,
DE_STATE_FLAG_FILE_TC_INSPECT,
- DE_STATE_FLAG_FILE_TC_MATCH,
+ DE_STATE_FLAG_FILE_TC_INSPECT,
1,
DetectFileInspectHttp },
{ ALPROTO_HTTP,
DETECT_SM_LIST_HSMDMATCH,
DE_STATE_FLAG_HSMD_INSPECT,
- DE_STATE_FLAG_HSMD_MATCH,
+ DE_STATE_FLAG_HSMD_INSPECT,
1,
DetectEngineInspectHttpStatMsg },
{ ALPROTO_HTTP,
DETECT_SM_LIST_HSCDMATCH,
DE_STATE_FLAG_HSCD_INSPECT,
- DE_STATE_FLAG_HSCD_MATCH,
+ DE_STATE_FLAG_HSCD_INSPECT,
1,
DetectEngineInspectHttpStatCode }
};
DetectEngineThreadCtx *det_ctx,
Signature *sig, Flow *f,
uint8_t flags, void *alstate,
- int32_t tx_id),
+ void *tx, uint64_t tx_id),
DetectEngineAppInspectionEngine *list[][2])
{
if ((list == NULL) ||
Flow *f,
uint8_t flags,
void *alstate,
- int32_t tx_id)
+ void *tx, uint64_t tx_id)
{
return 0;
}
Flow *f,
uint8_t flags,
void *alstate,
- int32_t tx_id)
+ void *tx, uint64_t tx_id)
{
return 0;
}
0 /* STREAM_TOSERVER */,
DETECT_SM_LIST_UMATCH,
DE_STATE_FLAG_URI_INSPECT,
- DE_STATE_FLAG_URI_MATCH,
+ DE_STATE_FLAG_URI_INSPECT,
DummyTestAppInspectionEngine01,
engine_list);
engine->dir != dir ||
engine->sm_list != DETECT_SM_LIST_UMATCH ||
engine->inspect_flags != DE_STATE_FLAG_URI_INSPECT ||
- engine->match_flags != DE_STATE_FLAG_URI_MATCH ||
+ engine->match_flags != DE_STATE_FLAG_URI_INSPECT ||
engine->Callback != DummyTestAppInspectionEngine01) {
printf("failed for http and dir(0-toserver)\n");
goto end;
0 /* STREAM_TOSERVER */,
DETECT_SM_LIST_UMATCH,
DE_STATE_FLAG_URI_INSPECT,
- DE_STATE_FLAG_URI_MATCH,
+ DE_STATE_FLAG_URI_INSPECT,
DummyTestAppInspectionEngine01,
engine_list);
DetectEngineRegisterAppInspectionEngine(ALPROTO_HTTP,
1 /* STREAM_TOCLIENT */,
DETECT_SM_LIST_UMATCH,
DE_STATE_FLAG_URI_INSPECT,
- DE_STATE_FLAG_URI_MATCH,
+ DE_STATE_FLAG_URI_INSPECT,
DummyTestAppInspectionEngine02,
engine_list);
engine->dir != dir ||
engine->sm_list != DETECT_SM_LIST_UMATCH ||
engine->inspect_flags != DE_STATE_FLAG_URI_INSPECT ||
- engine->match_flags != DE_STATE_FLAG_URI_MATCH ||
+ engine->match_flags != DE_STATE_FLAG_URI_INSPECT ||
engine->Callback != DummyTestAppInspectionEngine01) {
printf("failed for http and dir(0-toserver)\n");
goto end;
engine->dir != dir ||
engine->sm_list != DETECT_SM_LIST_UMATCH ||
engine->inspect_flags != DE_STATE_FLAG_URI_INSPECT ||
- engine->match_flags != DE_STATE_FLAG_URI_MATCH ||
+ engine->match_flags != DE_STATE_FLAG_URI_INSPECT ||
engine->Callback != DummyTestAppInspectionEngine02) {
printf("failed for http and dir(0-toclient)\n");
goto end;
DetectEngineThreadCtx *det_ctx,
Signature *sig, Flow *f,
uint8_t flags, void *alstate,
- int32_t tx_id);
+ void *tx, uint64_t tx_id);
};
struct test_data_t data[] = {
{ DETECT_SM_LIST_UMATCH,
DE_STATE_FLAG_URI_INSPECT,
- DE_STATE_FLAG_URI_MATCH,
+ DE_STATE_FLAG_URI_INSPECT,
0,
DummyTestAppInspectionEngine01 },
{ DETECT_SM_LIST_HCBDMATCH,
DE_STATE_FLAG_HCBD_INSPECT,
- DE_STATE_FLAG_HCBD_MATCH,
+ DE_STATE_FLAG_HCBD_INSPECT,
0,
DummyTestAppInspectionEngine02 },
{ DETECT_SM_LIST_HSBDMATCH,
DE_STATE_FLAG_HSBD_INSPECT,
- DE_STATE_FLAG_HSBD_MATCH,
+ DE_STATE_FLAG_HSBD_INSPECT,
1,
DummyTestAppInspectionEngine02 },
{ DETECT_SM_LIST_HHDMATCH,
DE_STATE_FLAG_HHD_INSPECT,
- DE_STATE_FLAG_HHD_MATCH,
+ DE_STATE_FLAG_HHD_INSPECT,
0,
DummyTestAppInspectionEngine01 },
{ DETECT_SM_LIST_HRHDMATCH,
DE_STATE_FLAG_HRHD_INSPECT,
- DE_STATE_FLAG_HRHD_MATCH,
+ DE_STATE_FLAG_HRHD_INSPECT,
0,
DummyTestAppInspectionEngine01 },
{ DETECT_SM_LIST_HMDMATCH,
DE_STATE_FLAG_HMD_INSPECT,
- DE_STATE_FLAG_HMD_MATCH,
+ DE_STATE_FLAG_HMD_INSPECT,
0,
DummyTestAppInspectionEngine02 },
{ DETECT_SM_LIST_HCDMATCH,
DE_STATE_FLAG_HCD_INSPECT,
- DE_STATE_FLAG_HCD_MATCH,
+ DE_STATE_FLAG_HCD_INSPECT,
0,
DummyTestAppInspectionEngine01 },
{ DETECT_SM_LIST_HRUDMATCH,
DE_STATE_FLAG_HRUD_INSPECT,
- DE_STATE_FLAG_HRUD_MATCH,
+ DE_STATE_FLAG_HRUD_INSPECT,
0,
DummyTestAppInspectionEngine01 },
{ DETECT_SM_LIST_FILEMATCH,
DE_STATE_FLAG_FILE_TS_INSPECT,
- DE_STATE_FLAG_FILE_TS_MATCH,
+ DE_STATE_FLAG_FILE_TS_INSPECT,
0,
DummyTestAppInspectionEngine02 },
{ DETECT_SM_LIST_FILEMATCH,
DE_STATE_FLAG_FILE_TC_INSPECT,
- DE_STATE_FLAG_FILE_TC_MATCH,
+ DE_STATE_FLAG_FILE_TC_INSPECT,
1,
DummyTestAppInspectionEngine02 },
{ DETECT_SM_LIST_HSMDMATCH,
DE_STATE_FLAG_HSMD_INSPECT,
- DE_STATE_FLAG_HSMD_MATCH,
+ DE_STATE_FLAG_HSMD_INSPECT,
0,
DummyTestAppInspectionEngine01 },
{ DETECT_SM_LIST_HSCDMATCH,
DE_STATE_FLAG_HSCD_INSPECT,
- DE_STATE_FLAG_HSCD_MATCH,
+ DE_STATE_FLAG_HSCD_INSPECT,
0,
DummyTestAppInspectionEngine01 },
{ DETECT_SM_LIST_HUADMATCH,
DE_STATE_FLAG_HUAD_INSPECT,
- DE_STATE_FLAG_HUAD_MATCH,
+ DE_STATE_FLAG_HUAD_INSPECT,
0,
DummyTestAppInspectionEngine02 },
};
uint32_t inspect_flags;
uint32_t match_flags;
+ /* \retval 0 No match. Don't discontinue matching yet. We need more data.
+ * 1 Match.
+ * 2 Sig can't match.
+ * 3 Special value used by filestore sigs to indicate disabling
+ * filestore for the tx.
+ */
int (*Callback)(ThreadVars *tv,
DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
Signature *sig, Flow *f, uint8_t flags, void *alstate,
- int32_t tx_id);
+ void *tx, uint64_t tx_id);
struct DetectEngineAppInspectionEngine_ *next;
} DetectEngineAppInspectionEngine;
DetectEngineThreadCtx *det_ctx,
Signature *sig, Flow *f,
uint8_t flags, void *alstate,
- int32_t tx_id),
+ void *tx, uint64_t tx_id),
DetectEngineAppInspectionEngine *list[][2]);
#endif /* __DETECT_ENGINE_H__ */
det_ctx->filestore[det_ctx->filestore_cnt].file_id = file_id;
det_ctx->filestore[det_ctx->filestore_cnt].tx_id = det_ctx->tx_id;
- SCLogDebug("%u, file %u, tx %u", det_ctx->filestore_cnt,
+ SCLogDebug("%u, file %u, tx %"PRIu64, det_ctx->filestore_cnt,
det_ctx->filestore[det_ctx->filestore_cnt].file_id,
det_ctx->filestore[det_ctx->filestore_cnt].tx_id);
goto end;
}
- if (list_size(htp_state->connp->conn->transactions) != 2) {
+ if (AppLayerGetTxCnt(ALPROTO_HTTP, htp_state) != 2) {
printf("The http app layer doesn't have 2 transactions, but it should: ");
goto end;
}
}
/* hardcoded check of the transactions and it's client body chunks */
- if (list_size(htp_state->connp->conn->transactions) != 2) {
+ if (AppLayerGetTxCnt(ALPROTO_HTTP, htp_state) != 2) {
printf("The http app layer doesn't have 2 transactions, but it should: ");
goto end;
}
- htp_tx_t *t1 = list_get(htp_state->connp->conn->transactions, 0);
- htp_tx_t *t2 = list_get(htp_state->connp->conn->transactions, 1);
+ htp_tx_t *t1 = AppLayerGetTx(ALPROTO_HTTP, htp_state, 0);
+ htp_tx_t *t2 = AppLayerGetTx(ALPROTO_HTTP, htp_state, 1);
HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(t1);
goto end;
}
- if (list_size(htp_state->connp->conn->transactions) != 2) {
+ if (AppLayerGetTxCnt(ALPROTO_HTTP, htp_state) != 2) {
printf("The http app layer doesn't have 2 transactions, but it should: ");
goto end;
}
goto end;
}
- if (list_size(htp_state->connp->conn->transactions) != 2) {
+ if (AppLayerGetTxCnt(ALPROTO_HTTP, htp_state) != 2) {
printf("The http app layer doesn't have 2 transactions, but it should: ");
goto end;
}
goto end;
}
- if (list_size(htp_state->connp->conn->transactions) != 2) {
+ if (AppLayerGetTxCnt(ALPROTO_HTTP, htp_state) != 2) {
printf("The http app layer doesn't have 2 transactions, but it should: ");
goto end;
}
goto end;
}
- if (list_size(htp_state->connp->conn->transactions) != 2) {
+ if (AppLayerGetTxCnt(ALPROTO_HTTP, htp_state) != 2) {
printf("The http app layer doesn't have 2 transactions, but it should: ");
goto end;
}
goto end;
}
- if (list_size(htp_state->connp->conn->transactions) != 2) {
+ if (AppLayerGetTxCnt(ALPROTO_HTTP, htp_state) != 2) {
printf("The http app layer doesn't have 2 transactions, but it should: ");
goto end;
}
goto end;
}
- if (list_size(htp_state->connp->conn->transactions) != 2) {
+ if (AppLayerGetTxCnt(ALPROTO_HTTP, htp_state) != 2) {
printf("The http app layer doesn't have 2 transactions, but it should: ");
goto end;
}
goto end;
}
- if (list_size(htp_state->connp->conn->transactions) != 2) {
+ if (AppLayerGetTxCnt(ALPROTO_HTTP, htp_state) != 2) {
printf("The http app layer doesn't have 2 transactions, but it should: ");
goto end;
}
FLOWLOCK_RDLOCK(p->flow);
HtpState *htp_state = p->flow->alstate;
if (htp_state != NULL && htp_state->connp != NULL && htp_state->connp->conn != NULL) {
- int idx = AppLayerTransactionGetInspectId(p->flow);
+ uint64_t idx = AppLayerTransactionGetInspectId(p->flow, flags);
if (idx != -1) {
htp_tx_t *tx = NULL;
- int size = (int)list_size(htp_state->connp->conn->transactions);
+ uint64_t total_txs= AppLayerGetNoOfTxs(ALPROTO_HTTP, htp_state);
for ( ; idx < size; idx++)
{
- tx = list_get(htp_state->connp->conn->transactions, idx);
+ tx = AppLayerGetTx(http_state, idx);
if (tx == NULL)
continue;
s->sm_lists[DETECT_SM_LIST_HMDMATCH] != NULL ||
s->sm_lists[DETECT_SM_LIST_HUADMATCH] != NULL) {
sig_flags |= SIG_FLAG_TOSERVER;
+ s->flags |= SIG_FLAG_TOSERVER;
+ s->flags &= ~SIG_FLAG_TOCLIENT;
}
if (s->sm_lists[DETECT_SM_LIST_HSBDMATCH] != NULL ||
s->sm_lists[DETECT_SM_LIST_HSMDMATCH] != NULL ||
s->sm_lists[DETECT_SM_LIST_HSCDMATCH] != NULL) {
sig_flags |= SIG_FLAG_TOCLIENT;
+ s->flags |= SIG_FLAG_TOCLIENT;
+ s->flags &= ~SIG_FLAG_TOSERVER;
}
if ((sig_flags & (SIG_FLAG_TOCLIENT | SIG_FLAG_TOSERVER)) == (SIG_FLAG_TOCLIENT | SIG_FLAG_TOSERVER)) {
SCLogError(SC_ERR_INVALID_SIGNATURE,"You seem to have mixed keywords "
}
/* hardcoded check of the transactions and it's client body chunks */
- if (list_size(htp_state->connp->conn->transactions) != 2) {
+ if (AppLayerGetTxCnt(ALPROTO_HTTP, htp_state) != 2) {
printf("The http app layer doesn't have 2 transactions, but it should: ");
goto end;
}
- htp_tx_t *t1 = list_get(htp_state->connp->conn->transactions, 0);
- htp_tx_t *t2 = list_get(htp_state->connp->conn->transactions, 1);
+ htp_tx_t *t1 = AppLayerGetTx(ALPROTO_HTTP, htp_state, 0);
+ htp_tx_t *t2 = AppLayerGetTx(ALPROTO_HTTP, htp_state, 1);
HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(t1);
if (htud == NULL) {
}
/* hardcoded check of the transactions and it's client body chunks */
- if (list_size(htp_state->connp->conn->transactions) != 2) {
+ if (AppLayerGetTxCnt(ALPROTO_HTTP, htp_state) != 2) {
printf("The http app layer doesn't have 2 transactions, but it should: ");
goto end;
}
- htp_tx_t *t1 = list_get(htp_state->connp->conn->transactions, 0);
- htp_tx_t *t2 = list_get(htp_state->connp->conn->transactions, 1);
+ htp_tx_t *t1 = AppLayerGetTx(ALPROTO_HTTP, htp_state, 0);
+ htp_tx_t *t2 = AppLayerGetTx(ALPROTO_HTTP, htp_state, 1);
HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(t1);
goto end;
}
- if (list_size(htp_state->connp->conn->transactions) != 2) {
+ if (AppLayerGetTxCnt(ALPROTO_HTTP, htp_state) != 2) {
printf("The http app layer doesn't have 2 transactions, but it should: ");
goto end;
}
}
/* do detect */
+ p->alerts.cnt = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (!PacketAlertCheck(p, 1))
}
/* do detect */
+ p->alerts.cnt = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (PacketAlertCheck(p, 1))
}
/* do detect */
+ p->alerts.cnt = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (PacketAlertCheck(p, 1))
}
/* do detect */
+ p->alerts.cnt = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (PacketAlertCheck(p, 1))
}
/* do detect */
+ p->alerts.cnt = 0;
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (PacketAlertCheck(p, 1))
* \todo what should we return? Just the fact that we matched?
*/
uint32_t DetectUricontentInspectMpm(DetectEngineThreadCtx *det_ctx, Flow *f,
- HtpState *htp_state, uint8_t flags)
+ HtpState *htp_state, uint8_t flags,
+ void *txv, uint64_t idx)
{
SCEnter();
+ htp_tx_t *tx = (htp_tx_t *)txv;
uint32_t cnt = 0;
- int idx = 0;
- htp_tx_t *tx = NULL;
-
- /* locking the flow, we will inspect the htp state */
- FLOWLOCK_RDLOCK(f);
-
- if (htp_state == NULL || htp_state->connp == NULL) {
- SCLogDebug("no HTTP state / no connp");
- FLOWLOCK_UNLOCK(f);
- SCReturnUInt(0U);
- }
-
- idx = AppLayerTransactionGetInspectId(f);
- if (idx == -1) {
+ if (tx->request_uri_normalized == NULL)
goto end;
- }
+ cnt = DoDetectAppLayerUricontentMatch(det_ctx, (uint8_t *)
+ bstr_ptr(tx->request_uri_normalized),
+ bstr_len(tx->request_uri_normalized),
+ flags);
- int size = (int)list_size(htp_state->connp->conn->transactions);
- for (; idx < size; idx++)
- {
- tx = list_get(htp_state->connp->conn->transactions, idx);
- if (tx == NULL || tx->request_uri_normalized == NULL)
- continue;
-
- cnt += DoDetectAppLayerUricontentMatch(det_ctx, (uint8_t *)
- bstr_ptr(tx->request_uri_normalized),
- bstr_len(tx->request_uri_normalized),
- flags);
- }
end:
- FLOWLOCK_UNLOCK(f);
SCReturnUInt(cnt);
}
goto end;
}
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = AppLayerGetTx(ALPROTO_HTTP, htp_state, 0);
if (tx->request_method_number != M_GET ||
tx->request_protocol_number != HTTP_1_1)
goto end;
}
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = AppLayerGetTx(ALPROTO_HTTP, htp_state, 0);
if (tx->request_method_number != M_GET ||
tx->request_protocol_number != HTTP_1_1)
goto end;
}
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = AppLayerGetTx(ALPROTO_HTTP, htp_state, 0);
if (tx->request_method_number != M_UNKNOWN ||
tx->request_protocol_number != HTTP_1_1)
goto end;
}
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, 0);
+ htp_tx_t *tx = AppLayerGetTx(ALPROTO_HTTP, htp_state, 0);
if (tx->request_method_number != M_GET ||
tx->request_protocol_number != HTTP_1_1)
if ((PacketAlertCheck(p, 1))) {
printf("sig 1 alerted, but it should not (chunk 2): ");
goto end;
- } else if (PacketAlertCheck(p, 2)) {
+ } else if (!PacketAlertCheck(p, 2)) {
printf("sig 2 alerted, but it should not (chunk 2): ");
goto end;
} else if (!(PacketAlertCheck(p, 3))) {
/* prototypes */
void DetectUricontentRegister (void);
uint32_t DetectUricontentMaxId(DetectEngineCtx *);
-//uint32_t DetectUricontentInspectMpm(DetectEngineThreadCtx *det_ctx, void *alstate);
void DetectUricontentPrint(DetectContentData *);
-uint32_t DetectUricontentInspectMpm(DetectEngineThreadCtx *, Flow *, HtpState *, uint8_t);
+uint32_t DetectUricontentInspectMpm(DetectEngineThreadCtx *det_ctx, Flow *f,
+ HtpState *htp_state, uint8_t flags,
+ void *tx, uint64_t idx);
#endif /* __DETECT_URICONTENT_H__ */
static pcre_extra *parse_regex_study;
/*prototypes*/
-int DetectUrilenMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f,
- uint8_t flags, void *state, Signature *s, SigMatch *m);
static int DetectUrilenSetup (DetectEngineCtx *, Signature *, char *);
void DetectUrilenFree (void *);
void DetectUrilenRegisterTests (void);
return;
}
-/**
- * \brief This function is used to match urilen rule option with the HTTP
- * uricontent.
- *
- * \param t pointer to thread vars
- * \param det_ctx pointer to the pattern matcher thread
- * \param p pointer to the current packet
- * \param m pointer to the sigmatch that we will cast into DetectUrilenData
- *
- * \retval 0 no match
- * \retval 1 match
- */
-int DetectUrilenMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f,
- uint8_t flags, void *state, Signature *s, SigMatch *m)
-{
- SCEnter();
- int ret = 0;
- int idx = 0;
- DetectUrilenData *urilend = (DetectUrilenData *) m->ctx;
-
- HtpState *htp_state = (HtpState *)state;
- if (htp_state == NULL) {
- SCLogDebug("no HTP state, no need to match further");
- SCReturnInt(ret);
- }
-
- FLOWLOCK_RDLOCK(f);
- htp_tx_t *tx = NULL;
-
- idx = AppLayerTransactionGetInspectId(f);
- if (idx == -1) {
- goto end;
- }
-
- int size = (int)list_size(htp_state->connp->conn->transactions);
- for (; idx < size; idx++)
- {
- tx = list_get(htp_state->connp->conn->transactions, idx);
- if (tx == NULL || tx->request_uri_normalized == NULL)
- goto end;
-
- switch (urilend->mode) {
- case DETECT_URILEN_EQ:
- if (bstr_len(tx->request_uri_normalized) == urilend->urilen1)
- ret = 1;
- break;
- case DETECT_URILEN_LT:
- if (bstr_len(tx->request_uri_normalized) < urilend->urilen1)
- ret = 1;
- break;
- case DETECT_URILEN_GT:
- if (bstr_len(tx->request_uri_normalized) > urilend->urilen1)
- ret = 1;
- break;
- case DETECT_URILEN_RA:
- if (bstr_len(tx->request_uri_normalized) > urilend->urilen1 &&
- bstr_len(tx->request_uri_normalized) < urilend->urilen2)
- ret = 1;
- break;
- }
- }
-end:
- FLOWLOCK_UNLOCK(f);
- SCReturnInt(ret);
-}
-
/**
* \brief This function is used to parse urilen options passed via urilen: keyword
*
* for this sig. If we have NOSTATE, stateful detection didn't
* start yet for this sig, so we will inspect it.
*/
- if (det_ctx->de_state_sig_array[s->num] != DE_STATE_MATCH_NEW &&
- det_ctx->de_state_sig_array[s->num] != DE_STATE_MATCH_NOSTATE) {
- SCLogDebug("de state not NEW or NOSTATE, ignoring");
+ if (det_ctx->de_state_sig_array[s->num] == DE_STATE_MATCH_NO_NEW_STATE)
return 0;
- }
}
return 1;
#endif
}
-static int SigMatchSignaturesRunPostMatch(ThreadVars *tv,
- DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p,
- Signature *s)
+int SigMatchSignaturesRunPostMatch(ThreadVars *tv,
+ DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p,
+ Signature *s)
{
/* run the packet match functions */
if (s->sm_lists[DETECT_SM_LIST_POSTMATCH] != NULL) {
}
/* all http based mpms */
- if (alproto == ALPROTO_HTTP && alstate != NULL) {
- if (p->flowflags & FLOW_PKT_TOSERVER) {
- if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_URI) {
- PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_URI);
- DetectUricontentInspectMpm(det_ctx, p->flow, alstate, flags);
- PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_URI);
- }
- if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HRUD) {
- PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HRUD);
- DetectEngineRunHttpRawUriMpm(det_ctx, p->flow, alstate, flags);
- PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HRUD);
- }
- if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HCBD) {
- PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HCBD);
- DetectEngineRunHttpClientBodyMpm(de_ctx, det_ctx, p->flow, alstate, flags);
- PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HCBD);
- }
- if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HMD) {
- PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HMD);
- DetectEngineRunHttpMethodMpm(det_ctx, p->flow, alstate, flags);
- PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HMD);
- }
- if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HUAD) {
- PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HUAD);
- DetectEngineRunHttpUAMpm(det_ctx, p->flow, alstate, flags);
- PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HUAD);
- }
- if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HHHD) {
- PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HHHD);
- DetectEngineRunHttpHHMpm(det_ctx, p->flow, alstate, flags);
- PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HHHD);
- }
- if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HRHHD) {
- PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HRHHD);
- DetectEngineRunHttpHRHMpm(det_ctx, p->flow, alstate, flags);
- PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HRHHD);
- }
- } else { /* implied FLOW_PKT_TOCLIENT */
- if ((p->flowflags & FLOW_PKT_TOCLIENT) && (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HSBD)) {
- PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HSBD);
- DetectEngineRunHttpServerBodyMpm(de_ctx, det_ctx, p->flow, alstate, flags);
- PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HSBD);
- }
- if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HSMD) {
- PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HSMD);
- DetectEngineRunHttpStatMsgMpm(det_ctx, p->flow, alstate, flags);
- PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HSMD);
- }
- if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HSCD) {
- PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HSCD);
- DetectEngineRunHttpStatCodeMpm(det_ctx, p->flow, alstate, flags);
- PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HSCD);
- }
- }
- if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HHD) {
- PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HHD);
- DetectEngineRunHttpHeaderMpm(det_ctx, p->flow, alstate, flags);
- PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HHD);
- }
- if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HRHD) {
- PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HRHD);
- DetectEngineRunHttpRawHeaderMpm(det_ctx, p->flow, alstate, flags);
- PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HRHD);
- }
- if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HCD) {
- PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HCD);
- DetectEngineRunHttpCookieMpm(det_ctx, p->flow, alstate, flags);
- PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HCD);
+ if (alstate != NULL && alproto == ALPROTO_HTTP) {
+ FLOWLOCK_WRLOCK(p->flow);
+
+ HtpState *htp_state = (HtpState *)alstate;
+ if (htp_state->connp == NULL) {
+ SCLogDebug("no HTTP connp");
+ FLOWLOCK_UNLOCK(p->flow);
+ return;
}
+
+ int tx_progress = 0;
+ uint64_t idx = AppLayerTransactionGetInspectId(p->flow, flags);
+ uint64_t total_txs = AppLayerGetTxCnt(ALPROTO_HTTP, alstate);
+ for (; idx < total_txs; idx++) {
+ htp_tx_t *tx = AppLayerGetTx(ALPROTO_HTTP, htp_state, idx);
+ if (tx == NULL)
+ continue;
+ tx_progress = AppLayerGetAlstateProgress(ALPROTO_HTTP, tx, 0);
+
+ if (p->flowflags & FLOW_PKT_TOSERVER) {
+ if (tx_progress > TX_PROGRESS_REQ_LINE) {
+ if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_URI) {
+ PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_URI);
+ DetectUricontentInspectMpm(det_ctx, p->flow, alstate, flags, tx, idx);
+ PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_URI);
+ }
+ if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HRUD) {
+ PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HRUD);
+ DetectEngineRunHttpRawUriMpm(det_ctx, p->flow, alstate, flags, tx, idx);
+ PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HRUD);
+ }
+ if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HMD) {
+ PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HMD);
+ DetectEngineRunHttpMethodMpm(det_ctx, p->flow, alstate, flags, tx, idx);
+ PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HMD);
+ }
+ }
+
+ if (tx_progress >= TX_PROGRESS_REQ_HEADERS) {
+ if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HHHD) {
+ PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HHHD);
+ DetectEngineRunHttpHHMpm(det_ctx, p->flow, alstate, flags, tx, idx);
+ PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HHHD);
+ }
+ if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HRHHD) {
+ PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HRHHD);
+ DetectEngineRunHttpHRHMpm(det_ctx, p->flow, alstate, flags, tx, idx);
+ PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HRHHD);
+ }
+ if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HCD) {
+ PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HCD);
+ DetectEngineRunHttpCookieMpm(det_ctx, p->flow, alstate, flags, tx, idx);
+ PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HCD);
+ }
+ if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HUAD) {
+ PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HUAD);
+ DetectEngineRunHttpUAMpm(det_ctx, p->flow, alstate, flags, tx, idx);
+ PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HUAD);
+ }
+ if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HHD) {
+ PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HHD);
+ DetectEngineRunHttpHeaderMpm(det_ctx, p->flow, alstate, flags, tx, idx);
+ PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HHD);
+ }
+ if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HRHD) {
+ PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HRHD);
+ DetectEngineRunHttpRawHeaderMpm(det_ctx, p->flow, alstate, flags, tx, idx);
+ PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HRHD);
+ }
+ }
+
+ if (tx_progress >= TX_PROGRESS_REQ_BODY) {
+ if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HCBD) {
+ PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HCBD);
+ DetectEngineRunHttpClientBodyMpm(de_ctx, det_ctx, p->flow, alstate, flags, tx, idx);
+ PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HCBD);
+ }
+ }
+ } else { /* implied FLOW_PKT_TOCLIENT */
+ tx_progress = AppLayerGetAlstateProgress(ALPROTO_HTTP, tx, 1);
+
+ if (tx_progress > TX_PROGRESS_RES_LINE) {
+ if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HSMD) {
+ PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HSMD);
+ DetectEngineRunHttpStatMsgMpm(det_ctx, p->flow, alstate, flags, tx, idx);
+ PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HSMD);
+ }
+ if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HSCD) {
+ PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HSCD);
+ DetectEngineRunHttpStatCodeMpm(det_ctx, p->flow, alstate, flags, tx, idx);
+ PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HSCD);
+ }
+ }
+
+ if (tx_progress >= TX_PROGRESS_RES_HEADERS) {
+ if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HHD) {
+ PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HHD);
+ DetectEngineRunHttpHeaderMpm(det_ctx, p->flow, alstate, flags, tx, idx);
+ PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HHD);
+ }
+ if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HRHD) {
+ PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HRHD);
+ DetectEngineRunHttpRawHeaderMpm(det_ctx, p->flow, alstate, flags, tx, idx);
+ PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HRHD);
+ }
+ if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HCD) {
+ PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HCD);
+ DetectEngineRunHttpCookieMpm(det_ctx, p->flow, alstate, flags, tx, idx);
+ PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HCD);
+ }
+ }
+
+ if (tx_progress >= TX_PROGRESS_RES_BODY) {
+ if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_HSBD) {
+ PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_HSBD);
+ DetectEngineRunHttpServerBodyMpm(de_ctx, det_ctx, p->flow, alstate, flags, tx, idx);
+ PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_HSBD);
+ }
+ }
+ }
+ } /* for */
+
+ FLOWLOCK_UNLOCK(p->flow);
}
} else {
SCLogDebug("NOT p->flowflags & FLOW_PKT_ESTABLISHED");
{
AppLayerParserStateStore *parser_state_store = f->alparser;
if (parser_state_store != NULL) {
- SCLogDebug("pcap_cnt %02"PRIu64", %s, %12s, avail_id %u, inspect_id %u, inspecting %u, smsg %s",
- p->pcap_cnt, p->flowflags & FLOW_PKT_TOSERVER ? "toserver" : "toclient",
- p->flags & PKT_STREAM_EST ? "established" : "stateless",
- parser_state_store->avail_id, parser_state_store->inspect_id,
- parser_state_store->inspect_id+1, smsg?"yes":"no");
+ SCLogDebug("pcap_cnt %02"PRIu64", %s, %12s, inspect_id(ts) %"PRIu64
+ ", inspect_id(tc) %"PRIu64", smsg %s",
+ p->pcap_cnt, p->flowflags & FLOW_PKT_TOSERVER ? "toserver" : "toclient",
+ p->flags & PKT_STREAM_EST ? "established" : "stateless",
+ parser_state_store->inspect_id[0], parser_state_store->inspect_id[1],
+ smsg?"yes":"no");
//if (smsg)
// PrintRawDataFp(stdout,smsg->data.data, smsg->data.data_len);
#ifdef PROFILING
int smatch = 0; /* signature match: 1, no match: 0 */
#endif
- int fmatch = 0;
uint32_t idx;
uint8_t flags = 0; /* flow/state flags */
void *alstate = NULL;
int reset_de_state = 0;
AppLayerDecoderEvents *app_decoder_events = NULL;
int app_decoder_events_cnt = 0;
+ int alerts = 0;
+ int i;
SCEnter();
/* reset because of ruleswap */
if (reset_de_state) {
SCMutexLock(&p->flow->de_state_m);
- DetectEngineStateReset(p->flow->de_state);
+ DetectEngineStateReset(p->flow->de_state, flags);
SCMutexUnlock(&p->flow->de_state_m);
- /* see if we need to increment the inspect_id and reset the de_state */
- } else if (alstate != NULL && alproto == ALPROTO_HTTP) {
- PACKET_PROFILING_DETECT_START(p, PROF_DETECT_STATEFUL);
- SCLogDebug("getting de_state_status");
- int de_state_status = DeStateUpdateInspectTransactionId(p->flow,
- (flags & STREAM_TOSERVER) ? STREAM_TOSERVER : STREAM_TOCLIENT);
- SCLogDebug("de_state_status %d", de_state_status);
-
- if (de_state_status == 2) {
- SCMutexLock(&p->flow->de_state_m);
- DetectEngineStateReset(p->flow->de_state);
- SCMutexUnlock(&p->flow->de_state_m);
- }
- PACKET_PROFILING_DETECT_END(p, PROF_DETECT_STATEFUL);
}
if (((p->flowflags & FLOW_PKT_TOSERVER) && !(p->flowflags & FLOW_PKT_TOSERVER_IPONLY_SET)) ||
goto end;
}
- /* run the mpm for each type */
- PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM);
- DetectMpmPrefilter(de_ctx, det_ctx, smsg, p, flags, alproto,
- alstate, &sms_runflags);
- PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM);
-
PACKET_PROFILING_DETECT_START(p, PROF_DETECT_STATEFUL);
/* stateful app layer detection */
if ((p->flags & PKT_HAS_FLOW) && alstate != NULL) {
- /* initialize to 0 (DE_STATE_MATCH_NOSTATE) */
+ /* initialize to 0(DE_STATE_MATCH_HAS_NEW_STATE) */
memset(det_ctx->de_state_sig_array, 0x00, det_ctx->de_state_sig_array_len);
-
- /* if applicable, continue stateful detection */
- int state = DeStateFlowHasState(p->flow, flags, alversion);
- if (state == 1 || (flags & STREAM_EOF)) {
- DeStateDetectContinueDetection(th_v, de_ctx, det_ctx, p->flow,
- flags, alstate, alproto, alversion);
- } else if (state == 2) {
+ int has_state = DeStateFlowHasInspectableState(p->flow, alversion, flags);
+ if (has_state == 1) {
+ DeStateDetectContinueDetection(th_v, de_ctx, det_ctx, p, p->flow,
+ flags, alstate, alproto, alversion);
+ } else if (has_state == 2) {
alstate = NULL;
}
}
PACKET_PROFILING_DETECT_END(p, PROF_DETECT_STATEFUL);
+ /* run the mpm for each type */
+ PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM);
+ DetectMpmPrefilter(de_ctx, det_ctx, smsg, p, flags, alproto, alstate, &sms_runflags);
+ PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM);
+
/* create our prefilter mask */
SignatureMask mask = 0;
PacketCreateMask(p, &mask, alproto, alstate, smsg, app_decoder_events_cnt);
/* inspect the sigs against the packet */
for (idx = 0; idx < det_ctx->match_array_cnt; idx++) {
RULE_PROFILING_START;
+ alerts = 0;
#ifdef PROFILING
smatch = 0;
#endif
goto next;
}
- if (det_ctx->de_state_sig_array[s->num] == DE_STATE_MATCH_NOSTATE) {
- SCLogDebug("stateful app layer match inspection starting");
-
- PACKET_PROFILING_DETECT_START(p, PROF_DETECT_STATEFUL);
- int de_r = DeStateDetectStartDetection(th_v, de_ctx, det_ctx, s,
- p->flow, flags, alstate, alproto, alversion);
- PACKET_PROFILING_DETECT_END(p, PROF_DETECT_STATEFUL);
-
- if (de_r != 1) {
- goto next;
- }
- } else {
- SCLogDebug("already having a destate");
-
- SCLogDebug("signature %"PRIu32" (%"PRIuMAX"): %s",
- s->id, (uintmax_t)s->num, DeStateMatchResultToString(det_ctx->de_state_sig_array[s->num]));
- if (det_ctx->de_state_sig_array[s->num] != DE_STATE_MATCH_NEW) {
- goto next;
- }
- }
+ SCLogDebug("stateful app layer match inspection starting");
+ PACKET_PROFILING_DETECT_START(p, PROF_DETECT_STATEFUL);
+ alerts = DeStateDetectStartDetection(th_v, de_ctx, det_ctx, s,
+ p->flow, flags, alstate, alproto, alversion);
+ PACKET_PROFILING_DETECT_END(p, PROF_DETECT_STATEFUL);
+ if (alerts == 0)
+ goto next;
/* match */
if (s->action & ACTION_DROP)
alert_flags |= PACKET_ALERT_FLAG_STATE_MATCH;
}
- /* match! */
- fmatch = 1;
+ /* If we have reached this stage and we don't have any alerts, it
+ * indicates that we didn't have a stateful sig, hence we set alerts
+ * to 1. But if we have an alert set, then the sig is definitely a
+ * stateful sig and we need to retain the no of alerts */
+ alerts = (alerts == 0) ? 1 : alerts;
#ifdef PROFILING
smatch = 1;
#endif
SigMatchSignaturesRunPostMatch(th_v, de_ctx, det_ctx, p, s);
if (!(s->flags & SIG_FLAG_NOALERT)) {
- PacketAlertAppend(det_ctx, s, p, alert_flags);
+ for (i = 0; i < alerts; i++)
+ PacketAlertAppend(det_ctx, s, p, alert_flags);
} else {
/* apply actions even if not alerting */
p->action |= s->action;
end:
/* see if we need to increment the inspect_id and reset the de_state */
- if (alstate != NULL && alproto != ALPROTO_HTTP) {
+ if (alstate != NULL && AppLayerAlprotoSupportsTxs(alproto)) {
PACKET_PROFILING_DETECT_START(p, PROF_DETECT_STATEFUL);
- SCLogDebug("getting de_state_status");
- int de_state_status = DeStateUpdateInspectTransactionId(p->flow,
- (flags & STREAM_TOSERVER) ? STREAM_TOSERVER : STREAM_TOCLIENT);
- SCLogDebug("de_state_status %d", de_state_status);
-
- if (de_state_status == 2) {
- SCMutexLock(&p->flow->de_state_m);
- DetectEngineStateReset(p->flow->de_state);
- SCMutexUnlock(&p->flow->de_state_m);
- }
+ DeStateUpdateInspectTransactionId(p->flow, flags);
PACKET_PROFILING_DETECT_END(p, PROF_DETECT_STATEFUL);
}
}
PACKET_PROFILING_DETECT_END(p, PROF_DETECT_CLEANUP);
- SCReturnInt(fmatch);
+ SCReturnInt((int)(alerts > 0));
}
/* tm module api functions */
uint16_t filestore_cnt;
HttpReassembledBody *hsbd;
- int hsbd_start_tx_id;
+ uint64_t hsbd_start_tx_id;
uint16_t hsbd_buffers_size;
uint16_t hsbd_buffers_list_len;
HttpReassembledBody *hcbd;
- int hcbd_start_tx_id;
+ uint64_t hcbd_start_tx_id;
uint16_t hcbd_buffers_size;
uint16_t hcbd_buffers_list_len;
uint32_t *hhd_buffers_len;
uint16_t hhd_buffers_size;
uint16_t hhd_buffers_list_len;
- int hhd_start_tx_id;
+ uint64_t hhd_start_tx_id;
/** id for alert counter */
uint16_t counter_alerts;
uint16_t flags;
/** ID of the transaction currently being inspected. */
- uint16_t tx_id;
+ uint64_t tx_id;
SC_ATOMIC_DECLARE(uint16_t, so_far_used_by_detect);
* function to finalize the store. */
struct {
uint16_t file_id;
- uint16_t tx_id;
+ uint64_t tx_id;
} filestore[DETECT_FILESTORE_MAX];
DetectEngineCtx *de_ctx;
} SigTableElmt;
-#define SIG_GROUP_HEAD_MPM_COPY (1)
-#define SIG_GROUP_HEAD_MPM_URI_COPY (1 << 1)
-#define SIG_GROUP_HEAD_MPM_STREAM_COPY (1 << 2)
-#define SIG_GROUP_HEAD_FREE (1 << 3)
-#define SIG_GROUP_HEAD_MPM_PACKET (1 << 4)
-#define SIG_GROUP_HEAD_MPM_STREAM (1 << 5)
-#define SIG_GROUP_HEAD_MPM_URI (1 << 6)
-#define SIG_GROUP_HEAD_MPM_HCBD (1 << 7)
-#define SIG_GROUP_HEAD_MPM_HHD (1 << 8)
-#define SIG_GROUP_HEAD_MPM_HRHD (1 << 9)
-#define SIG_GROUP_HEAD_MPM_HMD (1 << 10)
-#define SIG_GROUP_HEAD_MPM_HCD (1 << 11)
-#define SIG_GROUP_HEAD_MPM_HRUD (1 << 12)
-#define SIG_GROUP_HEAD_REFERENCED (1 << 13) /**< sgh is being referenced by others, don't clear */
-#define SIG_GROUP_HEAD_HAVEFILEMAGIC (1 << 14)
-#define SIG_GROUP_HEAD_MPM_HSBD (1 << 15)
-#define SIG_GROUP_HEAD_MPM_HSMD (1 << 16)
-#define SIG_GROUP_HEAD_MPM_HSCD (1 << 17)
-#define SIG_GROUP_HEAD_MPM_HUAD (1 << 18)
-#define SIG_GROUP_HEAD_MPM_HHHD (1 << 19)
-#define SIG_GROUP_HEAD_MPM_HRHHD (1 << 20)
+#define SIG_GROUP_HEAD_MPM_URI (1)
+#define SIG_GROUP_HEAD_MPM_HCBD (1 << 1)
+#define SIG_GROUP_HEAD_MPM_HHD (1 << 2)
+#define SIG_GROUP_HEAD_MPM_HRHD (1 << 3)
+#define SIG_GROUP_HEAD_MPM_HMD (1 << 4)
+#define SIG_GROUP_HEAD_MPM_HCD (1 << 5)
+#define SIG_GROUP_HEAD_MPM_HRUD (1 << 6)
+#define SIG_GROUP_HEAD_MPM_HSBD (1 << 7)
+#define SIG_GROUP_HEAD_MPM_HSMD (1 << 8)
+#define SIG_GROUP_HEAD_MPM_HSCD (1 << 9)
+#define SIG_GROUP_HEAD_MPM_HUAD (1 << 10)
+#define SIG_GROUP_HEAD_MPM_HHHD (1 << 11)
+#define SIG_GROUP_HEAD_MPM_HRHHD (1 << 12)
+
+#define SIG_GROUP_HEAD_MPM_COPY (1 << 13)
+#define SIG_GROUP_HEAD_MPM_URI_COPY (1 << 14)
+#define SIG_GROUP_HEAD_MPM_STREAM_COPY (1 << 15)
+#define SIG_GROUP_HEAD_FREE (1 << 16)
+#define SIG_GROUP_HEAD_MPM_PACKET (1 << 17)
+#define SIG_GROUP_HEAD_MPM_STREAM (1 << 18)
+#define SIG_GROUP_HEAD_REFERENCED (1 << 19) /**< sgh is being referenced by others, don't clear */
+#define SIG_GROUP_HEAD_HAVEFILEMAGIC (1 << 20)
#define SIG_GROUP_HEAD_HAVEFILEMD5 (1 << 21)
#define SIG_GROUP_HEAD_HAVEFILESIZE (1 << 22)
int DetectRegisterThreadCtxFuncs(DetectEngineCtx *, const char *name, void *(*InitFunc)(void *), void *data, void (*FreeFunc)(void *), int);
void *DetectThreadCtxGetKeywordThreadCtx(DetectEngineThreadCtx *, int);
+int SigMatchSignaturesRunPostMatch(ThreadVars *tv,
+ DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p,
+ Signature *s);
+
#endif /* __DETECT_H__ */
(f)->alproto = 0; \
(f)->de_ctx_id = 0; \
if ((f)->de_state != NULL) { \
- DetectEngineStateReset((f)->de_state); \
+ DetectEngineStateReset((f)->de_state, (STREAM_TOSERVER | STREAM_TOCLIENT)); \
} \
(f)->sgh_toserver = NULL; \
(f)->sgh_toclient = NULL; \
static void LogFileMetaGetUri(FILE *fp, Packet *p, File *ff) {
HtpState *htp_state = (HtpState *)p->flow->alstate;
if (htp_state != NULL) {
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, ff->txid);
+ htp_tx_t *tx = AppLayerGetTx(ALPROTO_HTTP, htp_state, ff->txid);
if (tx != NULL && tx->request_uri_normalized != NULL) {
PrintRawJsonFp(fp, (uint8_t *)bstr_ptr(tx->request_uri_normalized),
bstr_len(tx->request_uri_normalized));
static void LogFileMetaGetHost(FILE *fp, Packet *p, File *ff) {
HtpState *htp_state = (HtpState *)p->flow->alstate;
if (htp_state != NULL) {
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, ff->txid);
+ htp_tx_t *tx = AppLayerGetTx(ALPROTO_HTTP, htp_state, ff->txid);
if (tx != NULL) {
table_t *headers;
headers = tx->request_headers;
static void LogFileMetaGetReferer(FILE *fp, Packet *p, File *ff) {
HtpState *htp_state = (HtpState *)p->flow->alstate;
if (htp_state != NULL) {
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, ff->txid);
+ htp_tx_t *tx = AppLayerGetTx(ALPROTO_HTTP, htp_state, ff->txid);
if (tx != NULL) {
table_t *headers;
headers = tx->request_headers;
static void LogFileMetaGetUserAgent(FILE *fp, Packet *p, File *ff) {
HtpState *htp_state = (HtpState *)p->flow->alstate;
if (htp_state != NULL) {
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, ff->txid);
+ htp_tx_t *tx = AppLayerGetTx(ALPROTO_HTTP, htp_state, ff->txid);
if (tx != NULL) {
table_t *headers;
headers = tx->request_headers;
static void LogFilestoreMetaGetUri(FILE *fp, Packet *p, File *ff) {
HtpState *htp_state = (HtpState *)p->flow->alstate;
if (htp_state != NULL) {
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, ff->txid);
+ htp_tx_t *tx = AppLayerGetTx(ALPROTO_HTTP, htp_state, ff->txid);
if (tx != NULL && tx->request_uri_normalized != NULL) {
PrintRawUriFp(fp, (uint8_t *)bstr_ptr(tx->request_uri_normalized),
bstr_len(tx->request_uri_normalized));
static void LogFilestoreMetaGetHost(FILE *fp, Packet *p, File *ff) {
HtpState *htp_state = (HtpState *)p->flow->alstate;
if (htp_state != NULL) {
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, ff->txid);
+ htp_tx_t *tx = AppLayerGetTx(ALPROTO_HTTP, htp_state, ff->txid);
if (tx != NULL) {
table_t *headers;
headers = tx->request_headers;
static void LogFilestoreMetaGetReferer(FILE *fp, Packet *p, File *ff) {
HtpState *htp_state = (HtpState *)p->flow->alstate;
if (htp_state != NULL) {
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, ff->txid);
+ htp_tx_t *tx = AppLayerGetTx(ALPROTO_HTTP, htp_state, ff->txid);
if (tx != NULL) {
table_t *headers;
headers = tx->request_headers;
static void LogFilestoreMetaGetUserAgent(FILE *fp, Packet *p, File *ff) {
HtpState *htp_state = (HtpState *)p->flow->alstate;
if (htp_state != NULL) {
- htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, ff->txid);
+ htp_tx_t *tx = AppLayerGetTx(ALPROTO_HTTP, htp_state, ff->txid);
if (tx != NULL) {
table_t *headers;
headers = tx->request_headers;
{
SCEnter();
+ uint64_t tx_id = 0;
+ uint64_t total_txs = 0;
+ htp_tx_t *tx = NULL;
+ HtpState *htp_state = NULL;
+ int tx_progress = 0;
+ int tx_progress_done_value_ts = 0;
+ int tx_progress_done_value_tc = 0;
LogHttpLogThread *aft = (LogHttpLogThread *)data;
LogHttpFileCtx *hlog = aft->httplog_ctx;
char timebuf[64];
- size_t idx = 0;
/* no flow, no htp state */
if (p->flow == NULL) {
if (proto != ALPROTO_HTTP)
goto end;
- int r = AppLayerTransactionGetLoggedId(p->flow);
- if (r < 0) {
- goto end;
- }
- size_t logged = (size_t)r;
-
- r = HtpTransactionGetLoggableId(p->flow);
- if (r < 0) {
- goto end;
- }
- size_t loggable = (size_t)r;
-
- /* nothing to do */
- if (logged >= loggable) {
- goto end;
- }
-
- HtpState *htp_state = (HtpState *)AppLayerGetProtoStateFromPacket(p);
+ htp_state = (HtpState *)AppLayerGetProtoStateFromPacket(p);
if (htp_state == NULL) {
SCLogDebug("no http state, so no request logging");
goto end;
}
+ total_txs = AppLayerGetTxCnt(ALPROTO_HTTP, htp_state);
+ tx_id = AppLayerTransactionGetLogId(p->flow);
+ tx_progress_done_value_ts = AppLayerGetAlstateProgressCompletionStatus(ALPROTO_HTTP, 0);
+ tx_progress_done_value_tc = AppLayerGetAlstateProgressCompletionStatus(ALPROTO_HTTP, 1);
+
if (htp_state->connp == NULL || htp_state->connp->conn == NULL)
goto end;
- htp_tx_t *tx = NULL;
-
CreateTimeString(&p->ts, timebuf, sizeof(timebuf));
char srcip[46], dstip[46];
dp = p->sp;
}
- for (idx = logged; idx < loggable; idx++)
+ for (; tx_id < total_txs; tx_id++)
{
- tx = list_get(htp_state->connp->conn->transactions, idx);
+ tx = AppLayerGetTx(ALPROTO_HTTP, htp_state, tx_id);
if (tx == NULL) {
SCLogDebug("tx is NULL not logging !!");
continue;
}
+ if (!(((AppLayerParserStateStore *)p->flow->alparser)->id_flags & APP_LAYER_TRANSACTION_EOF)) {
+ tx_progress = AppLayerGetAlstateProgress(ALPROTO_HTTP, tx, 0);
+ if (tx_progress < tx_progress_done_value_ts)
+ break;
+
+ tx_progress = AppLayerGetAlstateProgress(ALPROTO_HTTP, tx, 1);
+ if (tx_progress < tx_progress_done_value_tc)
+ break;
+ }
+
SCLogDebug("got a HTTP request and now logging !!");
/* reset */
fflush(hlog->file_ctx->fp);
SCMutexUnlock(&hlog->file_ctx->fp_mutex);
- AppLayerTransactionUpdateLoggedId(p->flow);
+ AppLayerTransactionUpdateLogId(p->flow);
}
end:
LogTlsLogPem(aft, p, ssl_state, hlog, ipproto);
}
- int r = AppLayerTransactionGetLoggedId(p->flow);
-
- if (r != 0) {
+ if (AppLayerTransactionGetLogId(p->flow) != 0) {
goto end;
}
timebuf, srcip, sp, dstip, dp,
ssl_state->server_connp.cert0_subject, ssl_state->server_connp.cert0_issuerdn);
- AppLayerTransactionUpdateLoggedId(p->flow);
+ AppLayerTransactionUpdateLogId(p->flow);
if (hlog->flags & LOG_TLS_EXTENDED) {
LogTlsLogExtended(aft, ssl_state);
* \param ff The file to store
* \param txid the tx id
*/
-int FileSetTx(File *ff, uint16_t txid) {
- SCLogDebug("ff %p txid %"PRIu16, ff, txid);
+int FileSetTx(File *ff, uint64_t txid) {
+ SCLogDebug("ff %p txid %"PRIu64, ff, txid);
if (ff != NULL)
ff->txid = txid;
SCReturnInt(0);
* \param direction flow direction
* \param tx_id transaction id
*/
-void FileDisableStoringForTransaction(Flow *f, uint8_t direction, uint16_t tx_id) {
+void FileDisableStoringForTransaction(Flow *f, uint8_t direction, uint64_t tx_id) {
File *ptr = NULL;
DEBUG_ASSERT_FLOW_LOCKED(f);
typedef struct File_ {
uint16_t flags;
- uint16_t txid; /**< tx this file is part of */
+ uint64_t txid; /**< tx this file is part of */
unsigned int file_id;
uint8_t *name;
uint16_t name_len;
* \param ff The file to store
* \param txid the tx id
*/
-int FileSetTx(File *, uint16_t txid);
+int FileSetTx(File *, uint64_t txid);
/**
* \brief disable file storage for a flow
* \param f flow
* \param tx_id transaction id
*/
-void FileDisableStoringForTransaction(struct Flow_ *, uint8_t, uint16_t);
+void FileDisableStoringForTransaction(Flow *f, uint8_t direction, uint64_t tx_id);
void FlowFileDisableStoringForTransaction(struct Flow_ *f, uint16_t tx_id);
void FilePrune(FileContainer *ffc);