mirror of https://github.com/OISF/suricata
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
5840 lines
173 KiB
C
5840 lines
173 KiB
C
/* Copyright (C) 2007-2010 Open Information Security Foundation
|
|
*
|
|
* You can copy, redistribute or modify this Program under the terms of
|
|
* the GNU General Public License version 2 as published by the Free
|
|
* Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* version 2 along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
* 02110-1301, USA.
|
|
*/
|
|
|
|
/**
|
|
* \file
|
|
*
|
|
* \author Victor Julien <victor@inliniac.net>
|
|
*
|
|
* Generic App-layer parsing functions.
|
|
*/
|
|
|
|
#include "suricata-common.h"
|
|
#include "debug.h"
|
|
#include "util-unittest.h"
|
|
#include "decode.h"
|
|
#include "threads.h"
|
|
|
|
#include "util-print.h"
|
|
#include "util-pool.h"
|
|
|
|
#include "flow-util.h"
|
|
|
|
#include "detect-engine-state.h"
|
|
|
|
#include "stream-tcp.h"
|
|
#include "stream-tcp-private.h"
|
|
#include "stream.h"
|
|
#include "stream-tcp-reassemble.h"
|
|
|
|
#include "app-layer.h"
|
|
#include "app-layer-protos.h"
|
|
#include "app-layer-parser.h"
|
|
#include "app-layer-smb.h"
|
|
#include "app-layer-dcerpc.h"
|
|
#include "app-layer-dcerpc-udp.h"
|
|
#include "app-layer-htp.h"
|
|
#include "app-layer-ftp.h"
|
|
#include "app-layer-ssl.h"
|
|
#include "app-layer-ssh.h"
|
|
#include "app-layer-smtp.h"
|
|
|
|
#include "util-spm.h"
|
|
|
|
#include "util-debug.h"
|
|
#include "decode-events.h"
|
|
#include "util-unittest-helper.h"
|
|
#include "util-validate.h"
|
|
|
|
static AppLayerProto al_proto_table[ALPROTO_MAX]; /**< Application layer protocol
|
|
table mapped to their
|
|
corresponding parsers */
|
|
|
|
#define MAX_PARSERS 100
|
|
static AppLayerParserTableElement al_parser_table[MAX_PARSERS];
|
|
static uint16_t al_max_parsers = 0; /* incremented for every registered parser */
|
|
|
|
static Pool *al_result_pool = NULL;
|
|
static SCMutex al_result_pool_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
#ifdef DEBUG
|
|
static uint32_t al_result_pool_elmts = 0;
|
|
#endif /* DEBUG */
|
|
|
|
/** \brief Get the file container flow
|
|
* \param f flow pointer to a LOCKED flow
|
|
* \retval files void pointer to the state
|
|
* \retval direction flow direction, either STREAM_TOCLIENT or STREAM_TOSERVER
|
|
* \retval NULL in case we have no state */
|
|
FileContainer *AppLayerGetFilesFromFlow(Flow *f, uint8_t direction) {
|
|
SCEnter();
|
|
|
|
DEBUG_ASSERT_FLOW_LOCKED(f);
|
|
|
|
uint16_t alproto = f->alproto;
|
|
|
|
if (alproto == ALPROTO_UNKNOWN)
|
|
SCReturnPtr(NULL, "FileContainer");
|
|
|
|
if (al_proto_table[alproto].StateGetFiles != NULL) {
|
|
FileContainer *ptr = al_proto_table[alproto].StateGetFiles(AppLayerGetProtoStateFromFlow(f), direction);
|
|
SCReturnPtr(ptr, "FileContainer");
|
|
} else {
|
|
SCReturnPtr(NULL, "FileContainer");
|
|
}
|
|
}
|
|
|
|
/** \brief Alloc a AppLayerParserResultElmt func for the pool */
|
|
static void *AlpResultElmtPoolAlloc(void *null)
|
|
{
|
|
AppLayerParserResultElmt *e = (AppLayerParserResultElmt *)SCMalloc
|
|
(sizeof(AppLayerParserResultElmt));
|
|
if (e == NULL)
|
|
return NULL;
|
|
|
|
memset(e, 0, sizeof(AppLayerParserResultElmt));
|
|
|
|
#ifdef DEBUG
|
|
al_result_pool_elmts++;
|
|
SCLogDebug("al_result_pool_elmts %"PRIu32"", al_result_pool_elmts);
|
|
#endif /* DEBUG */
|
|
return e;
|
|
}
|
|
|
|
static void AlpResultElmtPoolFree(void *e)
|
|
{
|
|
AppLayerParserResultElmt *re = (AppLayerParserResultElmt *)e;
|
|
|
|
if (re->flags & ALP_RESULT_ELMT_ALLOC) {
|
|
if (re->data_ptr != NULL)
|
|
SCFree(re->data_ptr);
|
|
}
|
|
SCFree(re);
|
|
|
|
#ifdef DEBUG
|
|
al_result_pool_elmts--;
|
|
SCLogDebug("al_result_pool_elmts %"PRIu32"", al_result_pool_elmts);
|
|
#endif /* DEBUG */
|
|
}
|
|
|
|
static AppLayerParserResultElmt *AlpGetResultElmt(void)
|
|
{
|
|
SCMutexLock(&al_result_pool_mutex);
|
|
AppLayerParserResultElmt *e = (AppLayerParserResultElmt *)PoolGet(al_result_pool);
|
|
SCMutexUnlock(&al_result_pool_mutex);
|
|
|
|
if (e == NULL) {
|
|
return NULL;
|
|
}
|
|
e->next = NULL;
|
|
return e;
|
|
}
|
|
|
|
static void AlpReturnResultElmt(AppLayerParserResultElmt *e)
|
|
{
|
|
if (e->flags & ALP_RESULT_ELMT_ALLOC) {
|
|
if (e->data_ptr != NULL)
|
|
SCFree(e->data_ptr);
|
|
}
|
|
e->flags = 0;
|
|
e->data_ptr = NULL;
|
|
e->data_len = 0;
|
|
e->next = NULL;
|
|
|
|
SCMutexLock(&al_result_pool_mutex);
|
|
PoolReturn(al_result_pool, (void *)e);
|
|
SCMutexUnlock(&al_result_pool_mutex);
|
|
}
|
|
|
|
static void AlpAppendResultElmt(AppLayerParserResult *r, AppLayerParserResultElmt *e)
|
|
{
|
|
if (r->head == NULL) {
|
|
r->head = e;
|
|
r->tail = e;
|
|
r->cnt = 1;
|
|
} else {
|
|
r->tail->next = e;
|
|
r->tail = e;
|
|
r->cnt++;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \param alloc Is ptr alloc'd (1) or a ptr to static mem (0).
|
|
* \retval -1 error
|
|
* \retval 0 ok
|
|
*/
|
|
static int AlpStoreField(AppLayerParserResult *output, uint16_t idx,
|
|
uint8_t *ptr, uint32_t len, uint8_t alloc)
|
|
{
|
|
SCEnter();
|
|
|
|
AppLayerParserResultElmt *e = AlpGetResultElmt();
|
|
if (e == NULL) {
|
|
SCLogError(SC_ERR_POOL_EMPTY, "App layer \"al_result_pool\" is empty");
|
|
SCReturnInt(-1);
|
|
}
|
|
|
|
if (alloc == 1)
|
|
e->flags |= ALP_RESULT_ELMT_ALLOC;
|
|
|
|
e->name_idx = idx;
|
|
e->data_ptr = ptr;
|
|
e->data_len = len;
|
|
AlpAppendResultElmt(output, e);
|
|
|
|
SCReturnInt(0);
|
|
}
|
|
|
|
void AppLayerSetEOF(Flow *f)
|
|
{
|
|
if (f == NULL)
|
|
return;
|
|
|
|
AppLayerParserStateStore *parser_state_store =
|
|
(AppLayerParserStateStore *)f->alparser;
|
|
if (parser_state_store != NULL) {
|
|
parser_state_store->id_flags |= APP_LAYER_TRANSACTION_EOF;
|
|
parser_state_store->to_client.flags |= APP_LAYER_PARSER_EOF;
|
|
parser_state_store->to_server.flags |= APP_LAYER_PARSER_EOF;
|
|
}
|
|
}
|
|
|
|
/** \brief Parse a field up to we reach the size limit
|
|
*
|
|
* \retval 1 Field found and stored.
|
|
* \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)
|
|
{
|
|
SCEnter();
|
|
|
|
if ((pstate->store_len + input_len) < size) {
|
|
if (pstate->store_len == 0) {
|
|
pstate->store = SCMalloc(input_len);
|
|
if (pstate->store == NULL)
|
|
SCReturnInt(-1);
|
|
|
|
memcpy(pstate->store, input, input_len);
|
|
pstate->store_len = input_len;
|
|
} else {
|
|
pstate->store = SCRealloc(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;
|
|
}
|
|
} else {
|
|
if (pstate->store_len == 0) {
|
|
int r = AlpStoreField(output, field_idx, input, size, /* static mem */0);
|
|
if (r == -1) {
|
|
SCLogError(SC_ERR_ALPARSER, "Failed to store field value");
|
|
SCReturnInt(-1);
|
|
}
|
|
(*offset) += size;
|
|
|
|
SCReturnInt(1);
|
|
} else {
|
|
uint32_t diff = size - pstate->store_len;
|
|
|
|
pstate->store = SCRealloc(pstate->store, (diff + pstate->store_len));
|
|
if (pstate->store == NULL)
|
|
SCReturnInt(-1);
|
|
|
|
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);
|
|
if (r == -1) {
|
|
SCLogError(SC_ERR_ALPARSER, "Failed to store field value");
|
|
SCReturnInt(-1);
|
|
}
|
|
|
|
(*offset) += diff;
|
|
|
|
pstate->store = NULL;
|
|
pstate->store_len = 0;
|
|
|
|
SCReturnInt(1);
|
|
}
|
|
}
|
|
|
|
SCReturnInt(0);
|
|
}
|
|
|
|
/** \brief Parse a field up to the EOF
|
|
*
|
|
* \retval 1 Field found and stored.
|
|
* \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)
|
|
{
|
|
SCEnter();
|
|
|
|
if (pstate->store_len == 0) {
|
|
if (pstate->flags & APP_LAYER_PARSER_EOF) {
|
|
SCLogDebug("store_len 0 and EOF");
|
|
|
|
int r = AlpStoreField(output, field_idx, input, input_len, 0);
|
|
if (r == -1) {
|
|
SCLogError(SC_ERR_ALPARSER, "Failed to store field value");
|
|
SCReturnInt(-1);
|
|
}
|
|
|
|
SCReturnInt(1);
|
|
} else {
|
|
SCLogDebug("store_len 0 but no EOF");
|
|
|
|
/* delimiter field not found, so store the result for the next run */
|
|
pstate->store = SCMalloc(input_len);
|
|
if (pstate->store == NULL)
|
|
SCReturnInt(-1);
|
|
|
|
memcpy(pstate->store, input, input_len);
|
|
pstate->store_len = input_len;
|
|
}
|
|
} else {
|
|
if (pstate->flags & APP_LAYER_PARSER_EOF) {
|
|
SCLogDebug("store_len %" PRIu32 " and EOF", pstate->store_len);
|
|
|
|
pstate->store = SCRealloc(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;
|
|
|
|
int r = AlpStoreField(output, field_idx, pstate->store, pstate->store_len, 1);
|
|
if (r == -1) {
|
|
SCLogError(SC_ERR_ALPARSER, "Failed to store field value");
|
|
SCReturnInt(-1);
|
|
}
|
|
|
|
pstate->store = NULL;
|
|
pstate->store_len = 0;
|
|
|
|
SCReturnInt(1);
|
|
} else {
|
|
SCLogDebug("store_len %" PRIu32 " but no EOF", pstate->store_len);
|
|
|
|
/* delimiter field not found, so store the result for the next run */
|
|
pstate->store = SCRealloc(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;
|
|
}
|
|
|
|
}
|
|
|
|
SCReturnInt(0);
|
|
}
|
|
|
|
/** \brief Parse a field up to a delimeter.
|
|
*
|
|
* \retval 1 Field found and stored.
|
|
* \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)
|
|
{
|
|
SCEnter();
|
|
SCLogDebug("pstate->store_len %" PRIu32 ", delim_len %" PRIu32 "",
|
|
pstate->store_len, delim_len);
|
|
|
|
if (pstate->store_len == 0) {
|
|
uint8_t *ptr = SpmSearch(input, input_len, (uint8_t*)delim, delim_len);
|
|
if (ptr != NULL) {
|
|
uint32_t len = ptr - input;
|
|
SCLogDebug(" len %" PRIu32 "", len);
|
|
|
|
int r = AlpStoreField(output, field_idx, input, len, 0);
|
|
if (r == -1) {
|
|
SCLogError(SC_ERR_ALPARSER, "Failed to store field value");
|
|
SCReturnInt(-1);
|
|
}
|
|
(*offset) += (len + delim_len);
|
|
SCReturnInt(1);
|
|
} else {
|
|
if (pstate->flags & APP_LAYER_PARSER_EOF) {
|
|
SCLogDebug("delim not found and EOF");
|
|
SCReturnInt(0);
|
|
}
|
|
|
|
SCLogDebug("delim not found, continue");
|
|
|
|
/* delimiter field not found, so store the result for the next run */
|
|
pstate->store = SCMalloc(input_len);
|
|
if (pstate->store == NULL)
|
|
SCReturnInt(-1);
|
|
|
|
memcpy(pstate->store, input, input_len);
|
|
pstate->store_len = input_len;
|
|
}
|
|
} else {
|
|
uint8_t *ptr = SpmSearch(input, input_len, (uint8_t*)delim, delim_len);
|
|
if (ptr != NULL) {
|
|
uint32_t len = ptr - input;
|
|
SCLogDebug("len %" PRIu32 " + %" PRIu32 " = %" PRIu32 "", len,
|
|
pstate->store_len, len + pstate->store_len);
|
|
|
|
pstate->store = SCRealloc(pstate->store, (len + pstate->store_len));
|
|
if (pstate->store == NULL)
|
|
SCReturnInt(-1);
|
|
|
|
memcpy(pstate->store+pstate->store_len, input, len);
|
|
pstate->store_len += len;
|
|
|
|
int r = AlpStoreField(output, field_idx, pstate->store,
|
|
pstate->store_len, 1);
|
|
if (r == -1) {
|
|
SCLogError(SC_ERR_ALPARSER, "Failed to store field value");
|
|
SCReturnInt(-1);
|
|
}
|
|
pstate->store = NULL;
|
|
pstate->store_len = 0;
|
|
|
|
(*offset) += (len + delim_len);
|
|
SCReturnInt(1);
|
|
} else {
|
|
if (pstate->flags & APP_LAYER_PARSER_EOF) {
|
|
/* 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 = SCRealloc(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;
|
|
SCLogDebug("input_len < delim_len, checking pstate->store");
|
|
|
|
if (pstate->store_len >= delim_len) {
|
|
ptr = SpmSearch(pstate->store, pstate->store_len, (uint8_t*)delim,
|
|
delim_len);
|
|
if (ptr != NULL) {
|
|
SCLogDebug("now we found the delim");
|
|
|
|
uint32_t len = ptr - pstate->store;
|
|
int r = AlpStoreField(output, field_idx,
|
|
pstate->store, len, 1);
|
|
if (r == -1) {
|
|
SCLogError(SC_ERR_ALPARSER, "Failed to store "
|
|
"field value");
|
|
SCReturnInt(-1);
|
|
}
|
|
|
|
pstate->store = NULL;
|
|
pstate->store_len = 0;
|
|
|
|
(*offset) += (input_len);
|
|
|
|
SCLogDebug("offset %" PRIu32 "", (*offset));
|
|
SCReturnInt(1);
|
|
}
|
|
goto free_and_return;
|
|
}
|
|
goto free_and_return;
|
|
}
|
|
free_and_return:
|
|
SCLogDebug("not found and EOF, so free what we have so far.");
|
|
SCFree(pstate->store);
|
|
pstate->store = NULL;
|
|
pstate->store_len = 0;
|
|
SCReturnInt(0);
|
|
}
|
|
|
|
/* delimiter field not found, so store the result for the next run */
|
|
pstate->store = SCRealloc(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;
|
|
|
|
/* 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) {
|
|
SCLogDebug("input_len < delim_len, checking pstate->store");
|
|
|
|
ptr = SpmSearch(pstate->store, pstate->store_len, (uint8_t*)delim, delim_len);
|
|
if (ptr != NULL) {
|
|
SCLogDebug("now we found the delim");
|
|
|
|
uint32_t len = ptr - pstate->store;
|
|
int r = AlpStoreField(output, field_idx, pstate->store, len, 1);
|
|
if (r == -1) {
|
|
SCLogError(SC_ERR_ALPARSER, "Failed to store field value");
|
|
SCReturnInt(-1);
|
|
}
|
|
pstate->store = NULL;
|
|
pstate->store_len = 0;
|
|
|
|
(*offset) += (input_len);
|
|
|
|
SCLogDebug("ffset %" PRIu32 "", (*offset));
|
|
SCReturnInt(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
SCReturnInt(0);
|
|
}
|
|
|
|
uint16_t AppLayerGetProtoByName(const char *name)
|
|
{
|
|
uint8_t u = 1;
|
|
SCLogDebug("looking for name %s", name);
|
|
|
|
for ( ; u < ALPROTO_MAX; u++) {
|
|
if (al_proto_table[u].name == NULL)
|
|
continue;
|
|
|
|
SCLogDebug("name %s proto %"PRIu16"",
|
|
al_proto_table[u].name, u);
|
|
|
|
if (strcasecmp(name,al_proto_table[u].name) == 0) {
|
|
SCLogDebug("match, returning %"PRIu16"", u);
|
|
return u;
|
|
}
|
|
}
|
|
|
|
return ALPROTO_UNKNOWN;
|
|
}
|
|
|
|
/** \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.
|
|
* \param AppLayerParser pointer to the parser function
|
|
*
|
|
* \retval 0 on success
|
|
* \retval -1 on error
|
|
*/
|
|
int AppLayerRegisterParser(char *name, uint16_t proto, uint16_t parser_id,
|
|
int (*AppLayerParser)(Flow *f, void *protocol_state,
|
|
AppLayerParserState *parser_state,
|
|
uint8_t *input, uint32_t input_len,
|
|
void *local_data,
|
|
AppLayerParserResult *output),
|
|
char *dependency)
|
|
{
|
|
|
|
al_max_parsers++;
|
|
|
|
if(al_max_parsers >= MAX_PARSERS){
|
|
SCLogInfo("Failed to register %s al_parser_table array full",name);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
al_parser_table[al_max_parsers].name = name;
|
|
al_parser_table[al_max_parsers].proto = proto;
|
|
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 ", parser_local_id %" PRIu32 "",
|
|
AppLayerParser, proto, al_max_parsers,
|
|
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.
|
|
* \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)(Flow *f, void *protocol_state,
|
|
AppLayerParserState *parser_state,
|
|
uint8_t *input, uint32_t input_len,
|
|
void *local_data, AppLayerParserResult *output))
|
|
{
|
|
|
|
al_max_parsers++;
|
|
|
|
if(al_max_parsers >= MAX_PARSERS){
|
|
SCLogInfo("Failed to register %s al_parser_table array full",name);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
al_parser_table[al_max_parsers].name = name;
|
|
al_parser_table[al_max_parsers].AppLayerParser = AppLayerParser;
|
|
|
|
al_proto_table[proto].name = name;
|
|
|
|
/* create proto, direction -- parser mapping */
|
|
if (flags & STREAM_TOSERVER) {
|
|
al_proto_table[proto].to_server = al_max_parsers;
|
|
} else if (flags & STREAM_TOCLIENT) {
|
|
al_proto_table[proto].to_client = al_max_parsers;
|
|
}
|
|
|
|
SCLogDebug("registered %p at proto %" PRIu32 " flags %02X, al_proto_table "
|
|
"idx %" PRIu32 ", %s", AppLayerParser, proto,
|
|
flags, al_max_parsers, name);
|
|
return 0;
|
|
}
|
|
|
|
void AppLayerRegisterStateFuncs(uint16_t proto, void *(*StateAlloc)(void),
|
|
void (*StateFree)(void *))
|
|
{
|
|
al_proto_table[proto].StateAlloc = StateAlloc;
|
|
al_proto_table[proto].StateFree = StateFree;
|
|
}
|
|
|
|
void AppLayerRegisterTransactionIdFuncs(uint16_t proto,
|
|
void (*StateUpdateTransactionId)(void *state, uint16_t *), void (*StateTransactionFree)(void *, uint16_t))
|
|
{
|
|
al_proto_table[proto].StateUpdateTransactionId = StateUpdateTransactionId;
|
|
al_proto_table[proto].StateTransactionFree = StateTransactionFree;
|
|
}
|
|
|
|
void AppLayerRegisterLocalStorageFunc(uint16_t proto,
|
|
void *(*LocalStorageAlloc)(void),
|
|
void (*LocalStorageFree)(void *))
|
|
{
|
|
al_proto_table[proto].LocalStorageAlloc = LocalStorageAlloc;
|
|
al_proto_table[proto].LocalStorageFree = LocalStorageFree;
|
|
|
|
return;
|
|
}
|
|
|
|
void *AppLayerGetProtocolParserLocalStorage(uint16_t proto)
|
|
{
|
|
if (al_proto_table[proto].LocalStorageAlloc != NULL) {
|
|
return al_proto_table[proto].LocalStorageAlloc();
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void AppLayerRegisterGetFilesFunc(uint16_t proto,
|
|
FileContainer *(*StateGetFiles)(void *, uint8_t))
|
|
{
|
|
al_proto_table[proto].StateGetFiles = StateGetFiles;
|
|
}
|
|
|
|
/** \brief Indicate to the app layer parser that a logger is active
|
|
* for this protocol.
|
|
*/
|
|
void AppLayerRegisterLogger(uint16_t proto) {
|
|
al_proto_table[proto].logger = TRUE;
|
|
}
|
|
|
|
|
|
AppLayerParserStateStore *AppLayerParserStateStoreAlloc(void)
|
|
{
|
|
AppLayerParserStateStore *s = (AppLayerParserStateStore *)SCMalloc
|
|
(sizeof(AppLayerParserStateStore));
|
|
if (s == NULL)
|
|
return NULL;
|
|
|
|
memset(s, 0, sizeof(AppLayerParserStateStore));
|
|
|
|
/* when we start, we're working with transaction id 1 */
|
|
s->avail_id = 1;
|
|
|
|
return s;
|
|
}
|
|
|
|
/** \brief free a AppLayerParserStateStore structure
|
|
* \param s AppLayerParserStateStore structure to free */
|
|
void AppLayerParserStateStoreFree(AppLayerParserStateStore *s)
|
|
{
|
|
if (s->to_server.store != NULL)
|
|
SCFree(s->to_server.store);
|
|
if (s->to_client.store != NULL)
|
|
SCFree(s->to_client.store);
|
|
if (s->decoder_events != NULL)
|
|
AppLayerDecoderEventsFreeEvents(s->decoder_events);
|
|
s->decoder_events = NULL;
|
|
|
|
SCFree(s);
|
|
}
|
|
|
|
static void AppLayerParserResultCleanup(AppLayerParserResult *result)
|
|
{
|
|
AppLayerParserResultElmt *e = result->head;
|
|
while (e != NULL) {
|
|
AppLayerParserResultElmt *next_e = e->next;
|
|
|
|
result->head = next_e;
|
|
if (next_e == NULL)
|
|
result->tail = NULL;
|
|
result->cnt--;
|
|
|
|
AlpReturnResultElmt(e);
|
|
e = next_e;
|
|
}
|
|
}
|
|
|
|
static int AppLayerDoParse(void *local_data, Flow *f,
|
|
void *app_layer_state,
|
|
AppLayerParserState *parser_state,
|
|
uint8_t *input, uint32_t input_len,
|
|
uint16_t parser_idx,
|
|
uint16_t proto)
|
|
{
|
|
SCEnter();
|
|
DEBUG_ASSERT_FLOW_LOCKED(f);
|
|
|
|
int retval = 0;
|
|
AppLayerParserResult result = { NULL, NULL, 0 };
|
|
|
|
SCLogDebug("parser_idx %" PRIu32 "", parser_idx);
|
|
//printf("--- (%u)\n", input_len);
|
|
//PrintRawDataFp(stdout, input,input_len);
|
|
//printf("---\n");
|
|
|
|
/* invoke the parser */
|
|
int r = al_parser_table[parser_idx].
|
|
AppLayerParser(f, app_layer_state,
|
|
parser_state, input, input_len,
|
|
local_data, &result);
|
|
if (r < 0) {
|
|
if (r == -1) {
|
|
AppLayerParserResultCleanup(&result);
|
|
SCReturnInt(-1);
|
|
#ifdef DEBUG
|
|
} else {
|
|
BUG_ON(r); /* this is not supposed to happen!! */
|
|
#else
|
|
SCReturnInt(-1);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/* process the result elements */
|
|
AppLayerParserResultElmt *e = result.head;
|
|
for (; e != NULL; e = e->next) {
|
|
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)
|
|
{
|
|
SCLogDebug("no parser for proto %" PRIu32 ", parser_local_id "
|
|
"%" PRIu32 "", proto, e->name_idx);
|
|
continue;
|
|
}
|
|
|
|
uint16_t idx = al_proto_table[proto].map[e->name_idx]->parser_id;
|
|
|
|
/* prepare */
|
|
uint16_t tmp = parser_state->parse_field;
|
|
parser_state->parse_field = 0;
|
|
parser_state->flags |= APP_LAYER_PARSER_EOF;
|
|
|
|
r = AppLayerDoParse(local_data, f, app_layer_state, parser_state, e->data_ptr,
|
|
e->data_len, idx, proto);
|
|
|
|
/* restore */
|
|
parser_state->flags &= ~APP_LAYER_PARSER_EOF;
|
|
parser_state->parse_field = tmp;
|
|
|
|
/* bail out on a serious error */
|
|
if (r < 0) {
|
|
if (r == -1) {
|
|
retval = -1;
|
|
break;
|
|
#ifdef DEBUG
|
|
} else {
|
|
BUG_ON(r); /* this is not supposed to happen!! */
|
|
#else
|
|
SCReturnInt(-1);
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
AppLayerParserResultCleanup(&result);
|
|
SCReturnInt(retval);
|
|
}
|
|
|
|
/** \brief remove obsolete (inspected and logged) transactions */
|
|
static int AppLayerTransactionsCleanup(AppLayerProto *p, AppLayerParserStateStore *parser_state_store, void *app_layer_state) {
|
|
SCEnter();
|
|
|
|
uint16_t obsolete = 0;
|
|
|
|
if (p->StateTransactionFree == NULL) {
|
|
SCLogDebug("no StateTransactionFree function");
|
|
goto end;
|
|
}
|
|
|
|
if (p->logger == TRUE) {
|
|
uint16_t low = (parser_state_store->logged_id < parser_state_store->inspect_id) ?
|
|
parser_state_store->logged_id : parser_state_store->inspect_id;
|
|
|
|
obsolete = low - parser_state_store->base_id;
|
|
|
|
SCLogDebug("low %"PRIu16" (logged %"PRIu16", inspect %"PRIu16"), base_id %"PRIu16", obsolete %"PRIu16", avail_id %"PRIu16,
|
|
low, parser_state_store->logged_id, parser_state_store->inspect_id, parser_state_store->base_id, obsolete, parser_state_store->avail_id);
|
|
} else {
|
|
obsolete = parser_state_store->inspect_id - parser_state_store->base_id;
|
|
}
|
|
|
|
SCLogDebug("obsolete transactions: %"PRIu16, obsolete);
|
|
|
|
/* call the callback on the obsolete transactions */
|
|
while ((obsolete--)) {
|
|
p->StateTransactionFree(app_layer_state, parser_state_store->base_id);
|
|
parser_state_store->base_id++;
|
|
}
|
|
|
|
SCLogDebug("base_id %"PRIu16, parser_state_store->base_id);
|
|
|
|
end:
|
|
SCReturnInt(0);
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
uint32_t applayererrors = 0;
|
|
uint32_t applayerhttperrors = 0;
|
|
#endif
|
|
|
|
/**
|
|
* \brief Layer 7 Parsing main entry point.
|
|
*
|
|
* \param f Properly initialized and locked flow.
|
|
* \param proto L7 proto, e.g. ALPROTO_HTTP
|
|
* \param flags Stream flags
|
|
* \param input Input L7 data
|
|
* \param input_len Length of the input data.
|
|
*
|
|
* \retval -1 error
|
|
* \retval 0 ok
|
|
*/
|
|
int AppLayerParse(void *local_data, Flow *f, uint8_t proto,
|
|
uint8_t flags, uint8_t *input, uint32_t input_len)
|
|
{
|
|
SCEnter();
|
|
|
|
DEBUG_ASSERT_FLOW_LOCKED(f);
|
|
|
|
uint16_t parser_idx = 0;
|
|
AppLayerProto *p = &al_proto_table[proto];
|
|
TcpSession *ssn = NULL;
|
|
|
|
/* Used only if it's TCP */
|
|
ssn = f->protoctx;
|
|
|
|
/* Do this check before calling AppLayerParse */
|
|
if (flags & STREAM_GAP) {
|
|
SCLogDebug("stream gap detected (missing packets), this is not yet supported.");
|
|
goto error;
|
|
}
|
|
|
|
/* Get the parser state (if any) */
|
|
AppLayerParserStateStore *parser_state_store = f->alparser;
|
|
if (parser_state_store == NULL) {
|
|
parser_state_store = AppLayerParserStateStoreAlloc();
|
|
if (parser_state_store == NULL)
|
|
goto error;
|
|
|
|
f->alparser = (void *)parser_state_store;
|
|
}
|
|
|
|
parser_state_store->version++;
|
|
SCLogDebug("app layer state version incremented to %"PRIu16,
|
|
parser_state_store->version);
|
|
|
|
AppLayerParserState *parser_state = NULL;
|
|
if (flags & STREAM_TOSERVER) {
|
|
SCLogDebug("to_server msg (flow %p)", f);
|
|
|
|
parser_state = &parser_state_store->to_server;
|
|
if (!(parser_state->flags & APP_LAYER_PARSER_USE)) {
|
|
parser_idx = p->to_server;
|
|
parser_state->cur_parser = parser_idx;
|
|
parser_state->flags |= APP_LAYER_PARSER_USE;
|
|
} else {
|
|
SCLogDebug("using parser %" PRIu32 " we stored before (to_server)",
|
|
parser_state->cur_parser);
|
|
parser_idx = parser_state->cur_parser;
|
|
}
|
|
} else {
|
|
SCLogDebug("to_client msg (flow %p)", f);
|
|
|
|
parser_state = &parser_state_store->to_client;
|
|
if (!(parser_state->flags & APP_LAYER_PARSER_USE)) {
|
|
parser_idx = p->to_client;
|
|
parser_state->cur_parser = parser_idx;
|
|
parser_state->flags |= APP_LAYER_PARSER_USE;
|
|
} else {
|
|
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) {
|
|
SCLogDebug("no parser for protocol %" PRIu32 "", proto);
|
|
SCReturnInt(0);
|
|
}
|
|
|
|
if (flags & STREAM_EOF)
|
|
parser_state->flags |= APP_LAYER_PARSER_EOF;
|
|
|
|
/* See if we already have a 'app layer' state */
|
|
void *app_layer_state = f->alstate;
|
|
if (app_layer_state == NULL) {
|
|
/* lock the allocation of state as we may
|
|
* alloc more than one otherwise */
|
|
app_layer_state = p->StateAlloc();
|
|
if (app_layer_state == NULL) {
|
|
goto error;
|
|
}
|
|
|
|
f->alstate = app_layer_state;
|
|
SCLogDebug("alloced new app layer state %p (name %s)",
|
|
app_layer_state, al_proto_table[f->alproto].name);
|
|
} else {
|
|
SCLogDebug("using existing app layer state %p (name %s))",
|
|
app_layer_state, al_proto_table[f->alproto].name);
|
|
}
|
|
|
|
/* invoke the recursive parser, but only on data. We may get empty msgs on EOF */
|
|
if (input_len > 0) {
|
|
int r = AppLayerDoParse(local_data, f, app_layer_state, parser_state,
|
|
input, input_len, parser_idx, proto);
|
|
if (r < 0)
|
|
goto error;
|
|
}
|
|
|
|
/* set the packets to no inspection and reassembly if required */
|
|
if (parser_state->flags & APP_LAYER_PARSER_NO_INSPECTION) {
|
|
AppLayerSetEOF(f);
|
|
FlowSetNoPayloadInspectionFlag(f);
|
|
FlowSetSessionNoApplayerInspectionFlag(f);
|
|
|
|
/* Set the no reassembly flag for both the stream in this TcpSession */
|
|
if (parser_state->flags & APP_LAYER_PARSER_NO_REASSEMBLY) {
|
|
if (ssn != NULL) {
|
|
StreamTcpSetSessionNoReassemblyFlag(ssn,
|
|
flags & STREAM_TOCLIENT ? 1 : 0);
|
|
StreamTcpSetSessionNoReassemblyFlag(ssn,
|
|
flags & STREAM_TOSERVER ? 1 : 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* update the transaction id */
|
|
if (p->StateUpdateTransactionId != NULL) {
|
|
p->StateUpdateTransactionId(app_layer_state, &parser_state_store->avail_id);
|
|
|
|
/* next, see if we can get rid of transactions now */
|
|
AppLayerTransactionsCleanup(p, parser_state_store, app_layer_state);
|
|
}
|
|
if (parser_state->flags & APP_LAYER_PARSER_EOF) {
|
|
SCLogDebug("eof, flag Transaction id's");
|
|
parser_state_store->id_flags |= APP_LAYER_TRANSACTION_EOF;
|
|
}
|
|
|
|
SCReturnInt(0);
|
|
|
|
error:
|
|
if (ssn != NULL) {
|
|
#ifdef DEBUG
|
|
if (FLOW_IS_IPV4(f)) {
|
|
char src[16];
|
|
char dst[16];
|
|
PrintInet(AF_INET, (const void*)&f->src.addr_data32[0], src,
|
|
sizeof (src));
|
|
PrintInet(AF_INET, (const void*)&f->dst.addr_data32[0], dst,
|
|
sizeof (dst));
|
|
|
|
SCLogDebug("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[f->alproto].name,
|
|
f->proto, src, dst, f->sp, f->dp);
|
|
fflush(stdout);
|
|
} else if (FLOW_IS_IPV6(f)) {
|
|
char dst6[46];
|
|
char src6[46];
|
|
|
|
PrintInet(AF_INET6, (const void*)&f->src.addr_data32, src6,
|
|
sizeof (src6));
|
|
PrintInet(AF_INET6, (const void*)&f->dst.addr_data32, dst6,
|
|
sizeof (dst6));
|
|
|
|
SCLogDebug("Error occured in parsing \"%s\" app layer "
|
|
"protocol, using network protocol %"PRIu8", source IPv6 "
|
|
"address %s, destination IPv6 address %s, src port %"PRIu16" and "
|
|
"dst port %"PRIu16"", al_proto_table[f->alproto].name,
|
|
f->proto, src6, dst6, f->sp, f->dp);
|
|
fflush(stdout);
|
|
}
|
|
applayererrors++;
|
|
if (f->alproto == ALPROTO_HTTP)
|
|
applayerhttperrors++;
|
|
#endif
|
|
/* Set the no app layer inspection flag for both
|
|
* the stream in this Flow */
|
|
FlowSetSessionNoApplayerInspectionFlag(f);
|
|
AppLayerSetEOF(f);
|
|
}
|
|
|
|
SCReturnInt(-1);
|
|
}
|
|
|
|
/** \brief get the base transaction id */
|
|
int AppLayerTransactionGetBaseId(Flow *f) {
|
|
SCEnter();
|
|
|
|
DEBUG_ASSERT_FLOW_LOCKED(f);
|
|
|
|
AppLayerParserStateStore *parser_state_store =
|
|
(AppLayerParserStateStore *)f->alparser;
|
|
|
|
if (parser_state_store == NULL) {
|
|
SCLogDebug("no state store");
|
|
goto error;
|
|
}
|
|
|
|
SCReturnInt((int)parser_state_store->base_id);
|
|
|
|
error:
|
|
SCReturnInt(-1);
|
|
}
|
|
|
|
/** \brief get the base transaction id
|
|
*
|
|
* \retval txid or -1 on error
|
|
*/
|
|
int AppLayerTransactionGetInspectId(Flow *f) {
|
|
SCEnter();
|
|
|
|
DEBUG_ASSERT_FLOW_LOCKED(f);
|
|
|
|
AppLayerParserStateStore *parser_state_store =
|
|
(AppLayerParserStateStore *)f->alparser;
|
|
|
|
if (parser_state_store == NULL) {
|
|
SCLogDebug("no state store");
|
|
goto error;
|
|
}
|
|
|
|
SCReturnInt((int)parser_state_store->inspect_id);
|
|
|
|
error:
|
|
SCReturnInt(-1);
|
|
}
|
|
|
|
uint16_t AppLayerTransactionGetAvailId(Flow *f) {
|
|
SCEnter();
|
|
|
|
DEBUG_ASSERT_FLOW_LOCKED(f);
|
|
|
|
AppLayerParserStateStore *parser_state_store =
|
|
(AppLayerParserStateStore *)f->alparser;
|
|
|
|
if (parser_state_store == NULL) {
|
|
SCLogDebug("no state store");
|
|
SCReturnUInt(0);
|
|
}
|
|
|
|
SCReturnUInt(parser_state_store->avail_id);
|
|
}
|
|
|
|
/** \brief get the highest loggable transaction id */
|
|
int AppLayerTransactionGetLoggableId(Flow *f) {
|
|
SCEnter();
|
|
|
|
DEBUG_ASSERT_FLOW_LOCKED(f);
|
|
|
|
AppLayerParserStateStore *parser_state_store =
|
|
(AppLayerParserStateStore *)f->alparser;
|
|
|
|
if (parser_state_store == NULL) {
|
|
SCLogDebug("no state store");
|
|
goto error;
|
|
}
|
|
|
|
int id = 0;
|
|
|
|
if (parser_state_store->id_flags & APP_LAYER_TRANSACTION_EOF) {
|
|
SCLogDebug("eof, return current transaction as well");
|
|
id = (int)(parser_state_store->avail_id);
|
|
} else {
|
|
id = (int)(parser_state_store->avail_id - 1);
|
|
}
|
|
|
|
SCReturnInt(id);
|
|
|
|
error:
|
|
SCReturnInt(-1);
|
|
}
|
|
|
|
/** \brief get the highest loggable transaction id */
|
|
void AppLayerTransactionUpdateLoggedId(Flow *f) {
|
|
SCEnter();
|
|
|
|
DEBUG_ASSERT_FLOW_LOCKED(f);
|
|
|
|
AppLayerParserStateStore *parser_state_store =
|
|
(AppLayerParserStateStore *)f->alparser;
|
|
|
|
if (parser_state_store == NULL) {
|
|
SCLogDebug("no state store");
|
|
goto error;
|
|
}
|
|
|
|
parser_state_store->logged_id++;
|
|
SCReturn;
|
|
|
|
error:
|
|
SCReturn;
|
|
}
|
|
/** \brief get the highest loggable transaction id */
|
|
int AppLayerTransactionGetLoggedId(Flow *f) {
|
|
SCEnter();
|
|
|
|
DEBUG_ASSERT_FLOW_LOCKED(f);
|
|
|
|
AppLayerParserStateStore *parser_state_store =
|
|
(AppLayerParserStateStore *)f->alparser;
|
|
|
|
if (parser_state_store == NULL) {
|
|
SCLogDebug("no state store");
|
|
goto error;
|
|
}
|
|
|
|
SCReturnInt((int)parser_state_store->logged_id);
|
|
|
|
error:
|
|
SCReturnInt(-1);
|
|
}
|
|
|
|
/**
|
|
* \brief get the version of the state in a direction
|
|
*
|
|
* \param f LOCKED flow
|
|
* \param direction STREAM_TOSERVER or STREAM_TOCLIENT
|
|
*/
|
|
uint16_t AppLayerGetStateVersion(Flow *f) {
|
|
SCEnter();
|
|
|
|
DEBUG_ASSERT_FLOW_LOCKED(f);
|
|
|
|
uint16_t version = 0;
|
|
AppLayerParserStateStore *parser_state_store = NULL;
|
|
|
|
parser_state_store = (AppLayerParserStateStore *)f->alparser;
|
|
if (parser_state_store != NULL) {
|
|
version = parser_state_store->version;
|
|
}
|
|
|
|
SCReturnUInt(version);
|
|
}
|
|
|
|
/**
|
|
* \param f LOCKED flow
|
|
* \param direction STREAM_TOSERVER or STREAM_TOCLIENT
|
|
*
|
|
* \retval 2 current transaction done, new available
|
|
* \retval 1 current transaction done, no new (yet)
|
|
* \retval 0 current transaction is not done yet
|
|
*/
|
|
int AppLayerTransactionUpdateInspectId(Flow *f, char direction)
|
|
{
|
|
SCEnter();
|
|
|
|
DEBUG_ASSERT_FLOW_LOCKED(f);
|
|
|
|
int r = 0;
|
|
AppLayerParserStateStore *parser_state_store = NULL;
|
|
|
|
parser_state_store = (AppLayerParserStateStore *)f->alparser;
|
|
if (parser_state_store != NULL) {
|
|
/* update inspect_id and see if it there are other transactions
|
|
* as well */
|
|
|
|
SCLogDebug("avail_id %"PRIu16", inspect_id %"PRIu16,
|
|
parser_state_store->avail_id, parser_state_store->inspect_id);
|
|
|
|
if (direction == STREAM_TOSERVER) {
|
|
SCLogDebug("toserver");
|
|
parser_state_store->id_flags |= APP_LAYER_TRANSACTION_TOSERVER;
|
|
} else {
|
|
SCLogDebug("toclient");
|
|
parser_state_store->id_flags |= APP_LAYER_TRANSACTION_TOCLIENT;
|
|
}
|
|
|
|
if ((parser_state_store->inspect_id+1) < parser_state_store->avail_id &&
|
|
(parser_state_store->id_flags & APP_LAYER_TRANSACTION_TOCLIENT) &&
|
|
(parser_state_store->id_flags & APP_LAYER_TRANSACTION_TOSERVER))
|
|
{
|
|
parser_state_store->id_flags &=~ APP_LAYER_TRANSACTION_TOCLIENT;
|
|
parser_state_store->id_flags &=~ APP_LAYER_TRANSACTION_TOSERVER;
|
|
|
|
parser_state_store->inspect_id = parser_state_store->avail_id - 1;
|
|
if (parser_state_store->inspect_id < parser_state_store->avail_id) {
|
|
/* done and more transactions available */
|
|
r = 2;
|
|
|
|
SCLogDebug("inspect_id %"PRIu16", avail_id %"PRIu16,
|
|
parser_state_store->inspect_id,
|
|
parser_state_store->avail_id);
|
|
} else {
|
|
/* done but no more transactions available */
|
|
r = 1;
|
|
|
|
SCLogDebug("inspect_id %"PRIu16", avail_id %"PRIu16,
|
|
parser_state_store->inspect_id,
|
|
parser_state_store->avail_id);
|
|
}
|
|
}
|
|
}
|
|
|
|
SCReturnInt(r);
|
|
}
|
|
|
|
AppLayerDecoderEvents *AppLayerGetDecoderEventsForFlow(Flow *f)
|
|
{
|
|
DEBUG_ASSERT_FLOW_LOCKED(f);
|
|
|
|
/* Get the parser state (if any) */
|
|
AppLayerParserStateStore *parser_state_store = NULL;
|
|
|
|
if (f == NULL || f->alparser == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
parser_state_store = (AppLayerParserStateStore *)f->alparser;
|
|
if (parser_state_store != NULL) {
|
|
return parser_state_store->decoder_events;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* \brief Trigger "raw" stream reassembly from the app layer.
|
|
*
|
|
* This way HTTP for example, can trigger raw stream inspection right
|
|
* when the full request body is received. This is often smaller than
|
|
* our raw reassembly size limit.
|
|
*
|
|
* \param f flow, for access the stream state
|
|
*/
|
|
void AppLayerTriggerRawStreamReassembly(Flow *f) {
|
|
SCEnter();
|
|
|
|
DEBUG_ASSERT_FLOW_LOCKED(f);
|
|
|
|
#ifdef DEBUG
|
|
BUG_ON(f == NULL);
|
|
#endif
|
|
|
|
if (f != NULL && f->protoctx != NULL) {
|
|
TcpSession *ssn = (TcpSession *)f->protoctx;
|
|
StreamTcpReassembleTriggerRawReassembly(ssn);
|
|
}
|
|
|
|
SCReturn;
|
|
}
|
|
|
|
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));
|
|
|
|
/** setup result pool
|
|
* \todo Per thread pool */
|
|
al_result_pool = PoolInit(1000,250,AlpResultElmtPoolAlloc,NULL,AlpResultElmtPoolFree);
|
|
|
|
RegisterHTPParsers();
|
|
RegisterSSLParsers();
|
|
RegisterSMBParsers();
|
|
RegisterDCERPCParsers();
|
|
RegisterDCERPCUDPParsers();
|
|
RegisterFTPParsers();
|
|
RegisterSSHParsers();
|
|
RegisterSMTPParsers();
|
|
|
|
/** IMAP */
|
|
//AlpProtoAdd(&alp_proto_ctx, IPPROTO_TCP, ALPROTO_IMAP, "|2A 20|OK|20|", 5, 0, STREAM_TOCLIENT);
|
|
AlpProtoAdd(&alp_proto_ctx, IPPROTO_TCP, ALPROTO_IMAP, "1|20|capability", 12, 0, STREAM_TOSERVER);
|
|
|
|
/** MSN Messenger */
|
|
//AlpProtoAdd(&alp_proto_ctx, IPPROTO_TCP, ALPROTO_MSN, "MSNP", 10, 6, STREAM_TOCLIENT);
|
|
AlpProtoAdd(&alp_proto_ctx, IPPROTO_TCP, ALPROTO_MSN, "MSNP", 10, 6, STREAM_TOSERVER);
|
|
|
|
/** Jabber */
|
|
//AlpProtoAdd(&alp_proto_ctx, IPPROTO_TCP, ALPROTO_JABBER, "xmlns='jabber|3A|client'", 74, 53, STREAM_TOCLIENT);
|
|
//AlpProtoAdd(&alp_proto_ctx, IPPROTO_TCP, ALPROTO_JABBER, "xmlns='jabber|3A|client'", 74, 53, STREAM_TOSERVER);
|
|
|
|
return;
|
|
}
|
|
|
|
void AppLayerParserCleanupState(Flow *f)
|
|
{
|
|
if (f == NULL) {
|
|
SCLogDebug("no flow");
|
|
return;
|
|
}
|
|
if (f->alproto >= ALPROTO_MAX) {
|
|
SCLogDebug("app layer proto unknown");
|
|
return;
|
|
}
|
|
|
|
/* free the parser protocol state */
|
|
AppLayerProto *p = &al_proto_table[f->alproto];
|
|
if (p->StateFree != NULL && f->alstate != NULL) {
|
|
SCLogDebug("calling StateFree");
|
|
p->StateFree(f->alstate);
|
|
f->alstate = NULL;
|
|
}
|
|
|
|
/* free the app layer parser api state */
|
|
if (f->alparser != NULL) {
|
|
SCLogDebug("calling AppLayerParserStateStoreFree");
|
|
AppLayerParserStateStoreFree(f->alparser);
|
|
f->alparser = NULL;
|
|
}
|
|
}
|
|
|
|
/** \brief Create a mapping between the individual parsers local field id's
|
|
* and the global field parser id's.
|
|
*
|
|
*/
|
|
void AppLayerParsersInitPostProcess(void)
|
|
{
|
|
uint16_t u16 = 0;
|
|
|
|
/* build local->global mapping */
|
|
for (u16 = 1; u16 <= al_max_parsers; u16++) {
|
|
/* no local parser */
|
|
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;
|
|
}
|
|
SCLogDebug("map_size %" PRIu32 "", al_proto_table
|
|
[al_parser_table[u16].proto].map_size);
|
|
}
|
|
|
|
/* for each proto, alloc the map array */
|
|
for (u16 = 0; u16 < ALPROTO_MAX; u16++) {
|
|
if (al_proto_table[u16].map_size == 0)
|
|
continue;
|
|
|
|
al_proto_table[u16].map_size++;
|
|
al_proto_table[u16].map = (AppLayerLocalMap **)SCMalloc
|
|
(al_proto_table[u16].map_size *
|
|
sizeof(AppLayerLocalMap *));
|
|
if (al_proto_table[u16].map == NULL) {
|
|
SCLogError(SC_ERR_FATAL, "Fatal error encountered in AppLayerParsersInitPostProcess. Exiting...");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
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++) {
|
|
/* no local parser */
|
|
if (al_parser_table[u].parser_local_id == 0)
|
|
continue;
|
|
|
|
if (al_parser_table[u].proto != u16)
|
|
continue;
|
|
|
|
uint16_t parser_local_id = al_parser_table[u].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] = SCMalloc(sizeof(AppLayerLocalMap));
|
|
if (al_proto_table[u16].map[parser_local_id] == NULL) {
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
al_proto_table[u16].map[parser_local_id]->parser_id = u;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (u16 = 0; u16 < ALPROTO_MAX; u16++) {
|
|
if (al_proto_table[u16].map_size == 0)
|
|
continue;
|
|
|
|
if (al_proto_table[u16].map == NULL)
|
|
continue;
|
|
|
|
uint16_t x = 0;
|
|
for (x = 0; x < al_proto_table[u16].map_size; x++) {
|
|
if (al_proto_table[u16].map[x] == NULL)
|
|
continue;
|
|
|
|
SCLogDebug("al_proto_table[%" PRIu32 "].map[%" PRIu32 "]->parser_id:"
|
|
" %" PRIu32 "", u16, x, al_proto_table[u16].map[x]->parser_id);
|
|
}
|
|
}
|
|
}
|
|
|
|
/********************************Probing Parsers*******************************/
|
|
|
|
|
|
static uint32_t AppLayerProbingParserGetMask(uint16_t al_proto)
|
|
{
|
|
if (al_proto > ALPROTO_UNKNOWN &&
|
|
al_proto < ALPROTO_FAILED) {
|
|
return (1 << al_proto);
|
|
} else {
|
|
SCLogError(SC_ERR_ALPARSER, "Unknown protocol detected - %"PRIu16,
|
|
al_proto);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
}
|
|
|
|
static AppLayerProbingParserElement *
|
|
AppLayerCreateAppLayerProbingParserElement(const char *al_proto_name,
|
|
uint16_t ip_proto,
|
|
uint16_t al_proto,
|
|
uint16_t min_depth,
|
|
uint16_t max_depth,
|
|
uint16_t port,
|
|
uint8_t priority,
|
|
uint8_t top,
|
|
uint16_t (*AppLayerProbingParser)
|
|
(uint8_t *input, uint32_t input_len))
|
|
{
|
|
AppLayerProbingParserElement *pe = SCMalloc(sizeof(AppLayerProbingParserElement));
|
|
if (pe == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
pe->al_proto_name = al_proto_name;
|
|
pe->ip_proto = ip_proto;
|
|
pe->al_proto = al_proto;
|
|
pe->al_proto_mask = AppLayerProbingParserGetMask(al_proto);
|
|
pe->min_depth = min_depth;
|
|
pe->max_depth = max_depth;
|
|
pe->port = port;
|
|
pe->priority = priority;
|
|
pe->top = top;
|
|
pe->ProbingParser = AppLayerProbingParser;
|
|
pe->next = NULL;
|
|
|
|
if (max_depth != 0 && min_depth > max_depth) {
|
|
SCLogError(SC_ERR_ALPARSER, "Invalid arguments sent to "
|
|
"register the probing parser. min_depth > max_depth");
|
|
goto error;
|
|
}
|
|
if (al_proto <= ALPROTO_UNKNOWN || al_proto >= ALPROTO_MAX) {
|
|
SCLogError(SC_ERR_ALPARSER, "Invalid arguments sent to register "
|
|
"the probing parser. Invalid alproto - %d", al_proto);
|
|
goto error;
|
|
}
|
|
if (AppLayerProbingParser == NULL) {
|
|
SCLogError(SC_ERR_ALPARSER, "Invalid arguments sent to "
|
|
"register the probing parser. Probing parser func NULL");
|
|
goto error;
|
|
}
|
|
|
|
return pe;
|
|
error:
|
|
SCFree(pe);
|
|
return NULL;
|
|
}
|
|
|
|
static AppLayerProbingParserElement *
|
|
AppLayerDuplicateAppLayerProbingParserElement(AppLayerProbingParserElement *pe)
|
|
{
|
|
AppLayerProbingParserElement *new_pe = SCMalloc(sizeof(AppLayerProbingParserElement));
|
|
if (new_pe == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
new_pe->al_proto_name = pe->al_proto_name;
|
|
new_pe->ip_proto = pe->ip_proto;
|
|
new_pe->al_proto = pe->al_proto;
|
|
new_pe->al_proto_mask = pe->al_proto_mask;
|
|
new_pe->min_depth = pe->min_depth;
|
|
new_pe->max_depth = pe->max_depth;
|
|
new_pe->port = pe->port;
|
|
new_pe->priority = pe->priority;
|
|
new_pe->top = pe->top;
|
|
new_pe->ProbingParser = pe->ProbingParser;
|
|
new_pe->next = NULL;
|
|
|
|
return new_pe;
|
|
}
|
|
|
|
static void
|
|
AppLayerFreeAppLayerProbingParserElement(AppLayerProbingParserElement *pe)
|
|
{
|
|
SCFree(pe);
|
|
|
|
return;
|
|
}
|
|
|
|
static void
|
|
AppLayerInsertNewProbingParserSingleElement(AppLayerProbingParser *pp,
|
|
AppLayerProbingParser **probing_parsers,
|
|
AppLayerProbingParserElement *new_pe,
|
|
uint8_t flags)
|
|
{
|
|
if (pp == NULL) {
|
|
AppLayerProbingParser *new_pp = SCMalloc(sizeof(AppLayerProbingParser));
|
|
if (new_pp == NULL)
|
|
return;
|
|
memset(new_pp, 0, sizeof(AppLayerProbingParser));
|
|
|
|
new_pp->port = new_pe->port;
|
|
|
|
if (probing_parsers[0] == NULL) {
|
|
probing_parsers[0] = new_pp;
|
|
} else {
|
|
AppLayerProbingParser *pp = probing_parsers[0];
|
|
if (pp->port == 0) {
|
|
new_pp->next = probing_parsers[0];
|
|
probing_parsers[0] = new_pp;
|
|
} else {
|
|
/* port 0 based pp is always the last one. Hence the
|
|
* premature exit condition if port is 0 */
|
|
while (pp->next != NULL && pp->next->port != 0) {
|
|
pp = pp->next;
|
|
}
|
|
new_pp->next = pp->next;
|
|
pp->next = new_pp;
|
|
}
|
|
}
|
|
|
|
pp = new_pp;
|
|
}
|
|
|
|
AppLayerProbingParserElement *pe = NULL;
|
|
if (flags & STREAM_TOSERVER) {
|
|
pe = pp->toserver;
|
|
} else {
|
|
pe = pp->toclient;
|
|
}
|
|
|
|
if (pe == NULL) {
|
|
if (flags & STREAM_TOSERVER) {
|
|
pp->toserver = new_pe;
|
|
pp->toserver_max_depth = new_pe->max_depth;
|
|
} else {
|
|
pp->toclient = new_pe;
|
|
pp->toclient_max_depth = new_pe->max_depth;
|
|
}
|
|
} else {
|
|
uint8_t break_priority;
|
|
if (new_pe->top) {
|
|
break_priority = new_pe->priority;
|
|
} else {
|
|
break_priority = new_pe->priority + 1;
|
|
}
|
|
|
|
AppLayerProbingParserElement *prev_pe = pe;
|
|
while (pe != NULL) {
|
|
if (pe->priority < break_priority) {
|
|
prev_pe = pe;
|
|
pe = pe->next;
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
if (prev_pe == pe) {
|
|
if (flags & STREAM_TOSERVER) {
|
|
new_pe->next = pp->toserver;
|
|
pp->toserver = new_pe;
|
|
} else {
|
|
new_pe->next = pp->toclient;
|
|
pp->toclient = new_pe;
|
|
}
|
|
} else {
|
|
new_pe->next = prev_pe->next;
|
|
prev_pe->next = new_pe;
|
|
}
|
|
|
|
if (flags & STREAM_TOSERVER) {
|
|
if (new_pe->max_depth == 0) {
|
|
pp->toserver_max_depth = 0;
|
|
} else {
|
|
if (pp->toserver_max_depth != 0 &&
|
|
pp->toserver_max_depth < new_pe->max_depth) {
|
|
pp->toserver_max_depth = new_pe->max_depth;
|
|
}
|
|
}
|
|
} else {
|
|
if (new_pe->max_depth == 0) {
|
|
pp->toclient_max_depth = 0;
|
|
} else {
|
|
if (pp->toclient_max_depth != 0 &&
|
|
pp->toclient_max_depth < new_pe->max_depth) {
|
|
pp->toclient_max_depth = new_pe->max_depth;
|
|
}
|
|
}
|
|
} /* else - if (flags & STREAM_TOSERVER) */
|
|
|
|
} /* else - if (pe == NULL) */
|
|
|
|
if (flags & STREAM_TOSERVER)
|
|
pp->toserver_al_proto_mask |= new_pe->al_proto_mask;
|
|
else
|
|
pp->toclient_al_proto_mask |= new_pe->al_proto_mask;
|
|
|
|
return;
|
|
}
|
|
|
|
static void AppLayerInsertNewProbingParserElement(AppLayerProbingParser **probing_parsers,
|
|
AppLayerProbingParserElement *new_pe,
|
|
uint8_t flags)
|
|
{
|
|
AppLayerProbingParser *pp = probing_parsers[0];
|
|
|
|
if (new_pe->port != 0) {
|
|
AppLayerProbingParser *zero_pp = NULL;
|
|
while (pp != NULL) {
|
|
if (pp->port == new_pe->port) {
|
|
break;
|
|
}
|
|
if (pp->port == 0)
|
|
zero_pp = pp;
|
|
pp = pp->next;
|
|
}
|
|
AppLayerInsertNewProbingParserSingleElement(pp, probing_parsers, new_pe,
|
|
flags);
|
|
if (zero_pp != NULL) {
|
|
pp = probing_parsers[0];
|
|
while (pp != NULL) {
|
|
if (pp->port == new_pe->port)
|
|
break;
|
|
pp = pp->next;
|
|
}
|
|
BUG_ON(pp == NULL);
|
|
AppLayerProbingParserElement *temp_pe;
|
|
if (flags & STREAM_TOSERVER) {
|
|
temp_pe = zero_pp->toserver;
|
|
} else {
|
|
temp_pe = zero_pp->toclient;
|
|
}
|
|
while (temp_pe != NULL) {
|
|
AppLayerProbingParserElement *dup_pe =
|
|
AppLayerDuplicateAppLayerProbingParserElement(temp_pe);
|
|
AppLayerInsertNewProbingParserSingleElement(pp, probing_parsers, dup_pe,
|
|
flags);
|
|
temp_pe = temp_pe->next;
|
|
}
|
|
}
|
|
|
|
} else {
|
|
int zero_port_present = 0;
|
|
while (pp != NULL) {
|
|
AppLayerProbingParserElement *dup_pe =
|
|
AppLayerDuplicateAppLayerProbingParserElement(new_pe);
|
|
|
|
AppLayerInsertNewProbingParserSingleElement(pp, probing_parsers, dup_pe,
|
|
flags);
|
|
if (pp->port == 0)
|
|
zero_port_present = 1;
|
|
pp = pp->next;
|
|
}
|
|
|
|
if (zero_port_present == 0) {
|
|
AppLayerInsertNewProbingParserSingleElement(NULL, probing_parsers, new_pe,
|
|
flags);
|
|
} else {
|
|
SCFree(new_pe);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void AppLayerPrintProbingParsers(AppLayerProbingParser *pp)
|
|
{
|
|
AppLayerProbingParserElement *pe = NULL;
|
|
|
|
printf("\n");
|
|
while (pp != NULL) {
|
|
printf("Port: %"PRIu16 "\n", pp->port);
|
|
printf(" to_server: max-depth: %"PRIu16 ", "
|
|
"mask - %"PRIu32"\n", pp->toserver_max_depth,
|
|
pp->toserver_al_proto_mask);
|
|
pe = pp->toserver;
|
|
while (pe != NULL) {
|
|
printf(" name: %s\n", pe->al_proto_name);
|
|
|
|
if (pe->al_proto == ALPROTO_HTTP)
|
|
printf(" alproto: ALPROTO_HTTP\n");
|
|
else if (pe->al_proto == ALPROTO_FTP)
|
|
printf(" alproto: ALPROTO_FTP\n");
|
|
else if (pe->al_proto == ALPROTO_SMTP)
|
|
printf(" alproto: ALPROTO_SMTP\n");
|
|
else if (pe->al_proto == ALPROTO_TLS)
|
|
printf(" alproto: ALPROTO_TLS\n");
|
|
else if (pe->al_proto == ALPROTO_SSH)
|
|
printf(" alproto: ALPROTO_SSH\n");
|
|
else if (pe->al_proto == ALPROTO_IMAP)
|
|
printf(" alproto: ALPROTO_IMAP\n");
|
|
else if (pe->al_proto == ALPROTO_MSN)
|
|
printf(" alproto: ALPROTO_MSN\n");
|
|
else if (pe->al_proto == ALPROTO_JABBER)
|
|
printf(" alproto: ALPROTO_JABBER\n");
|
|
else if (pe->al_proto == ALPROTO_SMB)
|
|
printf(" alproto: ALPROTO_SMB\n");
|
|
else if (pe->al_proto == ALPROTO_SMB2)
|
|
printf(" alproto: ALPROTO_SMB2\n");
|
|
else if (pe->al_proto == ALPROTO_DCERPC)
|
|
printf(" alproto: ALPROTO_DCERPC\n");
|
|
else if (pe->al_proto == ALPROTO_DCERPC_UDP)
|
|
printf(" alproto: ALPROTO_DCERPC_UDP\n");
|
|
else if (pe->al_proto == ALPROTO_IRC)
|
|
printf(" alproto: ALPROTO_IRC\n");
|
|
else
|
|
printf("impossible\n");
|
|
|
|
printf(" port: %"PRIu16 "\n", pe->port);
|
|
|
|
if (pe->priority == APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
printf(" priority: HIGH\n");
|
|
else if (pe->priority == APP_LAYER_PROBING_PARSER_PRIORITY_MEDIUM)
|
|
printf(" priority: MEDIUM\n");
|
|
else if (pe->priority == APP_LAYER_PROBING_PARSER_PRIORITY_LOW)
|
|
printf(" priority: LOW\n");
|
|
else
|
|
printf(" priority: impossible\n");
|
|
|
|
printf(" top: %"PRIu8 "\n", pe->top);
|
|
|
|
printf(" min_depth: %"PRIu32 "\n", pe->min_depth);
|
|
printf(" max_depth: %"PRIu32 "\n", pe->max_depth);
|
|
printf(" mask: %"PRIu32 "\n", pe->al_proto_mask);
|
|
|
|
printf("\n");
|
|
pe = pe->next;
|
|
}
|
|
pp = pp->next;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
int AppLayerProbingParserInfoAdd(AlpProtoDetectCtx *ctx,
|
|
const char *al_proto_name,
|
|
uint16_t ip_proto,
|
|
uint16_t al_proto,
|
|
uint16_t (*ProbingParser)
|
|
(uint8_t *input, uint32_t input_len))
|
|
{
|
|
AppLayerProbingParserInfo *new_ppi = NULL;
|
|
|
|
AppLayerProbingParserInfo *ppi = ctx->probing_parsers_info;
|
|
while (ppi != NULL) {
|
|
if (strcmp(ppi->al_proto_name, al_proto_name) == 0)
|
|
break;
|
|
ppi = ppi->next;
|
|
}
|
|
|
|
if (ppi == NULL) {
|
|
new_ppi = SCMalloc(sizeof(AppLayerProbingParserInfo));
|
|
if (new_ppi == NULL) {
|
|
return -1;
|
|
}
|
|
memset(new_ppi, 0, sizeof(AppLayerProbingParserInfo));
|
|
new_ppi->al_proto_name = al_proto_name;
|
|
new_ppi->ip_proto = ip_proto;
|
|
new_ppi->al_proto = al_proto;
|
|
new_ppi->ProbingParser = ProbingParser;
|
|
|
|
if (ctx->probing_parsers_info == NULL) {
|
|
ctx->probing_parsers_info = new_ppi;
|
|
} else {
|
|
new_ppi->next = ctx->probing_parsers_info;
|
|
ctx->probing_parsers_info = new_ppi;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
if (ppi->ip_proto != ip_proto) {
|
|
SCLogError(SC_ERR_ALPARSER, "New probing parser \"%s\" being registered "
|
|
"already exists in the database of registered parsers, "
|
|
"except that the new one registers with a different ip_proto"
|
|
" %"PRIu16" compared to the existing entry of %"PRIu16,
|
|
ppi->al_proto_name, ppi->ip_proto, ip_proto);
|
|
return -1;
|
|
}
|
|
if (ppi->al_proto != al_proto) {
|
|
SCLogError(SC_ERR_ALPARSER, "New probing parser \"%s\" being registered "
|
|
"already exists in the database of registered parsers, "
|
|
"except that the new one registers with a different alproto "
|
|
"%"PRIu16" compared to the existing entry of %"PRIu16,
|
|
ppi->al_proto_name, ppi->al_proto, al_proto);
|
|
return -1;
|
|
}
|
|
if (ppi->ProbingParser != ProbingParser) {
|
|
SCLogError(SC_ERR_ALPARSER, "New probing parser \"%s\" being registered "
|
|
"already exists in the database of registered parsers, "
|
|
"except that the new one registers with a differnt "
|
|
"ProbingParser function compared to the existing entry "
|
|
"in the database", ppi->al_proto_name);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void AppLayerRegisterProbingParser(AlpProtoDetectCtx *ctx,
|
|
uint16_t port,
|
|
uint16_t ip_proto,
|
|
const char *al_proto_name,
|
|
uint16_t al_proto,
|
|
uint16_t min_depth,
|
|
uint16_t max_depth,
|
|
uint8_t flags,
|
|
uint8_t priority,
|
|
uint8_t top,
|
|
uint16_t (*ProbingParser)
|
|
(uint8_t *input, uint32_t input_len))
|
|
{
|
|
AppLayerProbingParser **probing_parsers = &ctx->probing_parsers;
|
|
AppLayerProbingParserElement *pe = NULL;
|
|
AppLayerProbingParserElement *new_pe = NULL;
|
|
AppLayerProbingParser *pp = NULL;
|
|
|
|
/* Add info about this probing parser to our database. Also detects any
|
|
* duplicate existance of this parser but with conflicting parameters */
|
|
if (AppLayerProbingParserInfoAdd(ctx, al_proto_name, ip_proto, al_proto,
|
|
ProbingParser) < 0) {
|
|
goto error;
|
|
}
|
|
|
|
/* \todo introduce parsing port range here */
|
|
|
|
/* Get a new parser element */
|
|
new_pe = AppLayerCreateAppLayerProbingParserElement(al_proto_name, ip_proto,
|
|
al_proto, min_depth,
|
|
max_depth, port,
|
|
priority, top,
|
|
ProbingParser);
|
|
if (new_pe == NULL)
|
|
goto error;
|
|
|
|
pp = AppLayerGetProbingParsers(probing_parsers[0], ip_proto, port);
|
|
if (pp != NULL) {
|
|
if (flags & STREAM_TOSERVER) {
|
|
pe = pp->toserver;
|
|
} else {
|
|
pe = pp->toclient;
|
|
}
|
|
}
|
|
|
|
/* check if this parser has already been registered for this port + dir */
|
|
if (pe != NULL) {
|
|
AppLayerProbingParserElement *tmp_pe = pe;
|
|
while (tmp_pe != NULL) {
|
|
if (pe->al_proto == al_proto ||
|
|
strcmp(pe->al_proto_name, al_proto_name) == 0) {
|
|
/* looks like we have it registered for this port + dir */
|
|
SCLogWarning(SC_ERR_ALPARSER, "App layer probing parser already "
|
|
"registered for this port, direction");
|
|
goto error;
|
|
}
|
|
tmp_pe = tmp_pe->next;
|
|
}
|
|
}
|
|
|
|
AppLayerInsertNewProbingParserElement(probing_parsers, new_pe, flags);
|
|
|
|
return;
|
|
error:
|
|
if (new_pe != NULL)
|
|
SCFree(new_pe);
|
|
return;
|
|
}
|
|
|
|
void AppLayerFreeProbingParsersInfo(AppLayerProbingParserInfo *probing_parsers_info)
|
|
{
|
|
AppLayerProbingParserInfo *ppi = probing_parsers_info;
|
|
AppLayerProbingParserInfo *next_ppi = NULL;
|
|
|
|
while (ppi != NULL) {
|
|
next_ppi = ppi->next;
|
|
SCFree(ppi);
|
|
ppi = next_ppi;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void AppLayerFreeProbingParsers(AppLayerProbingParser *probing_parsers)
|
|
{
|
|
while (probing_parsers != NULL) {
|
|
AppLayerProbingParserElement *pe;
|
|
AppLayerProbingParserElement *next_pe;
|
|
|
|
pe = probing_parsers->toserver;
|
|
while (pe != NULL) {
|
|
next_pe = pe->next;
|
|
AppLayerFreeAppLayerProbingParserElement(pe);
|
|
pe = next_pe;
|
|
}
|
|
|
|
pe = probing_parsers->toclient;
|
|
while (pe != NULL) {
|
|
next_pe = pe->next;
|
|
AppLayerFreeAppLayerProbingParserElement(pe);
|
|
pe = next_pe;
|
|
}
|
|
|
|
probing_parsers = probing_parsers->next;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**************************************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(Flow *f, void *test_state, AppLayerParserState *pstate,
|
|
uint8_t *input, uint32_t input_len,
|
|
void *local_data, AppLayerParserResult *output)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
/** \brief Function to allocates the Test protocol state memory
|
|
*/
|
|
static void *TestProtocolStateAlloc(void)
|
|
{
|
|
void *s = SCMalloc(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)
|
|
{
|
|
SCFree(s);
|
|
}
|
|
|
|
/** \test Test the deallocation of app layer parser memory on occurance of
|
|
* error in the parsing process.
|
|
*/
|
|
static int AppLayerParserTest01 (void)
|
|
{
|
|
int result = 0;
|
|
Flow *f = NULL;
|
|
uint8_t testbuf[] = { 0x11 };
|
|
uint32_t testlen = sizeof(testbuf);
|
|
TcpSession ssn;
|
|
|
|
memset(&ssn, 0, sizeof(ssn));
|
|
|
|
/* Register the Test protocol state and parser functions */
|
|
AppLayerRegisterProto("test", ALPROTO_TEST, STREAM_TOSERVER,
|
|
TestProtocolParser);
|
|
AppLayerRegisterStateFuncs(ALPROTO_TEST, TestProtocolStateAlloc,
|
|
TestProtocolStateFree);
|
|
|
|
f = UTHBuildFlow(AF_INET, "1.2.3.4", "4.3.2.1", 20, 40);
|
|
if (f == NULL)
|
|
goto end;
|
|
f->protoctx = &ssn;
|
|
|
|
f->alproto = ALPROTO_TEST;
|
|
f->proto = IPPROTO_TCP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
int r = AppLayerParse(NULL, f, ALPROTO_TEST, STREAM_TOSERVER|STREAM_EOF, testbuf,
|
|
testlen);
|
|
if (r != -1) {
|
|
printf("returned %" PRId32 ", expected -1: ", r);
|
|
goto end;
|
|
}
|
|
|
|
if (!(f->flags & FLOW_NO_APPLAYER_INSPECTION))
|
|
{
|
|
printf("flag should have been set, but is not: ");
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
end:
|
|
StreamTcpFreeConfig(TRUE);
|
|
|
|
UTHFreeFlow(f);
|
|
return result;
|
|
}
|
|
|
|
/** \test Test the deallocation of app layer parser memory on occurance of
|
|
* error in the parsing process for UDP.
|
|
*/
|
|
static int AppLayerParserTest02 (void)
|
|
{
|
|
int result = 1;
|
|
Flow *f = NULL;
|
|
uint8_t testbuf[] = { 0x11 };
|
|
uint32_t testlen = sizeof(testbuf);
|
|
|
|
/* Register the Test protocol state and parser functions */
|
|
AppLayerRegisterProto("test", ALPROTO_TEST, STREAM_TOSERVER,
|
|
TestProtocolParser);
|
|
AppLayerRegisterStateFuncs(ALPROTO_TEST, TestProtocolStateAlloc,
|
|
TestProtocolStateFree);
|
|
|
|
f = UTHBuildFlow(AF_INET, "1.2.3.4", "4.3.2.1", 20, 40);
|
|
if (f == NULL)
|
|
goto end;
|
|
f->alproto = ALPROTO_TEST;
|
|
f->proto = IPPROTO_UDP;
|
|
|
|
StreamTcpInitConfig(TRUE);
|
|
|
|
int r = AppLayerParse(NULL, f, ALPROTO_TEST, STREAM_TOSERVER|STREAM_EOF, testbuf,
|
|
testlen);
|
|
if (r != -1) {
|
|
printf("returned %" PRId32 ", expected -1: \n", r);
|
|
result = 0;
|
|
goto end;
|
|
}
|
|
|
|
end:
|
|
StreamTcpFreeConfig(TRUE);
|
|
UTHFreeFlow(f);
|
|
return result;
|
|
}
|
|
|
|
uint16_t ProbingParserDummyForTesting(uint8_t *input, uint32_t input_len)
|
|
{
|
|
return 0;
|
|
}
|
|
static int AppLayerProbingParserTest01(void)
|
|
{
|
|
AlpProtoDetectCtx ctx;
|
|
AlpProtoInit(&ctx);
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"http",
|
|
ALPROTO_HTTP,
|
|
5, 5,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
|
|
ProbingParserDummyForTesting);
|
|
if (ctx.probing_parsers == NULL)
|
|
return 0;
|
|
|
|
AlpProtoTestDestroy(&ctx);
|
|
return 1;
|
|
}
|
|
|
|
static int AppLayerProbingParserTest02(void)
|
|
{
|
|
int result = 0;
|
|
AppLayerProbingParser *pp;
|
|
AppLayerProbingParserElement *pe;
|
|
|
|
AlpProtoDetectCtx ctx;
|
|
AlpProtoInit(&ctx);
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"http",
|
|
ALPROTO_HTTP,
|
|
5, 8,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next != NULL)
|
|
goto end;
|
|
if (pp->toserver_al_proto_mask != 1 << ALPROTO_HTTP)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
if (pe->al_proto_mask != 1 << ALPROTO_HTTP)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"smb",
|
|
ALPROTO_SMB,
|
|
5, 5,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next != NULL)
|
|
goto end;
|
|
if (pp->toserver_al_proto_mask != (1 << ALPROTO_HTTP |
|
|
1 << ALPROTO_SMB)) {
|
|
goto end;
|
|
}
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 5)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
if (pe->al_proto_mask != 1 << ALPROTO_SMB) {
|
|
goto end;
|
|
}
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
if (pe->al_proto_mask != 1 << ALPROTO_HTTP) {
|
|
goto end;
|
|
}
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"dcerpc",
|
|
ALPROTO_DCERPC,
|
|
9, 10,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 10)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next->next != NULL)
|
|
goto end;
|
|
if (pp->toserver_al_proto_mask != (1 << ALPROTO_HTTP |
|
|
1 << ALPROTO_SMB |
|
|
1 << ALPROTO_DCERPC)) {
|
|
goto end;
|
|
}
|
|
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "dcerpc") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_DCERPC)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 9)
|
|
goto end;
|
|
if (pe->max_depth != 10)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
if (pe->al_proto_mask != 1 << ALPROTO_DCERPC) {
|
|
goto end;
|
|
}
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 5)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
if (pe->al_proto_mask != 1 << ALPROTO_SMB) {
|
|
goto end;
|
|
}
|
|
/* third one */
|
|
pe = pp->toserver->next->next;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
if (pe->al_proto_mask != 1 << ALPROTO_HTTP) {
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
AlpProtoTestDestroy(&ctx);
|
|
return result;
|
|
}
|
|
|
|
static int AppLayerProbingParserTest03(void)
|
|
{
|
|
int result = 0;
|
|
AppLayerProbingParser *pp;
|
|
AppLayerProbingParserElement *pe;
|
|
|
|
AlpProtoDetectCtx ctx;
|
|
AlpProtoInit(&ctx);
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"http",
|
|
ALPROTO_HTTP,
|
|
5, 8,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 0,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next != NULL)
|
|
goto end;
|
|
if (pp->toserver_al_proto_mask != (1 << ALPROTO_HTTP)) {
|
|
goto end;
|
|
}
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
if (pe->al_proto_mask != 1 << ALPROTO_HTTP) {
|
|
goto end;
|
|
}
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"smb",
|
|
ALPROTO_SMB,
|
|
5, 5,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 0,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next != NULL)
|
|
goto end;
|
|
if (pp->toserver_al_proto_mask != (1 << ALPROTO_HTTP |
|
|
1 << ALPROTO_SMB)) {
|
|
goto end;
|
|
}
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
if (pe->al_proto_mask != 1 << ALPROTO_HTTP) {
|
|
goto end;
|
|
}
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 5)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
if (pe->al_proto_mask != 1 << ALPROTO_SMB) {
|
|
goto end;
|
|
}
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"dcerpc",
|
|
ALPROTO_DCERPC,
|
|
9, 10,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 0,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 10)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next->next != NULL)
|
|
goto end;
|
|
if (pp->toserver_al_proto_mask != (1 << ALPROTO_HTTP |
|
|
1 << ALPROTO_DCERPC |
|
|
1 << ALPROTO_SMB)) {
|
|
goto end;
|
|
}
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
if (pe->al_proto_mask != 1 << ALPROTO_HTTP) {
|
|
goto end;
|
|
}
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 5)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
if (pe->al_proto_mask != 1 << ALPROTO_SMB) {
|
|
goto end;
|
|
}
|
|
/* third one */
|
|
pe = pp->toserver->next->next;
|
|
if (strcmp(pe->al_proto_name, "dcerpc") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_DCERPC)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 9)
|
|
goto end;
|
|
if (pe->max_depth != 10)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
if (pe->al_proto_mask != 1 << ALPROTO_DCERPC) {
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
AlpProtoTestDestroy(&ctx);
|
|
return result;
|
|
}
|
|
|
|
static int AppLayerProbingParserTest04(void)
|
|
{
|
|
int result = 0;
|
|
AppLayerProbingParser *pp;
|
|
AppLayerProbingParserElement *pe;
|
|
|
|
AlpProtoDetectCtx ctx;
|
|
AlpProtoInit(&ctx);
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"http",
|
|
ALPROTO_HTTP,
|
|
5, 8,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next != NULL)
|
|
goto end;
|
|
if (pp->toserver_al_proto_mask != (1 << ALPROTO_HTTP)) {
|
|
goto end;
|
|
}
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
if (pe->al_proto_mask != 1 << ALPROTO_HTTP) {
|
|
goto end;
|
|
}
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"smb",
|
|
ALPROTO_SMB,
|
|
5, 5,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next != NULL)
|
|
goto end;
|
|
if (pp->toserver_al_proto_mask != (1 << ALPROTO_HTTP |
|
|
1 << ALPROTO_SMB)) {
|
|
goto end;
|
|
}
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 5)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
if (pe->al_proto_mask != 1 << ALPROTO_SMB) {
|
|
goto end;
|
|
}
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
if (pe->al_proto_mask != 1 << ALPROTO_HTTP) {
|
|
goto end;
|
|
}
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"dcerpc",
|
|
ALPROTO_DCERPC,
|
|
9, 10,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 0,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 10)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next->next != NULL)
|
|
goto end;
|
|
if (pp->toserver_al_proto_mask != (1 << ALPROTO_HTTP |
|
|
1 << ALPROTO_DCERPC |
|
|
1 << ALPROTO_SMB)) {
|
|
goto end;
|
|
}
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 5)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
if (pe->al_proto_mask != 1 << ALPROTO_SMB) {
|
|
goto end;
|
|
}
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
if (pe->al_proto_mask != 1 << ALPROTO_HTTP) {
|
|
goto end;
|
|
}
|
|
/* third one */
|
|
pe = pp->toserver->next->next;
|
|
if (strcmp(pe->al_proto_name, "dcerpc") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_DCERPC)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 9)
|
|
goto end;
|
|
if (pe->max_depth != 10)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
if (pe->al_proto_mask != 1 << ALPROTO_DCERPC) {
|
|
goto end;
|
|
}
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
AlpProtoTestDestroy(&ctx);
|
|
return result;
|
|
}
|
|
|
|
static int AppLayerProbingParserTest05(void)
|
|
{
|
|
int result = 0;
|
|
AppLayerProbingParser *pp;
|
|
AppLayerProbingParserElement *pe;
|
|
|
|
AlpProtoDetectCtx ctx;
|
|
AlpProtoInit(&ctx);
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"http",
|
|
ALPROTO_HTTP,
|
|
5, 8,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"smb",
|
|
ALPROTO_SMB,
|
|
5, 5,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_LOW, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 5)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"dcerpc",
|
|
ALPROTO_DCERPC,
|
|
9, 10,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_LOW, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 10)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "dcerpc") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_DCERPC)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW)
|
|
goto end;
|
|
if (pe->min_depth != 9)
|
|
goto end;
|
|
if (pe->max_depth != 10)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* third one */
|
|
pe = pp->toserver->next->next;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 5)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
AlpProtoTestDestroy(&ctx);
|
|
return result;
|
|
}
|
|
|
|
static int AppLayerProbingParserTest06(void)
|
|
{
|
|
int result = 0;
|
|
AppLayerProbingParser *pp;
|
|
AppLayerProbingParserElement *pe;
|
|
|
|
AlpProtoDetectCtx ctx;
|
|
AlpProtoInit(&ctx);
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"http",
|
|
ALPROTO_HTTP,
|
|
5, 8,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"smb",
|
|
ALPROTO_SMB,
|
|
5, 5,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_LOW, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 5)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"dcerpc",
|
|
ALPROTO_DCERPC,
|
|
9, 10,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_LOW, 0,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 10)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 5)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* third one */
|
|
pe = pp->toserver->next->next;
|
|
if (strcmp(pe->al_proto_name, "dcerpc") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_DCERPC)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW)
|
|
goto end;
|
|
if (pe->min_depth != 9)
|
|
goto end;
|
|
if (pe->max_depth != 10)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
AlpProtoTestDestroy(&ctx);
|
|
return result;
|
|
}
|
|
|
|
static int AppLayerProbingParserTest07(void)
|
|
{
|
|
int result = 0;
|
|
AppLayerProbingParser *pp;
|
|
AppLayerProbingParserElement *pe;
|
|
|
|
AlpProtoDetectCtx ctx;
|
|
AlpProtoInit(&ctx);
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"http",
|
|
ALPROTO_HTTP,
|
|
5, 8,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"smb",
|
|
ALPROTO_SMB,
|
|
5, 5,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_LOW, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 5)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"dcerpc",
|
|
ALPROTO_DCERPC,
|
|
9, 10,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 10)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "dcerpc") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_DCERPC)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 9)
|
|
goto end;
|
|
if (pe->max_depth != 10)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* third one */
|
|
pe = pp->toserver->next->next;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 5)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
AlpProtoTestDestroy(&ctx);
|
|
return result;
|
|
}
|
|
|
|
static int AppLayerProbingParserTest08(void)
|
|
{
|
|
int result = 0;
|
|
AppLayerProbingParser *pp;
|
|
AppLayerProbingParserElement *pe;
|
|
|
|
AlpProtoDetectCtx ctx;
|
|
AlpProtoInit(&ctx);
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"http",
|
|
ALPROTO_HTTP,
|
|
5, 8,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"smb",
|
|
ALPROTO_SMB,
|
|
5, 5,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_LOW, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 5)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"dcerpc",
|
|
ALPROTO_DCERPC,
|
|
9, 10,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 0,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 10)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "dcerpc") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_DCERPC)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 9)
|
|
goto end;
|
|
if (pe->max_depth != 10)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* third one */
|
|
pe = pp->toserver->next->next;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 5)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
AlpProtoTestDestroy(&ctx);
|
|
return result;
|
|
}
|
|
|
|
static int AppLayerProbingParserTest09(void)
|
|
{
|
|
int result = 0;
|
|
AppLayerProbingParser *pp;
|
|
AppLayerProbingParserElement *pe;
|
|
|
|
AlpProtoDetectCtx ctx;
|
|
AlpProtoInit(&ctx);
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"http",
|
|
ALPROTO_HTTP,
|
|
5, 8,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_LOW, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"smb",
|
|
ALPROTO_SMB,
|
|
5, 5,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 5)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"dcerpc",
|
|
ALPROTO_DCERPC,
|
|
9, 10,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_LOW, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 10)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 5)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "dcerpc") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_DCERPC)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW)
|
|
goto end;
|
|
if (pe->min_depth != 9)
|
|
goto end;
|
|
if (pe->max_depth != 10)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* third one */
|
|
pe = pp->toserver->next->next;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
AlpProtoTestDestroy(&ctx);
|
|
return result;
|
|
}
|
|
|
|
static int AppLayerProbingParserTest10(void)
|
|
{
|
|
int result = 0;
|
|
AppLayerProbingParser *pp;
|
|
AppLayerProbingParserElement *pe;
|
|
|
|
AlpProtoDetectCtx ctx;
|
|
AlpProtoInit(&ctx);
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"http",
|
|
ALPROTO_HTTP,
|
|
5, 8,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_LOW, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"smb",
|
|
ALPROTO_SMB,
|
|
5, 5,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 5)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"dcerpc",
|
|
ALPROTO_DCERPC,
|
|
9, 10,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_LOW, 0,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 10)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 5)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* third one */
|
|
pe = pp->toserver->next->next;
|
|
if (strcmp(pe->al_proto_name, "dcerpc") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_DCERPC)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW)
|
|
goto end;
|
|
if (pe->min_depth != 9)
|
|
goto end;
|
|
if (pe->max_depth != 10)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
AlpProtoTestDestroy(&ctx);
|
|
return result;
|
|
}
|
|
|
|
static int AppLayerProbingParserTest11(void)
|
|
{
|
|
int result = 0;
|
|
AppLayerProbingParser *pp;
|
|
AppLayerProbingParserElement *pe;
|
|
|
|
AlpProtoDetectCtx ctx;
|
|
AlpProtoInit(&ctx);
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"http",
|
|
ALPROTO_HTTP,
|
|
5, 8,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"smb",
|
|
ALPROTO_SMB,
|
|
5, 5,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 5)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
81,
|
|
IPPROTO_TCP,
|
|
"dcerpc",
|
|
ALPROTO_DCERPC,
|
|
9, 10,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
/* first pp */
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next == NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 5)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second pp */
|
|
if (pp->next->next != NULL)
|
|
goto end;
|
|
if (pp->next->toclient != NULL)
|
|
goto end;
|
|
if (pp->next->port != 81)
|
|
goto end;
|
|
if (pp->next->toserver_max_depth != 10)
|
|
goto end;
|
|
if (pp->next->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->next->toserver == NULL)
|
|
goto end;
|
|
if (pp->next->toserver->next != NULL)
|
|
goto end;
|
|
/* second pp - first one */
|
|
pe = pp->next->toserver;
|
|
if (strcmp(pe->al_proto_name, "dcerpc") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_DCERPC)
|
|
goto end;
|
|
if (pe->port != 81)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 9)
|
|
goto end;
|
|
if (pe->max_depth != 10)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
81,
|
|
IPPROTO_TCP,
|
|
"ftp",
|
|
ALPROTO_FTP,
|
|
7, 15,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
/* first pp */
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next == NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 5)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second pp */
|
|
if (pp->next->next != NULL)
|
|
goto end;
|
|
if (pp->next->toclient != NULL)
|
|
goto end;
|
|
if (pp->next->port != 81)
|
|
goto end;
|
|
if (pp->next->toserver_max_depth != 15)
|
|
goto end;
|
|
if (pp->next->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->next->toserver == NULL)
|
|
goto end;
|
|
if (pp->next->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->next->toserver->next->next != NULL)
|
|
goto end;
|
|
/* second pp - first one */
|
|
pe = pp->next->toserver;
|
|
if (strcmp(pe->al_proto_name, "ftp") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_FTP)
|
|
goto end;
|
|
if (pe->port != 81)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 7)
|
|
goto end;
|
|
if (pe->max_depth != 15)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second pp - second one */
|
|
pe = pp->next->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "dcerpc") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_DCERPC)
|
|
goto end;
|
|
if (pe->port != 81)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 9)
|
|
goto end;
|
|
if (pe->max_depth != 10)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
AlpProtoTestDestroy(&ctx);
|
|
return result;
|
|
}
|
|
|
|
static int AppLayerProbingParserTest12(void)
|
|
{
|
|
int result = 0;
|
|
AppLayerProbingParser *pp;
|
|
AppLayerProbingParserElement *pe;
|
|
|
|
AlpProtoDetectCtx ctx;
|
|
AlpProtoInit(&ctx);
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"http",
|
|
ALPROTO_HTTP,
|
|
5, 8,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
81,
|
|
IPPROTO_TCP,
|
|
"dcerpc",
|
|
ALPROTO_DCERPC,
|
|
9, 10,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
/* first pp */
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next == NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second pp */
|
|
if (pp->next->next != NULL)
|
|
goto end;
|
|
if (pp->next->toclient != NULL)
|
|
goto end;
|
|
if (pp->next->port != 81)
|
|
goto end;
|
|
if (pp->next->toserver_max_depth != 10)
|
|
goto end;
|
|
if (pp->next->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->next->toserver == NULL)
|
|
goto end;
|
|
if (pp->next->toserver->next != NULL)
|
|
goto end;
|
|
/* second pp - first one */
|
|
pe = pp->next->toserver;
|
|
if (strcmp(pe->al_proto_name, "dcerpc") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_DCERPC)
|
|
goto end;
|
|
if (pe->port != 81)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 9)
|
|
goto end;
|
|
if (pe->max_depth != 10)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"smb",
|
|
ALPROTO_SMB,
|
|
5, 5,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next == NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 5)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second pp */
|
|
if (pp->next->next != NULL)
|
|
goto end;
|
|
if (pp->next->toclient != NULL)
|
|
goto end;
|
|
if (pp->next->port != 81)
|
|
goto end;
|
|
if (pp->next->toserver_max_depth != 10)
|
|
goto end;
|
|
if (pp->next->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->next->toserver == NULL)
|
|
goto end;
|
|
if (pp->next->toserver->next != NULL)
|
|
goto end;
|
|
/* second pp - first one */
|
|
pe = pp->next->toserver;
|
|
if (strcmp(pe->al_proto_name, "dcerpc") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_DCERPC)
|
|
goto end;
|
|
if (pe->port != 81)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 9)
|
|
goto end;
|
|
if (pe->max_depth != 10)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
81,
|
|
IPPROTO_TCP,
|
|
"ftp",
|
|
ALPROTO_FTP,
|
|
7, 15,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
/* first pp */
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next == NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 5)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second pp */
|
|
if (pp->next->next != NULL)
|
|
goto end;
|
|
if (pp->next->toclient != NULL)
|
|
goto end;
|
|
if (pp->next->port != 81)
|
|
goto end;
|
|
if (pp->next->toserver_max_depth != 15)
|
|
goto end;
|
|
if (pp->next->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->next->toserver == NULL)
|
|
goto end;
|
|
if (pp->next->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->next->toserver->next->next != NULL)
|
|
goto end;
|
|
/* second pp - first one */
|
|
pe = pp->next->toserver;
|
|
if (strcmp(pe->al_proto_name, "ftp") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_FTP)
|
|
goto end;
|
|
if (pe->port != 81)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 7)
|
|
goto end;
|
|
if (pe->max_depth != 15)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second pp - second one */
|
|
pe = pp->next->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "dcerpc") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_DCERPC)
|
|
goto end;
|
|
if (pe->port != 81)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 9)
|
|
goto end;
|
|
if (pe->max_depth != 10)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
AlpProtoTestDestroy(&ctx);
|
|
return result;
|
|
}
|
|
|
|
static int AppLayerProbingParserTest13(void)
|
|
{
|
|
int result = 0;
|
|
AppLayerProbingParser *pp;
|
|
AppLayerProbingParserElement *pe;
|
|
|
|
AlpProtoDetectCtx ctx;
|
|
AlpProtoInit(&ctx);
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"http",
|
|
ALPROTO_HTTP,
|
|
5, 8,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
81,
|
|
IPPROTO_TCP,
|
|
"dcerpc",
|
|
ALPROTO_DCERPC,
|
|
9, 10,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_LOW, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
/* first pp */
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next == NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second pp */
|
|
if (pp->next->next != NULL)
|
|
goto end;
|
|
if (pp->next->toclient != NULL)
|
|
goto end;
|
|
if (pp->next->port != 81)
|
|
goto end;
|
|
if (pp->next->toserver_max_depth != 10)
|
|
goto end;
|
|
if (pp->next->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->next->toserver == NULL)
|
|
goto end;
|
|
if (pp->next->toserver->next != NULL)
|
|
goto end;
|
|
/* second pp - first one */
|
|
pe = pp->next->toserver;
|
|
if (strcmp(pe->al_proto_name, "dcerpc") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_DCERPC)
|
|
goto end;
|
|
if (pe->port != 81)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW)
|
|
goto end;
|
|
if (pe->min_depth != 9)
|
|
goto end;
|
|
if (pe->max_depth != 10)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"smb",
|
|
ALPROTO_SMB,
|
|
5, 5,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 0,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next == NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 5)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second pp */
|
|
if (pp->next->next != NULL)
|
|
goto end;
|
|
if (pp->next->toclient != NULL)
|
|
goto end;
|
|
if (pp->next->port != 81)
|
|
goto end;
|
|
if (pp->next->toserver_max_depth != 10)
|
|
goto end;
|
|
if (pp->next->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->next->toserver == NULL)
|
|
goto end;
|
|
if (pp->next->toserver->next != NULL)
|
|
goto end;
|
|
/* second pp - first one */
|
|
pe = pp->next->toserver;
|
|
if (strcmp(pe->al_proto_name, "dcerpc") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_DCERPC)
|
|
goto end;
|
|
if (pe->port != 81)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW)
|
|
goto end;
|
|
if (pe->min_depth != 9)
|
|
goto end;
|
|
if (pe->max_depth != 10)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
81,
|
|
IPPROTO_TCP,
|
|
"ftp",
|
|
ALPROTO_FTP,
|
|
7, 15,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
/* first pp */
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next == NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 5)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second pp */
|
|
if (pp->next->next != NULL)
|
|
goto end;
|
|
if (pp->next->toclient != NULL)
|
|
goto end;
|
|
if (pp->next->port != 81)
|
|
goto end;
|
|
if (pp->next->toserver_max_depth != 15)
|
|
goto end;
|
|
if (pp->next->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->next->toserver == NULL)
|
|
goto end;
|
|
if (pp->next->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->next->toserver->next->next != NULL)
|
|
goto end;
|
|
/* second pp - first one */
|
|
pe = pp->next->toserver;
|
|
if (strcmp(pe->al_proto_name, "ftp") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_FTP)
|
|
goto end;
|
|
if (pe->port != 81)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 7)
|
|
goto end;
|
|
if (pe->max_depth != 15)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second pp - second one */
|
|
pe = pp->next->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "dcerpc") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_DCERPC)
|
|
goto end;
|
|
if (pe->port != 81)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW)
|
|
goto end;
|
|
if (pe->min_depth != 9)
|
|
goto end;
|
|
if (pe->max_depth != 10)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerPrintProbingParsers(ctx.probing_parsers);
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
AlpProtoTestDestroy(&ctx);
|
|
return result;
|
|
}
|
|
|
|
static int AppLayerProbingParserTest14(void)
|
|
{
|
|
int result = 0;
|
|
AppLayerProbingParser *pp;
|
|
AppLayerProbingParserElement *pe;
|
|
|
|
AlpProtoDetectCtx ctx;
|
|
AlpProtoInit(&ctx);
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"http",
|
|
ALPROTO_HTTP,
|
|
5, 8,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"smb",
|
|
ALPROTO_SMB,
|
|
5, 15,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 0,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 15)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 15)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
0,
|
|
IPPROTO_TCP,
|
|
"dcerpc",
|
|
ALPROTO_DCERPC,
|
|
5, 25,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 0,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next == NULL)
|
|
goto end;
|
|
if (pp->next->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 25)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 15)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
pe = pp->toserver->next->next;
|
|
if (strcmp(pe->al_proto_name, "dcerpc") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_DCERPC)
|
|
goto end;
|
|
if (pe->port != 0)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 25)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second probing parser */
|
|
pp = pp->next;
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 0)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 25)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "dcerpc") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_DCERPC)
|
|
goto end;
|
|
if (pe->port != 0)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 25)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
81,
|
|
IPPROTO_TCP,
|
|
"ftp",
|
|
ALPROTO_FTP,
|
|
7, 50,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next == NULL)
|
|
goto end;
|
|
if (pp->next->next == NULL)
|
|
goto end;
|
|
if (pp->next->next->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 25)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 15)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
pe = pp->toserver->next->next;
|
|
if (strcmp(pe->al_proto_name, "dcerpc") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_DCERPC)
|
|
goto end;
|
|
if (pe->port != 0)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 25)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
/* second probing parser */
|
|
pp = pp->next;
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next == NULL)
|
|
goto end;
|
|
if (pp->next->next != NULL)
|
|
goto end;
|
|
if (pp->port != 81)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 50)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "ftp") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_FTP)
|
|
goto end;
|
|
if (pe->port != 81)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 7)
|
|
goto end;
|
|
if (pe->max_depth != 50)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "dcerpc") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_DCERPC)
|
|
goto end;
|
|
if (pe->port != 0)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 25)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
/* third probing parser */
|
|
pp = pp->next;
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 0)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 25)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "dcerpc") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_DCERPC)
|
|
goto end;
|
|
if (pe->port != 0)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 25)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerPrintProbingParsers(ctx.probing_parsers);
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
AlpProtoTestDestroy(&ctx);
|
|
return result;
|
|
}
|
|
|
|
static int AppLayerProbingParserTest15(void)
|
|
{
|
|
int result = 0;
|
|
AppLayerProbingParser *pp;
|
|
AppLayerProbingParserElement *pe;
|
|
|
|
AlpProtoDetectCtx ctx;
|
|
AlpProtoInit(&ctx);
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"http",
|
|
ALPROTO_HTTP,
|
|
5, 8,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 8)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
80,
|
|
IPPROTO_TCP,
|
|
"smb",
|
|
ALPROTO_SMB,
|
|
5, 15,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 0,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 15)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 15)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
0,
|
|
IPPROTO_TCP,
|
|
"dcerpc",
|
|
ALPROTO_DCERPC,
|
|
5, 25,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 0,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next == NULL)
|
|
goto end;
|
|
if (pp->next->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 25)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 15)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
pe = pp->toserver->next->next;
|
|
if (strcmp(pe->al_proto_name, "dcerpc") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_DCERPC)
|
|
goto end;
|
|
if (pe->port != 0)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 25)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second probing parser */
|
|
pp = pp->next;
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 0)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 25)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "dcerpc") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_DCERPC)
|
|
goto end;
|
|
if (pe->port != 0)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 25)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerRegisterProbingParser(&ctx,
|
|
81,
|
|
IPPROTO_TCP,
|
|
"ftp",
|
|
ALPROTO_FTP,
|
|
7, 15,
|
|
STREAM_TOSERVER,
|
|
APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1,
|
|
ProbingParserDummyForTesting);
|
|
pp = ctx.probing_parsers;
|
|
if (ctx.probing_parsers == NULL) {
|
|
goto end;
|
|
}
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next == NULL)
|
|
goto end;
|
|
if (pp->next->next == NULL)
|
|
goto end;
|
|
if (pp->next->next->next != NULL)
|
|
goto end;
|
|
if (pp->port != 80)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 25)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "http") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_HTTP)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 8)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "smb") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_SMB)
|
|
goto end;
|
|
if (pe->port != 80)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 15)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
pe = pp->toserver->next->next;
|
|
if (strcmp(pe->al_proto_name, "dcerpc") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_DCERPC)
|
|
goto end;
|
|
if (pe->port != 0)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 25)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
/* second probing parser */
|
|
pp = pp->next;
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next == NULL)
|
|
goto end;
|
|
if (pp->next->next != NULL)
|
|
goto end;
|
|
if (pp->port != 81)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 25)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next == NULL)
|
|
goto end;
|
|
if (pp->toserver->next->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "ftp") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_FTP)
|
|
goto end;
|
|
if (pe->port != 81)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 7)
|
|
goto end;
|
|
if (pe->max_depth != 15)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
/* second one */
|
|
pe = pp->toserver->next;
|
|
if (strcmp(pe->al_proto_name, "dcerpc") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_DCERPC)
|
|
goto end;
|
|
if (pe->port != 0)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 25)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
/* third probing parser */
|
|
pp = pp->next;
|
|
if (pp->toclient != NULL)
|
|
goto end;
|
|
if (pp->next != NULL)
|
|
goto end;
|
|
if (pp->port != 0)
|
|
goto end;
|
|
if (pp->toserver_max_depth != 25)
|
|
goto end;
|
|
if (pp->toclient_max_depth != 0)
|
|
goto end;
|
|
if (pp->toserver == NULL)
|
|
goto end;
|
|
if (pp->toserver->next != NULL)
|
|
goto end;
|
|
/* first one */
|
|
pe = pp->toserver;
|
|
if (strcmp(pe->al_proto_name, "dcerpc") != 0)
|
|
goto end;
|
|
if (pe->al_proto != ALPROTO_DCERPC)
|
|
goto end;
|
|
if (pe->port != 0)
|
|
goto end;
|
|
if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH)
|
|
goto end;
|
|
if (pe->min_depth != 5)
|
|
goto end;
|
|
if (pe->max_depth != 25)
|
|
goto end;
|
|
if (pe->ProbingParser != ProbingParserDummyForTesting)
|
|
goto end;
|
|
|
|
AppLayerPrintProbingParsers(ctx.probing_parsers);
|
|
|
|
result = 1;
|
|
|
|
end:
|
|
AlpProtoTestDestroy(&ctx);
|
|
return result;
|
|
}
|
|
|
|
#endif /* UNITESTS */
|
|
|
|
void AppLayerParserRegisterTests(void)
|
|
{
|
|
#ifdef UNITTESTS
|
|
UtRegisterTest("AppLayerParserTest01", AppLayerParserTest01, 1);
|
|
UtRegisterTest("AppLayerParserTest02", AppLayerParserTest02, 1);
|
|
UtRegisterTest("AppLayerProbingParserTest01", AppLayerProbingParserTest01, 1);
|
|
UtRegisterTest("AppLayerProbingParserTest02", AppLayerProbingParserTest02, 1);
|
|
UtRegisterTest("AppLayerProbingParserTest03", AppLayerProbingParserTest03, 1);
|
|
UtRegisterTest("AppLayerProbingParserTest04", AppLayerProbingParserTest04, 1);
|
|
UtRegisterTest("AppLayerProbingParserTest05", AppLayerProbingParserTest05, 1);
|
|
UtRegisterTest("AppLayerProbingParserTest06", AppLayerProbingParserTest06, 1);
|
|
UtRegisterTest("AppLayerProbingParserTest07", AppLayerProbingParserTest07, 1);
|
|
UtRegisterTest("AppLayerProbingParserTest08", AppLayerProbingParserTest08, 1);
|
|
UtRegisterTest("AppLayerProbingParserTest09", AppLayerProbingParserTest09, 1);
|
|
UtRegisterTest("AppLayerProbingParserTest10", AppLayerProbingParserTest10, 1);
|
|
UtRegisterTest("AppLayerProbingParserTest11", AppLayerProbingParserTest11, 1);
|
|
UtRegisterTest("AppLayerProbingParserTest12", AppLayerProbingParserTest12, 1);
|
|
UtRegisterTest("AppLayerProbingParserTest13", AppLayerProbingParserTest13, 1);
|
|
UtRegisterTest("AppLayerProbingParserTest14", AppLayerProbingParserTest14, 1);
|
|
UtRegisterTest("AppLayerProbingParserTest15", AppLayerProbingParserTest15, 1);
|
|
#endif /* UNITTESTS */
|
|
|
|
return;
|
|
}
|