app-layer/template: code cleanups

pull/3487/head
Victor Julien 7 years ago
parent 33914c2f2f
commit a013cece69

@ -36,25 +36,24 @@
#include "suricata-common.h" #include "suricata-common.h"
#include "stream.h" #include "stream.h"
#include "conf.h" #include "conf.h"
#include "util-unittest.h"
#include "app-layer-detect-proto.h" #include "app-layer-detect-proto.h"
#include "app-layer-parser.h" #include "app-layer-parser.h"
#include "app-layer-template.h" #include "app-layer-template.h"
#include "util-unittest.h"
/* The default port to probe for echo traffic if not provided in the /* The default port to probe for echo traffic if not provided in the
* configuration file. */ * configuration file. */
#define TEMPLATE_DEFAULT_PORT "7" #define TEMPLATE_DEFAULT_PORT "7"
/* The minimum size for an echo message. For some protocols this might /* The minimum size for a message. For some protocols this might
* be the size of a header. */ * be the size of a header. */
#define TEMPLATE_MIN_FRAME_LEN 1 #define TEMPLATE_MIN_FRAME_LEN 1
/* Enum of app-layer events for an echo protocol. Normally you might /* Enum of app-layer events for the protocol. Normally you might
* have events for errors in parsing data, like unexpected data being * have events for errors in parsing data, like unexpected data being
* received. For echo we'll make something up, and log an app-layer * received. For template we'll make something up, and log an app-layer
* level alert if an empty message is received. * level alert if an empty message is received.
* *
* Example rule: * Example rule:
@ -73,7 +72,7 @@ SCEnumCharMap template_decoder_event_table[] = {
{ NULL, -1 }, { NULL, -1 },
}; };
static TemplateTransaction *TemplateTxAlloc(TemplateState *echo) static TemplateTransaction *TemplateTxAlloc(TemplateState *state)
{ {
TemplateTransaction *tx = SCCalloc(1, sizeof(TemplateTransaction)); TemplateTransaction *tx = SCCalloc(1, sizeof(TemplateTransaction));
if (unlikely(tx == NULL)) { if (unlikely(tx == NULL)) {
@ -82,26 +81,26 @@ static TemplateTransaction *TemplateTxAlloc(TemplateState *echo)
/* Increment the transaction ID on the state each time one is /* Increment the transaction ID on the state each time one is
* allocated. */ * allocated. */
tx->tx_id = echo->transaction_max++; tx->tx_id = state->transaction_max++;
TAILQ_INSERT_TAIL(&echo->tx_list, tx, next); TAILQ_INSERT_TAIL(&state->tx_list, tx, next);
return tx; return tx;
} }
static void TemplateTxFree(void *tx) static void TemplateTxFree(void *txv)
{ {
TemplateTransaction *templatetx = tx; TemplateTransaction *tx = txv;
if (templatetx->request_buffer != NULL) { if (tx->request_buffer != NULL) {
SCFree(templatetx->request_buffer); SCFree(tx->request_buffer);
} }
if (templatetx->response_buffer != NULL) { if (tx->response_buffer != NULL) {
SCFree(templatetx->response_buffer); SCFree(tx->response_buffer);
} }
AppLayerDecoderEventsFreeEvents(&templatetx->decoder_events); AppLayerDecoderEventsFreeEvents(&tx->decoder_events);
SCFree(tx); SCFree(tx);
} }
@ -135,14 +134,14 @@ static void TemplateStateFree(void *state)
* \param state a void pointer to the TemplateState object. * \param state a void pointer to the TemplateState object.
* \param tx_id the transaction ID to free. * \param tx_id the transaction ID to free.
*/ */
static void TemplateStateTxFree(void *state, uint64_t tx_id) static void TemplateStateTxFree(void *statev, uint64_t tx_id)
{ {
TemplateState *echo = state; TemplateState *state = statev;
TemplateTransaction *tx = NULL, *ttx; TemplateTransaction *tx = NULL, *ttx;
SCLogNotice("Freeing transaction %"PRIu64, tx_id); SCLogNotice("Freeing transaction %"PRIu64, tx_id);
TAILQ_FOREACH_SAFE(tx, &echo->tx_list, next, ttx) { TAILQ_FOREACH_SAFE(tx, &state->tx_list, next, ttx) {
/* Continue if this is not the transaction we are looking /* Continue if this is not the transaction we are looking
* for. */ * for. */
@ -151,7 +150,7 @@ static void TemplateStateTxFree(void *state, uint64_t tx_id)
} }
/* Remove and free the transaction. */ /* Remove and free the transaction. */
TAILQ_REMOVE(&echo->tx_list, tx, next); TAILQ_REMOVE(&state->tx_list, tx, next);
TemplateTxFree(tx); TemplateTxFree(tx);
return; return;
} }
@ -175,12 +174,12 @@ static int TemplateStateGetEventInfo(const char *event_name, int *event_id,
return 0; return 0;
} }
static AppLayerDecoderEvents *TemplateGetEvents(void *state, uint64_t tx_id) static AppLayerDecoderEvents *TemplateGetEvents(void *statev, uint64_t tx_id)
{ {
TemplateState *template_state = state; TemplateState *state = statev;
TemplateTransaction *tx; TemplateTransaction *tx;
TAILQ_FOREACH(tx, &template_state->tx_list, next) { TAILQ_FOREACH(tx, &state->tx_list, next) {
if (tx->tx_id == tx_id) { if (tx->tx_id == tx_id) {
return tx->decoder_events; return tx->decoder_events;
} }
@ -190,14 +189,14 @@ static AppLayerDecoderEvents *TemplateGetEvents(void *state, uint64_t tx_id)
} }
/** /**
* \brief Probe the input to see if it looks like echo. * \brief Probe the input to see if it looks like template.
* *
* \retval ALPROTO_TEMPLATE if it looks like echo, otherwise * \retval ALPROTO_TEMPLATE if it looks like template, otherwise
* ALPROTO_UNKNOWN. * ALPROTO_UNKNOWN.
*/ */
static AppProto TemplateProbingParser(Flow *f, uint8_t *input, uint32_t input_len) static AppProto TemplateProbingParser(Flow *f, uint8_t *input, uint32_t input_len)
{ {
/* Very simple test - if there is input, this is echo. */ /* Very simple test - if there is input, this is template. */
if (input_len >= TEMPLATE_MIN_FRAME_LEN) { if (input_len >= TEMPLATE_MIN_FRAME_LEN) {
SCLogNotice("Detected as ALPROTO_TEMPLATE."); SCLogNotice("Detected as ALPROTO_TEMPLATE.");
return ALPROTO_TEMPLATE; return ALPROTO_TEMPLATE;
@ -207,13 +206,13 @@ static AppProto TemplateProbingParser(Flow *f, uint8_t *input, uint32_t input_le
return ALPROTO_UNKNOWN; return ALPROTO_UNKNOWN;
} }
static int TemplateParseRequest(Flow *f, void *state, static int TemplateParseRequest(Flow *f, void *statev,
AppLayerParserState *pstate, uint8_t *input, uint32_t input_len, AppLayerParserState *pstate, uint8_t *input, uint32_t input_len,
void *local_data, const uint8_t flags) void *local_data, const uint8_t flags)
{ {
TemplateState *echo = state; TemplateState *state = statev;
SCLogNotice("Parsing echo request: len=%"PRIu32, input_len); SCLogNotice("Parsing template request: len=%"PRIu32, input_len);
/* Likely connection closed, we can just return here. */ /* Likely connection closed, we can just return here. */
if ((input == NULL || input_len == 0) && if ((input == NULL || input_len == 0) &&
@ -247,13 +246,13 @@ static int TemplateParseRequest(Flow *f, void *state,
* may need to look for the transaction that this newly recieved * may need to look for the transaction that this newly recieved
* data belongs to. * data belongs to.
*/ */
TemplateTransaction *tx = TemplateTxAlloc(echo); TemplateTransaction *tx = TemplateTxAlloc(state);
if (unlikely(tx == NULL)) { if (unlikely(tx == NULL)) {
SCLogNotice("Failed to allocate new Template tx."); SCLogNotice("Failed to allocate new Template tx.");
goto end; goto end;
} }
SCLogNotice("Allocated Template tx %"PRIu64".", tx->tx_id); SCLogNotice("Allocated Template tx %"PRIu64".", tx->tx_id);
/* Make a copy of the request. */ /* Make a copy of the request. */
tx->request_buffer = SCCalloc(1, input_len); tx->request_buffer = SCCalloc(1, input_len);
if (unlikely(tx->request_buffer == NULL)) { if (unlikely(tx->request_buffer == NULL)) {
@ -269,19 +268,18 @@ static int TemplateParseRequest(Flow *f, void *state,
SCLogNotice("Creating event for empty message."); SCLogNotice("Creating event for empty message.");
AppLayerDecoderEventsSetEventRaw(&tx->decoder_events, AppLayerDecoderEventsSetEventRaw(&tx->decoder_events,
TEMPLATE_DECODER_EVENT_EMPTY_MESSAGE); TEMPLATE_DECODER_EVENT_EMPTY_MESSAGE);
echo->events++;
} }
end: end:
return 0; return 0;
} }
static int TemplateParseResponse(Flow *f, void *state, AppLayerParserState *pstate, static int TemplateParseResponse(Flow *f, void *statev, AppLayerParserState *pstate,
uint8_t *input, uint32_t input_len, void *local_data, uint8_t *input, uint32_t input_len, void *local_data,
const uint8_t flags) const uint8_t flags)
{ {
TemplateState *echo = state; TemplateState *state = statev;
TemplateTransaction *tx = NULL, *ttx;; TemplateTransaction *tx = NULL, *ttx;
SCLogNotice("Parsing Template response."); SCLogNotice("Parsing Template response.");
@ -304,18 +302,18 @@ static int TemplateParseResponse(Flow *f, void *state, AppLayerParserState *psta
/* We should just grab the last transaction, but this is to /* We should just grab the last transaction, but this is to
* illustrate how you might traverse the transaction list to find * illustrate how you might traverse the transaction list to find
* the transaction associated with this response. */ * the transaction associated with this response. */
TAILQ_FOREACH(ttx, &echo->tx_list, next) { TAILQ_FOREACH(ttx, &state->tx_list, next) {
tx = ttx; tx = ttx;
} }
if (tx == NULL) { if (tx == NULL) {
SCLogNotice("Failed to find transaction for response on echo state %p.", SCLogNotice("Failed to find transaction for response on state %p.",
echo); state);
goto end; goto end;
} }
SCLogNotice("Found transaction %"PRIu64" for response on echo state %p.", SCLogNotice("Found transaction %"PRIu64" for response on state %p.",
tx->tx_id, echo); tx->tx_id, state);
/* If the protocol requires multiple chunks of data to complete, you may /* If the protocol requires multiple chunks of data to complete, you may
* run into the case where you have existing response data. * run into the case where you have existing response data.
@ -345,21 +343,21 @@ end:
return 0; return 0;
} }
static uint64_t TemplateGetTxCnt(void *state) static uint64_t TemplateGetTxCnt(void *statev)
{ {
TemplateState *echo = state; const TemplateState *state = statev;
SCLogNotice("Current tx count is %"PRIu64".", echo->transaction_max); SCLogNotice("Current tx count is %"PRIu64".", state->transaction_max);
return echo->transaction_max; return state->transaction_max;
} }
static void *TemplateGetTx(void *state, uint64_t tx_id) static void *TemplateGetTx(void *statev, uint64_t tx_id)
{ {
TemplateState *echo = state; TemplateState *state = statev;
TemplateTransaction *tx; TemplateTransaction *tx;
SCLogNotice("Requested tx ID %"PRIu64".", tx_id); SCLogNotice("Requested tx ID %"PRIu64".", tx_id);
TAILQ_FOREACH(tx, &echo->tx_list, next) { TAILQ_FOREACH(tx, &state->tx_list, next) {
if (tx->tx_id == tx_id) { if (tx->tx_id == tx_id) {
SCLogNotice("Transaction %"PRIu64" found, returning tx object %p.", SCLogNotice("Transaction %"PRIu64" found, returning tx object %p.",
tx_id, tx); tx_id, tx);
@ -379,7 +377,7 @@ static void TemplateSetTxLogged(void *state, void *vtx, LoggerId logged)
static LoggerId TemplateGetTxLogged(void *state, void *vtx) static LoggerId TemplateGetTxLogged(void *state, void *vtx)
{ {
TemplateTransaction *tx = (TemplateTransaction *)vtx; const TemplateTransaction *tx = (TemplateTransaction *)vtx;
return tx->logged; return tx->logged;
} }
@ -405,18 +403,18 @@ static int TemplateGetAlstateProgressCompletionStatus(uint8_t direction) {
* needs to be seen. The response_done flag is set on response for * needs to be seen. The response_done flag is set on response for
* checking here. * checking here.
*/ */
static int TemplateGetStateProgress(void *tx, uint8_t direction) static int TemplateGetStateProgress(void *txv, uint8_t direction)
{ {
TemplateTransaction *echotx = tx; TemplateTransaction *tx = txv;
SCLogNotice("Transaction progress requested for tx ID %"PRIu64 SCLogNotice("Transaction progress requested for tx ID %"PRIu64
", direction=0x%02x", echotx->tx_id, direction); ", direction=0x%02x", tx->tx_id, direction);
if (direction & STREAM_TOCLIENT && echotx->response_done) { if (direction & STREAM_TOCLIENT && tx->response_done) {
return 1; return 1;
} }
else if (direction & STREAM_TOSERVER) { else if (direction & STREAM_TOSERVER) {
/* For echo, just the existence of the transaction means the /* For the template, just the existence of the transaction means the
* request is done. */ * request is done. */
return 1; return 1;
} }
@ -425,7 +423,7 @@ static int TemplateGetStateProgress(void *tx, uint8_t direction)
} }
/** /**
* \brief ??? * \brief retrieve the detection engine per tx state
*/ */
static DetectEngineState *TemplateGetTxDetectState(void *vtx) static DetectEngineState *TemplateGetTxDetectState(void *vtx)
{ {
@ -434,7 +432,7 @@ static DetectEngineState *TemplateGetTxDetectState(void *vtx)
} }
/** /**
* \brief ??? * \brief get the detection engine per tx state
*/ */
static int TemplateSetTxDetectState(void *vtx, static int TemplateSetTxDetectState(void *vtx,
DetectEngineState *s) DetectEngineState *s)
@ -474,7 +472,7 @@ void RegisterTemplateParsers(void)
if (!AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP, if (!AppLayerProtoDetectPPParseConfPorts("tcp", IPPROTO_TCP,
proto_name, ALPROTO_TEMPLATE, 0, TEMPLATE_MIN_FRAME_LEN, proto_name, ALPROTO_TEMPLATE, 0, TEMPLATE_MIN_FRAME_LEN,
TemplateProbingParser, NULL)) { TemplateProbingParser, NULL)) {
SCLogNotice("No echo app-layer configuration, enabling echo" SCLogNotice("No template app-layer configuration, enabling echo"
" detection TCP detection on port %s.", " detection TCP detection on port %s.",
TEMPLATE_DEFAULT_PORT); TEMPLATE_DEFAULT_PORT);
AppLayerProtoDetectPPRegister(IPPROTO_TCP, AppLayerProtoDetectPPRegister(IPPROTO_TCP,
@ -492,7 +490,7 @@ void RegisterTemplateParsers(void)
return; return;
} }
if (AppLayerParserConfParserEnabled("udp", proto_name)) { if (AppLayerParserConfParserEnabled("tcp", proto_name)) {
SCLogNotice("Registering Template protocol parser."); SCLogNotice("Registering Template protocol parser.");

@ -1,4 +1,4 @@
/* Copyright (C) 2015 Open Information Security Foundation /* Copyright (C) 2015-2018 Open Information Security Foundation
* *
* You can copy, redistribute or modify this Program under the terms of * You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free * the GNU General Public License version 2 as published by the Free
@ -31,20 +31,20 @@
void RegisterTemplateParsers(void); void RegisterTemplateParsers(void);
void TemplateParserRegisterTests(void); void TemplateParserRegisterTests(void);
typedef struct TemplateTransaction_ { typedef struct TemplateTransaction
{
/** Internal transaction ID. */
uint64_t tx_id;
uint64_t tx_id; /*<< Internal transaction ID. */ /** Application layer events that occurred
* while parsing this transaction. */
AppLayerDecoderEvents *decoder_events; /*<< Application layer AppLayerDecoderEvents *decoder_events;
* events that occurred
* while parsing this
* transaction. */
uint8_t *request_buffer; uint8_t *request_buffer;
uint32_t request_buffer_len; uint32_t request_buffer_len;
/* flags indicating which loggers that have logged */ /** flags indicating which loggers that have logged */
uint32_t logged; LoggerId logged;
uint8_t *response_buffer; uint8_t *response_buffer;
uint32_t response_buffer_len; uint32_t response_buffer_len;
@ -54,25 +54,20 @@ typedef struct TemplateTransaction_ {
DetectEngineState *de_state; DetectEngineState *de_state;
TAILQ_ENTRY(TemplateTransaction_) next; TAILQ_ENTRY(TemplateTransaction) next;
} TemplateTransaction; } TemplateTransaction;
typedef struct TemplateState_ { typedef struct TemplateState {
TAILQ_HEAD(, TemplateTransaction_) tx_list; /**< List of Template transactions
* associated with this
* state. */
uint64_t transaction_max; /**< A count of the number of
* transactions created. The
* transaction ID for each transaction
* is allocted by incrementing this
* value. */
uint16_t events; /**< Number of application layer events created /** List of Template transactions associated with this
* for this state. */ * state. */
TAILQ_HEAD(, TemplateTransaction) tx_list;
/** A count of the number of transactions created. The
* transaction ID for each transaction is allocted
* by incrementing this value. */
uint64_t transaction_max;
} TemplateState; } TemplateState;
#endif /* __APP_LAYER_TEMPLATE_H__ */ #endif /* __APP_LAYER_TEMPLATE_H__ */

Loading…
Cancel
Save