diff --git a/config.h.in b/config.h.in index b570a556ff..83df21570d 100644 --- a/config.h.in +++ b/config.h.in @@ -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 diff --git a/src/app-layer-dcerpc.c b/src/app-layer-dcerpc.c index a930266183..f1d3b81723 100644 --- a/src/app-layer-dcerpc.c +++ b/src/app-layer-dcerpc.c @@ -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); } diff --git a/src/app-layer-detect-proto.c b/src/app-layer-detect-proto.c index c4d3c0d308..4014b079e3 100644 --- a/src/app-layer-detect-proto.c +++ b/src/app-layer-detect-proto.c @@ -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) diff --git a/src/app-layer-parser.c b/src/app-layer-parser.c index d26ceb9899..cf845c0f3a 100644 --- a/src/app-layer-parser.c +++ b/src/app-layer-parser.c @@ -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 */ +} diff --git a/src/app-layer-parser.h b/src/app-layer-parser.h index 05fab06a3b..77ab19fdc3 100644 --- a/src/app-layer-parser.h +++ b/src/app-layer-parser.h @@ -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 *); diff --git a/src/app-layer-protos.h b/src/app-layer-protos.h index dc1e1f778f..6603a043f4 100644 --- a/src/app-layer-protos.h +++ b/src/app-layer-protos.h @@ -14,7 +14,9 @@ enum { ALPROTO_JABBER, ALPROTO_SMB, ALPROTO_DCERPC, - +#ifdef UNITTESTS + ALPROTO_TEST, +#endif /* UNITESTS */ /* keep last */ ALPROTO_MAX, }; diff --git a/src/app-layer-smb.c b/src/app-layer-smb.c index 4fc5001f4a..5c165cc313 100644 --- a/src/app-layer-smb.c +++ b/src/app-layer-smb.c @@ -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) { diff --git a/src/app-layer-tls.c b/src/app-layer-tls.c index 1c3b8993e9..8dbb72d7f0 100644 --- a/src/app-layer-tls.c +++ b/src/app-layer-tls.c @@ -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; } diff --git a/src/eidps.c b/src/eidps.c index 23b12f535d..8a05972e65 100644 --- a/src/eidps.c +++ b/src/eidps.c @@ -471,6 +471,7 @@ int main(int argc, char **argv) SigGroupHeadRegisterTests(); SCHInfoRegisterTests(); SCRuleVarsRegisterTests(); + AppLayerParserRegisterTests(); if (list_unittests) { UtListTests(regex_arg); } diff --git a/src/stream-tcp-reassemble.c b/src/stream-tcp-reassemble.c index 5484fea934..e850bd9560 100644 --- a/src/stream-tcp-reassemble.c +++ b/src/stream-tcp-reassemble.c @@ -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) { diff --git a/src/stream-tcp.c b/src/stream-tcp.c index 0d0e259c54..318ac0556d 100644 --- a/src/stream-tcp.c +++ b/src/stream-tcp.c @@ -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) diff --git a/src/util-error.c b/src/util-error.c index 806ae961ab..0aac067ae6 100644 --- a/src/util-error.c +++ b/src/util-error.c @@ -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"; }