app layer error handling

remotes/origin/master-1.0.x
Gurvinder Singh 16 years ago committed by Victor Julien
parent 43fb771268
commit c1e485cc44

@ -130,9 +130,6 @@
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION

@ -12,6 +12,7 @@
#include "util-print.h"
#include "util-pool.h"
#include "util-debug.h"
#include "stream-tcp-private.h"
#include "stream-tcp-reassemble.h"
@ -80,6 +81,8 @@ static int DCERPCParseBINDACK(void *dcerpc_state, AppLayerParserState *pstate, u
#endif
static int DCERPCParseHeader(void *dcerpc_state, AppLayerParserState *pstate, uint8_t *input, uint32_t input_len, AppLayerParserResult *output) {
SCEnter();
DCERPCState *sstate = (DCERPCState *)dcerpc_state;
uint8_t *p = input;
//hexdump(p, input_len);
@ -87,8 +90,8 @@ static int DCERPCParseHeader(void *dcerpc_state, AppLayerParserState *pstate, ui
switch (sstate->bytesprocessed) {
case 0:
if (input_len >= DCERPC_HDR_LEN) {
//if (*p != 5) return 1;
//if (!(*(p + 1 ) == 0 || (*(p + 1) == 1))) return 2;
//if (*p != 5) SCReturnInt(1);
//if (!(*(p + 1 ) == 0 || (*(p + 1) == 1))) SCReturnInt(2);
sstate->dcerpc.rpc_vers = *p;
sstate->dcerpc.rpc_vers_minor = *(p + 1);
sstate->dcerpc.type = *(p + 2);
@ -106,17 +109,17 @@ static int DCERPCParseHeader(void *dcerpc_state, AppLayerParserState *pstate, ui
sstate->dcerpc.call_id |= *(p + 14) << 8;
sstate->dcerpc.call_id |= *(p + 15);
sstate->bytesprocessed = 16;
return 1;
SCReturnInt(1);
break;
} else {
sstate->dcerpc.rpc_vers = *(p++);
// if (sstate->dcerpc.rpc_vers != 5) return 2;
// if (sstate->dcerpc.rpc_vers != 5) SCReturnInt(2);
if (!(--input_len)) break;
}
case 1:
sstate->dcerpc.rpc_vers_minor = *(p++);
if ((sstate->dcerpc.rpc_vers_minor != 0) ||
(sstate->dcerpc.rpc_vers_minor != 1)) return 3;
(sstate->dcerpc.rpc_vers_minor != 1)) SCReturnInt(3);
if (!(--input_len)) break;
case 2:
sstate->dcerpc.type = *(p++);
@ -162,36 +165,41 @@ static int DCERPCParseHeader(void *dcerpc_state, AppLayerParserState *pstate, ui
--input_len;
break;
default: // SHOULD NEVER OCCUR
printf("Odd\n");
return 8;
SCLogDebug("Odd");
SCReturnInt(8);
}
}
sstate->bytesprocessed += (p - input);
return 0;
SCReturnInt(0);
}
static int DCERPCParse(void *dcerpc_state, AppLayerParserState *pstate, uint8_t *input, uint32_t input_len, AppLayerParserResult *output) {
SCEnter();
// DCERPCState *sstate = (DCERPCState *)dcerpc_state;
uint16_t max_fields = 3;
uint16_t u = 0;
uint32_t offset = 0;
if (pstate == NULL)
return -1;
SCReturnInt(-1);
for (u = pstate->parse_field; u < max_fields; u++) {
printf("DCERPCParse: u %" PRIu32 "\n", u);
switch(u) {
case 0:
{
int r = AlpParseFieldBySize(output, pstate, DCERPC_PARSE_DCERPC_HEADER, DCERPC_HDR_LEN, input, input_len, &offset);
if (r == 0) {
pstate->parse_field = 0;
return 0;
}
break;
{
int r = AlpParseFieldBySize(output, pstate, DCERPC_PARSE_DCERPC_HEADER, DCERPC_HDR_LEN, input, input_len, &offset);
if (r == 0) {
pstate->parse_field = 0;
SCReturnInt(0);
} else if (r == -1) {
SCLogError(SC_ALPARSER_ERR, "AlpParseFieldBySize failed, "
"r %d", r);
SCReturnInt(-1);
}
break;
}
}
}
@ -200,7 +208,7 @@ static int DCERPCParse(void *dcerpc_state, AppLayerParserState *pstate, uint8_t
pstate->parse_field = 0;
pstate->flags |= APP_LAYER_PARSER_DONE;
return 1;
SCReturnInt(1);
}

@ -301,8 +301,11 @@ end:
return proto;
}
int AppLayerHandleMsg(StreamMsg *smsg, char need_lock) {
int AppLayerHandleMsg(StreamMsg *smsg, char need_lock)
{
SCEnter();
uint16_t alproto = ALPROTO_UNKNOWN;
int r = 0;
if (need_lock == TRUE) mutex_lock(&smsg->flow->m);
TcpSession *ssn = smsg->flow->protoctx;
@ -313,13 +316,15 @@ int AppLayerHandleMsg(StreamMsg *smsg, char need_lock) {
if (ssn != NULL) {
if (smsg->flags & STREAM_START) {
//printf("L7AppDetectThread: stream initializer (len %" PRIu32 " (%" PRIu32 "))\n", smsg->data.data_len, MSG_DATA_SIZE);
SCLogDebug("Stream initializer (len %" PRIu32 " (%" PRIu32 "))",
smsg->data.data_len, MSG_DATA_SIZE);
//printf("=> Init Stream Data -- start\n");
//PrintRawDataFp(stdout, smsg->init.data, smsg->init.data_len);
//printf("=> Init Stream Data -- end\n");
alproto = AppLayerDetectGetProto(&alp_proto_ctx, &alp_proto_tctx, smsg->data.data, smsg->data.data_len, smsg->flags);
alproto = AppLayerDetectGetProto(&alp_proto_ctx, &alp_proto_tctx,
smsg->data.data, smsg->data.data_len, smsg->flags);
if (alproto != ALPROTO_UNKNOWN) {
/* store the proto and setup the L7 data array */
if (need_lock == TRUE) mutex_lock(&smsg->flow->m);
@ -327,10 +332,12 @@ int AppLayerHandleMsg(StreamMsg *smsg, char need_lock) {
ssn->alproto = alproto;
if (need_lock == TRUE) mutex_unlock(&smsg->flow->m);
AppLayerParse(smsg->flow, alproto, smsg->flags, smsg->data.data, smsg->data.data_len, need_lock);
r = AppLayerParse(smsg->flow, alproto, smsg->flags,
smsg->data.data, smsg->data.data_len, need_lock);
}
} else {
//printf("AppLayerDetectThread: stream data (len %" PRIu32 " (%" PRIu32 ")), alproto %"PRIu16"\n", smsg->data.data_len, MSG_DATA_SIZE, alproto);
SCLogDebug("stream data (len %" PRIu32 " (%" PRIu32 ")), alproto "
"%"PRIu16"", smsg->data.data_len, MSG_DATA_SIZE, alproto);
//printf("=> Stream Data -- start\n");
//PrintRawDataFp(stdout, smsg->data.data, smsg->data.data_len);
@ -339,9 +346,10 @@ int AppLayerHandleMsg(StreamMsg *smsg, char need_lock) {
/* if we don't have a data object here we are not getting it
* a start msg should have gotten us one */
if (alproto != ALPROTO_UNKNOWN) {
AppLayerParse(smsg->flow, alproto, smsg->flags, smsg->data.data, smsg->data.data_len, need_lock);
r = AppLayerParse(smsg->flow, alproto, smsg->flags,
smsg->data.data, smsg->data.data_len, need_lock);
} else {
//printf("AppLayerDetectThread: smsg not start, but no l7 data? Weird\n");
SCLogDebug(" smsg not start, but no l7 data? Weird");
}
}
}
@ -353,7 +361,7 @@ int AppLayerHandleMsg(StreamMsg *smsg, char need_lock) {
/* return the used message to the queue */
StreamMsgReturnToPool(smsg);
return 0;
SCReturnInt(r);
}
void *AppLayerDetectProtoThread(void *td)

@ -2,6 +2,7 @@
#include "eidps-common.h"
#include "debug.h"
#include "util-unittest.h"
#include "decode.h"
#include "threads.h"
@ -22,8 +23,10 @@
static Pool *al_result_pool = NULL;
/** \brief Alloc a AppLayerParserResultElmt func for the pool */
static void *AlpResultElmtPoolAlloc(void *null) {
AppLayerParserResultElmt *e = (AppLayerParserResultElmt *)malloc(sizeof(AppLayerParserResultElmt));
static void *AlpResultElmtPoolAlloc(void *null)
{
AppLayerParserResultElmt *e = (AppLayerParserResultElmt *)malloc
(sizeof(AppLayerParserResultElmt));
if (e == NULL) {
return NULL;
}
@ -32,7 +35,8 @@ static void *AlpResultElmtPoolAlloc(void *null) {
return e;
}
static void AlpResultElmtPoolFree(void *e) {
static void AlpResultElmtPoolFree(void *e)
{
AppLayerParserResultElmt *re = (AppLayerParserResultElmt *)e;
if (re->flags & ALP_RESULT_ELMT_ALLOC) {
@ -42,7 +46,8 @@ static void AlpResultElmtPoolFree(void *e) {
free(re);
}
static AppLayerParserResultElmt *AlpGetResultElmt(void) {
static AppLayerParserResultElmt *AlpGetResultElmt(void)
{
AppLayerParserResultElmt *e = (AppLayerParserResultElmt *)PoolGet(al_result_pool);
if (e == NULL) {
return NULL;
@ -51,7 +56,8 @@ static AppLayerParserResultElmt *AlpGetResultElmt(void) {
return e;
}
static void AlpReturnResultElmt(AppLayerParserResultElmt *e) {
static void AlpReturnResultElmt(AppLayerParserResultElmt *e)
{
if (e->flags & ALP_RESULT_ELMT_ALLOC) {
if (e->data_ptr != NULL)
free(e->data_ptr);
@ -64,7 +70,8 @@ static void AlpReturnResultElmt(AppLayerParserResultElmt *e) {
PoolReturn(al_result_pool, (void *)e);
}
static void AlpAppendResultElmt(AppLayerParserResult *r, AppLayerParserResultElmt *e) {
static void AlpAppendResultElmt(AppLayerParserResult *r, AppLayerParserResultElmt *e)
{
if (r->head == NULL) {
r->head = e;
r->tail = e;
@ -81,7 +88,9 @@ static void AlpAppendResultElmt(AppLayerParserResult *r, AppLayerParserResultElm
* \retval -1 error
* \retval 0 ok
*/
static int AlpStoreField(AppLayerParserResult *output, uint16_t idx, uint8_t *ptr, uint32_t len, uint8_t alloc) {
static int AlpStoreField(AppLayerParserResult *output, uint16_t idx,
uint8_t *ptr, uint32_t len, uint8_t alloc)
{
SCEnter();
AppLayerParserResultElmt *e = AlpGetResultElmt();
@ -105,7 +114,10 @@ static int AlpStoreField(AppLayerParserResult *output, uint16_t idx, uint8_t *pt
* \retval 0 Field parsing in progress.
* \retval -1 error
*/
int AlpParseFieldBySize(AppLayerParserResult *output, AppLayerParserState *pstate, uint16_t field_idx, uint32_t size, uint8_t *input, uint32_t input_len, uint32_t *offset) {
int AlpParseFieldBySize(AppLayerParserResult *output, AppLayerParserState *pstate,
uint16_t field_idx, uint32_t size, uint8_t *input,
uint32_t input_len, uint32_t *offset)
{
SCEnter();
if ((pstate->store_len + input_len) < size) {
@ -146,7 +158,8 @@ int AlpParseFieldBySize(AppLayerParserResult *output, AppLayerParserState *pstat
memcpy(pstate->store+pstate->store_len, input, diff);
pstate->store_len += diff;
int r = AlpStoreField(output, field_idx, pstate->store, pstate->store_len, /* alloc mem */1);
int r = AlpStoreField(output, field_idx, pstate->store,
pstate->store_len, /* alloc mem */1);
if (r == -1) {
SCReturnInt(-1);
}
@ -169,7 +182,9 @@ int AlpParseFieldBySize(AppLayerParserResult *output, AppLayerParserState *pstat
* \retval 0 Field parsing in progress.
* \retval -1 error
*/
int AlpParseFieldByEOF(AppLayerParserResult *output, AppLayerParserState *pstate, uint16_t field_idx, uint8_t *input, uint32_t input_len) {
int AlpParseFieldByEOF(AppLayerParserResult *output, AppLayerParserState *pstate,
uint16_t field_idx, uint8_t *input, uint32_t input_len)
{
SCEnter();
if (pstate->store_len == 0) {
@ -239,15 +254,19 @@ int AlpParseFieldByEOF(AppLayerParserResult *output, AppLayerParserState *pstate
* \retval 0 Field parsing in progress.
* \retval -1 error
*/
int AlpParseFieldByDelimiter(AppLayerParserResult *output, AppLayerParserState *pstate, uint16_t field_idx, const uint8_t *delim, uint8_t delim_len, uint8_t *input, uint32_t input_len, uint32_t *offset) {
int AlpParseFieldByDelimiter(AppLayerParserResult *output, AppLayerParserState *pstate,
uint16_t field_idx, const uint8_t *delim, uint8_t delim_len,
uint8_t *input, uint32_t input_len, uint32_t *offset)
{
SCEnter();
SCLogDebug("pstate->store_len %" PRIu32 ", delim_len %" PRIu32 "", pstate->store_len, delim_len);
SCLogDebug("pstate->store_len %" PRIu32 ", delim_len %" PRIu32 "",
pstate->store_len, delim_len);
if (pstate->store_len == 0) {
uint8_t *ptr = BinSearch(input, input_len, delim, delim_len);
if (ptr != NULL) {
uint32_t len = ptr - input;
//printf("ParseFieldByDelimiter: len %" PRIu32 "\n", len);
SCLogDebug(" len %" PRIu32 "", len);
int r = AlpStoreField(output, field_idx, input, len, 0);
if (r == -1) {
@ -257,11 +276,11 @@ int AlpParseFieldByDelimiter(AppLayerParserResult *output, AppLayerParserState *
SCReturnInt(1);
} else {
if (pstate->flags & APP_LAYER_PARSER_EOF) {
//printf("ParseFieldByDelimiter: delim not found and EOF\n");
SCLogDebug("delim not found and EOF");
SCReturnInt(0);
}
//printf("ParseFieldByDelimiter: delim not found, continue\n");
SCLogDebug("delim not found, continue");
/* delimiter field not found, so store the result for the next run */
pstate->store = malloc(input_len);
@ -276,7 +295,8 @@ int AlpParseFieldByDelimiter(AppLayerParserResult *output, AppLayerParserState *
uint8_t *ptr = BinSearch(input, input_len, delim, delim_len);
if (ptr != NULL) {
uint32_t len = ptr - input;
//printf("ParseFieldByDelimiter: len %" PRIu32 " + %" PRIu32 " = %" PRIu32 "\n", len, pstate->store_len, len + pstate->store_len);
SCLogDebug("len %" PRIu32 " + %" PRIu32 " = %" PRIu32 "", len,
pstate->store_len, len + pstate->store_len);
pstate->store = realloc(pstate->store, (len + pstate->store_len));
if (pstate->store == NULL) {
@ -286,7 +306,8 @@ int AlpParseFieldByDelimiter(AppLayerParserResult *output, AppLayerParserState *
memcpy(pstate->store+pstate->store_len, input, len);
pstate->store_len += len;
int r = AlpStoreField(output, field_idx, pstate->store, pstate->store_len, 1);
int r = AlpStoreField(output, field_idx, pstate->store,
pstate->store_len, 1);
if (r == -1) {
SCReturnInt(-1);
}
@ -300,23 +321,27 @@ int AlpParseFieldByDelimiter(AppLayerParserResult *output, AppLayerParserState *
/* if the input len is smaller than the delim len we search the
* pstate->store since we may match there. */
if (delim_len > input_len) {
/* delimiter field not found, so store the result for the next run */
pstate->store = realloc(pstate->store, (input_len + pstate->store_len));
/* delimiter field not found, so store the result for the
* next run */
pstate->store = realloc(pstate->store, (input_len +
pstate->store_len));
if (pstate->store == NULL) {
SCReturnInt(-1);
}
memcpy(pstate->store+pstate->store_len, input, input_len);
pstate->store_len += input_len;
//printf("ParseFieldByDelimiter: input_len < delim_len, checking pstate->store\n");
SCLogDebug("input_len < delim_len, checking pstate->store");
if (pstate->store_len >= delim_len) {
ptr = BinSearch(pstate->store, pstate->store_len, delim, delim_len);
ptr = BinSearch(pstate->store, pstate->store_len, delim,
delim_len);
if (ptr != NULL) {
//printf("ParseFieldByDelimiter: now we found the delim\n");
SCLogDebug("now we found the delim");
uint32_t len = ptr - pstate->store;
int r = AlpStoreField(output, field_idx, pstate->store, len, 1);
int r = AlpStoreField(output, field_idx,
pstate->store, len, 1);
if (r == -1) {
SCReturnInt(-1);
}
@ -326,7 +351,7 @@ int AlpParseFieldByDelimiter(AppLayerParserResult *output, AppLayerParserState *
(*offset) += (input_len);
//printf("ParseFieldByDelimiter: offset %" PRIu32 "\n", (*offset));
SCLogDebug("offset %" PRIu32 "", (*offset));
SCReturnInt(1);
}
goto free_and_return;
@ -334,7 +359,7 @@ int AlpParseFieldByDelimiter(AppLayerParserResult *output, AppLayerParserState *
goto free_and_return;
}
free_and_return:
//printf("ParseFieldByDelimiter: not found and EOF, so free what we have so far.\n");
SCLogDebug("not found and EOF, so free what we have so far.");
free(pstate->store);
pstate->store = NULL;
pstate->store_len = 0;
@ -353,11 +378,11 @@ int AlpParseFieldByDelimiter(AppLayerParserResult *output, AppLayerParserState *
/* if the input len is smaller than the delim len we search the
* pstate->store since we may match there. */
if (delim_len > input_len && delim_len <= pstate->store_len) {
//printf("ParseFieldByDelimiter: input_len < delim_len, checking pstate->store\n");
SCLogDebug("input_len < delim_len, checking pstate->store");
ptr = BinSearch(pstate->store, pstate->store_len, delim, delim_len);
if (ptr != NULL) {
//printf("ParseFieldByDelimiter: now we found the delim\n");
SCLogDebug("now we found the delim");
uint32_t len = ptr - pstate->store;
int r = AlpStoreField(output, field_idx, pstate->store, len, 1);
@ -369,7 +394,7 @@ int AlpParseFieldByDelimiter(AppLayerParserResult *output, AppLayerParserState *
(*offset) += (input_len);
//printf("ParseFieldByDelimiter: offset %" PRIu32 "\n", (*offset));
SCLogDebug("ffset %" PRIu32 "", (*offset));
SCReturnInt(1);
}
}
@ -391,11 +416,13 @@ static uint16_t al_max_parsers = 0; /* incremented for every registered parser *
*
* \retval Parser subsys id
*/
uint16_t AppLayerParserGetStorageId(void) {
uint16_t AppLayerParserGetStorageId(void)
{
return app_layer_sid;
}
uint16_t AppLayerGetProtoByName(const char *name) {
uint16_t AppLayerGetProtoByName(const char *name)
{
uint8_t u = 1;
SCLogDebug("looking for name %s", name);
@ -418,14 +445,20 @@ uint16_t AppLayerGetProtoByName(const char *name) {
/** \brief Description: register a parser.
*
* \param name full parser name, e.g. "http.request_line"
* \todo do we need recursive, so a "http" and a "request_line" where the engine knows it's actually "http.request_line"... same difference maybe.
* \todo do we need recursive, so a "http" and a "request_line" where the engine
* knows it's actually "http.request_line"... same difference maybe.
* \param AppLayerParser pointer to the parser function
* \param max_outputs max number of unique outputs the parser can generate
*
* \retval 0 on success
* \retval -1 on error
*/
int AppLayerRegisterParser(char *name, uint16_t proto, uint16_t parser_id, int (*AppLayerParser)(void *protocol_state, AppLayerParserState *parser_state, uint8_t *input, uint32_t input_len, AppLayerParserResult *output), char *dependency) {
int AppLayerRegisterParser(char *name, uint16_t proto, uint16_t parser_id,
int (*AppLayerParser)(void *protocol_state,
AppLayerParserState *parser_state, uint8_t *input,
uint32_t input_len, AppLayerParserResult *output),
char *dependency)
{
al_max_parsers++;
@ -439,21 +472,28 @@ int AppLayerRegisterParser(char *name, uint16_t proto, uint16_t parser_id, int (
al_parser_table[al_max_parsers].parser_local_id = parser_id;
al_parser_table[al_max_parsers].AppLayerParser = AppLayerParser;
SCLogDebug("registered %p at proto %" PRIu32 ", al_proto_table idx %" PRIu32 ", storage_id %" PRIu32 ", parser_local_id %" PRIu32 "",
AppLayerParser, proto, al_max_parsers, al_proto_table[proto].storage_id, parser_id);
SCLogDebug("registered %p at proto %" PRIu32 ", al_proto_table idx "
"%" PRIu32 ", storage_id %" PRIu32 ", parser_local_id %" PRIu32 "",
AppLayerParser, proto, al_max_parsers,
al_proto_table[proto].storage_id, parser_id);
return 0;
}
/** \brief Description: register a protocol parser.
*
* \param name full parser name, e.g. "http.request_line"
* \todo do we need recursive, so a "http" and a "request_line" where the engine knows it's actually "http.request_line"... same difference maybe.
* \todo do we need recursive, so a "http" and a "request_line" where the engine
* knows it's actually "http.request_line"... same difference maybe.
* \param AppLayerParser pointer to the parser function
*
* \retval 0 on success
* \retval -1 on error
*/
int AppLayerRegisterProto(char *name, uint8_t proto, uint8_t flags, int (*AppLayerParser)(void *protocol_state, AppLayerParserState *parser_state, uint8_t *input, uint32_t input_len, AppLayerParserResult *output)) {
int AppLayerRegisterProto(char *name, uint8_t proto, uint8_t flags,
int (*AppLayerParser)(void *protocol_state,
AppLayerParserState *parser_state, uint8_t *input,
uint32_t input_len, AppLayerParserResult *output))
{
al_max_parsers++;
@ -478,22 +518,28 @@ int AppLayerRegisterProto(char *name, uint8_t proto, uint8_t flags, int (*AppLay
al_proto_table[proto].storage_id = StreamL7RegisterModule();
}
SCLogDebug("registered %p at proto %" PRIu32 " flags %02X, al_proto_table idx %" PRIu32 ", storage_id %" PRIu32 "",
AppLayerParser, proto, flags, al_max_parsers, al_proto_table[proto].storage_id);
SCLogDebug("registered %p at proto %" PRIu32 " flags %02X, al_proto_table "
"idx %" PRIu32 ", storage_id %" PRIu32 " %s \n", AppLayerParser, proto,
flags, al_max_parsers, al_proto_table[proto].storage_id, name);
return 0;
}
void AppLayerRegisterStateFuncs(uint16_t proto, void *(*StateAlloc)(void), void (*StateFree)(void *)) {
void AppLayerRegisterStateFuncs(uint16_t proto, void *(*StateAlloc)(void),
void (*StateFree)(void *))
{
al_proto_table[proto].StateAlloc = StateAlloc;
al_proto_table[proto].StateFree = StateFree;
}
uint16_t AlpGetStateIdx(uint16_t proto) {
uint16_t AlpGetStateIdx(uint16_t proto)
{
return al_proto_table[proto].storage_id;
}
AppLayerParserStateStore *AppLayerParserStateStoreAlloc(void) {
AppLayerParserStateStore *s = (AppLayerParserStateStore *)malloc(sizeof(AppLayerParserStateStore));
AppLayerParserStateStore *AppLayerParserStateStoreAlloc(void)
{
AppLayerParserStateStore *s = (AppLayerParserStateStore *)malloc
(sizeof(AppLayerParserStateStore));
if (s == NULL)
return NULL;
@ -503,7 +549,8 @@ AppLayerParserStateStore *AppLayerParserStateStoreAlloc(void) {
/** \brief free a AppLayerParserStateStore structure
* \param s AppLayerParserStateStore structure to free */
void AppLayerParserStateStoreFree(AppLayerParserStateStore *s) {
void AppLayerParserStateStoreFree(AppLayerParserStateStore *s)
{
if (s->to_server.store != NULL)
free(s->to_server.store);
if (s->to_client.store != NULL)
@ -512,7 +559,8 @@ void AppLayerParserStateStoreFree(AppLayerParserStateStore *s) {
free(s);
}
static void AppLayerParserResultCleanup(AppLayerParserResult *result) {
static void AppLayerParserResultCleanup(AppLayerParserResult *result)
{
AppLayerParserResultElmt *e = result->head;
while (e != NULL) {
AppLayerParserResultElmt *next_e = e->next;
@ -527,27 +575,42 @@ static void AppLayerParserResultCleanup(AppLayerParserResult *result) {
}
}
static int AppLayerDoParse(void *app_layer_state, AppLayerParserState *parser_state, uint8_t *input, uint32_t input_len, uint16_t parser_idx, uint16_t proto) {
static int AppLayerDoParse(void *app_layer_state, AppLayerParserState *parser_state,
uint8_t *input, uint32_t input_len, uint16_t parser_idx,
uint16_t proto)
{
SCEnter();
int retval = 0;
AppLayerParserResult result = { NULL, NULL, 0 };
//printf("AppLayerDoParse: parser_idx %" PRIu32 "\n", parser_idx);
SCLogDebug("parser_idx %" PRIu32 "", parser_idx);
//PrintRawDataFp(stdout, input,input_len);
/* invoke the parser */
int r = al_parser_table[parser_idx].AppLayerParser(app_layer_state, parser_state, input, input_len, &result);
if (r < 0)
return -1;
int r = al_parser_table[parser_idx].AppLayerParser(app_layer_state,
parser_state, input, input_len, &result);
if (r < 0) {
if (r == -1) {
AppLayerParserResultCleanup(&result);
SCReturnInt(-1);
} else {
BUG_ON(r); /* this is not supposed to happen!! */
}
}
/* process the result elements */
AppLayerParserResultElmt *e = result.head;
for (; e != NULL; e = e->next) {
//printf("AppLayerParse: e %p e->name_idx %" PRIu32 ", e->data_ptr %p, e->data_len %" PRIu32 ", map_size %" PRIu32 "\n",
// e, e->name_idx, e->data_ptr, e->data_len, al_proto_table[proto].map_size);
SCLogDebug("e %p e->name_idx %" PRIu32 ", e->data_ptr %p, e->data_len "
"%" PRIu32 ", map_size %" PRIu32 "", e, e->name_idx,
e->data_ptr, e->data_len, al_proto_table[proto].map_size);
/* no parser defined for this field. */
if (e->name_idx >= al_proto_table[proto].map_size || al_proto_table[proto].map[e->name_idx] == NULL) {
//printf("AppLayerParse: no parser for proto %" PRIu32 ", parser_local_id %" PRIu32 "\n", proto, e->name_idx);
if (e->name_idx >= al_proto_table[proto].map_size ||
al_proto_table[proto].map[e->name_idx] == NULL)
{
SCLogDebug("no parser for proto %" PRIu32 ", parser_local_id "
"%" PRIu32 "", proto, e->name_idx);
continue;
}
@ -558,7 +621,8 @@ static int AppLayerDoParse(void *app_layer_state, AppLayerParserState *parser_st
parser_state->parse_field = 0;
parser_state->flags |= APP_LAYER_PARSER_EOF;
r = AppLayerDoParse(app_layer_state, parser_state, e->data_ptr, e->data_len, idx, proto);
r = AppLayerDoParse(app_layer_state, parser_state, e->data_ptr,
e->data_len, idx, proto);
/* restore */
parser_state->flags &= ~APP_LAYER_PARSER_EOF;
@ -566,13 +630,17 @@ static int AppLayerDoParse(void *app_layer_state, AppLayerParserState *parser_st
/* bail out on a serious error */
if (r < 0) {
retval = -1;
break;
if (r == -1) {
retval = -1;
break;
} else {
BUG_ON(r);
}
}
}
AppLayerParserResultCleanup(&result);
return retval;
SCReturnInt(retval);
}
/**
@ -588,7 +656,9 @@ static int AppLayerDoParse(void *app_layer_state, AppLayerParserState *parser_st
* \retval -1 error
* \retval 0 ok
*/
int AppLayerParse(Flow *f, uint8_t proto, uint8_t flags, uint8_t *input, uint32_t input_len, char need_lock) {
int AppLayerParse(Flow *f, uint8_t proto, uint8_t flags, uint8_t *input,
uint32_t input_len, char need_lock)
{
SCEnter();
uint16_t parser_idx = 0;
@ -596,20 +666,28 @@ int AppLayerParse(Flow *f, uint8_t proto, uint8_t flags, uint8_t *input, uint32_
TcpSession *ssn = f->protoctx;
if (ssn == NULL) {
printf("AppLayerParse: no session\n");
SCLogDebug("no TCP session");
goto error;
}
/* Get the parser state (if any) */
AppLayerParserStateStore *parser_state_store = (AppLayerParserStateStore *)ssn->aldata[app_layer_sid];
if (parser_state_store == NULL) {
parser_state_store = AppLayerParserStateStoreAlloc();
if (parser_state_store == NULL)
goto error;
AppLayerParserStateStore *parser_state_store = NULL;
if (need_lock == TRUE) mutex_lock(&f->m);
ssn->aldata[app_layer_sid] = (void *)parser_state_store;
if (need_lock == TRUE) mutex_unlock(&f->m);
if (ssn->aldata != NULL) {
parser_state_store = (AppLayerParserStateStore *)
ssn->aldata[app_layer_sid];
if (parser_state_store == NULL) {
parser_state_store = AppLayerParserStateStoreAlloc();
if (parser_state_store == NULL)
goto error;
if (need_lock == TRUE) mutex_lock(&f->m);
ssn->aldata[app_layer_sid] = (void *)parser_state_store;
if (need_lock == TRUE) mutex_unlock(&f->m);
}
} else {
SCLogDebug("No App Layer Data");
goto error;
}
AppLayerParserState *parser_state = NULL;
@ -620,7 +698,8 @@ int AppLayerParse(Flow *f, uint8_t proto, uint8_t flags, uint8_t *input, uint32_
parser_state->cur_parser = parser_idx;
parser_state->flags |= APP_LAYER_PARSER_USE;
} else {
//printf("AppLayerParse: using parser %" PRIu32 " we stored before (to_server)\n", parser_state->cur_parser);
SCLogDebug("using parser %" PRIu32 " we stored before (to_server)",
parser_state->cur_parser);
parser_idx = parser_state->cur_parser;
}
} else {
@ -630,13 +709,14 @@ int AppLayerParse(Flow *f, uint8_t proto, uint8_t flags, uint8_t *input, uint32_
parser_state->cur_parser = parser_idx;
parser_state->flags |= APP_LAYER_PARSER_USE;
} else {
//printf("AppLayerParse: using parser %" PRIu32 " we stored before (to_client)\n", parser_state->cur_parser);
SCLogDebug("using parser %" PRIu32 " we stored before (to_client)",
parser_state->cur_parser);
parser_idx = parser_state->cur_parser;
}
}
if (parser_idx == 0 || parser_state->flags & APP_LAYER_PARSER_DONE) {
//printf("AppLayerParse: no parser for protocol %" PRIu32 "\n", proto);
SCLogDebug("no parser for protocol %" PRIu32 "", proto);
SCReturnInt(0);
}
@ -660,7 +740,8 @@ int AppLayerParse(Flow *f, uint8_t proto, uint8_t flags, uint8_t *input, uint32_
}
/* invoke the recursive parser */
int r = AppLayerDoParse(app_layer_state, parser_state, input, input_len, parser_idx, proto);
int r = AppLayerDoParse(app_layer_state, parser_state, input, input_len,
parser_idx, proto);
if (r < 0)
goto error;
@ -682,10 +763,44 @@ int AppLayerParse(Flow *f, uint8_t proto, uint8_t flags, uint8_t *input, uint32_
SCReturnInt(0);
error:
if (ssn != NULL) {
char src[16];
char dst[16];
char dst6[46];
char src6[46];
/* Clear the app layer protocol state memory and the given function also
* cleans the parser state memory */
AppLayerParserCleanupState(ssn);
/* Set the no reassembly flag for both the stream in this TcpSession */
StreamTcpSetSessionNoReassemblyFlag(ssn, flags & STREAM_TOCLIENT ? 1 : 0);
StreamTcpSetSessionNoReassemblyFlag(ssn, flags & STREAM_TOSERVER ? 1 : 0);
if (f->src.family == AF_INET) {
inet_ntop(AF_INET, &f->src.addr_data32[0], src,
sizeof (src));
inet_ntop(AF_INET, &f->dst.addr_data32[0], dst,
sizeof (dst));
} else {
inet_ntop(AF_INET6, &f->src.addr_data32[0], src6,
sizeof (src6));
inet_ntop(AF_INET6, &f->dst.addr_data32[0], dst6,
sizeof (dst6));
}
SCLogError(SC_ALPARSER_ERR, "Error occured in parsing \"%s\" app layer "
"protocol, using network protocol %"PRIu8", source IP "
"address %s, destination IP address %s, src port %"PRIu16" and "
"dst port %"PRIu16"", al_proto_table[ssn->alproto].name,
f->proto, src, dst, ntohs(f->sp), ntohs(f->dp));
}
SCReturnInt(-1);
}
void RegisterAppLayerParsers(void) {
void RegisterAppLayerParsers(void)
{
/** \todo move to general init function */
memset(&al_proto_table, 0, sizeof(al_proto_table));
memset(&al_parser_table, 0, sizeof(al_parser_table));
@ -697,22 +812,23 @@ void RegisterAppLayerParsers(void) {
al_result_pool = PoolInit(250,10,AlpResultElmtPoolAlloc,NULL,AlpResultElmtPoolFree);
}
void AppLayerParserCleanupState(TcpSession *ssn) {
void AppLayerParserCleanupState(TcpSession *ssn)
{
if (ssn == NULL) {
//printf("AppLayerParserCleanupState: no ssn\n");
SCLogDebug("no ssn");
return;
}
AppLayerProto *p = &al_proto_table[ssn->alproto];
if (p == NULL) {
//printf("AppLayerParserCleanupState: no parser state for %"PRIu16"\n", ssn->alproto);
SCLogDebug("no parser state for %"PRIu16"", ssn->alproto);
return;
}
/* free the parser protocol state */
if (p->StateFree != NULL) {
if (p->StateFree != NULL && ssn->aldata != NULL) {
if (ssn->aldata[p->storage_id] != NULL) {
//printf("AppLayerParserCleanupState: calling StateFree\n");
SCLogDebug("calling StateFree");
p->StateFree(ssn->aldata[p->storage_id]);
ssn->aldata[p->storage_id] = NULL;
}
@ -720,7 +836,7 @@ void AppLayerParserCleanupState(TcpSession *ssn) {
if (ssn->aldata != NULL) {
if (ssn->aldata[app_layer_sid] != NULL) {
//printf("AppLayerParserCleanupState: calling AppLayerParserStateStoreFree\n");
SCLogDebug("calling AppLayerParserStateStoreFree");
AppLayerParserStateStoreFree(ssn->aldata[app_layer_sid]);
ssn->aldata[app_layer_sid] = NULL;
}
@ -734,7 +850,8 @@ void AppLayerParserCleanupState(TcpSession *ssn) {
* and the global field parser id's.
*
*/
void AppLayerParsersInitPostProcess(void) {
void AppLayerParsersInitPostProcess(void)
{
uint16_t u16 = 0;
/* build local->global mapping */
@ -743,10 +860,14 @@ void AppLayerParsersInitPostProcess(void) {
if (al_parser_table[u16].parser_local_id == 0)
continue;
if (al_parser_table[u16].parser_local_id > al_proto_table[al_parser_table[u16].proto].map_size)
al_proto_table[al_parser_table[u16].proto].map_size = al_parser_table[u16].parser_local_id;
//printf("AppLayerParsersInitPostProcess: map_size %" PRIu32 "\n", al_proto_table[al_parser_table[u16].proto].map_size);
if (al_parser_table[u16].parser_local_id >
al_proto_table[al_parser_table[u16].proto].map_size)
{
al_proto_table[al_parser_table[u16].proto].map_size =
al_parser_table[u16].parser_local_id;
}
SCLogDebug("map_size %" PRIu32 "", al_proto_table
[al_parser_table[u16].proto].map_size);
}
/* for each proto, alloc the map array */
@ -755,12 +876,15 @@ void AppLayerParsersInitPostProcess(void) {
continue;
al_proto_table[u16].map_size++;
al_proto_table[u16].map = (AppLayerLocalMap **)malloc(al_proto_table[u16].map_size * sizeof(AppLayerLocalMap *));
al_proto_table[u16].map = (AppLayerLocalMap **)malloc
(al_proto_table[u16].map_size *
sizeof(AppLayerLocalMap *));
if (al_proto_table[u16].map == NULL) {
printf("XXX memory error\n");
SCLogError(SC_ERR_MEM_ALLOC, "memory error");
exit(1);
}
memset(al_proto_table[u16].map, 0, al_proto_table[u16].map_size * sizeof(AppLayerLocalMap *));
memset(al_proto_table[u16].map, 0, al_proto_table[u16].map_size *
sizeof(AppLayerLocalMap *));
uint16_t u = 0;
for (u = 1; u <= al_max_parsers; u++) {
@ -771,14 +895,13 @@ void AppLayerParsersInitPostProcess(void) {
if (al_parser_table[u].proto != u16)
continue;
//printf("AppLayerParsersInitPostProcess: al_proto_table[%" PRIu32 "].map_size %" PRIu32 ", %p %p\n", u16, al_proto_table[u16].map_size, al_proto_table[u16].map[x], al_proto_table[u16].map);
uint16_t parser_local_id = al_parser_table[u].parser_local_id;
//printf("AppLayerParsersInitPostProcess: parser_local_id: %" PRIu32 "\n", parser_local_id);
SCLogDebug("parser_local_id: %" PRIu32 "", parser_local_id);
if (parser_local_id < al_proto_table[u16].map_size) {
al_proto_table[u16].map[parser_local_id] = malloc(sizeof(AppLayerLocalMap));
if (al_proto_table[u16].map[parser_local_id] == NULL) {
printf("XXX memory error\n");
SCLogError(SC_ERR_MEM_ALLOC, "XXX memory error");
exit(1);
}
@ -799,8 +922,121 @@ void AppLayerParsersInitPostProcess(void) {
if (al_proto_table[u16].map[x] == NULL)
continue;
//printf("AppLayerParsersInitPostProcess: al_proto_table[%" PRIu32 "].map[%" PRIu32 "]->parser_id: %" PRIu32 "\n", u16, x, al_proto_table[u16].map[x]->parser_id);
SCLogDebug("al_proto_table[%" PRIu32 "].map[%" PRIu32 "]->parser_id:"
" %" PRIu32 "\n", u16, x, al_proto_table[u16].map[x]->parser_id);
}
}
}
/* UNITTESTS*/
#ifdef UNITTESTS
typedef struct TestState_ {
uint8_t test;
}TestState;
/**
* \brief Test parser function to test the memory deallocation of app layer
* parser of occurence of an error.
*/
static int TestProtocolParser(void *test_state, AppLayerParserState *pstate,
uint8_t *input, uint32_t input_len,
AppLayerParserResult *output)
{
return -1;
}
/** \brief Function to allocates the Test protocol state memory
*/
static void *TestProtocolStateAlloc(void)
{
void *s = malloc(sizeof(TestState));
if (s == NULL)
return NULL;
memset(s, 0, sizeof(TestState));
return s;
}
/** \brief Function to free the Test Protocol state memory
*/
static void TestProtocolStateFree(void *s)
{
free(s);
}
/** \test Test the deallocation of app layer parser memory on occurance of
* error in the parsing process.
*/
static int AppLayerParserTest01 (void)
{
int result = 1;
Flow f;
uint8_t testbuf[] = { 0x11 };
uint32_t testlen = sizeof(testbuf);
TcpSession ssn;
struct in_addr addr;
struct in_addr addr1;
Address src;
Address dst;
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
memset(&src, 0, sizeof(src));
memset(&dst, 0, sizeof(dst));
/* Register the Test protocol state and parser functions */
AppLayerRegisterProto("test", ALPROTO_TEST, STREAM_TOSERVER,
TestProtocolParser);
AppLayerRegisterStateFuncs(ALPROTO_TEST, TestProtocolStateAlloc,
TestProtocolStateFree);
ssn.alproto = ALPROTO_TEST;
StreamL7DataPtrInit(&ssn,StreamL7GetStorageSize());
f.protoctx = (void *)&ssn;
inet_pton(AF_INET, "1.2.3.4", &addr.s_addr);
src.family = AF_INET;
src.addr_data32[0] = addr.s_addr;
inet_pton(AF_INET, "4.3.2.1", &addr1.s_addr);
dst.family = AF_INET;
dst.addr_data32[0] = addr1.s_addr;
f.src = src;
f.dst = dst;
f.sp = htons(20);
f.dp = htons(40);
f.proto = IPPROTO_TCP;
int r = AppLayerParse(&f, ALPROTO_TEST, STREAM_TOSERVER|STREAM_EOF, testbuf,
testlen, FALSE);
if (r != -1) {
printf("returned %" PRId32 ", expected -1: \n", r);
result = 0;
goto end;
}
if (!(ssn.flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY) ||
!(ssn.flags & STREAMTCP_FLAG_NOCLIENT_REASSEMBLY))
{
printf("flags should be set, but they are not !\n");
result = 0;
goto end;
}
if (ssn.aldata != NULL) {
printf("App Layer state has not been cleared\n");
result = 0;
goto end;
}
end:
return result;
}
#endif /* UNITESTS */
void AppLayerParserRegisterTests(void)
{
#ifdef UNITTESTS
UtRegisterTest("AppLayerParserTest01", AppLayerParserTest01, 1);
#endif /* UNITTESTS */
}

@ -97,6 +97,8 @@ uint16_t AlpGetStateIdx(uint16_t);
uint16_t AppLayerGetProtoByName(const char *);
void AppLayerParserRegisterTests(void);
#include "stream-tcp-private.h"
void AppLayerParserCleanupState(TcpSession *);

@ -14,7 +14,9 @@ enum {
ALPROTO_JABBER,
ALPROTO_SMB,
ALPROTO_DCERPC,
#ifdef UNITTESTS
ALPROTO_TEST,
#endif /* UNITESTS */
/* keep last */
ALPROTO_MAX,
};

@ -12,6 +12,7 @@
#include "util-print.h"
#include "util-pool.h"
#include "util-debug.h"
#include "stream-tcp-private.h"
#include "stream-tcp-reassemble.h"
@ -125,7 +126,9 @@ static int SMBParseAndX(void *smb_state, AppLayerParserState *pstate,
* Determine if this is an SMB AndX Command
*/
static int SMBGetWordCount(void *smb_state, AppLayerParserState *pstate,
uint8_t *input, uint32_t input_len, AppLayerParserResult *output) {
uint8_t *input, uint32_t input_len, AppLayerParserResult *output)
{
SCEnter();
if (input_len) {
SMBState *sstate = (SMBState *) smb_state;
sstate->wordcount.wordcount = *(input) * 2;
@ -133,9 +136,10 @@ static int SMBGetWordCount(void *smb_state, AppLayerParserState *pstate,
sstate->bytecount.bytecountbytes = 0;
sstate->andx.isandx = isAndX(sstate);
--input_len;
return 1;
SCLogDebug("Wordcount (%u):", sstate->wordcount.wordcount);
SCReturnInt(1);
}
return 0;
SCReturnInt(0);
}
/*
@ -144,7 +148,9 @@ static int SMBGetWordCount(void *smb_state, AppLayerParserState *pstate,
*/
static int SMBGetByteCount(void *smb_state, AppLayerParserState *pstate,
uint8_t *input, uint32_t input_len, AppLayerParserResult *output) {
uint8_t *input, uint32_t input_len, AppLayerParserResult *output)
{
SCEnter();
SMBState *sstate = (SMBState *) smb_state;
uint8_t *p = input;
if (input_len && sstate->bytesprocessed == NBSS_HDR_LEN + SMB_HDR_LEN +
@ -157,43 +163,55 @@ static int SMBGetByteCount(void *smb_state, AppLayerParserState *pstate,
2 + sstate->wordcount.wordcount) {
sstate->bytecount.bytecount |= *(p++) << 8;
sstate->bytesprocessed++;
printf("Bytecount (%u)\n", sstate->bytecount.bytecount);
SCLogDebug("Bytecount %u", sstate->bytecount.bytecount);
--input_len;
}
return (p - input);
SCReturInt(p - input);
}
static int SMBParseWordCount(void *smb_state, AppLayerParserState *pstate,
uint8_t *input, uint32_t input_len, AppLayerParserResult *output) {
uint8_t *input, uint32_t input_len, AppLayerParserResult *output)
{
SCEnter();
SMBState *sstate = (SMBState *) smb_state;
uint8_t *p = input;
while (sstate->wordcount.wordcount-- && input_len--) {
while (sstate->wordcount.wordcount > 0 && input_len > 0) {
if (sstate->andx.isandx) {
SMBParseAndX(smb_state, pstate, input, input_len, output);
}
printf("0x%02x ", *(p++));
SCLogDebug("0x%02x", *(p++));
sstate->wordcount.wordcount--;
input_len--;
}
printf("\n");
sstate->bytesprocessed += (p - input);
return (p - input);
SCReturnInt(p - input);
}
static int SMBParseByteCount(void *smb_state, AppLayerParserState *pstate,
uint8_t *input, uint32_t input_len, AppLayerParserResult *output) {
uint8_t *input, uint32_t input_len, AppLayerParserResult *output)
{
SCEnter();
SMBState *sstate = (SMBState *) smb_state;
uint8_t *p = input;
while (sstate->bytecount.bytecount-- && input_len--) {
printf("0x%02x bytecount %u input_len %u\n", *(p++),
while (sstate->bytecount.bytecount && input_len) {
SCLogDebug("0x%02x bytecount %u input_len %u", *(p++),
sstate->bytecount.bytecount, input_len);
sstate->wordcount.wordcount--;
input_len--;
}
printf("\n");
sstate->bytesprocessed += (p - input);
return (p - input);
SCReturnInt(p - input);
}
#define DEBUG 1
static int NBSSParseHeader(void *smb_state, AppLayerParserState *pstate,
uint8_t *input, uint32_t input_len, AppLayerParserResult *output) {
uint8_t *input, uint32_t input_len, AppLayerParserResult *output)
{
SCEnter();
SMBState *sstate = (SMBState *) smb_state;
uint8_t *p = input;
@ -209,7 +227,7 @@ static int NBSSParseHeader(void *smb_state, AppLayerParserState *pstate,
sstate->nbss.length |= *(p + 3);
input_len -= NBSS_HDR_LEN;
sstate->bytesprocessed += NBSS_HDR_LEN;
return NBSS_HDR_LEN;
SCReturnInt(NBSS_HDR_LEN);
} else {
sstate->nbss.type = *(p++);
if (!(--input_len)) break;
@ -225,16 +243,18 @@ static int NBSSParseHeader(void *smb_state, AppLayerParserState *pstate,
--input_len;
break;
default:
return -1;
SCReturnInt(-1);
break;
}
sstate->bytesprocessed += (p - input);
}
return (p - input);
SCReturnInt(p - input);
}
static int SMBParseHeader(void *smb_state, AppLayerParserState *pstate,
uint8_t *input, uint32_t input_len, AppLayerParserResult *output) {
uint8_t *input, uint32_t input_len, AppLayerParserResult *output)
{
SCEnter();
SMBState *sstate = (SMBState *) smb_state;
uint8_t *p = input;
if (input_len) {
@ -242,8 +262,8 @@ static int SMBParseHeader(void *smb_state, AppLayerParserState *pstate,
case 4:
if (input_len >= SMB_HDR_LEN) {
if (memcmp(p, "\xff\x53\x4d\x42", 4) != 0) {
printf("SMB Header did not validate\n");
return 0;
SCLogDebug("SMB Header did not validate");
SCReturnInt(0);
}
sstate->smb.command = *(p + 4);
sstate->smb.status = *(p + 5) << 24;
@ -273,28 +293,28 @@ static int SMBParseHeader(void *smb_state, AppLayerParserState *pstate,
sstate->smb.mid |= *(p + 31);
input_len -= SMB_HDR_LEN;
sstate->bytesprocessed += SMB_HDR_LEN;
return SMB_HDR_LEN;
SCReturnInt(SMB_HDR_LEN);
break;
} else {
//sstate->smb.protocol[0] = *(p++);
if (*(p++) != 0xff)
return 0;
SCReturnInt(0);
if (!(--input_len)) break;
}
case 5:
//sstate->smb.protocol[1] = *(p++);
if (*(p++) != 'S')
return 0;
SCReturnInt(0);
if (!(--input_len)) break;
case 6:
//sstate->smb.protocol[2] = *(p++);
if (*(p++) != 'M')
return 0;
SCReturnInt(0);
if (!(--input_len)) break;
case 7:
//sstate->smb.protocol[3] = *(p++);
if (*(p++) != 'B')
return 0;
SCReturnInt(0);
if (!(--input_len)) break;
case 8:
sstate->smb.command = *(p++);
@ -382,29 +402,33 @@ static int SMBParseHeader(void *smb_state, AppLayerParserState *pstate,
--input_len;
break;
default: // SHOULD NEVER OCCUR
return 0;
SCReturnInt(8);
}
}
sstate->bytesprocessed += (p - input);
return (p - input);
SCReturnInt(p - input);
}
static int SMBParse(void *smb_state, AppLayerParserState *pstate,
uint8_t *input, uint32_t input_len, AppLayerParserResult *output) {
uint8_t *input, uint32_t input_len, AppLayerParserResult *output)
{
SCEnter();
SMBState *sstate = (SMBState *) smb_state;
uint32_t retval = 0;
uint32_t parsed = 0;
if (pstate == NULL)
return -1;
SCReturnInt(-1);
while (sstate->bytesprocessed < NBSS_HDR_LEN) {
retval = NBSSParseHeader(smb_state, pstate, input, input_len, output);
parsed += retval;
input_len -= retval;
printf("\nNBSS Header (%u/%u) Type 0x%02x Length 0x%04x parsed %u input_len %u\n",
sstate->bytesprocessed, NBSS_HDR_LEN, sstate->nbss.type,
sstate->nbss.length, parsed, input_len);
retval = NBSSParseHeader(smb_state, pstate, input, input_len, output);
parsed += retval;
input_len -= retval;
SCLogDebug("NBSS Header (%u/%u) Type 0x%02x Length 0x%04x parsed %u input_len %u",
sstate->bytesprocessed, NBSS_HDR_LEN, sstate->nbss.type,
sstate->nbss.length, parsed, input_len);
}
switch(sstate->nbss.type) {
@ -459,7 +483,7 @@ static int SMBParse(void *smb_state, AppLayerParserState *pstate,
}
pstate->parse_field = 0;
pstate->flags |= APP_LAYER_PARSER_DONE;
return 1;
SCReturnInt(1);
}
int isAndX(SMBState *smb_state) {

@ -45,13 +45,15 @@ static int TLSParseClientContentType(void *tls_state, AppLayerParserState
*pstate, uint8_t *input, uint32_t input_len,
AppLayerParserResult *output)
{
SCEnter();
TlsState *state = (TlsState *)tls_state;
if (input == NULL)
return 0;
SCReturnInt(-1);
if (input_len != 1) {
return 0;
SCReturnInt(-1);
}
/* check if we received the correct content type */
@ -62,7 +64,7 @@ static int TLSParseClientContentType(void *tls_state, AppLayerParserState
case TLS_APPLICATION_PROTOCOL:
break;
default:
return 0;
SCReturnInt(0);
}
state->client_content_type = *input;
@ -86,7 +88,7 @@ static int TLSParseClientContentType(void *tls_state, AppLayerParserState
if (state->client_content_type == TLS_CHANGE_CIPHER_SPEC)
state->flags |= TLS_FLAG_CLIENT_CHANGE_CIPHER_SPEC;
return 1;
SCReturnInt(0);
}
/**
@ -102,10 +104,12 @@ static int TLSParseClientContentType(void *tls_state, AppLayerParserState
static int TLSParseClientVersion(void *tls_state, AppLayerParserState *pstate,
uint8_t *input, uint32_t input_len, AppLayerParserResult *output)
{
SCEnter();
TlsState *state = (TlsState *)tls_state;
if (input_len != 2)
return 0;
SCReturnInt(-1);
/** \todo there must be an easier way to get from uint8_t * to a uint16_t */
struct u16conv_ {
@ -126,7 +130,7 @@ static int TLSParseClientVersion(void *tls_state, AppLayerParserState *pstate,
}
SCLogDebug("version %04"PRIx16"", state->client_version);
return 1;
SCReturnInt(0);
}
/**
@ -174,7 +178,8 @@ static int TLSParseClientRecord(void *tls_state, AppLayerParserState *pstate,
pstate->parse_field = 0;
SCReturnInt(0);
} else if (r == -1) {
SCLogError(SC_ALPARSER_ERR, "AlpParseFieldBySize failed, r %d", r);
SCLogError(SC_ALPARSER_ERR, "AlpParseFieldBySize failed, "
"r %d", r);
SCReturnInt(-1);
}
break;
@ -192,7 +197,8 @@ static int TLSParseClientRecord(void *tls_state, AppLayerParserState *pstate,
pstate->parse_field = 1;
SCReturnInt(0);
} else if (r == -1) {
SCLogError(SC_ALPARSER_ERR, "AlpParseFieldBySize failed, r %d", r);
SCLogError(SC_ALPARSER_ERR, "AlpParseFieldBySize failed, "
"r %d", r);
SCReturnInt(-1);
}
break;
@ -205,12 +211,14 @@ static int TLSParseClientRecord(void *tls_state, AppLayerParserState *pstate,
int r = AlpParseFieldBySize(output, pstate, TLS_FIELD_LENGTH,
/* 2 byte field */2, data, data_len,
&offset);
SCLogDebug("AlpParseFieldBySize returned r %d, offset %"PRIu32"", r, offset);
SCLogDebug("AlpParseFieldBySize returned r %d, offset %"PRIu32""
, r, offset);
if (r == 0) {
pstate->parse_field = 2;
SCReturnInt(0);
} else if (r == -1) {
SCLogError(SC_ALPARSER_ERR, "AlpParseFieldBySize failed, r %d", r);
SCLogError(SC_ALPARSER_ERR, "AlpParseFieldBySize failed, "
"r %d", r);
SCReturnInt(-1);
}
@ -229,7 +237,8 @@ static int TLSParseClientRecord(void *tls_state, AppLayerParserState *pstate,
* is in the data */
uint32_t record_offset = (offset + record_len);
SCLogDebug("record offset %"PRIu32" (offset %"PRIu32", record_len %"PRIu16")", record_offset, offset, record_len);
SCLogDebug("record offset %"PRIu32" (offset %"PRIu32", record_len"
" %"PRIu16")", record_offset, offset, record_len);
/* if our input buffer is bigger than the data up to and
* including the current record, we instruct the parser to
@ -294,7 +303,8 @@ static int TLSParseServerRecord(void *tls_state, AppLayerParserState *pstate,
pstate->parse_field = 0;
SCReturnInt(0);
} else if (r == -1) {
SCLogError(SC_ALPARSER_ERR, "AlpParseFieldBySize failed, r %d", r);
SCLogError(SC_ALPARSER_ERR, "AlpParseFieldBySize failed, "
"r %d", r);
SCReturnInt(-1);
}
break;
@ -311,7 +321,8 @@ static int TLSParseServerRecord(void *tls_state, AppLayerParserState *pstate,
pstate->parse_field = 1;
SCReturnInt(0);
} else if (r == -1) {
SCLogError(SC_ALPARSER_ERR, "AlpParseFieldBySize failed, r %d", r);
SCLogError(SC_ALPARSER_ERR, "AlpParseFieldBySize failed, "
"r %d", r);
SCReturnInt(-1);
}
break;
@ -329,7 +340,8 @@ static int TLSParseServerRecord(void *tls_state, AppLayerParserState *pstate,
pstate->parse_field = 2;
SCReturnInt(0);
} else if (r == -1) {
SCLogError(SC_ALPARSER_ERR, "AlpParseFieldBySize failed, r %d", r);
SCLogError(SC_ALPARSER_ERR, "AlpParseFieldBySize failed, "
"r %d", r);
SCReturnInt(-1);
}
@ -348,7 +360,8 @@ static int TLSParseServerRecord(void *tls_state, AppLayerParserState *pstate,
* is in the data */
uint32_t record_offset = (offset + record_len);
SCLogDebug("record offset %"PRIu32" (offset %"PRIu32", record_len %"PRIu16")", record_offset, offset, record_len);
SCLogDebug("record offset %"PRIu32" (offset %"PRIu32", record_len"
" %"PRIu16")", record_offset, offset, record_len);
/* if our input buffer is bigger than the data up to and
* including the current record, we instruct the parser to
@ -382,10 +395,11 @@ static int TLSParseServerVersion(void *tls_state, AppLayerParserState *pstate,
uint8_t *input, uint32_t input_len,
AppLayerParserResult *output)
{
SCEnter();
TlsState *state = (TlsState *)tls_state;
if (input_len != 2)
return 0;
SCReturnInt(-1);
/** \todo there must be an easier way to get from uint8_t * to a uint16_t */
struct u16conv_ {
@ -396,7 +410,7 @@ static int TLSParseServerVersion(void *tls_state, AppLayerParserState *pstate,
state->server_version = ntohs(u16conv->u);
SCLogDebug("version %04"PRIx16"", state->server_version);
return 1;
SCReturnInt(0);
}
/**
@ -412,13 +426,14 @@ static int TLSParseServerContentType(void *tls_state, AppLayerParserState *pstat
uint8_t *input, uint32_t input_len,
AppLayerParserResult *output)
{
SCEnter();
TlsState *state = (TlsState *)tls_state;
if (input == NULL)
return 0;
SCReturnInt(-1);
if (input_len != 1) {
return 0;
SCReturnInt(-1);
}
/* check if we received the correct content type */
@ -429,7 +444,7 @@ static int TLSParseServerContentType(void *tls_state, AppLayerParserState *pstat
case TLS_APPLICATION_PROTOCOL:
break;
default:
return 0;
SCReturnInt(0);
}
state->server_content_type = *input;
@ -456,7 +471,7 @@ static int TLSParseServerContentType(void *tls_state, AppLayerParserState *pstat
pstate->flags |= APP_LAYER_PARSER_NO_REASSEMBLY;
}
return 1;
SCReturnInt(0);
}
/** \brief Function to allocates the TLS state memory
@ -548,7 +563,8 @@ static int TLSParserTest01(void) {
}
if (tls_state->client_version != TLS_VERSION_10) {
printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", TLS_VERSION_10, tls_state->client_version);
printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ",
TLS_VERSION_10, tls_state->client_version);
result = 0;
goto end;
}
@ -601,7 +617,8 @@ static int TLSParserTest02(void) {
}
if (tls_state->client_version != TLS_VERSION_10) {
printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", TLS_VERSION_10, tls_state->client_version);
printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ",
TLS_VERSION_10, tls_state->client_version);
result = 0;
goto end;
}
@ -663,7 +680,8 @@ static int TLSParserTest03(void) {
}
if (tls_state->client_version != TLS_VERSION_10) {
printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", TLS_VERSION_10, tls_state->client_version);
printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ",
TLS_VERSION_10, tls_state->client_version);
result = 0;
goto end;
}
@ -1033,7 +1051,8 @@ static int TLSParserMultimsgTest01(void) {
}
if (tls_state->client_version != TLS_VERSION_10) {
printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ", TLS_VERSION_10, tls_state->client_version);
printf("expected version %04" PRIu16 ", got %04" PRIu16 ": ",
TLS_VERSION_10, tls_state->client_version);
result = 0;
goto end;
}

@ -471,6 +471,7 @@ int main(int argc, char **argv)
SigGroupHeadRegisterTests();
SCHInfoRegisterTests();
SCRuleVarsRegisterTests();
AppLayerParserRegisterTests();
if (list_unittests) {
UtListTests(regex_arg);
}

@ -1218,7 +1218,10 @@ int StreamTcpReassembleHandleSegmentUpdateACK (TcpReassemblyThreadCtx *ra_ctx, T
* \param ra_ctx Reassembly thread ctx, contains the queue
* \retval 0 ok
*/
int StreamTcpReassembleProcessAppLayer(TcpReassemblyThreadCtx *ra_ctx) {
int StreamTcpReassembleProcessAppLayer(TcpReassemblyThreadCtx *ra_ctx)
{
SCEnter();
int r = 0;
if (ra_ctx != NULL && ra_ctx->stream_q && ra_ctx->stream_q->len > 0) {
StreamMsg *smsg = NULL;
do {
@ -1227,11 +1230,13 @@ int StreamTcpReassembleProcessAppLayer(TcpReassemblyThreadCtx *ra_ctx) {
break;
/** Handle the stream msg. No need to use locking, flow is already locked */
AppLayerHandleMsg(smsg, FALSE);
r = AppLayerHandleMsg(smsg, FALSE);
if (r < 0)
break;
} while (ra_ctx->stream_q->len > 0);
}
return 0;
SCReturnInt(r);
}
int StreamTcpReassembleHandleSegment(TcpReassemblyThreadCtx *ra_ctx, TcpSession *ssn, TcpStream *stream, Packet *p) {

@ -1877,12 +1877,14 @@ static int StreamTcpPacketStateTimeWait(ThreadVars *tv, Packet *p, StreamTcpThre
}
/* flow is and stays locked */
static int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt) {
static int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt)
{
SCEnter();
TcpSession *ssn = (TcpSession *)p->flow->protoctx;
if (ssn == NULL || ssn->state == TCP_NONE) {
if (StreamTcpPacketStateNone(tv, p, stt, ssn) == -1)
return -1;
SCReturnInt(-1);
} else {
/* check if the packet is in right direction, when we missed the
SYN packet and picked up midstream session. */
@ -1892,39 +1894,39 @@ static int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt) {
switch (ssn->state) {
case TCP_SYN_SENT:
if(StreamTcpPacketStateSynSent(tv, p, stt, ssn))
return -1;
SCReturnInt(-1);
break;
case TCP_SYN_RECV:
if(StreamTcpPacketStateSynRecv(tv, p, stt, ssn))
return -1;
SCReturnInt(-1);
break;
case TCP_ESTABLISHED:
if(StreamTcpPacketStateEstablished(tv, p, stt, ssn))
return -1;
SCReturnInt(-1);
break;
case TCP_FIN_WAIT1:
if(StreamTcpPacketStateFinWait1(tv, p, stt, ssn))
return -1;
SCReturnInt(-1);
break;
case TCP_FIN_WAIT2:
if(StreamTcpPacketStateFinWait2(tv, p, stt, ssn))
return -1;
SCReturnInt(-1);
break;
case TCP_CLOSING:
if(StreamTcpPacketStateClosing(tv, p, stt, ssn))
return -1;
SCReturnInt(-1);
break;
case TCP_CLOSE_WAIT:
if(StreamTcpPacketStateCloseWait(tv, p, stt, ssn))
return -1;
SCReturnInt(-1);
break;
case TCP_LAST_ACK:
if(StreamTcpPakcetStateLastAck(tv, p, stt, ssn))
return -1;
SCReturnInt(-1);
break;
case TCP_TIME_WAIT:
if(StreamTcpPacketStateTimeWait(tv, p, stt, ssn))
return -1;
SCReturnInt(-1);
break;
case TCP_CLOSED:
//printf("StreamTcpPacket: packet received on closed state\n");
@ -1936,8 +1938,10 @@ static int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt) {
}
/* Process stream smsgs we may have in queue */
StreamTcpReassembleProcessAppLayer(stt->ra_ctx);
return 0;
if (StreamTcpReassembleProcessAppLayer(stt->ra_ctx) < 0)
SCReturnInt(-1);
SCReturnInt(0);
}
TmEcode StreamTcp (ThreadVars *tv, Packet *p, void *data, PacketQueue *pq)

@ -43,6 +43,7 @@ const char * SCErrorToString(SCError err)
CASE_CODE (SC_NUMERIC_VALUE_ERANGE);
CASE_CODE (SC_INVALID_NUM_BYTES);
CASE_CODE (SC_ERR_ARG_LEN_LONG);
CASE_CODE (SC_ALPARSER_ERR);
default:
return "UNKNOWN_ERROR";
}

Loading…
Cancel
Save