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.
suricata/src/app-layer.c

2835 lines
126 KiB
C

/* Copyright (C) 2007-2021 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>
* \author Anoop Saldanha <anoopsaldanha@gmail.com>
*
* Generic App-layer functions
*/
#include "suricata-common.h"
#include "suricata.h"
#include "app-layer.h"
#include "app-layer-parser.h"
#include "app-layer-protos.h"
#include "app-layer-expectation.h"
#include "app-layer-ftp.h"
#include "app-layer-detect-proto.h"
#include "app-layer-frames.h"
#include "stream-tcp-reassemble.h"
#include "stream-tcp-private.h"
#include "stream-tcp-inline.h"
#include "stream-tcp.h"
#include "flow.h"
#include "flow-util.h"
#include "flow-private.h"
#include "ippair.h"
#include "util-debug.h"
#include "util-print.h"
#include "util-profiling.h"
#include "util-validate.h"
#include "decode-events.h"
#include "app-layer-htp-mem.h"
#include "util-exception-policy.h"
/**
* \brief This is for the app layer in general and it contains per thread
* context relevant to both the alpd and alp.
*/
struct AppLayerThreadCtx_ {
/* App layer protocol detection thread context, from AppLayerProtoDetectGetCtxThread(). */
AppLayerProtoDetectThreadCtx *alpd_tctx;
/* App layer parser thread context, from AppLayerParserThreadCtxAlloc(). */
AppLayerParserThreadCtx *alp_tctx;
#ifdef PROFILING
uint64_t ticks_start;
uint64_t ticks_end;
uint64_t ticks_spent;
AppProto alproto;
uint64_t proto_detect_ticks_start;
uint64_t proto_detect_ticks_end;
uint64_t proto_detect_ticks_spent;
#endif
};
#define FLOW_PROTO_CHANGE_MAX_DEPTH 4096
#define MAX_COUNTER_SIZE 64
typedef struct AppLayerCounterNames_ {
char name[MAX_COUNTER_SIZE];
char tx_name[MAX_COUNTER_SIZE];
char gap_error[MAX_COUNTER_SIZE];
char parser_error[MAX_COUNTER_SIZE];
char internal_error[MAX_COUNTER_SIZE];
char alloc_error[MAX_COUNTER_SIZE];
} AppLayerCounterNames;
typedef struct AppLayerCounters_ {
uint16_t counter_id;
uint16_t counter_tx_id;
uint16_t gap_error_id;
uint16_t parser_error_id;
uint16_t internal_error_id;
uint16_t alloc_error_id;
} AppLayerCounters;
/* counter names. Only used at init. */
AppLayerCounterNames applayer_counter_names[FLOW_PROTO_APPLAYER_MAX][ALPROTO_MAX];
/* counter id's. Used that runtime. */
AppLayerCounters applayer_counters[FLOW_PROTO_APPLAYER_MAX][ALPROTO_MAX];
void AppLayerSetupCounters(void);
void AppLayerDeSetupCounters(void);
/***** L7 layer dispatchers *****/
static inline int ProtoDetectDone(const Flow *f, const TcpSession *ssn, uint8_t direction) {
const TcpStream *stream = (direction & STREAM_TOSERVER) ? &ssn->client : &ssn->server;
return ((stream->flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED) ||
(FLOW_IS_PM_DONE(f, direction) && FLOW_IS_PP_DONE(f, direction)));
}
/**
* \note id can be 0 if protocol parser is disabled but detection
* is enabled.
*/
static void AppLayerIncFlowCounter(ThreadVars *tv, Flow *f)
{
const uint16_t id = applayer_counters[f->protomap][f->alproto].counter_id;
if (likely(tv && id > 0)) {
StatsIncr(tv, id);
}
}
void AppLayerIncTxCounter(ThreadVars *tv, Flow *f, uint64_t step)
{
const uint16_t id = applayer_counters[f->protomap][f->alproto].counter_tx_id;
if (likely(tv && id > 0)) {
StatsAddUI64(tv, id, step);
}
}
void AppLayerIncGapErrorCounter(ThreadVars *tv, Flow *f)
{
const uint16_t id = applayer_counters[f->protomap][f->alproto].gap_error_id;
if (likely(tv && id > 0)) {
StatsIncr(tv, id);
}
}
void AppLayerIncAllocErrorCounter(ThreadVars *tv, Flow *f)
{
const uint16_t id = applayer_counters[f->protomap][f->alproto].alloc_error_id;
if (likely(tv && id > 0)) {
StatsIncr(tv, id);
}
}
void AppLayerIncParserErrorCounter(ThreadVars *tv, Flow *f)
{
const uint16_t id = applayer_counters[f->protomap][f->alproto].parser_error_id;
if (likely(tv && id > 0)) {
StatsIncr(tv, id);
}
}
void AppLayerIncInternalErrorCounter(ThreadVars *tv, Flow *f)
{
const uint16_t id = applayer_counters[f->protomap][f->alproto].internal_error_id;
if (likely(tv && id > 0)) {
StatsIncr(tv, id);
}
}
/* in IDS mode protocol detection is done in reverse order:
* when TCP data is ack'd. We want to flag the correct packet,
* so in this case we set a flag in the flow so that the first
* packet in the correct direction can be tagged.
*
* For IPS we update packet and flow. */
static inline void FlagPacketFlow(Packet *p, Flow *f, uint8_t flags)
{
if (p->proto != IPPROTO_TCP || EngineModeIsIPS()) {
if (flags & STREAM_TOSERVER) {
if (p->flowflags & FLOW_PKT_TOSERVER) {
p->flags |= PKT_PROTO_DETECT_TS_DONE;
f->flags |= FLOW_PROTO_DETECT_TS_DONE;
} else {
f->flags |= FLOW_PROTO_DETECT_TS_DONE;
}
} else {
if (p->flowflags & FLOW_PKT_TOCLIENT) {
p->flags |= PKT_PROTO_DETECT_TC_DONE;
f->flags |= FLOW_PROTO_DETECT_TC_DONE;
} else {
f->flags |= FLOW_PROTO_DETECT_TC_DONE;
}
}
} else {
if (flags & STREAM_TOSERVER) {
f->flags |= FLOW_PROTO_DETECT_TS_DONE;
} else {
f->flags |= FLOW_PROTO_DETECT_TC_DONE;
}
}
}
static void DisableAppLayer(ThreadVars *tv, Flow *f, Packet *p)
{
SCLogDebug("disable app layer for flow %p alproto %u ts %u tc %u",
f, f->alproto, f->alproto_ts, f->alproto_tc);
FlowCleanupAppLayer(f);
StreamTcpDisableAppLayer(f);
TcpSession *ssn = f->protoctx;
ssn->data_first_seen_dir = APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER;
f->alproto = ALPROTO_FAILED;
AppLayerIncFlowCounter(tv, f);
if (f->alproto_tc != ALPROTO_FAILED) {
if (f->alproto_tc == ALPROTO_UNKNOWN) {
f->alproto_tc = ALPROTO_FAILED;
}
FlagPacketFlow(p, f, STREAM_TOCLIENT);
}
if (f->alproto_ts != ALPROTO_FAILED) {
if (f->alproto_ts == ALPROTO_UNKNOWN) {
f->alproto_ts = ALPROTO_FAILED;
}
FlagPacketFlow(p, f, STREAM_TOSERVER);
}
SCLogDebug("disabled app layer for flow %p alproto %u ts %u tc %u",
f, f->alproto, f->alproto_ts, f->alproto_tc);
}
/* See if we're going to have to give up:
*
* If we're getting a lot of data in one direction and the
* proto for this direction is unknown, proto detect will
* hold up segments in the segment list in the stream.
* They are held so that if we detect the protocol on the
* opposing stream, we can still parse this side of the stream
* as well. However, some sessions are very unbalanced. FTP
* data channels, large PUT/POST request and many others, can
* lead to cases where we would have to store many megabytes
* worth of segments before we see the opposing stream. This
* leads to risks of resource starvation.
*
* Here a cutoff point is enforced. If we've stored 100k in
* one direction and we've seen no data in the other direction,
* we give up.
*
* Giving up means we disable applayer an set an applayer event
*/
static void TCPProtoDetectCheckBailConditions(ThreadVars *tv,
Flow *f, TcpSession *ssn, Packet *p)
{
if (ssn->state < TCP_ESTABLISHED) {
SCLogDebug("skip as long as TCP is not ESTABLISHED (TCP fast open)");
return;
}
const uint32_t size_ts = StreamDataAvailableForProtoDetect(&ssn->client);
const uint32_t size_tc = StreamDataAvailableForProtoDetect(&ssn->server);
SCLogDebug("size_ts %" PRIu32 ", size_tc %" PRIu32, size_ts, size_tc);
/* at least 100000 whatever the conditions
* and can be more if window is bigger and if configuration allows it */
const uint32_t size_tc_limit =
MAX(100000, MIN(ssn->client.window, stream_config.reassembly_depth));
const uint32_t size_ts_limit =
MAX(100000, MIN(ssn->server.window, stream_config.reassembly_depth));
if (ProtoDetectDone(f, ssn, STREAM_TOSERVER) &&
ProtoDetectDone(f, ssn, STREAM_TOCLIENT))
{
goto failure;
/* we bail out whatever the pp and pm states if
* we received too much data */
} else if (size_tc > 2 * size_tc_limit || size_ts > 2 * size_ts_limit) {
AppLayerDecoderEventsSetEventRaw(&p->app_layer_events, APPLAYER_PROTO_DETECTION_SKIPPED);
goto failure;
} else if (FLOW_IS_PM_DONE(f, STREAM_TOSERVER) && FLOW_IS_PP_DONE(f, STREAM_TOSERVER) &&
size_ts > size_ts_limit && size_tc == 0) {
AppLayerDecoderEventsSetEventRaw(&p->app_layer_events,
APPLAYER_PROTO_DETECTION_SKIPPED);
goto failure;
} else if (FLOW_IS_PM_DONE(f, STREAM_TOCLIENT) && FLOW_IS_PP_DONE(f, STREAM_TOCLIENT) &&
size_tc > size_tc_limit && size_ts == 0) {
AppLayerDecoderEventsSetEventRaw(&p->app_layer_events,
APPLAYER_PROTO_DETECTION_SKIPPED);
goto failure;
/* little data in ts direction, pp done, pm not done (max
* depth not reached), ts direction done, lots of data in
* tc direction. */
} else if (size_tc > size_tc_limit && FLOW_IS_PP_DONE(f, STREAM_TOSERVER) &&
!(FLOW_IS_PM_DONE(f, STREAM_TOSERVER)) && FLOW_IS_PM_DONE(f, STREAM_TOCLIENT) &&
FLOW_IS_PP_DONE(f, STREAM_TOCLIENT)) {
AppLayerDecoderEventsSetEventRaw(&p->app_layer_events,
APPLAYER_PROTO_DETECTION_SKIPPED);
goto failure;
/* little data in tc direction, pp done, pm not done (max
* depth not reached), tc direction done, lots of data in
* ts direction. */
} else if (size_ts > size_ts_limit && FLOW_IS_PP_DONE(f, STREAM_TOCLIENT) &&
!(FLOW_IS_PM_DONE(f, STREAM_TOCLIENT)) && FLOW_IS_PM_DONE(f, STREAM_TOSERVER) &&
FLOW_IS_PP_DONE(f, STREAM_TOSERVER)) {
AppLayerDecoderEventsSetEventRaw(&p->app_layer_events,
APPLAYER_PROTO_DETECTION_SKIPPED);
goto failure;
}
return;
failure:
DisableAppLayer(tv, f, p);
return;
}
static int TCPProtoDetectTriggerOpposingSide(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
Packet *p, TcpSession *ssn, const TcpStream *stream)
{
TcpStream *opposing_stream = NULL;
if (stream == &ssn->client) {
opposing_stream = &ssn->server;
} else {
opposing_stream = &ssn->client;
}
/* if the opposing side is not going to work, then
* we just have to give up. */
if (opposing_stream->flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY) {
SCLogDebug("opposing dir has STREAMTCP_STREAM_FLAG_NOREASSEMBLY set");
return -1;
}
enum StreamUpdateDir dir = StreamTcpInlineMode() ?
UPDATE_DIR_OPPOSING :
UPDATE_DIR_PACKET;
int ret = StreamTcpReassembleAppLayer(tv, ra_ctx, ssn,
opposing_stream, p, dir);
return ret;
}
extern enum ExceptionPolicy g_applayerparser_error_policy;
/** \todo data const
* \retval int -1 error
* \retval int 0 ok
*/
static int TCPProtoDetect(ThreadVars *tv,
TcpReassemblyThreadCtx *ra_ctx, AppLayerThreadCtx *app_tctx,
Packet *p, Flow *f, TcpSession *ssn, TcpStream **stream,
uint8_t *data, uint32_t data_len, uint8_t flags)
{
AppProto *alproto;
AppProto *alproto_otherdir;
uint8_t direction = (flags & STREAM_TOSERVER) ? 0 : 1;
if (flags & STREAM_TOSERVER) {
alproto = &f->alproto_ts;
alproto_otherdir = &f->alproto_tc;
} else {
alproto = &f->alproto_tc;
alproto_otherdir = &f->alproto_ts;
}
SCLogDebug("Stream initializer (len %" PRIu32 ")", data_len);
#ifdef PRINT
if (data_len > 0) {
printf("=> Init Stream Data (app layer) -- start %s%s\n",
flags & STREAM_TOCLIENT ? "toclient" : "",
flags & STREAM_TOSERVER ? "toserver" : "");
PrintRawDataFp(stdout, data, data_len);
printf("=> Init Stream Data -- end\n");
}
#endif
bool reverse_flow = false;
DEBUG_VALIDATE_BUG_ON(data == NULL && data_len > 0);
PACKET_PROFILING_APP_PD_START(app_tctx);
*alproto = AppLayerProtoDetectGetProto(app_tctx->alpd_tctx,
f, data, data_len,
IPPROTO_TCP, flags, &reverse_flow);
PACKET_PROFILING_APP_PD_END(app_tctx);
SCLogDebug("alproto %u rev %s", *alproto, reverse_flow ? "true" : "false");
if (*alproto != ALPROTO_UNKNOWN) {
if (*alproto_otherdir != ALPROTO_UNKNOWN && *alproto_otherdir != *alproto) {
AppLayerDecoderEventsSetEventRaw(&p->app_layer_events,
APPLAYER_MISMATCH_PROTOCOL_BOTH_DIRECTIONS);
if (ssn->data_first_seen_dir == APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) {
/* if we already invoked the parser, we go with that proto */
f->alproto = *alproto_otherdir;
} else {
/* no data sent to parser yet, we can still choose
* we're trusting the server more. */
if (flags & STREAM_TOCLIENT)
f->alproto = *alproto;
else
f->alproto = *alproto_otherdir;
}
} else {
f->alproto = *alproto;
}
StreamTcpSetStreamFlagAppProtoDetectionCompleted(*stream);
TcpSessionSetReassemblyDepth(ssn,
AppLayerParserGetStreamDepth(f));
FlagPacketFlow(p, f, flags);
/* if protocol detection indicated that we need to reverse
* the direction of the flow, do it now. We flip the flow,
* packet and the direction flags */
if (reverse_flow &&
((ssn->flags & (STREAMTCP_FLAG_MIDSTREAM | STREAMTCP_FLAG_MIDSTREAM_SYNACK)) ==
STREAMTCP_FLAG_MIDSTREAM)) {
/* but only if we didn't already detect it on the other side. */
if (*alproto_otherdir == ALPROTO_UNKNOWN) {
SCLogDebug("reversing flow after proto detect told us so");
PacketSwap(p);
FlowSwap(f);
SWAP_FLAGS(flags, STREAM_TOSERVER, STREAM_TOCLIENT);
if (*stream == &ssn->client) {
*stream = &ssn->server;
} else {
*stream = &ssn->client;
}
direction = 1 - direction;
} else {
// TODO event, error?
}
}
/* account flow if we have both sides */
if (*alproto_otherdir != ALPROTO_UNKNOWN) {
AppLayerIncFlowCounter(tv, f);
}
/* if we have seen data from the other direction first, send
* data for that direction first to the parser. This shouldn't
* be an issue, since each stream processing happens
* independently of the other stream direction. At this point of
* call, you need to know that this function's already being
* called by the very same StreamReassembly() function that we
* will now call shortly for the opposing direction. */
if ((ssn->data_first_seen_dir & (STREAM_TOSERVER | STREAM_TOCLIENT)) &&
!(flags & ssn->data_first_seen_dir))
{
SCLogDebug("protocol %s needs first data in other direction",
AppProtoToString(*alproto));
if (TCPProtoDetectTriggerOpposingSide(tv, ra_ctx,
p, ssn, *stream) != 0)
{
goto detect_error;
}
if (FlowChangeProto(f)) {
/* We have the first data which requested a protocol change from P1 to P2
* even if it was not recognized at first as being P1
* As the second data was recognized as P1, the protocol did not change !
*/
FlowUnsetChangeProtoFlag(f);
AppLayerDecoderEventsSetEventRaw(&p->app_layer_events,
APPLAYER_UNEXPECTED_PROTOCOL);
}
}
/* if the parser operates such that it needs to see data from
* a particular direction first, we check if we have seen
* data from that direction first for the flow. IF it is not
* the same, we set an event and exit.
*
* \todo We need to figure out a more robust solution for this,
* as this can lead to easy evasion tactics, where the
* attackeer can first send some dummy data in the wrong
* direction first to mislead our proto detection process.
* While doing this we need to update the parsers as well,
* since the parsers must be robust to see such wrong
* direction data.
* Either ways the moment we see the
* APPLAYER_WRONG_DIRECTION_FIRST_DATA event set for the
* flow, it shows something's fishy.
*/
if (ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) {
uint8_t first_data_dir;
first_data_dir = AppLayerParserGetFirstDataDir(f->proto, f->alproto);
if (first_data_dir && !(first_data_dir & ssn->data_first_seen_dir)) {
AppLayerDecoderEventsSetEventRaw(&p->app_layer_events,
APPLAYER_WRONG_DIRECTION_FIRST_DATA);
goto detect_error;
}
/* This can happen if the current direction is not the
* right direction, and the data from the other(also
* the right direction) direction is available to be sent
* to the app layer, but it is not ack'ed yet and hence
* the forced call to STreamTcpAppLayerReassemble still
* hasn't managed to send data from the other direction
* to the app layer. */
if (first_data_dir && !(first_data_dir & flags)) {
FlowCleanupAppLayer(f);
StreamTcpResetStreamFlagAppProtoDetectionCompleted(*stream);
FLOW_RESET_PP_DONE(f, flags);
FLOW_RESET_PM_DONE(f, flags);
FLOW_RESET_PE_DONE(f, flags);
SCReturnInt(-1);
}
}
/* Set a value that is neither STREAM_TOSERVER, nor STREAM_TOCLIENT */
ssn->data_first_seen_dir = APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER;
/* finally, invoke the parser */
PACKET_PROFILING_APP_START(app_tctx, f->alproto);
int r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto,
flags, data, data_len);
PACKET_PROFILING_APP_END(app_tctx, f->alproto);
p->flags |= PKT_APPLAYER_UPDATE;
if (r != 1) {
StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
}
if (r < 0) {
goto parser_error;
}
} else {
/* if the ssn is midstream, we may end up with a case where the
* start of an HTTP request is missing. We won't detect HTTP based
* on the request. However, the reply is fine, so we detect
* HTTP anyway. This leads to passing the incomplete request to
* the htp parser.
*
* This has been observed, where the http parser then saw many
* bogus requests in the incomplete data.
*
* To counter this case, a midstream session MUST find it's
* protocol in the toserver direction. If not, we assume the
* start of the request/toserver is incomplete and no reliable
* detection and parsing is possible. So we give up.
*/
if ((ssn->flags & STREAMTCP_FLAG_MIDSTREAM) &&
!(ssn->flags & STREAMTCP_FLAG_MIDSTREAM_SYNACK))
{
if (FLOW_IS_PM_DONE(f, STREAM_TOSERVER) && FLOW_IS_PP_DONE(f, STREAM_TOSERVER)) {
SCLogDebug("midstream end pd %p", ssn);
/* midstream and toserver detection failed: give up */
DisableAppLayer(tv, f, p);
SCReturnInt(0);
}
}
if (*alproto_otherdir != ALPROTO_UNKNOWN) {
uint8_t first_data_dir;
first_data_dir = AppLayerParserGetFirstDataDir(f->proto, *alproto_otherdir);
/* this would handle this test case -
* http parser which says it wants to see toserver data first only.
* tcp handshake
* toclient data first received. - RUBBISH DATA which
* we don't detect as http
* toserver data next sent - we detect this as http.
* at this stage we see that toclient is the first data seen
* for this session and we try and redetect the app protocol,
* but we are unable to detect the app protocol like before.
* But since we have managed to detect the protocol for the
* other direction as http, we try to use that. At this
* stage we check if the direction of this stream matches
* to that acceptable by the app parser. If it is not the
* acceptable direction we error out.
*/
if ((ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) &&
(first_data_dir) && !(first_data_dir & flags))
{
goto detect_error;
}
/* if protocol detection is marked done for our direction we
* pass our data on. We're only succeeded in finding one
* direction: the opposing stream
*
* If PD was not yet complete, we don't do anything.
*/
if (FLOW_IS_PM_DONE(f, flags) && FLOW_IS_PP_DONE(f, flags)) {
if (data_len > 0)
ssn->data_first_seen_dir = APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER;
if (*alproto_otherdir != ALPROTO_FAILED) {
PACKET_PROFILING_APP_START(app_tctx, f->alproto);
int r = AppLayerParserParse(tv, app_tctx->alp_tctx, f,
f->alproto, flags,
data, data_len);
PACKET_PROFILING_APP_END(app_tctx, f->alproto);
p->flags |= PKT_APPLAYER_UPDATE;
if (r != 1) {
StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
}
AppLayerDecoderEventsSetEventRaw(&p->app_layer_events,
APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION);
TcpSessionSetReassemblyDepth(ssn,
AppLayerParserGetStreamDepth(f));
*alproto = *alproto_otherdir;
SCLogDebug("packet %"PRIu64": pd done(us %u them %u), parser called (r==%d), APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION set",
p->pcap_cnt, *alproto, *alproto_otherdir, r);
if (r < 0) {
goto parser_error;
}
}
*alproto = ALPROTO_FAILED;
StreamTcpSetStreamFlagAppProtoDetectionCompleted(*stream);
AppLayerIncFlowCounter(tv, f);
FlagPacketFlow(p, f, flags);
} else if (flags & STREAM_EOF) {
*alproto = f->alproto;
StreamTcpSetStreamFlagAppProtoDetectionCompleted(*stream);
AppLayerIncFlowCounter(tv, f);
}
} else {
/* both sides unknown, let's see if we need to give up */
if (FlowChangeProto(f)) {
/* TCPProtoDetectCheckBailConditions does not work well because
* size_tc from STREAM_RIGHT_EDGE is not reset to zero
* so, we set a lower limit to the data we inspect
* We could instead have set ssn->server.sb.stream_offset = 0;
*/
if (data_len >= FLOW_PROTO_CHANGE_MAX_DEPTH || (flags & STREAM_EOF)) {
DisableAppLayer(tv, f, p);
}
} else {
TCPProtoDetectCheckBailConditions(tv, f, ssn, p);
}
}
}
SCReturnInt(0);
parser_error:
ExceptionPolicyApply(p, g_applayerparser_error_policy, PKT_DROP_REASON_APPLAYER_ERROR);
SCReturnInt(-1);
detect_error:
DisableAppLayer(tv, f, p);
SCReturnInt(-2);
}
/** \brief handle TCP data for the app-layer.
*
* First run protocol detection and then when the protocol is known invoke
* the app layer parser.
*
* \param stream ptr-to-ptr to stream object. Might change if flow dir is
* reversed.
*/
int AppLayerHandleTCPData(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
Packet *p, Flow *f,
TcpSession *ssn, TcpStream **stream,
uint8_t *data, uint32_t data_len,
uint8_t flags)
{
SCEnter();
DEBUG_ASSERT_FLOW_LOCKED(f);
DEBUG_VALIDATE_BUG_ON(data_len > (uint32_t)INT_MAX);
AppLayerThreadCtx *app_tctx = ra_ctx->app_tctx;
AppProto alproto;
int r = 0;
SCLogDebug("data_len %u flags %02X", data_len, flags);
if (ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED) {
SCLogDebug("STREAMTCP_FLAG_APP_LAYER_DISABLED is set");
goto end;
}
const uint8_t direction = (flags & STREAM_TOSERVER) ? 0 : 1;
if (flags & STREAM_TOSERVER) {
alproto = f->alproto_ts;
} else {
alproto = f->alproto_tc;
}
/* If a gap notification, relay the notification on to the
* app-layer if known. */
if (flags & STREAM_GAP) {
if (alproto == ALPROTO_UNKNOWN) {
StreamTcpSetStreamFlagAppProtoDetectionCompleted(*stream);
SCLogDebug("ALPROTO_UNKNOWN flow %p, due to GAP in stream start", f);
/* if the other side didn't already find the proto, we're done */
if (f->alproto == ALPROTO_UNKNOWN) {
goto failure;
}
AppLayerIncFlowCounter(tv, f);
}
if (FlowChangeProto(f)) {
FlowUnsetChangeProtoFlag(f);
SCLogDebug("Cannot handle gap while changing protocol");
goto failure;
}
PACKET_PROFILING_APP_START(app_tctx, f->alproto);
r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto,
flags, data, data_len);
PACKET_PROFILING_APP_END(app_tctx, f->alproto);
p->flags |= PKT_APPLAYER_UPDATE;
/* ignore parser result for gap */
StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
if (r < 0) {
ExceptionPolicyApply(p, g_applayerparser_error_policy, PKT_DROP_REASON_APPLAYER_ERROR);
SCReturnInt(-1);
}
goto end;
}
/* if we don't know the proto yet and we have received a stream
* initializer message, we run proto detection.
* We receive 2 stream init msgs (one for each direction), we
* only run the proto detection for both and emit an event
* in the case protocols mismatch. */
if (alproto == ALPROTO_UNKNOWN && (flags & STREAM_START)) {
DEBUG_VALIDATE_BUG_ON(FlowChangeProto(f));
/* run protocol detection */
if (TCPProtoDetect(tv, ra_ctx, app_tctx, p, f, ssn, stream,
data, data_len, flags) != 0) {
goto failure;
}
} else if (alproto != ALPROTO_UNKNOWN && FlowChangeProto(f)) {
SCLogDebug("protocol change, old %s", AppProtoToString(f->alproto_orig));
void *alstate_orig = f->alstate;
AppLayerParserState *alparser = f->alparser;
// we delay AppLayerParserStateCleanup because we may need previous parser state
AppLayerProtoDetectReset(f);
StreamTcpResetStreamFlagAppProtoDetectionCompleted(&ssn->client);
StreamTcpResetStreamFlagAppProtoDetectionCompleted(&ssn->server);
/* rerun protocol detection */
int rd = TCPProtoDetect(tv, ra_ctx, app_tctx, p, f, ssn, stream, data, data_len, flags);
if (f->alproto == ALPROTO_UNKNOWN) {
DEBUG_VALIDATE_BUG_ON(alstate_orig != f->alstate);
// not enough data, revert AppLayerProtoDetectReset to rerun detection
f->alparser = alparser;
f->alproto = f->alproto_orig;
f->alproto_tc = f->alproto_orig;
f->alproto_ts = f->alproto_orig;
} else {
FlowUnsetChangeProtoFlag(f);
AppLayerParserStateProtoCleanup(f->protomap, f->alproto_orig, alstate_orig, alparser);
if (alstate_orig == f->alstate) {
// we just freed it
f->alstate = NULL;
}
}
if (rd != 0) {
SCLogDebug("proto detect failure");
goto failure;
}
SCLogDebug("protocol change, old %s, new %s",
AppProtoToString(f->alproto_orig), AppProtoToString(f->alproto));
if (f->alproto_expect != ALPROTO_UNKNOWN && f->alproto != ALPROTO_UNKNOWN &&
f->alproto != f->alproto_expect) {
AppLayerDecoderEventsSetEventRaw(&p->app_layer_events,
APPLAYER_UNEXPECTED_PROTOCOL);
if (f->alproto_expect == ALPROTO_TLS && f->alproto != ALPROTO_TLS) {
AppLayerDecoderEventsSetEventRaw(&p->app_layer_events,
APPLAYER_NO_TLS_AFTER_STARTTLS);
}
}
} else {
SCLogDebug("stream data (len %" PRIu32 " alproto "
"%"PRIu16" (flow %p)", data_len, f->alproto, f);
#ifdef PRINT
if (data_len > 0) {
printf("=> Stream Data (app layer) -- start %s%s\n",
flags & STREAM_TOCLIENT ? "toclient" : "",
flags & STREAM_TOSERVER ? "toserver" : "");
PrintRawDataFp(stdout, data, data_len);
printf("=> Stream Data -- end\n");
}
#endif
/* if we don't have a data object here we are not getting it
* a start msg should have gotten us one */
if (f->alproto != ALPROTO_UNKNOWN) {
PACKET_PROFILING_APP_START(app_tctx, f->alproto);
r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto,
flags, data, data_len);
PACKET_PROFILING_APP_END(app_tctx, f->alproto);
p->flags |= PKT_APPLAYER_UPDATE;
if (r != 1) {
StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
if (r < 0) {
ExceptionPolicyApply(
p, g_applayerparser_error_policy, PKT_DROP_REASON_APPLAYER_ERROR);
SCReturnInt(-1);
}
}
}
}
goto end;
failure:
r = -1;
end:
SCReturnInt(r);
}
/**
* \brief Handle a app layer UDP message
*
* If the protocol is yet unknown, the proto detection code is run first.
*
* \param dp_ctx Thread app layer detect context
* \param f *locked* flow
* \param p UDP packet
*
* \retval 0 ok
* \retval -1 error
*/
int AppLayerHandleUdp(ThreadVars *tv, AppLayerThreadCtx *tctx, Packet *p, Flow *f)
{
SCEnter();
AppProto *alproto;
AppProto *alproto_otherdir;
if (f->alproto_ts == ALPROTO_FAILED && f->alproto_tc == ALPROTO_FAILED) {
SCReturnInt(0);
}
int r = 0;
uint8_t flags = 0;
if (p->flowflags & FLOW_PKT_TOSERVER) {
flags |= STREAM_TOSERVER;
alproto = &f->alproto_ts;
alproto_otherdir = &f->alproto_tc;
} else {
flags |= STREAM_TOCLIENT;
alproto = &f->alproto_tc;
alproto_otherdir = &f->alproto_ts;
}
AppLayerProfilingReset(tctx);
/* if the protocol is still unknown, run detection */
if (*alproto == ALPROTO_UNKNOWN) {
SCLogDebug("Detecting AL proto on udp mesg (len %" PRIu32 ")",
p->payload_len);
bool reverse_flow = false;
PACKET_PROFILING_APP_PD_START(tctx);
*alproto = AppLayerProtoDetectGetProto(
tctx->alpd_tctx, f, p->payload, p->payload_len, IPPROTO_UDP, flags, &reverse_flow);
PACKET_PROFILING_APP_PD_END(tctx);
switch (*alproto) {
case ALPROTO_UNKNOWN:
if (*alproto_otherdir != ALPROTO_UNKNOWN) {
// Use recognized side
f->alproto = *alproto_otherdir;
// do not keep ALPROTO_UNKNOWN for this side so as not to loop
*alproto = *alproto_otherdir;
if (*alproto_otherdir == ALPROTO_FAILED) {
SCLogDebug("ALPROTO_UNKNOWN flow %p", f);
}
} else {
// First side of protocol is unknown
*alproto = ALPROTO_FAILED;
}
break;
case ALPROTO_FAILED:
if (*alproto_otherdir != ALPROTO_UNKNOWN) {
// Use recognized side
f->alproto = *alproto_otherdir;
if (*alproto_otherdir == ALPROTO_FAILED) {
SCLogDebug("ALPROTO_UNKNOWN flow %p", f);
}
}
// else wait for second side of protocol
break;
default:
if (*alproto_otherdir != ALPROTO_UNKNOWN && *alproto_otherdir != ALPROTO_FAILED) {
if (*alproto_otherdir != *alproto) {
AppLayerDecoderEventsSetEventRaw(
&p->app_layer_events, APPLAYER_MISMATCH_PROTOCOL_BOTH_DIRECTIONS);
// data already sent to parser, we cannot change the protocol to use the one
// of the server
}
} else {
f->alproto = *alproto;
}
}
if (*alproto_otherdir == ALPROTO_UNKNOWN) {
if (f->alproto == ALPROTO_UNKNOWN) {
// so as to increase stat about .app_layer.flow.failed_udp
f->alproto = ALPROTO_FAILED;
}
// If the other side is unknown, this is the first packet of the flow
AppLayerIncFlowCounter(tv, f);
}
// parse the data if we recognized one protocol
if (f->alproto != ALPROTO_UNKNOWN && f->alproto != ALPROTO_FAILED) {
if (reverse_flow) {
SCLogDebug("reversing flow after proto detect told us so");
PacketSwap(p);
FlowSwap(f);
SWAP_FLAGS(flags, STREAM_TOSERVER, STREAM_TOCLIENT);
}
PACKET_PROFILING_APP_START(tctx, f->alproto);
r = AppLayerParserParse(tv, tctx->alp_tctx, f, f->alproto,
flags, p->payload, p->payload_len);
PACKET_PROFILING_APP_END(tctx, f->alproto);
p->flags |= PKT_APPLAYER_UPDATE;
}
PACKET_PROFILING_APP_STORE(tctx, p);
/* we do only inspection in one direction, so flag both
* sides as done here */
FlagPacketFlow(p, f, STREAM_TOSERVER);
FlagPacketFlow(p, f, STREAM_TOCLIENT);
} else {
SCLogDebug("data (len %" PRIu32 " ), alproto "
"%"PRIu16" (flow %p)", p->payload_len, f->alproto, f);
/* run the parser */
PACKET_PROFILING_APP_START(tctx, f->alproto);
r = AppLayerParserParse(tv, tctx->alp_tctx, f, f->alproto,
flags, p->payload, p->payload_len);
PACKET_PROFILING_APP_END(tctx, f->alproto);
PACKET_PROFILING_APP_STORE(tctx, p);
p->flags |= PKT_APPLAYER_UPDATE;
}
if (r < 0) {
ExceptionPolicyApply(p, g_applayerparser_error_policy, PKT_DROP_REASON_APPLAYER_ERROR);
SCReturnInt(-1);
}
SCReturnInt(r);
}
/***** Utility *****/
AppProto AppLayerGetProtoByName(char *alproto_name)
{
SCEnter();
AppProto r = AppLayerProtoDetectGetProtoByName(alproto_name);
SCReturnCT(r, "AppProto");
}
const char *AppLayerGetProtoName(AppProto alproto)
{
SCEnter();
const char * r = AppLayerProtoDetectGetProtoName(alproto);
SCReturnCT(r, "char *");
}
void AppLayerListSupportedProtocols(void)
{
SCEnter();
AppProto alproto;
AppProto alprotos[ALPROTO_MAX];
AppLayerProtoDetectSupportedAppProtocols(alprotos);
printf("=========Supported App Layer Protocols=========\n");
for (alproto = 0; alproto < ALPROTO_MAX; alproto++) {
if (alprotos[alproto] == 1)
printf("%s\n", AppLayerGetProtoName(alproto));
}
SCReturn;
}
/***** Setup/General Registration *****/
int AppLayerSetup(void)
{
SCEnter();
AppLayerProtoDetectSetup();
AppLayerParserSetup();
AppLayerParserRegisterProtocolParsers();
AppLayerProtoDetectPrepareState();
AppLayerSetupCounters();
SCReturnInt(0);
}
int AppLayerDeSetup(void)
{
SCEnter();
AppLayerProtoDetectDeSetup();
AppLayerParserDeSetup();
AppLayerDeSetupCounters();
SCReturnInt(0);
}
AppLayerThreadCtx *AppLayerGetCtxThread(ThreadVars *tv)
{
SCEnter();
AppLayerThreadCtx *app_tctx = SCMalloc(sizeof(*app_tctx));
if (app_tctx == NULL)
goto error;
memset(app_tctx, 0, sizeof(*app_tctx));
if ((app_tctx->alpd_tctx = AppLayerProtoDetectGetCtxThread()) == NULL)
goto error;
if ((app_tctx->alp_tctx = AppLayerParserThreadCtxAlloc()) == NULL)
goto error;
goto done;
error:
AppLayerDestroyCtxThread(app_tctx);
app_tctx = NULL;
done:
SCReturnPtr(app_tctx, "void *");
}
void AppLayerDestroyCtxThread(AppLayerThreadCtx *app_tctx)
{
SCEnter();
if (app_tctx == NULL)
SCReturn;
if (app_tctx->alpd_tctx != NULL)
AppLayerProtoDetectDestroyCtxThread(app_tctx->alpd_tctx);
if (app_tctx->alp_tctx != NULL)
AppLayerParserThreadCtxFree(app_tctx->alp_tctx);
SCFree(app_tctx);
SCReturn;
}
#ifdef PROFILING
void AppLayerProfilingResetInternal(AppLayerThreadCtx *app_tctx)
{
PACKET_PROFILING_APP_RESET(app_tctx);
}
void AppLayerProfilingStoreInternal(AppLayerThreadCtx *app_tctx, Packet *p)
{
PACKET_PROFILING_APP_STORE(app_tctx, p);
}
#endif
/** \brief HACK to work around our broken unix manager (re)init loop
*/
void AppLayerRegisterGlobalCounters(void)
{
StatsRegisterGlobalCounter("http.memuse", HTPMemuseGlobalCounter);
StatsRegisterGlobalCounter("http.memcap", HTPMemcapGlobalCounter);
StatsRegisterGlobalCounter("ftp.memuse", FTPMemuseGlobalCounter);
StatsRegisterGlobalCounter("ftp.memcap", FTPMemcapGlobalCounter);
StatsRegisterGlobalCounter("app_layer.expectations", ExpectationGetCounter);
}
#define IPPROTOS_MAX 2
void AppLayerSetupCounters(void)
{
const uint8_t ipprotos[] = { IPPROTO_TCP, IPPROTO_UDP };
AppProto alprotos[ALPROTO_MAX];
const char *str = "app_layer.flow.";
const char *estr = "app_layer.error.";
AppLayerProtoDetectSupportedAppProtocols(alprotos);
for (uint8_t p = 0; p < IPPROTOS_MAX; p++) {
const uint8_t ipproto = ipprotos[p];
const uint8_t ipproto_map = FlowGetProtoMapping(ipproto);
const uint8_t other_ipproto = ipproto == IPPROTO_TCP ? IPPROTO_UDP : IPPROTO_TCP;
const char *ipproto_suffix = (ipproto == IPPROTO_TCP) ? "_tcp" : "_udp";
for (AppProto alproto = 0; alproto < ALPROTO_MAX; alproto++) {
if (alprotos[alproto] == 1) {
const char *tx_str = "app_layer.tx.";
const char *alproto_str = AppLayerGetProtoName(alproto);
if (AppLayerParserProtoIsRegistered(ipproto, alproto) &&
AppLayerParserProtoIsRegistered(other_ipproto, alproto)) {
snprintf(applayer_counter_names[ipproto_map][alproto].name,
sizeof(applayer_counter_names[ipproto_map][alproto].name),
"%s%s%s", str, alproto_str, ipproto_suffix);
snprintf(applayer_counter_names[ipproto_map][alproto].tx_name,
sizeof(applayer_counter_names[ipproto_map][alproto].tx_name),
"%s%s%s", tx_str, alproto_str, ipproto_suffix);
if (ipproto == IPPROTO_TCP) {
snprintf(applayer_counter_names[ipproto_map][alproto].gap_error,
sizeof(applayer_counter_names[ipproto_map][alproto].gap_error),
"%s%s%s.gap", estr, alproto_str, ipproto_suffix);
}
snprintf(applayer_counter_names[ipproto_map][alproto].alloc_error,
sizeof(applayer_counter_names[ipproto_map][alproto].alloc_error),
"%s%s%s.alloc", estr, alproto_str, ipproto_suffix);
snprintf(applayer_counter_names[ipproto_map][alproto].parser_error,
sizeof(applayer_counter_names[ipproto_map][alproto].parser_error),
"%s%s%s.parser", estr, alproto_str, ipproto_suffix);
snprintf(applayer_counter_names[ipproto_map][alproto].internal_error,
sizeof(applayer_counter_names[ipproto_map][alproto].internal_error),
"%s%s%s.internal", estr, alproto_str, ipproto_suffix);
} else {
snprintf(applayer_counter_names[ipproto_map][alproto].name,
sizeof(applayer_counter_names[ipproto_map][alproto].name),
"%s%s", str, alproto_str);
snprintf(applayer_counter_names[ipproto_map][alproto].tx_name,
sizeof(applayer_counter_names[ipproto_map][alproto].tx_name),
"%s%s", tx_str, alproto_str);
if (ipproto == IPPROTO_TCP) {
snprintf(applayer_counter_names[ipproto_map][alproto].gap_error,
sizeof(applayer_counter_names[ipproto_map][alproto].gap_error),
"%s%s.gap", estr, alproto_str);
}
snprintf(applayer_counter_names[ipproto_map][alproto].alloc_error,
sizeof(applayer_counter_names[ipproto_map][alproto].alloc_error),
"%s%s.alloc", estr, alproto_str);
snprintf(applayer_counter_names[ipproto_map][alproto].parser_error,
sizeof(applayer_counter_names[ipproto_map][alproto].parser_error),
"%s%s.parser", estr, alproto_str);
snprintf(applayer_counter_names[ipproto_map][alproto].internal_error,
sizeof(applayer_counter_names[ipproto_map][alproto].internal_error),
"%s%s.internal", estr, alproto_str);
}
} else if (alproto == ALPROTO_FAILED) {
snprintf(applayer_counter_names[ipproto_map][alproto].name,
sizeof(applayer_counter_names[ipproto_map][alproto].name),
"%s%s%s", str, "failed", ipproto_suffix);
if (ipproto == IPPROTO_TCP) {
snprintf(applayer_counter_names[ipproto_map][alproto].gap_error,
sizeof(applayer_counter_names[ipproto_map][alproto].gap_error),
"%sfailed%s.gap", estr, ipproto_suffix);
}
}
}
}
}
void AppLayerRegisterThreadCounters(ThreadVars *tv)
{
const uint8_t ipprotos[] = { IPPROTO_TCP, IPPROTO_UDP };
AppProto alprotos[ALPROTO_MAX];
AppLayerProtoDetectSupportedAppProtocols(alprotos);
for (uint8_t p = 0; p < IPPROTOS_MAX; p++) {
const uint8_t ipproto = ipprotos[p];
const uint8_t ipproto_map = FlowGetProtoMapping(ipproto);
for (AppProto alproto = 0; alproto < ALPROTO_MAX; alproto++) {
if (alprotos[alproto] == 1) {
applayer_counters[ipproto_map][alproto].counter_id =
StatsRegisterCounter(applayer_counter_names[ipproto_map][alproto].name, tv);
applayer_counters[ipproto_map][alproto].counter_tx_id =
StatsRegisterCounter(applayer_counter_names[ipproto_map][alproto].tx_name, tv);
if (ipproto == IPPROTO_TCP) {
applayer_counters[ipproto_map][alproto].gap_error_id = StatsRegisterCounter(
applayer_counter_names[ipproto_map][alproto].gap_error, tv);
}
applayer_counters[ipproto_map][alproto].alloc_error_id = StatsRegisterCounter(
applayer_counter_names[ipproto_map][alproto].alloc_error, tv);
applayer_counters[ipproto_map][alproto].parser_error_id = StatsRegisterCounter(
applayer_counter_names[ipproto_map][alproto].parser_error, tv);
applayer_counters[ipproto_map][alproto].internal_error_id = StatsRegisterCounter(
applayer_counter_names[ipproto_map][alproto].internal_error, tv);
} else if (alproto == ALPROTO_FAILED) {
applayer_counters[ipproto_map][alproto].counter_id =
StatsRegisterCounter(applayer_counter_names[ipproto_map][alproto].name, tv);
if (ipproto == IPPROTO_TCP) {
applayer_counters[ipproto_map][alproto].gap_error_id = StatsRegisterCounter(
applayer_counter_names[ipproto_map][alproto].gap_error, tv);
}
}
}
}
}
void AppLayerDeSetupCounters(void)
{
memset(applayer_counter_names, 0, sizeof(applayer_counter_names));
memset(applayer_counters, 0, sizeof(applayer_counters));
}
/***** Unittests *****/
#ifdef UNITTESTS
#include "pkt-var.h"
#include "stream-tcp-util.h"
#include "stream.h"
#include "util-unittest.h"
#define TEST_START \
Packet *p = PacketGetFromAlloc(); \
FAIL_IF_NULL(p); \
Flow f; \
ThreadVars tv; \
StreamTcpThread *stt = NULL; \
TCPHdr tcph; \
PacketQueueNoLock pq; \
memset(&pq, 0, sizeof(PacketQueueNoLock)); \
memset(&f, 0, sizeof(Flow)); \
memset(&tv, 0, sizeof(ThreadVars)); \
memset(&tcph, 0, sizeof(TCPHdr)); \
\
FLOW_INITIALIZE(&f); \
f.flags = FLOW_IPV4; \
f.proto = IPPROTO_TCP; \
p->flow = &f; \
p->tcph = &tcph; \
\
StreamTcpInitConfig(true); \
IPPairInitConfig(true); \
StreamTcpThreadInit(&tv, NULL, (void **)&stt); \
\
/* handshake */ \
tcph.th_win = htons(5480); \
tcph.th_flags = TH_SYN; \
p->flowflags = FLOW_PKT_TOSERVER; \
p->payload_len = 0; \
p->payload = NULL; \
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1); \
TcpSession *ssn = (TcpSession *)f.protoctx; \
\
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); \
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); \
FAIL_IF(f.alproto != ALPROTO_UNKNOWN); \
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN); \
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN); \
FAIL_IF(ssn->flags &STREAMTCP_FLAG_APP_LAYER_DISABLED); \
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER)); \
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER)); \
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT)); \
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); \
FAIL_IF(ssn->data_first_seen_dir != 0); \
\
/* handshake */ \
p->tcph->th_ack = htonl(1); \
p->tcph->th_flags = TH_SYN | TH_ACK; \
p->flowflags = FLOW_PKT_TOCLIENT; \
p->payload_len = 0; \
p->payload = NULL; \
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1); \
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); \
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); \
FAIL_IF(f.alproto != ALPROTO_UNKNOWN); \
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN); \
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN); \
FAIL_IF(ssn->flags &STREAMTCP_FLAG_APP_LAYER_DISABLED); \
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER)); \
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER)); \
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT)); \
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); \
FAIL_IF(ssn->data_first_seen_dir != 0); \
\
/* handshake */ \
p->tcph->th_ack = htonl(1); \
p->tcph->th_seq = htonl(1); \
p->tcph->th_flags = TH_ACK; \
p->flowflags = FLOW_PKT_TOSERVER; \
p->payload_len = 0; \
p->payload = NULL; \
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1); \
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); \
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); \
FAIL_IF(f.alproto != ALPROTO_UNKNOWN); \
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN); \
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN); \
FAIL_IF(ssn->flags &STREAMTCP_FLAG_APP_LAYER_DISABLED); \
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER)); \
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER)); \
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT)); \
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); \
FAIL_IF(ssn->data_first_seen_dir != 0);
#define TEST_END \
StreamTcpSessionClear(p->flow->protoctx); \
StreamTcpThreadDeinit(&tv, (void *)stt); \
StreamTcpFreeConfig(true); \
PacketFree(p); \
FLOW_DESTROY(&f); \
StatsThreadCleanup(&tv);
/**
* \test GET -> HTTP/1.1
*/
static int AppLayerTest01(void)
{
TEST_START;
/* full request */
uint8_t request[] = {
0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
p->tcph->th_ack = htonl(1);
p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = sizeof(request);
p->payload = request;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
/* full response - request ack */
uint8_t response[] = {
0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
p->tcph->th_ack = htonl(88);
p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = sizeof(response);
p->payload = response;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_HTTP1);
FAIL_IF(f.alproto_ts != ALPROTO_HTTP1);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
/* response ack */
p->tcph->th_ack = htonl(328);
p->tcph->th_seq = htonl(88);
p->tcph->th_flags = TH_ACK;
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = 0;
p->payload = NULL;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_HTTP1);
FAIL_IF(f.alproto_ts != ALPROTO_HTTP1);
FAIL_IF(f.alproto_tc != ALPROTO_HTTP1);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
TEST_END;
PASS;
}
/**
* \test GE -> T -> HTTP/1.1
*/
static int AppLayerTest02(void)
{
TEST_START;
/* partial request */
uint8_t request1[] = { 0x47, 0x45, };
p->tcph->th_ack = htonl(1);
p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = sizeof(request1);
p->payload = request1;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
/* response ack against partial request */
p->tcph->th_ack = htonl(3);
p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_ACK;
p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = 0;
p->payload = NULL;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
/* complete partial request */
uint8_t request2[] = {
0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
p->tcph->th_ack = htonl(1);
p->tcph->th_seq = htonl(3);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = sizeof(request2);
p->payload = request2;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
/* response - request ack */
uint8_t response[] = {
0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
p->tcph->th_ack = htonl(88);
p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = sizeof(response);
p->payload = response;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_HTTP1);
FAIL_IF(f.alproto_ts != ALPROTO_HTTP1);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
/* response ack */
p->tcph->th_ack = htonl(328);
p->tcph->th_seq = htonl(88);
p->tcph->th_flags = TH_ACK;
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = 0;
p->payload = NULL;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_HTTP1);
FAIL_IF(f.alproto_ts != ALPROTO_HTTP1);
FAIL_IF(f.alproto_tc != ALPROTO_HTTP1);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
TEST_END;
PASS;
}
/**
* \test GET -> RUBBISH(PM AND PP DONE IN ONE GO)
*/
static int AppLayerTest03(void)
{
TEST_START;
/* request */
uint8_t request[] = {
0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
p->tcph->th_ack = htonl(1);
p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = sizeof(request);
p->payload = request;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
/* rubbish response */
uint8_t response[] = {
0x58, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
p->tcph->th_ack = htonl(88);
p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = sizeof(response);
p->payload = response;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_HTTP1);
FAIL_IF(f.alproto_ts != ALPROTO_HTTP1);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
/* response ack */
p->tcph->th_ack = htonl(328);
p->tcph->th_seq = htonl(88);
p->tcph->th_flags = TH_ACK;
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = 0;
p->payload = NULL;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_HTTP1);
FAIL_IF(f.alproto_ts != ALPROTO_HTTP1);
FAIL_IF(f.alproto_tc != ALPROTO_FAILED);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
TEST_END;
PASS;
}
/**
* \test GE -> RUBBISH(TC - PM AND PP NOT DONE) -> RUBBISH(TC - PM AND PP DONE).
*/
static int AppLayerTest04(void)
{
TEST_START;
/* request */
uint8_t request[] = {
0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
PrintRawDataFp(stdout, request, sizeof(request));
p->tcph->th_ack = htonl(1);
p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = sizeof(request);
p->payload = request;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER); // TOSERVER data now seen
/* partial response */
uint8_t response1[] = { 0x58, 0x54, 0x54, 0x50, };
PrintRawDataFp(stdout, response1, sizeof(response1));
p->tcph->th_ack = htonl(88);
p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = sizeof(response1);
p->payload = response1;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); // toserver complete
FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
/* partial response ack */
p->tcph->th_ack = htonl(5);
p->tcph->th_seq = htonl(88);
p->tcph->th_flags = TH_ACK;
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = 0;
p->payload = NULL;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); // toserver complete
FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
/* remaining response */
uint8_t response2[] = {
0x2f, 0x31, 0x2e, 0x31,
0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
PrintRawDataFp(stdout, response2, sizeof(response2));
p->tcph->th_ack = htonl(88);
p->tcph->th_seq = htonl(5);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = sizeof(response2);
p->payload = response2;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); // toserver complete
FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
/* response ack */
p->tcph->th_ack = htonl(328);
p->tcph->th_seq = htonl(88);
p->tcph->th_flags = TH_ACK;
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = 0;
p->payload = NULL;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); // toclient complete (failed)
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); // toserver complete
FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
FAIL_IF(f.alproto_tc != ALPROTO_FAILED); // tc failed
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
TEST_END;
PASS;
}
/**
* \test RUBBISH -> HTTP/1.1
*/
static int AppLayerTest05(void)
{
TEST_START;
/* full request */
uint8_t request[] = {
0x48, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
PrintRawDataFp(stdout, request, sizeof(request));
p->tcph->th_ack = htonl(1);
p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = sizeof(request);
p->payload = request;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
/* full response - request ack */
uint8_t response[] = {
0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
PrintRawDataFp(stdout, response, sizeof(response));
p->tcph->th_ack = htonl(88);
p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = sizeof(response);
p->payload = response;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
/* response ack */
p->tcph->th_ack = htonl(328);
p->tcph->th_seq = htonl(88);
p->tcph->th_flags = TH_ACK;
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = 0;
p->payload = NULL;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_HTTP1);
FAIL_IF(f.alproto_ts != ALPROTO_FAILED);
FAIL_IF(f.alproto_tc != ALPROTO_HTTP1);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
TEST_END;
PASS;
}
/**
* \test HTTP/1.1 -> GET
*/
static int AppLayerTest06(void)
{
TEST_START;
/* full response - request ack */
uint8_t response[] = {
0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
p->tcph->th_ack = htonl(1);
p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = sizeof(response);
p->payload = response;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != STREAM_TOCLIENT);
/* full request - response ack*/
uint8_t request[] = {
0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
p->tcph->th_ack = htonl(328);
p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = sizeof(request);
p->payload = request;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_HTTP1);
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_tc != ALPROTO_HTTP1);
FAIL_IF((ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
p->tcph->th_ack = htonl(1 + sizeof(request));
p->tcph->th_seq = htonl(328);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = 0;
p->payload = NULL;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_HTTP1);
FAIL_IF(f.alproto_ts != ALPROTO_HTTP1);
FAIL_IF(f.alproto_tc != ALPROTO_HTTP1);
FAIL_IF((ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED));
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
TEST_END;
PASS;
}
/**
* \test GET -> DCERPC
*/
static int AppLayerTest07(void)
{
TEST_START;
/* full request */
uint8_t request[] = {
0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
p->tcph->th_ack = htonl(1);
p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = sizeof(request);
p->payload = request;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
/* full response - request ack */
uint8_t response[] = { 0x05, 0x00, 0x4d, 0x42, 0x00, 0x01, 0x2e, 0x31, 0x20, 0x32, 0x30, 0x30,
0x20, 0x4f, 0x4b, 0x0d, 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, 0x72, 0x69, 0x2c,
0x20, 0x32, 0x33, 0x20, 0x53, 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20, 0x30, 0x36,
0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, 0x72,
0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69, 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f,
0x32, 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65,
0x64, 0x3a, 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34, 0x20, 0x4e, 0x6f, 0x76, 0x20,
0x32, 0x30, 0x31, 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a, 0x34, 0x36, 0x20, 0x47,
0x4d, 0x54, 0x0d, 0x0a, 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61, 0x62, 0x38, 0x39,
0x36, 0x35, 0x2d, 0x32, 0x63, 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61, 0x37, 0x66,
0x37, 0x66, 0x38, 0x30, 0x22, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x52,
0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20,
0x34, 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a,
0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d,
0x6c, 0x0d, 0x0a, 0x58, 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64,
0x20, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d, 0x0a, 0x0d,
0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x68,
0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
p->tcph->th_ack = htonl(88);
p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = sizeof(response);
p->payload = response;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_HTTP1);
FAIL_IF(f.alproto_ts != ALPROTO_HTTP1);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
/* response ack */
p->tcph->th_ack = htonl(328);
p->tcph->th_seq = htonl(88);
p->tcph->th_flags = TH_ACK;
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = 0;
p->payload = NULL;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_HTTP1);
FAIL_IF(f.alproto_ts != ALPROTO_HTTP1);
FAIL_IF(f.alproto_tc != ALPROTO_DCERPC);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
TEST_END;
PASS;
}
/**
* \test SMB -> HTTP/1.1
*/
static int AppLayerTest08(void)
{
TEST_START;
/* full request */
uint8_t request[] = { 0x05, 0x00, 0x54, 0x20, 0x00, 0x01, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68,
0x74, 0x6d, 0x6c, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x0d, 0x0a, 0x48,
0x6f, 0x73, 0x74, 0x3a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x0d,
0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41, 0x70,
0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
p->tcph->th_ack = htonl(1);
p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = sizeof(request);
p->payload = request;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
/* full response - request ack */
uint8_t response[] = {
0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
p->tcph->th_ack = htonl(88);
p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = sizeof(response);
p->payload = response;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_DCERPC);
FAIL_IF(f.alproto_ts != ALPROTO_DCERPC);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
/* response ack */
p->tcph->th_ack = htonl(328);
p->tcph->th_seq = htonl(88);
p->tcph->th_flags = TH_ACK;
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = 0;
p->payload = NULL;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_DCERPC);
FAIL_IF(f.alproto_ts != ALPROTO_DCERPC);
FAIL_IF(f.alproto_tc != ALPROTO_HTTP1);
FAIL_IF(!(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED));
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
TEST_END;
PASS;
}
/**
* \test RUBBISH(TC - PM and PP NOT DONE) ->
* RUBBISH(TC - PM and PP DONE) ->
* RUBBISH(TS - PM and PP DONE)
*/
static int AppLayerTest09(void)
{
TEST_START;
/* full request */
uint8_t request1[] = {
0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64 };
p->tcph->th_ack = htonl(1);
p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = sizeof(request1);
p->payload = request1;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
/* response - request ack */
p->tcph->th_ack = htonl(9);
p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = 0;
p->payload = NULL;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
/* full request */
uint8_t request2[] = {
0x44, 0x44, 0x45, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff };
p->tcph->th_ack = htonl(1);
p->tcph->th_seq = htonl(9);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = sizeof(request2);
p->payload = request2;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
/* full response - request ack */
uint8_t response[] = {
0x55, 0x74, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
p->tcph->th_ack = htonl(18);
p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = sizeof(response);
p->payload = response;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
/* response ack */
p->tcph->th_ack = htonl(328);
p->tcph->th_seq = htonl(18);
p->tcph->th_flags = TH_ACK;
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = 0;
p->payload = NULL;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_FAILED);
FAIL_IF(f.alproto_ts != ALPROTO_FAILED);
FAIL_IF(f.alproto_tc != ALPROTO_FAILED);
FAIL_IF(!(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED));
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
TEST_END;
PASS;
}
/**
* \test RUBBISH(TC - PM and PP DONE) ->
* RUBBISH(TS - PM and PP DONE)
*/
static int AppLayerTest10(void)
{
TEST_START;
/* full request */
uint8_t request1[] = {
0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64,
0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff };
p->tcph->th_ack = htonl(1);
p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = sizeof(request1);
p->payload = request1;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
/* response - request ack */
p->tcph->th_ack = htonl(18);
p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = 0;
p->payload = NULL;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
/* full response - request ack */
uint8_t response[] = {
0x55, 0x74, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
p->tcph->th_ack = htonl(18);
p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = sizeof(response);
p->payload = response;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
/* response ack */
p->tcph->th_ack = htonl(328);
p->tcph->th_seq = htonl(18);
p->tcph->th_flags = TH_ACK;
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = 0;
p->payload = NULL;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_FAILED);
FAIL_IF(f.alproto_ts != ALPROTO_FAILED);
FAIL_IF(f.alproto_tc != ALPROTO_FAILED);
FAIL_IF(!(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED));
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
TEST_END;
PASS;
}
/**
* \test RUBBISH(TC - PM and PP DONE) ->
* RUBBISH(TS - PM and PP NOT DONE) ->
* RUBBISH(TS - PM and PP DONE)
*/
static int AppLayerTest11(void)
{
TEST_START;
/* full request */
uint8_t request1[] = {
0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64,
0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff };
p->tcph->th_ack = htonl(1);
p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = sizeof(request1);
p->payload = request1;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
/* response - request ack */
p->tcph->th_ack = htonl(18);
p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = 0;
p->payload = NULL;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
/* full response - request ack */
uint8_t response1[] = {
0x55, 0x74, 0x54, 0x50, };
p->tcph->th_ack = htonl(18);
p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = sizeof(response1);
p->payload = response1;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
/* response ack from request */
p->tcph->th_ack = htonl(5);
p->tcph->th_seq = htonl(18);
p->tcph->th_flags = TH_ACK;
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = 0;
p->payload = NULL;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
uint8_t response2[] = {
0x2f, 0x31, 0x2e, 0x31,
0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
p->tcph->th_ack = htonl(18);
p->tcph->th_seq = htonl(5);
p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = sizeof(response2);
p->payload = response2;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
/* response ack from request */
p->tcph->th_ack = htonl(328);
p->tcph->th_seq = htonl(18);
p->tcph->th_flags = TH_ACK;
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = 0;
p->payload = NULL;
FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_FAILED);
FAIL_IF(f.alproto_ts != ALPROTO_FAILED);
FAIL_IF(f.alproto_tc != ALPROTO_FAILED);
FAIL_IF(!(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED));
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
TEST_END;
PASS;
}
void AppLayerUnittestsRegister(void)
{
SCEnter();
UtRegisterTest("AppLayerTest01", AppLayerTest01);
UtRegisterTest("AppLayerTest02", AppLayerTest02);
UtRegisterTest("AppLayerTest03", AppLayerTest03);
UtRegisterTest("AppLayerTest04", AppLayerTest04);
UtRegisterTest("AppLayerTest05", AppLayerTest05);
UtRegisterTest("AppLayerTest06", AppLayerTest06);
UtRegisterTest("AppLayerTest07", AppLayerTest07);
UtRegisterTest("AppLayerTest08", AppLayerTest08);
UtRegisterTest("AppLayerTest09", AppLayerTest09);
UtRegisterTest("AppLayerTest10", AppLayerTest10);
UtRegisterTest("AppLayerTest11", AppLayerTest11);
SCReturn;
}
#endif /* UNITTESTS */