suricata
app-layer.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2024 Open Information Security Foundation
2 *
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
5 * Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18/**
19 * \file
20 *
21 * \author Victor Julien <victor@inliniac.net>
22 * \author Anoop Saldanha <anoopsaldanha@gmail.com>
23 *
24 * Generic App-layer functions
25 */
26
27#include "suricata-common.h"
28#include "suricata.h"
29#include "app-layer.h"
30#include "app-layer-parser.h"
31#include "app-layer-protos.h"
33#include "app-layer-ftp.h"
34#include "app-layer-htp-range.h"
36#include "app-layer-frames.h"
37#include "app-layer-events.h"
39#include "stream-tcp-private.h"
40#include "stream-tcp-inline.h"
41#include "stream-tcp.h"
42#include "flow.h"
43#include "flow-util.h"
44#include "flow-private.h"
45#include "ippair.h"
46#include "util-debug.h"
47#include "util-print.h"
48#include "util-profiling.h"
49#include "util-validate.h"
50#include "decode-events.h"
51#include "app-layer-htp-mem.h"
53
55/**
56 * \brief This is for the app layer in general and it contains per thread
57 * context relevant to both the alpd and alp.
58 */
60 /* App layer protocol detection thread context, from AppLayerProtoDetectGetCtxThread(). */
62 /* App layer parser thread context, from AppLayerParserThreadCtxAlloc(). */
64
65#ifdef PROFILING
66 uint64_t ticks_start;
67 uint64_t ticks_end;
68 uint64_t ticks_spent;
73#endif
74};
75
76#define FLOW_PROTO_CHANGE_MAX_DEPTH 4096
77
78#define MAX_COUNTER_SIZE 64
88
98
99/* counter names. Only used at init. */
101/* counter id's. Used that runtime. */
103/* Exception policy global counters ids */
105
106/* Settings order as in the enum */
107// clang-format off
110 /* EXCEPTION_POLICY_NOT_SET */ false,
111 /* EXCEPTION_POLICY_AUTO */ false,
112 /* EXCEPTION_POLICY_PASS_PACKET */ true,
113 /* EXCEPTION_POLICY_PASS_FLOW */ true,
114 /* EXCEPTION_POLICY_BYPASS_FLOW */ true,
115 /* EXCEPTION_POLICY_DROP_PACKET */ false,
116 /* EXCEPTION_POLICY_DROP_FLOW */ false,
117 /* EXCEPTION_POLICY_REJECT */ true,
118 },
119 .valid_settings_ips = {
120 /* EXCEPTION_POLICY_NOT_SET */ false,
121 /* EXCEPTION_POLICY_AUTO */ false,
122 /* EXCEPTION_POLICY_PASS_PACKET */ true,
123 /* EXCEPTION_POLICY_PASS_FLOW */ true,
124 /* EXCEPTION_POLICY_BYPASS_FLOW */ true,
125 /* EXCEPTION_POLICY_DROP_PACKET */ true,
126 /* EXCEPTION_POLICY_DROP_FLOW */ true,
127 /* EXCEPTION_POLICY_REJECT */ true,
128 },
129};
130// clang-format on
131
132void AppLayerSetupCounters(void);
133void AppLayerDeSetupCounters(void);
134
135/***** L7 layer dispatchers *****/
136
137static inline int ProtoDetectDone(const Flow *f, const TcpSession *ssn, uint8_t direction) {
138 const TcpStream *stream = (direction & STREAM_TOSERVER) ? &ssn->client : &ssn->server;
140 (FLOW_IS_PM_DONE(f, direction) && FLOW_IS_PP_DONE(f, direction)));
141}
142
143/**
144 * \note id can be 0 if protocol parser is disabled but detection
145 * is enabled.
146 */
147static void AppLayerIncFlowCounter(ThreadVars *tv, Flow *f)
148{
149 const uint16_t id = applayer_counters[f->alproto][f->protomap].counter_id;
150 if (likely(tv && id > 0)) {
151 StatsIncr(tv, id);
152 }
153}
154
155void AppLayerIncTxCounter(ThreadVars *tv, Flow *f, uint64_t step)
156{
157 const uint16_t id = applayer_counters[f->alproto][f->protomap].counter_tx_id;
158 if (likely(tv && id > 0)) {
159 StatsAddUI64(tv, id, step);
160 }
161}
162
164{
165 const uint16_t id = applayer_counters[f->alproto][f->protomap].gap_error_id;
166 if (likely(tv && id > 0)) {
167 StatsIncr(tv, id);
168 }
169}
170
172{
173 const uint16_t id = applayer_counters[f->alproto][f->protomap].alloc_error_id;
174 if (likely(tv && id > 0)) {
175 StatsIncr(tv, id);
176 }
177}
178
180{
181 const uint16_t id = applayer_counters[f->alproto][f->protomap].parser_error_id;
182 if (likely(tv && id > 0)) {
183 StatsIncr(tv, id);
184 }
185}
186
188{
189 const uint16_t id = applayer_counters[f->alproto][f->protomap].internal_error_id;
190 if (likely(tv && id > 0)) {
191 StatsIncr(tv, id);
192 }
193}
194
195static void AppLayerIncrErrorExcPolicyCounter(ThreadVars *tv, Flow *f, enum ExceptionPolicy policy)
196{
197#ifdef UNITTESTS
198 if (tv == NULL) {
199 return;
200 }
201#endif
202 uint16_t id = applayer_counters[f->alproto][f->protomap].eps_error.eps_id[policy];
203 /* for the summary values */
204 uint16_t g_id = eps_error_summary.eps_id[policy];
205
206 if (likely(id > 0)) {
207 StatsIncr(tv, id);
208 }
209 if (likely(g_id > 0)) {
210 StatsIncr(tv, g_id);
211 }
212}
213
214/* in IDS mode protocol detection is done in reverse order:
215 * when TCP data is ack'd. We want to flag the correct packet,
216 * so in this case we set a flag in the flow so that the first
217 * packet in the correct direction can be tagged.
218 *
219 * For IPS we update packet and flow. */
220static inline void FlagPacketFlow(Packet *p, Flow *f, uint8_t flags)
221{
222 if (p->proto != IPPROTO_TCP || EngineModeIsIPS()) {
223 if (flags & STREAM_TOSERVER) {
224 if (p->flowflags & FLOW_PKT_TOSERVER) {
227 } else {
229 }
230 } else {
231 if (p->flowflags & FLOW_PKT_TOCLIENT) {
234 } else {
236 }
237 }
238 } else {
239 if (flags & STREAM_TOSERVER) {
241 } else {
243 }
244 }
245}
246
247static void DisableAppLayer(ThreadVars *tv, Flow *f, Packet *p)
248{
249 SCLogDebug("disable app layer for flow %p alproto %u ts %u tc %u",
250 f, f->alproto, f->alproto_ts, f->alproto_tc);
253 TcpSession *ssn = f->protoctx;
256 AppLayerIncFlowCounter(tv, f);
257
258 if (f->alproto_tc != ALPROTO_FAILED) {
259 if (f->alproto_tc == ALPROTO_UNKNOWN) {
261 }
262 FlagPacketFlow(p, f, STREAM_TOCLIENT);
263 }
264 if (f->alproto_ts != ALPROTO_FAILED) {
265 if (f->alproto_ts == ALPROTO_UNKNOWN) {
267 }
268 FlagPacketFlow(p, f, STREAM_TOSERVER);
269 }
270 SCLogDebug("disabled app layer for flow %p alproto %u ts %u tc %u",
271 f, f->alproto, f->alproto_ts, f->alproto_tc);
272}
273
274/* See if we're going to have to give up:
275 *
276 * If we're getting a lot of data in one direction and the
277 * proto for this direction is unknown, proto detect will
278 * hold up segments in the segment list in the stream.
279 * They are held so that if we detect the protocol on the
280 * opposing stream, we can still parse this side of the stream
281 * as well. However, some sessions are very unbalanced. FTP
282 * data channels, large PUT/POST request and many others, can
283 * lead to cases where we would have to store many megabytes
284 * worth of segments before we see the opposing stream. This
285 * leads to risks of resource starvation.
286 *
287 * Here a cutoff point is enforced. If we've stored 100k in
288 * one direction and we've seen no data in the other direction,
289 * we give up.
290 *
291 * Giving up means we disable applayer an set an applayer event
292 */
293static void TCPProtoDetectCheckBailConditions(ThreadVars *tv,
294 Flow *f, TcpSession *ssn, Packet *p)
295{
296 if (ssn->state < TCP_ESTABLISHED) {
297 SCLogDebug("skip as long as TCP is not ESTABLISHED (TCP fast open)");
298 return;
299 }
300
301 const uint32_t size_ts = StreamDataAvailableForProtoDetect(&ssn->client);
302 const uint32_t size_tc = StreamDataAvailableForProtoDetect(&ssn->server);
303 SCLogDebug("size_ts %" PRIu32 ", size_tc %" PRIu32, size_ts, size_tc);
304
305 /* at least 100000 whatever the conditions
306 * and can be more if window is bigger and if configuration allows it */
307 const uint32_t size_tc_limit =
309 const uint32_t size_ts_limit =
311
312 if (ProtoDetectDone(f, ssn, STREAM_TOSERVER) &&
313 ProtoDetectDone(f, ssn, STREAM_TOCLIENT))
314 {
315 goto failure;
316
317 /* we bail out whatever the pp and pm states if
318 * we received too much data */
319 } else if (size_tc > 2 * size_tc_limit || size_ts > 2 * size_ts_limit) {
321 goto failure;
322
323 } else if (FLOW_IS_PM_DONE(f, STREAM_TOSERVER) && FLOW_IS_PP_DONE(f, STREAM_TOSERVER) &&
324 size_ts > size_ts_limit && size_tc == 0) {
327 goto failure;
328
329 } else if (FLOW_IS_PM_DONE(f, STREAM_TOCLIENT) && FLOW_IS_PP_DONE(f, STREAM_TOCLIENT) &&
330 size_tc > size_tc_limit && size_ts == 0) {
333 goto failure;
334
335 /* little data in ts direction, pp done, pm not done (max
336 * depth not reached), ts direction done, lots of data in
337 * tc direction. */
338 } else if (size_tc > size_tc_limit && FLOW_IS_PP_DONE(f, STREAM_TOSERVER) &&
339 !(FLOW_IS_PM_DONE(f, STREAM_TOSERVER)) && FLOW_IS_PM_DONE(f, STREAM_TOCLIENT) &&
340 FLOW_IS_PP_DONE(f, STREAM_TOCLIENT)) {
343 goto failure;
344
345 /* little data in tc direction, pp done, pm not done (max
346 * depth not reached), tc direction done, lots of data in
347 * ts direction. */
348 } else if (size_ts > size_ts_limit && FLOW_IS_PP_DONE(f, STREAM_TOCLIENT) &&
349 !(FLOW_IS_PM_DONE(f, STREAM_TOCLIENT)) && FLOW_IS_PM_DONE(f, STREAM_TOSERVER) &&
350 FLOW_IS_PP_DONE(f, STREAM_TOSERVER)) {
353 goto failure;
354 }
355 return;
356
357failure:
358 DisableAppLayer(tv, f, p);
359}
360
361static int TCPProtoDetectTriggerOpposingSide(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
362 Packet *p, TcpSession *ssn, const TcpStream *stream)
363{
364 TcpStream *opposing_stream = NULL;
365 if (stream == &ssn->client) {
366 opposing_stream = &ssn->server;
367 } else {
368 opposing_stream = &ssn->client;
369 }
370
371 /* if the opposing side is not going to work, then
372 * we just have to give up. */
373 if (opposing_stream->flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY) {
374 SCLogDebug("opposing dir has STREAMTCP_STREAM_FLAG_NOREASSEMBLY set");
375 return -1;
376 }
377
381 int ret = StreamTcpReassembleAppLayer(tv, ra_ctx, ssn,
382 opposing_stream, p, dir);
383 return ret;
384}
385
387
388/** \todo data const
389 * \retval int -1 error
390 * \retval int 0 ok
391 */
392static int TCPProtoDetect(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
393 AppLayerThreadCtx *app_tctx, Packet *p, Flow *f, TcpSession *ssn, TcpStream **stream,
394 uint8_t *data, uint32_t data_len, uint8_t flags, enum StreamUpdateDir app_update_dir)
395{
396 AppProto *alproto;
397 AppProto *alproto_otherdir;
398 uint8_t direction = (flags & STREAM_TOSERVER) ? 0 : 1;
399
400 if (flags & STREAM_TOSERVER) {
401 alproto = &f->alproto_ts;
402 alproto_otherdir = &f->alproto_tc;
403 } else {
404 alproto = &f->alproto_tc;
405 alproto_otherdir = &f->alproto_ts;
406 }
407
408 SCLogDebug("Stream initializer (len %" PRIu32 ")", data_len);
409#ifdef PRINT
410 if (data_len > 0) {
411 printf("=> Init Stream Data (app layer) -- start %s%s\n",
412 flags & STREAM_TOCLIENT ? "toclient" : "",
413 flags & STREAM_TOSERVER ? "toserver" : "");
414 PrintRawDataFp(stdout, data, data_len);
415 printf("=> Init Stream Data -- end\n");
416 }
417#endif
418
419 bool reverse_flow = false;
420 DEBUG_VALIDATE_BUG_ON(data == NULL && data_len > 0);
422 *alproto = AppLayerProtoDetectGetProto(app_tctx->alpd_tctx,
423 f, data, data_len,
424 IPPROTO_TCP, flags, &reverse_flow);
426 SCLogDebug("alproto %u rev %s", *alproto, reverse_flow ? "true" : "false");
427
428 if (*alproto != ALPROTO_UNKNOWN) {
429 if (*alproto_otherdir != ALPROTO_UNKNOWN && *alproto_otherdir != *alproto) {
432
434 /* if we already invoked the parser, we go with that proto */
435 f->alproto = *alproto_otherdir;
436 } else {
437 /* no data sent to parser yet, we can still choose
438 * we're trusting the server more. */
439 if (flags & STREAM_TOCLIENT)
440 f->alproto = *alproto;
441 else
442 f->alproto = *alproto_otherdir;
443 }
444 } else {
445 f->alproto = *alproto;
446 }
447
451 FlagPacketFlow(p, f, flags);
452
453 /* if protocol detection indicated that we need to reverse
454 * the direction of the flow, do it now. We flip the flow,
455 * packet and the direction flags */
456 if (reverse_flow &&
459 /* but only if we didn't already detect it on the other side. */
460 if (*alproto_otherdir == ALPROTO_UNKNOWN) {
461 SCLogDebug("reversing flow after proto detect told us so");
462 PacketSwap(p);
463 FlowSwap(f);
464 // Will reset signature groups in DetectRunSetup
465 f->de_ctx_version = UINT32_MAX;
466 SWAP_FLAGS(flags, STREAM_TOSERVER, STREAM_TOCLIENT);
467 if (*stream == &ssn->client) {
468 *stream = &ssn->server;
469 } else {
470 *stream = &ssn->client;
471 }
472 direction = 1 - direction;
473 } else {
474 // TODO event, error?
475 }
476 }
477
478 /* account flow if we have both sides */
479 if (*alproto_otherdir != ALPROTO_UNKNOWN) {
480 AppLayerIncFlowCounter(tv, f);
481 }
482
483 /* if we have seen data from the other direction first, send
484 * data for that direction first to the parser. This shouldn't
485 * be an issue, since each stream processing happens
486 * independently of the other stream direction. At this point of
487 * call, you need to know that this function's already being
488 * called by the very same StreamReassembly() function that we
489 * will now call shortly for the opposing direction. */
490 if ((ssn->data_first_seen_dir & (STREAM_TOSERVER | STREAM_TOCLIENT)) &&
491 !(flags & ssn->data_first_seen_dir))
492 {
493 SCLogDebug("protocol %s needs first data in other direction",
494 AppProtoToString(*alproto));
495
496 if (TCPProtoDetectTriggerOpposingSide(tv, ra_ctx,
497 p, ssn, *stream) != 0)
498 {
499 goto detect_error;
500 }
501 if (FlowChangeProto(f)) {
502 /* We have the first data which requested a protocol change from P1 to P2
503 * even if it was not recognized at first as being P1
504 * As the second data was recognized as P1, the protocol did not change !
505 */
509 }
510 }
511
512 /* if the parser operates such that it needs to see data from
513 * a particular direction first, we check if we have seen
514 * data from that direction first for the flow. IF it is not
515 * the same, we set an event and exit.
516 *
517 * \todo We need to figure out a more robust solution for this,
518 * as this can lead to easy evasion tactics, where the
519 * attacker can first send some dummy data in the wrong
520 * direction first to mislead our proto detection process.
521 * While doing this we need to update the parsers as well,
522 * since the parsers must be robust to see such wrong
523 * direction data.
524 * Either ways the moment we see the
525 * APPLAYER_WRONG_DIRECTION_FIRST_DATA event set for the
526 * flow, it shows something's fishy.
527 */
529 uint8_t first_data_dir;
530 first_data_dir = AppLayerParserGetFirstDataDir(f->proto, f->alproto);
531
532 if (first_data_dir && !(first_data_dir & ssn->data_first_seen_dir)) {
535 goto detect_error;
536 }
537 /* This can happen if the current direction is not the
538 * right direction, and the data from the other(also
539 * the right direction) direction is available to be sent
540 * to the app layer, but it is not ack'ed yet and hence
541 * the forced call to STreamTcpAppLayerReassemble still
542 * hasn't managed to send data from the other direction
543 * to the app layer. */
544 if (first_data_dir && !(first_data_dir & flags)) {
550 SCReturnInt(-1);
551 }
552 }
553
554 /* Set a value that is neither STREAM_TOSERVER, nor STREAM_TOCLIENT */
556
557 /* finally, invoke the parser */
559 int r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto,
560 flags, data, data_len);
561 PACKET_PROFILING_APP_END(app_tctx);
562 p->app_update_direction = (uint8_t)app_update_dir;
563 if (r != 1) {
564 StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
565 }
566 if (r == 0) {
567 if (*alproto_otherdir == ALPROTO_UNKNOWN) {
568 TcpStream *opposing_stream;
569 if (*stream == &ssn->client) {
570 opposing_stream = &ssn->server;
571 } else {
572 opposing_stream = &ssn->client;
573 }
575 // can happen in detection-only
576 AppLayerIncFlowCounter(tv, f);
577 }
578 }
579 }
580 if (r < 0) {
581 goto parser_error;
582 }
583 } else {
584 /* if the ssn is midstream, we may end up with a case where the
585 * start of an HTTP request is missing. We won't detect HTTP based
586 * on the request. However, the reply is fine, so we detect
587 * HTTP anyway. This leads to passing the incomplete request to
588 * the htp parser.
589 *
590 * This has been observed, where the http parser then saw many
591 * bogus requests in the incomplete data.
592 *
593 * To counter this case, a midstream session MUST find it's
594 * protocol in the toserver direction. If not, we assume the
595 * start of the request/toserver is incomplete and no reliable
596 * detection and parsing is possible. So we give up.
597 */
598 if ((ssn->flags & STREAMTCP_FLAG_MIDSTREAM) &&
600 {
601 if (FLOW_IS_PM_DONE(f, STREAM_TOSERVER) && FLOW_IS_PP_DONE(f, STREAM_TOSERVER)) {
602 SCLogDebug("midstream end pd %p", ssn);
603 /* midstream and toserver detection failed: give up */
604 DisableAppLayer(tv, f, p);
605 SCReturnInt(0);
606 }
607 }
608
609 if (*alproto_otherdir != ALPROTO_UNKNOWN) {
610 uint8_t first_data_dir;
611 first_data_dir = AppLayerParserGetFirstDataDir(f->proto, *alproto_otherdir);
612
613 /* this would handle this test case -
614 * http parser which says it wants to see toserver data first only.
615 * tcp handshake
616 * toclient data first received. - RUBBISH DATA which
617 * we don't detect as http
618 * toserver data next sent - we detect this as http.
619 * at this stage we see that toclient is the first data seen
620 * for this session and we try and redetect the app protocol,
621 * but we are unable to detect the app protocol like before.
622 * But since we have managed to detect the protocol for the
623 * other direction as http, we try to use that. At this
624 * stage we check if the direction of this stream matches
625 * to that acceptable by the app parser. If it is not the
626 * acceptable direction we error out.
627 */
629 (first_data_dir) && !(first_data_dir & flags))
630 {
631 goto detect_error;
632 }
633
634 /* if protocol detection is marked done for our direction we
635 * pass our data on. We're only succeeded in finding one
636 * direction: the opposing stream
637 *
638 * If PD was not yet complete, we don't do anything.
639 */
641 if (data_len > 0)
643
644 if (*alproto_otherdir != ALPROTO_FAILED) {
646 int r = AppLayerParserParse(tv, app_tctx->alp_tctx, f,
647 f->alproto, flags,
648 data, data_len);
649 PACKET_PROFILING_APP_END(app_tctx);
650 p->app_update_direction = (uint8_t)app_update_dir;
651 if (r != 1) {
652 StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
653 }
654
659 AppLayerIncFlowCounter(tv, f);
660
661 *alproto = *alproto_otherdir;
662 SCLogDebug("packet %"PRIu64": pd done(us %u them %u), parser called (r==%d), APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION set",
663 p->pcap_cnt, *alproto, *alproto_otherdir, r);
664 if (r < 0) {
665 goto parser_error;
666 }
667 }
668 *alproto = ALPROTO_FAILED;
670 FlagPacketFlow(p, f, flags);
671
672 } else if (flags & STREAM_EOF) {
673 *alproto = f->alproto;
675 AppLayerIncFlowCounter(tv, f);
676 }
677 } else {
678 /* both sides unknown, let's see if we need to give up */
679 if (FlowChangeProto(f)) {
680 /* TCPProtoDetectCheckBailConditions does not work well because
681 * size_tc from STREAM_RIGHT_EDGE is not reset to zero
682 * so, we set a lower limit to the data we inspect
683 * We could instead have set ssn->server.sb.stream_offset = 0;
684 */
685 if (data_len >= FLOW_PROTO_CHANGE_MAX_DEPTH || (flags & STREAM_EOF)) {
686 DisableAppLayer(tv, f, p);
687 }
688 } else {
689 TCPProtoDetectCheckBailConditions(tv, f, ssn, p);
690 }
691 }
692 }
693 SCReturnInt(0);
694parser_error:
696 AppLayerIncrErrorExcPolicyCounter(tv, f, g_applayerparser_error_policy);
697 SCReturnInt(-1);
698detect_error:
699 DisableAppLayer(tv, f, p);
700 SCReturnInt(-2);
701}
702
703/** \brief handle TCP data for the app-layer.
704 *
705 * First run protocol detection and then when the protocol is known invoke
706 * the app layer parser.
707 *
708 * \param stream ptr-to-ptr to stream object. Might change if flow dir is
709 * reversed.
710 */
712 TcpSession *ssn, TcpStream **stream, uint8_t *data, uint32_t data_len, uint8_t flags,
713 enum StreamUpdateDir app_update_dir)
714{
715 SCEnter();
716
718 DEBUG_VALIDATE_BUG_ON(data_len > (uint32_t)INT_MAX);
719
720 AppLayerThreadCtx *app_tctx = ra_ctx->app_tctx;
721 AppProto alproto;
722 int r = 0;
723
724 SCLogDebug("data_len %u flags %02X", data_len, flags);
726 SCLogDebug("STREAMTCP_FLAG_APP_LAYER_DISABLED is set");
727 goto end;
728 }
729
730 const uint8_t direction = (flags & STREAM_TOSERVER) ? 0 : 1;
731
732 if (flags & STREAM_TOSERVER) {
733 alproto = f->alproto_ts;
734 } else {
735 alproto = f->alproto_tc;
736 }
737
738 /* If a gap notification, relay the notification on to the
739 * app-layer if known. */
740 if (flags & STREAM_GAP) {
741 SCLogDebug("GAP of size %u", data_len);
742 if (alproto == ALPROTO_UNKNOWN) {
744 SCLogDebug("ALPROTO_UNKNOWN flow %p, due to GAP in stream start", f);
745 /* if the other side didn't already find the proto, we're done */
746 if (f->alproto == ALPROTO_UNKNOWN) {
747 goto failure;
748 }
749 AppLayerIncFlowCounter(tv, f);
750 }
751 if (FlowChangeProto(f)) {
753 SCLogDebug("Cannot handle gap while changing protocol");
754 goto failure;
755 }
757 r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto,
758 flags, data, data_len);
759 PACKET_PROFILING_APP_END(app_tctx);
760 p->app_update_direction = (uint8_t)app_update_dir;
761 /* ignore parser result for gap */
762 StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
763 if (r < 0) {
765 AppLayerIncrErrorExcPolicyCounter(tv, f, g_applayerparser_error_policy);
766 SCReturnInt(-1);
767 }
768 goto end;
769 }
770
771 /* if we don't know the proto yet and we have received a stream
772 * initializer message, we run proto detection.
773 * We receive 2 stream init msgs (one for each direction), we
774 * only run the proto detection for both and emit an event
775 * in the case protocols mismatch. */
776 if (alproto == ALPROTO_UNKNOWN && (flags & STREAM_START)) {
778 /* run protocol detection */
779 if (TCPProtoDetect(tv, ra_ctx, app_tctx, p, f, ssn, stream, data, data_len, flags,
780 app_update_dir) != 0) {
781 goto failure;
782 }
783 } else if (alproto != ALPROTO_UNKNOWN && FlowChangeProto(f)) {
784 SCLogDebug("protocol change, old %s", AppProtoToString(f->alproto_orig));
785 void *alstate_orig = f->alstate;
786 AppLayerParserState *alparser = f->alparser;
787 // we delay AppLayerParserStateCleanup because we may need previous parser state
791 /* rerun protocol detection */
792 int rd = TCPProtoDetect(
793 tv, ra_ctx, app_tctx, p, f, ssn, stream, data, data_len, flags, app_update_dir);
794 if (f->alproto == ALPROTO_UNKNOWN) {
795 DEBUG_VALIDATE_BUG_ON(alstate_orig != f->alstate);
796 // not enough data, revert AppLayerProtoDetectReset to rerun detection
797 f->alparser = alparser;
798 f->alproto = f->alproto_orig;
799 f->alproto_tc = f->alproto_orig;
800 f->alproto_ts = f->alproto_orig;
801 } else {
803 AppLayerParserStateProtoCleanup(f->protomap, f->alproto_orig, alstate_orig, alparser);
804 if (alstate_orig == f->alstate) {
805 // we just freed it
806 f->alstate = NULL;
807 }
808 }
809 if (rd != 0) {
810 SCLogDebug("proto detect failure");
811 goto failure;
812 }
813 SCLogDebug("protocol change, old %s, new %s",
815
817 f->alproto != f->alproto_expect) {
820
821 if (f->alproto_expect == ALPROTO_TLS && f->alproto != ALPROTO_TLS) {
824
825 }
826 }
827 } else {
828 SCLogDebug("stream data (len %" PRIu32 " alproto "
829 "%"PRIu16" (flow %p)", data_len, f->alproto, f);
830#ifdef PRINT
831 if (data_len > 0) {
832 printf("=> Stream Data (app layer) -- start %s%s\n",
833 flags & STREAM_TOCLIENT ? "toclient" : "",
834 flags & STREAM_TOSERVER ? "toserver" : "");
835 PrintRawDataFp(stdout, data, data_len);
836 printf("=> Stream Data -- end\n");
837 }
838#endif
839 /* if we don't have a data object here we are not getting it
840 * a start msg should have gotten us one */
841 if (f->alproto != ALPROTO_UNKNOWN) {
843 r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto,
844 flags, data, data_len);
845 PACKET_PROFILING_APP_END(app_tctx);
846 p->app_update_direction = (uint8_t)app_update_dir;
847 if (r != 1) {
848 StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
849 if (r < 0) {
852 AppLayerIncrErrorExcPolicyCounter(tv, f, g_applayerparser_error_policy);
853 SCReturnInt(-1);
854 }
855 }
856 }
857 }
858
859 goto end;
860 failure:
861 r = -1;
862 end:
863 SCReturnInt(r);
864}
865
866/**
867 * \brief Handle a app layer UDP message
868 *
869 * If the protocol is yet unknown, the proto detection code is run first.
870 *
871 * \param dp_ctx Thread app layer detect context
872 * \param f *locked* flow
873 * \param p UDP packet
874 *
875 * \retval 0 ok
876 * \retval -1 error
877 */
879{
880 SCEnter();
881 AppProto *alproto;
882 AppProto *alproto_otherdir;
883
885 SCReturnInt(0);
886 }
887
888 int r = 0;
889 uint8_t flags = 0;
890 if (p->flowflags & FLOW_PKT_TOSERVER) {
891 flags |= STREAM_TOSERVER;
892 alproto = &f->alproto_ts;
893 alproto_otherdir = &f->alproto_tc;
894 } else {
895 flags |= STREAM_TOCLIENT;
896 alproto = &f->alproto_tc;
897 alproto_otherdir = &f->alproto_ts;
898 }
899
901
902 /* if the protocol is still unknown, run detection */
903 if (*alproto == ALPROTO_UNKNOWN) {
904 SCLogDebug("Detecting AL proto on udp mesg (len %" PRIu32 ")",
905 p->payload_len);
906
907 bool reverse_flow = false;
910 tctx->alpd_tctx, f, p->payload, p->payload_len, IPPROTO_UDP, flags, &reverse_flow);
912
913 switch (*alproto) {
914 case ALPROTO_UNKNOWN:
915 if (*alproto_otherdir != ALPROTO_UNKNOWN) {
916 // Use recognized side
917 f->alproto = *alproto_otherdir;
918 // do not keep ALPROTO_UNKNOWN for this side so as not to loop
919 *alproto = *alproto_otherdir;
920 if (*alproto_otherdir == ALPROTO_FAILED) {
921 SCLogDebug("ALPROTO_UNKNOWN flow %p", f);
922 }
923 } else {
924 // First side of protocol is unknown
925 *alproto = ALPROTO_FAILED;
926 }
927 break;
928 case ALPROTO_FAILED:
929 if (*alproto_otherdir != ALPROTO_UNKNOWN) {
930 // Use recognized side
931 f->alproto = *alproto_otherdir;
932 if (*alproto_otherdir == ALPROTO_FAILED) {
933 SCLogDebug("ALPROTO_UNKNOWN flow %p", f);
934 }
935 }
936 // else wait for second side of protocol
937 break;
938 default:
939 if (*alproto_otherdir != ALPROTO_UNKNOWN && *alproto_otherdir != ALPROTO_FAILED) {
940 if (*alproto_otherdir != *alproto) {
943 // data already sent to parser, we cannot change the protocol to use the one
944 // of the server
945 }
946 } else {
947 f->alproto = *alproto;
948 }
949 }
950 if (*alproto_otherdir == ALPROTO_UNKNOWN) {
951 if (f->alproto == ALPROTO_UNKNOWN) {
952 // so as to increase stat about .app_layer.flow.failed_udp
954 }
955 // If the other side is unknown, this is the first packet of the flow
956 AppLayerIncFlowCounter(tv, f);
957 }
958
959 // parse the data if we recognized one protocol
960 if (f->alproto != ALPROTO_UNKNOWN && f->alproto != ALPROTO_FAILED) {
961 if (reverse_flow) {
962 SCLogDebug("reversing flow after proto detect told us so");
963 PacketSwap(p);
964 FlowSwap(f);
965 SWAP_FLAGS(flags, STREAM_TOSERVER, STREAM_TOCLIENT);
966 }
967
969 r = AppLayerParserParse(tv, tctx->alp_tctx, f, f->alproto,
970 flags, p->payload, p->payload_len);
973 }
975 /* we do only inspection in one direction, so flag both
976 * sides as done here */
977 FlagPacketFlow(p, f, STREAM_TOSERVER);
978 FlagPacketFlow(p, f, STREAM_TOCLIENT);
979 } else {
980 SCLogDebug("data (len %" PRIu32 " ), alproto "
981 "%"PRIu16" (flow %p)", p->payload_len, f->alproto, f);
982
983 /* run the parser */
985 r = AppLayerParserParse(tv, tctx->alp_tctx, f, f->alproto,
986 flags, p->payload, p->payload_len);
990 }
991 if (r < 0) {
993 AppLayerIncrErrorExcPolicyCounter(tv, f, g_applayerparser_error_policy);
994 SCReturnInt(-1);
995 }
996
997 SCReturnInt(r);
998}
999
1000/***** Utility *****/
1001
1002AppProto AppLayerGetProtoByName(const char *alproto_name)
1003{
1004 SCEnter();
1006 SCReturnCT(r, "AppProto");
1007}
1008
1009const char *AppLayerGetProtoName(AppProto alproto)
1010{
1011 SCEnter();
1012 const char * r = AppLayerProtoDetectGetProtoName(alproto);
1013 SCReturnCT(r, "char *");
1014}
1015
1017{
1018 SCEnter();
1019
1020 AppProto alproto;
1021 AppProto alprotos[g_alproto_max];
1022
1024
1025 printf("=========Supported App Layer Protocols=========\n");
1026 for (alproto = 0; alproto < g_alproto_max; alproto++) {
1027 if (alprotos[alproto] == 1)
1028 printf("%s\n", AppLayerGetProtoName(alproto));
1029 }
1030
1031 SCReturn;
1032}
1033
1034/***** Setup/General Registration *****/
1035static void AppLayerNamesSetup(void)
1036{
1076}
1077
1079{
1080 SCEnter();
1081
1082 AppLayerNamesSetup();
1085
1088
1091
1092 SCReturnInt(0);
1093}
1094
1096{
1097 SCEnter();
1098
1101
1104
1105 SCReturnInt(0);
1106}
1107
1109{
1110 SCEnter();
1111
1112 AppLayerThreadCtx *app_tctx = SCCalloc(1, sizeof(*app_tctx));
1113 if (app_tctx == NULL)
1114 goto error;
1115
1116 if ((app_tctx->alpd_tctx = AppLayerProtoDetectGetCtxThread()) == NULL)
1117 goto error;
1118 if ((app_tctx->alp_tctx = AppLayerParserThreadCtxAlloc()) == NULL)
1119 goto error;
1120
1121 goto done;
1122 error:
1123 AppLayerDestroyCtxThread(app_tctx);
1124 app_tctx = NULL;
1125 done:
1126 SCReturnPtr(app_tctx, "void *");
1127}
1128
1130{
1131 SCEnter();
1132
1133 if (app_tctx == NULL)
1134 SCReturn;
1135
1136 if (app_tctx->alpd_tctx != NULL)
1138 if (app_tctx->alp_tctx != NULL)
1140 SCFree(app_tctx);
1141
1142 SCReturn;
1143}
1144
1145#ifdef PROFILING
1150
1155#endif
1156
1157/** \brief HACK to work around our broken unix manager (re)init loop
1158 */
1173
1174static bool IsAppLayerErrorExceptionPolicyStatsValid(enum ExceptionPolicy policy)
1175{
1176 if (EngineModeIsIPS()) {
1178 }
1180}
1181
1182static void AppLayerSetupExceptionPolicyPerProtoCounters(
1183 uint8_t ipproto_map, AppProto alproto, const char *alproto_str, const char *ipproto_suffix)
1184{
1188 if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1189 snprintf(applayer_counter_names[alproto][ipproto_map].eps_name[i],
1190 sizeof(applayer_counter_names[alproto][ipproto_map].eps_name[i]),
1191 "app_layer.error.%s%s.exception_policy.%s", alproto_str, ipproto_suffix,
1193 }
1194 }
1195 }
1196}
1197
1199{
1200 const uint8_t ipprotos[] = { IPPROTO_TCP, IPPROTO_UDP };
1201 AppProto alprotos[g_alproto_max];
1202 const char *str = "app_layer.flow.";
1203 const char *estr = "app_layer.error.";
1204
1207 if (unlikely(applayer_counter_names == NULL)) {
1208 FatalError("Unable to alloc applayer_counter_names.");
1209 }
1211 if (unlikely(applayer_counters == NULL)) {
1212 FatalError("Unable to alloc applayer_counters.");
1213 }
1214 /* We don't log stats counters if exception policy is `ignore`/`not set` */
1216 /* Register global counters for app layer error exception policy summary */
1217 const char *eps_default_str = "exception_policy.app_layer.error.";
1219 if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1221 sizeof(app_layer_error_eps_stats.eps_name[i]), "%s%s", eps_default_str,
1223 }
1224 }
1225 }
1226
1228
1229 for (uint8_t p = 0; p < FLOW_PROTO_APPLAYER_MAX; p++) {
1230 const uint8_t ipproto = ipprotos[p];
1231 const uint8_t ipproto_map = FlowGetProtoMapping(ipproto);
1232 const char *ipproto_suffix = (ipproto == IPPROTO_TCP) ? "_tcp" : "_udp";
1233 uint8_t ipprotos_all[256 / 8];
1234
1235 for (AppProto alproto = 0; alproto < g_alproto_max; alproto++) {
1236 if (alprotos[alproto] == 1) {
1237 const char *tx_str = "app_layer.tx.";
1238 const char *alproto_str = AppLayerGetProtoName(alproto);
1239
1240 memset(ipprotos_all, 0, sizeof(ipprotos_all));
1241 AppLayerProtoDetectSupportedIpprotos(alproto, ipprotos_all);
1242 if ((ipprotos_all[IPPROTO_TCP / 8] & (1 << (IPPROTO_TCP % 8))) &&
1243 (ipprotos_all[IPPROTO_UDP / 8] & (1 << (IPPROTO_UDP % 8)))) {
1244 snprintf(applayer_counter_names[alproto][ipproto_map].name,
1245 sizeof(applayer_counter_names[alproto][ipproto_map].name), "%s%s%s",
1246 str, alproto_str, ipproto_suffix);
1247 snprintf(applayer_counter_names[alproto][ipproto_map].tx_name,
1248 sizeof(applayer_counter_names[alproto][ipproto_map].tx_name), "%s%s%s",
1249 tx_str, alproto_str, ipproto_suffix);
1250
1251 if (ipproto == IPPROTO_TCP) {
1252 snprintf(applayer_counter_names[alproto][ipproto_map].gap_error,
1253 sizeof(applayer_counter_names[alproto][ipproto_map].gap_error),
1254 "%s%s%s.gap", estr, alproto_str, ipproto_suffix);
1255 }
1256 snprintf(applayer_counter_names[alproto][ipproto_map].alloc_error,
1257 sizeof(applayer_counter_names[alproto][ipproto_map].alloc_error),
1258 "%s%s%s.alloc", estr, alproto_str, ipproto_suffix);
1259 snprintf(applayer_counter_names[alproto][ipproto_map].parser_error,
1260 sizeof(applayer_counter_names[alproto][ipproto_map].parser_error),
1261 "%s%s%s.parser", estr, alproto_str, ipproto_suffix);
1262 snprintf(applayer_counter_names[alproto][ipproto_map].internal_error,
1263 sizeof(applayer_counter_names[alproto][ipproto_map].internal_error),
1264 "%s%s%s.internal", estr, alproto_str, ipproto_suffix);
1265
1266 AppLayerSetupExceptionPolicyPerProtoCounters(
1267 ipproto_map, alproto, alproto_str, ipproto_suffix);
1268 } else {
1269 snprintf(applayer_counter_names[alproto][ipproto_map].name,
1270 sizeof(applayer_counter_names[alproto][ipproto_map].name), "%s%s", str,
1271 alproto_str);
1272 snprintf(applayer_counter_names[alproto][ipproto_map].tx_name,
1273 sizeof(applayer_counter_names[alproto][ipproto_map].tx_name), "%s%s",
1274 tx_str, alproto_str);
1275
1276 if (ipproto == IPPROTO_TCP) {
1277 snprintf(applayer_counter_names[alproto][ipproto_map].gap_error,
1278 sizeof(applayer_counter_names[alproto][ipproto_map].gap_error),
1279 "%s%s.gap", estr, alproto_str);
1280 }
1281 snprintf(applayer_counter_names[alproto][ipproto_map].alloc_error,
1282 sizeof(applayer_counter_names[alproto][ipproto_map].alloc_error),
1283 "%s%s.alloc", estr, alproto_str);
1284 snprintf(applayer_counter_names[alproto][ipproto_map].parser_error,
1285 sizeof(applayer_counter_names[alproto][ipproto_map].parser_error),
1286 "%s%s.parser", estr, alproto_str);
1287 snprintf(applayer_counter_names[alproto][ipproto_map].internal_error,
1288 sizeof(applayer_counter_names[alproto][ipproto_map].internal_error),
1289 "%s%s.internal", estr, alproto_str);
1290 AppLayerSetupExceptionPolicyPerProtoCounters(
1291 ipproto_map, alproto, alproto_str, "");
1292 }
1293 } else if (alproto == ALPROTO_FAILED) {
1294 snprintf(applayer_counter_names[alproto][ipproto_map].name,
1295 sizeof(applayer_counter_names[alproto][ipproto_map].name), "%s%s%s", str,
1296 "failed", ipproto_suffix);
1297 if (ipproto == IPPROTO_TCP) {
1298 snprintf(applayer_counter_names[alproto][ipproto_map].gap_error,
1299 sizeof(applayer_counter_names[alproto][ipproto_map].gap_error),
1300 "%sfailed%s.gap", estr, ipproto_suffix);
1301 }
1302 }
1303 }
1304 }
1305}
1306
1308{
1309 const uint8_t ipprotos[] = { IPPROTO_TCP, IPPROTO_UDP };
1310 AppProto alprotos[g_alproto_max];
1312
1313 /* We don't log stats counters if exception policy is `ignore`/`not set` */
1315 /* Register global counters for app layer error exception policy summary */
1317 if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1320 }
1321 }
1322 }
1323
1324 for (uint8_t p = 0; p < FLOW_PROTO_APPLAYER_MAX; p++) {
1325 const uint8_t ipproto = ipprotos[p];
1326 const uint8_t ipproto_map = FlowGetProtoMapping(ipproto);
1327
1328 for (AppProto alproto = 0; alproto < g_alproto_max; alproto++) {
1329 if (alprotos[alproto] == 1) {
1330 applayer_counters[alproto][ipproto_map].counter_id =
1331 StatsRegisterCounter(applayer_counter_names[alproto][ipproto_map].name, tv);
1332
1334 applayer_counter_names[alproto][ipproto_map].tx_name, tv);
1335
1336 if (ipproto == IPPROTO_TCP) {
1337 applayer_counters[alproto][ipproto_map].gap_error_id = StatsRegisterCounter(
1338 applayer_counter_names[alproto][ipproto_map].gap_error, tv);
1339 }
1341 applayer_counter_names[alproto][ipproto_map].alloc_error, tv);
1343 applayer_counter_names[alproto][ipproto_map].parser_error, tv);
1345 applayer_counter_names[alproto][ipproto_map].internal_error, tv);
1346 /* We don't log stats counters if exception policy is `ignore`/`not set` */
1349 for (enum ExceptionPolicy i = EXCEPTION_POLICY_NOT_SET + 1;
1350 i < EXCEPTION_POLICY_MAX; i++) {
1351 if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1352 applayer_counters[alproto][ipproto_map]
1354 applayer_counter_names[alproto][ipproto_map].eps_name[i], tv);
1355 }
1356 }
1357 }
1358 } else if (alproto == ALPROTO_FAILED) {
1359 applayer_counters[alproto][ipproto_map].counter_id =
1360 StatsRegisterCounter(applayer_counter_names[alproto][ipproto_map].name, tv);
1361
1362 if (ipproto == IPPROTO_TCP) {
1363 applayer_counters[alproto][ipproto_map].gap_error_id = StatsRegisterCounter(
1364 applayer_counter_names[alproto][ipproto_map].gap_error, tv);
1365 }
1366 }
1367 }
1368 }
1369}
1370
1376
1377/***** Unittests *****/
1378
1379#ifdef UNITTESTS
1380#include "pkt-var.h"
1381#include "stream-tcp-util.h"
1382#include "stream.h"
1383#include "util-unittest.h"
1384
1385#define TEST_START \
1386 Packet *p = PacketGetFromAlloc(); \
1387 FAIL_IF_NULL(p); \
1388 Flow f; \
1389 ThreadVars tv; \
1390 StreamTcpThread *stt = NULL; \
1391 TCPHdr tcph; \
1392 PacketQueueNoLock pq; \
1393 memset(&pq, 0, sizeof(PacketQueueNoLock)); \
1394 memset(&f, 0, sizeof(Flow)); \
1395 memset(&tv, 0, sizeof(ThreadVars)); \
1396 memset(&tcph, 0, sizeof(TCPHdr)); \
1397 \
1398 FLOW_INITIALIZE(&f); \
1399 f.flags = FLOW_IPV4; \
1400 f.proto = IPPROTO_TCP; \
1401 p->flow = &f; \
1402 PacketSetTCP(p, (uint8_t *)&tcph); \
1403 \
1404 StreamTcpInitConfig(true); \
1405 IPPairInitConfig(true); \
1406 StreamTcpThreadInit(&tv, NULL, (void **)&stt); \
1407 \
1408 /* handshake */ \
1409 tcph.th_win = htons(5480); \
1410 tcph.th_flags = TH_SYN; \
1411 p->flowflags = FLOW_PKT_TOSERVER; \
1412 p->payload_len = 0; \
1413 p->payload = NULL; \
1414 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1); \
1415 TcpSession *ssn = (TcpSession *)f.protoctx; \
1416 \
1417 FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); \
1418 FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); \
1419 FAIL_IF(f.alproto != ALPROTO_UNKNOWN); \
1420 FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN); \
1421 FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN); \
1422 FAIL_IF(ssn->flags &STREAMTCP_FLAG_APP_LAYER_DISABLED); \
1423 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER)); \
1424 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER)); \
1425 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT)); \
1426 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); \
1427 FAIL_IF(ssn->data_first_seen_dir != 0); \
1428 \
1429 /* handshake */ \
1430 tcph.th_ack = htonl(1); \
1431 tcph.th_flags = TH_SYN | TH_ACK; \
1432 p->flowflags = FLOW_PKT_TOCLIENT; \
1433 p->payload_len = 0; \
1434 p->payload = NULL; \
1435 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1); \
1436 FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); \
1437 FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); \
1438 FAIL_IF(f.alproto != ALPROTO_UNKNOWN); \
1439 FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN); \
1440 FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN); \
1441 FAIL_IF(ssn->flags &STREAMTCP_FLAG_APP_LAYER_DISABLED); \
1442 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER)); \
1443 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER)); \
1444 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT)); \
1445 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); \
1446 FAIL_IF(ssn->data_first_seen_dir != 0); \
1447 \
1448 /* handshake */ \
1449 tcph.th_ack = htonl(1); \
1450 tcph.th_seq = htonl(1); \
1451 tcph.th_flags = TH_ACK; \
1452 p->flowflags = FLOW_PKT_TOSERVER; \
1453 p->payload_len = 0; \
1454 p->payload = NULL; \
1455 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1); \
1456 FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); \
1457 FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); \
1458 FAIL_IF(f.alproto != ALPROTO_UNKNOWN); \
1459 FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN); \
1460 FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN); \
1461 FAIL_IF(ssn->flags &STREAMTCP_FLAG_APP_LAYER_DISABLED); \
1462 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER)); \
1463 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER)); \
1464 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT)); \
1465 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); \
1466 FAIL_IF(ssn->data_first_seen_dir != 0);
1467#define TEST_END \
1468 StreamTcpSessionClear(p->flow->protoctx); \
1469 StreamTcpThreadDeinit(&tv, (void *)stt); \
1470 StreamTcpFreeConfig(true); \
1471 PacketFree(p); \
1472 FLOW_DESTROY(&f); \
1473 StatsThreadCleanup(&tv);
1474
1475/**
1476 * \test GET -> HTTP/1.1
1477 */
1478static int AppLayerTest01(void)
1479{
1480 TEST_START;
1481
1482 /* full request */
1483 uint8_t request[] = {
1484 0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1485 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1486 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1487 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1488 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1489 0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1490 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1491 0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1492 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1493 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1494 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1495 tcph.th_ack = htonl(1);
1496 tcph.th_seq = htonl(1);
1497 tcph.th_flags = TH_PUSH | TH_ACK;
1499 p->payload_len = sizeof(request);
1500 p->payload = request;
1501 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1508 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1509 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1510 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1511 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1512 FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1513
1514 /* full response - request ack */
1515 uint8_t response[] = {
1516 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
1517 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1518 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1519 0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1520 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1521 0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1522 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1523 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1524 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1525 0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1526 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1527 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1528 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1529 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1530 0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1531 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1532 0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1533 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1534 0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1535 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1536 0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1537 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1538 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1539 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1540 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1541 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1542 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1543 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1544 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1545 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1546 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1547 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1548 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1549 0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1550 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1551 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1552 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1553 0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1554 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1555 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1556 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1557 tcph.th_ack = htonl(88);
1558 tcph.th_seq = htonl(1);
1559 tcph.th_flags = TH_PUSH | TH_ACK;
1561 p->payload_len = sizeof(response);
1562 p->payload = response;
1563 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1570 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1571 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1572 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1573 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1575
1576 /* response ack */
1577 tcph.th_ack = htonl(328);
1578 tcph.th_seq = htonl(88);
1579 tcph.th_flags = TH_ACK;
1581 p->payload_len = 0;
1582 p->payload = NULL;
1583 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1590 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1591 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1592 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1593 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1595
1596 TEST_END;
1597 PASS;
1598}
1599
1600/**
1601 * \test GE -> T -> HTTP/1.1
1602 */
1603static int AppLayerTest02(void)
1604{
1605 TEST_START;
1606
1607 /* partial request */
1608 uint8_t request1[] = { 0x47, 0x45, };
1609 tcph.th_ack = htonl(1);
1610 tcph.th_seq = htonl(1);
1611 tcph.th_flags = TH_PUSH | TH_ACK;
1613 p->payload_len = sizeof(request1);
1614 p->payload = request1;
1615 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1622 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1623 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1624 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1625 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1626 FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1627
1628 /* response ack against partial request */
1629 tcph.th_ack = htonl(3);
1630 tcph.th_seq = htonl(1);
1631 tcph.th_flags = TH_ACK;
1633 p->payload_len = 0;
1634 p->payload = NULL;
1635 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1642 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1643 FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1644 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1645 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1646 FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1647
1648 /* complete partial request */
1649 uint8_t request2[] = {
1650 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1651 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1652 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1653 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1654 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1655 0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1656 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1657 0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1658 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1659 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1660 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1661 tcph.th_ack = htonl(1);
1662 tcph.th_seq = htonl(3);
1663 tcph.th_flags = TH_PUSH | TH_ACK;
1665 p->payload_len = sizeof(request2);
1666 p->payload = request2;
1667 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1674 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1675 FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1676 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1677 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1678 FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1679
1680 /* response - request ack */
1681 uint8_t response[] = {
1682 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
1683 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1684 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1685 0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1686 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1687 0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1688 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1689 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1690 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1691 0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1692 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1693 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1694 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1695 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1696 0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1697 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1698 0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1699 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1700 0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1701 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1702 0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1703 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1704 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1705 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1706 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1707 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1708 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1709 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1710 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1711 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1712 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1713 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1714 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1715 0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1716 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1717 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1718 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1719 0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1720 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1721 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1722 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1723 tcph.th_ack = htonl(88);
1724 tcph.th_seq = htonl(1);
1725 tcph.th_flags = TH_PUSH | TH_ACK;
1727 p->payload_len = sizeof(response);
1728 p->payload = response;
1729 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1736 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1737 FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1738 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1739 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1741
1742 /* response ack */
1743 tcph.th_ack = htonl(328);
1744 tcph.th_seq = htonl(88);
1745 tcph.th_flags = TH_ACK;
1747 p->payload_len = 0;
1748 p->payload = NULL;
1749 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1756 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1757 FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1758 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1759 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1761
1762 TEST_END;
1763 PASS;
1764}
1765
1766/**
1767 * \test GET -> RUBBISH(PM AND PP DONE IN ONE GO)
1768 */
1769static int AppLayerTest03(void)
1770{
1771 TEST_START;
1772
1773 /* request */
1774 uint8_t request[] = {
1775 0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1776 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1777 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1778 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1779 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1780 0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1781 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1782 0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1783 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1784 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1785 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1786 tcph.th_ack = htonl(1);
1787 tcph.th_seq = htonl(1);
1788 tcph.th_flags = TH_PUSH | TH_ACK;
1790 p->payload_len = sizeof(request);
1791 p->payload = request;
1792 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1799 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1800 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1801 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1802 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1803 FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1804
1805 /* rubbish response */
1806 uint8_t response[] = {
1807 0x58, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
1808 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1809 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1810 0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1811 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1812 0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1813 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1814 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1815 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1816 0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1817 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1818 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1819 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1820 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1821 0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1822 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1823 0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1824 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1825 0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1826 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1827 0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1828 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1829 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1830 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1831 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1832 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1833 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1834 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1835 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1836 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1837 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1838 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1839 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1840 0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1841 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1842 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1843 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1844 0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1845 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1846 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1847 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1848 tcph.th_ack = htonl(88);
1849 tcph.th_seq = htonl(1);
1850 tcph.th_flags = TH_PUSH | TH_ACK;
1852 p->payload_len = sizeof(response);
1853 p->payload = response;
1854 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1861 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1862 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1863 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1864 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1866
1867 /* response ack */
1868 tcph.th_ack = htonl(328);
1869 tcph.th_seq = htonl(88);
1870 tcph.th_flags = TH_ACK;
1872 p->payload_len = 0;
1873 p->payload = NULL;
1874 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1881 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1882 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1883 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1884 FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1886
1887 TEST_END;
1888 PASS;
1889}
1890
1891/**
1892 * \test GE -> RUBBISH(TC - PM AND PP NOT DONE) -> RUBBISH(TC - PM AND PP DONE).
1893 */
1894static int AppLayerTest04(void)
1895{
1896 TEST_START;
1897
1898 /* request */
1899 uint8_t request[] = {
1900 0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1901 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1902 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1903 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1904 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1905 0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1906 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1907 0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1908 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1909 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1910 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1911 PrintRawDataFp(stdout, request, sizeof(request));
1912 tcph.th_ack = htonl(1);
1913 tcph.th_seq = htonl(1);
1914 tcph.th_flags = TH_PUSH | TH_ACK;
1916 p->payload_len = sizeof(request);
1917 p->payload = request;
1918 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1925 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1926 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1927 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1928 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1929 FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER); // TOSERVER data now seen
1930
1931 /* partial response */
1932 uint8_t response1[] = { 0x58, 0x54, 0x54, 0x50, };
1933 PrintRawDataFp(stdout, response1, sizeof(response1));
1934 tcph.th_ack = htonl(88);
1935 tcph.th_seq = htonl(1);
1936 tcph.th_flags = TH_PUSH | TH_ACK;
1938 p->payload_len = sizeof(response1);
1939 p->payload = response1;
1940 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1943 FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
1944 FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
1947 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1948 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1949 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1950 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1951 FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
1952
1953 /* partial response ack */
1954 tcph.th_ack = htonl(5);
1955 tcph.th_seq = htonl(88);
1956 tcph.th_flags = TH_ACK;
1958 p->payload_len = 0;
1959 p->payload = NULL;
1960 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1963 FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
1964 FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
1967 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1968 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1969 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1970 FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
1971 FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
1972
1973 /* remaining response */
1974 uint8_t response2[] = {
1975 0x2f, 0x31, 0x2e, 0x31,
1976 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1977 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1978 0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1979 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1980 0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1981 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1982 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1983 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1984 0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1985 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1986 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1987 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1988 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1989 0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1990 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1991 0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1992 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1993 0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1994 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1995 0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1996 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1997 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1998 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1999 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2000 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2001 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2002 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2003 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2004 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2005 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2006 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2007 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2008 0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2009 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2010 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2011 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2012 0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2013 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2014 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2015 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2016 PrintRawDataFp(stdout, response2, sizeof(response2));
2017 tcph.th_ack = htonl(88);
2018 tcph.th_seq = htonl(5);
2019 tcph.th_flags = TH_PUSH | TH_ACK;
2021 p->payload_len = sizeof(response2);
2022 p->payload = response2;
2023 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2026 FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
2027 FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
2030 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2031 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2032 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2033 FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
2034 FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
2035
2036 /* response ack */
2037 tcph.th_ack = htonl(328);
2038 tcph.th_seq = htonl(88);
2039 tcph.th_flags = TH_ACK;
2041 p->payload_len = 0;
2042 p->payload = NULL;
2043 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2044 FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); // toclient complete (failed)
2046 FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
2047 FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
2048 FAIL_IF(f.alproto_tc != ALPROTO_FAILED); // tc failed
2050 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2051 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2052 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2053 FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
2054 FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
2055
2056 TEST_END;
2057 PASS;
2058}
2059
2060/**
2061 * \test RUBBISH -> HTTP/1.1
2062 */
2063static int AppLayerTest05(void)
2064{
2065 TEST_START;
2066
2067 /* full request */
2068 uint8_t request[] = {
2069 0x48, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2070 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
2071 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
2072 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
2073 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
2074 0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
2075 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
2076 0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
2077 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2078 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
2079 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2080 PrintRawDataFp(stdout, request, sizeof(request));
2081 tcph.th_ack = htonl(1);
2082 tcph.th_seq = htonl(1);
2083 tcph.th_flags = TH_PUSH | TH_ACK;
2085 p->payload_len = sizeof(request);
2086 p->payload = request;
2087 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2094 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2095 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2096 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2097 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2098 FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2099
2100 /* full response - request ack */
2101 uint8_t response[] = {
2102 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2103 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2104 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2105 0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2106 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2107 0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2108 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2109 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2110 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2111 0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2112 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2113 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2114 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2115 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2116 0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2117 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2118 0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2119 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2120 0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2121 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2122 0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2123 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2124 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2125 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2126 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2127 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2128 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2129 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2130 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2131 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2132 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2133 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2134 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2135 0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2136 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2137 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2138 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2139 0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2140 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2141 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2142 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2143 PrintRawDataFp(stdout, response, sizeof(response));
2144 tcph.th_ack = htonl(88);
2145 tcph.th_seq = htonl(1);
2146 tcph.th_flags = TH_PUSH | TH_ACK;
2148 p->payload_len = sizeof(response);
2149 p->payload = response;
2150 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2157 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2158 FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2159 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2160 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2161 FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2162
2163 /* response ack */
2164 tcph.th_ack = htonl(328);
2165 tcph.th_seq = htonl(88);
2166 tcph.th_flags = TH_ACK;
2168 p->payload_len = 0;
2169 p->payload = NULL;
2170 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2177 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2178 FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2179 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2180 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2182
2183 TEST_END;
2184 PASS;
2185}
2186
2187/**
2188 * \test HTTP/1.1 -> GET
2189 */
2190static int AppLayerTest06(void)
2191{
2192 TEST_START;
2193
2194 /* full response - request ack */
2195 uint8_t response[] = {
2196 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2197 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2198 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2199 0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2200 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2201 0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2202 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2203 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2204 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2205 0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2206 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2207 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2208 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2209 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2210 0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2211 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2212 0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2213 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2214 0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2215 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2216 0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2217 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2218 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2219 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2220 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2221 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2222 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2223 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2224 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2225 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2226 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2227 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2228 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2229 0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2230 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2231 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2232 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2233 0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2234 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2235 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2236 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2237 tcph.th_ack = htonl(1);
2238 tcph.th_seq = htonl(1);
2239 tcph.th_flags = TH_PUSH | TH_ACK;
2241 p->payload_len = sizeof(response);
2242 p->payload = response;
2243 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2250 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2251 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2252 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2253 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2254 FAIL_IF(ssn->data_first_seen_dir != STREAM_TOCLIENT);
2255
2256 /* full request - response ack*/
2257 uint8_t request[] = {
2258 0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2259 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
2260 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
2261 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
2262 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
2263 0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
2264 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
2265 0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
2266 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2267 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
2268 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2269 tcph.th_ack = htonl(328);
2270 tcph.th_seq = htonl(1);
2271 tcph.th_flags = TH_PUSH | TH_ACK;
2273 p->payload_len = sizeof(request);
2274 p->payload = request;
2275 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2282 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2283 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2284 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2285 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2287
2288 tcph.th_ack = htonl(1 + sizeof(request));
2289 tcph.th_seq = htonl(328);
2290 tcph.th_flags = TH_PUSH | TH_ACK;
2292 p->payload_len = 0;
2293 p->payload = NULL;
2294 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2301 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2302 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2303 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2304 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2306
2307 TEST_END;
2308 PASS;
2309}
2310
2311/**
2312 * \test GET -> DCERPC
2313 */
2314static int AppLayerTest07(void)
2315{
2316 TEST_START;
2317
2318 /* full request */
2319 uint8_t request[] = {
2320 0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2321 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
2322 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
2323 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
2324 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
2325 0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
2326 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
2327 0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
2328 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2329 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
2330 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2331 tcph.th_ack = htonl(1);
2332 tcph.th_seq = htonl(1);
2333 tcph.th_flags = TH_PUSH | TH_ACK;
2335 p->payload_len = sizeof(request);
2336 p->payload = request;
2337 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2344 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2345 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2346 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2347 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2348 FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2349
2350 /* full response - request ack */
2351 uint8_t response[] = { 0x05, 0x00, 0x4d, 0x42, 0x00, 0x01, 0x2e, 0x31, 0x20, 0x32, 0x30, 0x30,
2352 0x20, 0x4f, 0x4b, 0x0d, 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, 0x72, 0x69, 0x2c,
2353 0x20, 0x32, 0x33, 0x20, 0x53, 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20, 0x30, 0x36,
2354 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, 0x72,
2355 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2356 0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69, 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f,
2357 0x32, 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65,
2358 0x64, 0x3a, 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34, 0x20, 0x4e, 0x6f, 0x76, 0x20,
2359 0x32, 0x30, 0x31, 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a, 0x34, 0x36, 0x20, 0x47,
2360 0x4d, 0x54, 0x0d, 0x0a, 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61, 0x62, 0x38, 0x39,
2361 0x36, 0x35, 0x2d, 0x32, 0x63, 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61, 0x37, 0x66,
2362 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x52,
2363 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2364 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20,
2365 0x34, 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a,
2366 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
2367 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d,
2368 0x6c, 0x0d, 0x0a, 0x58, 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64,
2369 0x20, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d, 0x0a, 0x0d,
2370 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x68,
2371 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2372 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2373 tcph.th_ack = htonl(88);
2374 tcph.th_seq = htonl(1);
2375 tcph.th_flags = TH_PUSH | TH_ACK;
2377 p->payload_len = sizeof(response);
2378 p->payload = response;
2379 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2386 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2387 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2388 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2389 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2391
2392 /* response ack */
2393 tcph.th_ack = htonl(328);
2394 tcph.th_seq = htonl(88);
2395 tcph.th_flags = TH_ACK;
2397 p->payload_len = 0;
2398 p->payload = NULL;
2399 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2406 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2407 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2408 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2409 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2411
2412 TEST_END;
2413 PASS;
2414}
2415
2416/**
2417 * \test RUBBISH(TC - PM and PP NOT DONE) ->
2418 * RUBBISH(TC - PM and PP DONE) ->
2419 * RUBBISH(TS - PM and PP DONE)
2420 */
2421static int AppLayerTest09(void)
2422{
2423 TEST_START;
2424
2425 /* full request */
2426 uint8_t request1[] = {
2427 0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64 };
2428 tcph.th_ack = htonl(1);
2429 tcph.th_seq = htonl(1);
2430 tcph.th_flags = TH_PUSH | TH_ACK;
2432 p->payload_len = sizeof(request1);
2433 p->payload = request1;
2434 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2441 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2442 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2443 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2444 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2445 FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2446
2447 /* response - request ack */
2448 tcph.th_ack = htonl(9);
2449 tcph.th_seq = htonl(1);
2450 tcph.th_flags = TH_PUSH | TH_ACK;
2452 p->payload_len = 0;
2453 p->payload = NULL;
2454 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2461 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2462 FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2463 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2464 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2465 FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2466
2467 /* full request */
2468 uint8_t request2[] = {
2469 0x44, 0x44, 0x45, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff };
2470 tcph.th_ack = htonl(1);
2471 tcph.th_seq = htonl(9);
2472 tcph.th_flags = TH_PUSH | TH_ACK;
2474 p->payload_len = sizeof(request2);
2475 p->payload = request2;
2476 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2483 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2484 FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2485 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2486 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2487 FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2488
2489 /* full response - request ack */
2490 uint8_t response[] = {
2491 0x55, 0x74, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2492 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2493 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2494 0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2495 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2496 0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2497 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2498 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2499 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2500 0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2501 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2502 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2503 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2504 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2505 0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2506 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2507 0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2508 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2509 0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2510 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2511 0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2512 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2513 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2514 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2515 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2516 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2517 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2518 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2519 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2520 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2521 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2522 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2523 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2524 0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2525 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2526 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2527 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2528 0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2529 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2530 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2531 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2532 tcph.th_ack = htonl(18);
2533 tcph.th_seq = htonl(1);
2534 tcph.th_flags = TH_PUSH | TH_ACK;
2536 p->payload_len = sizeof(response);
2537 p->payload = response;
2538 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2545 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2546 FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2547 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2548 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2549 FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2550
2551 /* response ack */
2552 tcph.th_ack = htonl(328);
2553 tcph.th_seq = htonl(18);
2554 tcph.th_flags = TH_ACK;
2556 p->payload_len = 0;
2557 p->payload = NULL;
2558 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2565 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2566 FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2567 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2568 FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2570
2571 TEST_END;
2572 PASS;
2573}
2574
2575/**
2576 * \test RUBBISH(TC - PM and PP DONE) ->
2577 * RUBBISH(TS - PM and PP DONE)
2578 */
2579static int AppLayerTest10(void)
2580{
2581 TEST_START;
2582
2583 /* full request */
2584 uint8_t request1[] = {
2585 0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2586 0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff };
2587 tcph.th_ack = htonl(1);
2588 tcph.th_seq = htonl(1);
2589 tcph.th_flags = TH_PUSH | TH_ACK;
2591 p->payload_len = sizeof(request1);
2592 p->payload = request1;
2593 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2600 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2601 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2602 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2603 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2604 FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2605
2606 /* response - request ack */
2607 tcph.th_ack = htonl(18);
2608 tcph.th_seq = htonl(1);
2609 tcph.th_flags = TH_PUSH | TH_ACK;
2611 p->payload_len = 0;
2612 p->payload = NULL;
2613 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2620 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2621 FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2622 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2623 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2624 FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2625
2626 /* full response - request ack */
2627 uint8_t response[] = {
2628 0x55, 0x74, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2629 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2630 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2631 0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2632 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2633 0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2634 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2635 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2636 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2637 0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2638 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2639 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2640 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2641 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2642 0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2643 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2644 0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2645 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2646 0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2647 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2648 0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2649 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2650 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2651 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2652 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2653 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2654 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2655 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2656 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2657 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2658 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2659 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2660 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2661 0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2662 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2663 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2664 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2665 0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2666 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2667 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2668 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2669 tcph.th_ack = htonl(18);
2670 tcph.th_seq = htonl(1);
2671 tcph.th_flags = TH_PUSH | TH_ACK;
2673 p->payload_len = sizeof(response);
2674 p->payload = response;
2675 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2682 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2683 FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2684 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2685 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2686 FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2687
2688 /* response ack */
2689 tcph.th_ack = htonl(328);
2690 tcph.th_seq = htonl(18);
2691 tcph.th_flags = TH_ACK;
2693 p->payload_len = 0;
2694 p->payload = NULL;
2695 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2702 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2703 FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2704 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2705 FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2707
2708 TEST_END;
2709 PASS;
2710}
2711
2712/**
2713 * \test RUBBISH(TC - PM and PP DONE) ->
2714 * RUBBISH(TS - PM and PP NOT DONE) ->
2715 * RUBBISH(TS - PM and PP DONE)
2716 */
2717static int AppLayerTest11(void)
2718{
2719 TEST_START;
2720
2721 /* full request */
2722 uint8_t request1[] = {
2723 0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2724 0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff };
2725 tcph.th_ack = htonl(1);
2726 tcph.th_seq = htonl(1);
2727 tcph.th_flags = TH_PUSH | TH_ACK;
2729 p->payload_len = sizeof(request1);
2730 p->payload = request1;
2731 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2738 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2739 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2740 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2741 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2742 FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2743
2744 /* response - request ack */
2745 tcph.th_ack = htonl(18);
2746 tcph.th_seq = htonl(1);
2747 tcph.th_flags = TH_PUSH | TH_ACK;
2749 p->payload_len = 0;
2750 p->payload = NULL;
2751 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2758 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2759 FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2760 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2761 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2762 FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2763
2764 /* full response - request ack */
2765 uint8_t response1[] = {
2766 0x55, 0x74, 0x54, 0x50, };
2767 tcph.th_ack = htonl(18);
2768 tcph.th_seq = htonl(1);
2769 tcph.th_flags = TH_PUSH | TH_ACK;
2771 p->payload_len = sizeof(response1);
2772 p->payload = response1;
2773 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2780 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2781 FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2782 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2783 FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2784 FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2785
2786 /* response ack from request */
2787 tcph.th_ack = htonl(5);
2788 tcph.th_seq = htonl(18);
2789 tcph.th_flags = TH_ACK;
2791 p->payload_len = 0;
2792 p->payload = NULL;
2793 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2800 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2801 FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2802 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2803 FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2804 FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2805
2806 uint8_t response2[] = {
2807 0x2f, 0x31, 0x2e, 0x31,
2808 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2809 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2810 0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2811 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2812 0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2813 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2814 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2815 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2816 0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2817 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2818 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2819 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2820 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2821 0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2822 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2823 0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2824 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2825 0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2826 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2827 0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2828 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2829 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2830 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2831 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2832 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2833 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2834 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2835 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2836 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2837 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2838 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2839 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2840 0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2841 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2842 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2843 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2844 0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2845 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2846 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2847 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2848 tcph.th_ack = htonl(18);
2849 tcph.th_seq = htonl(5);
2850 tcph.th_flags = TH_PUSH | TH_ACK;
2852 p->payload_len = sizeof(response2);
2853 p->payload = response2;
2854 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2861 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2862 FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2863 FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2864 FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2865 FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2866
2867 /* response ack from request */
2868 tcph.th_ack = htonl(328);
2869 tcph.th_seq = htonl(18);
2870 tcph.th_flags = TH_ACK;
2872 p->payload_len = 0;
2873 p->payload = NULL;
2874 FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2881 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2882 FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2883 FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2884 FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2886
2887 TEST_END;
2888 PASS;
2889}
2890
2892{
2893 SCEnter();
2894
2895 UtRegisterTest("AppLayerTest01", AppLayerTest01);
2896 UtRegisterTest("AppLayerTest02", AppLayerTest02);
2897 UtRegisterTest("AppLayerTest03", AppLayerTest03);
2898 UtRegisterTest("AppLayerTest04", AppLayerTest04);
2899 UtRegisterTest("AppLayerTest05", AppLayerTest05);
2900 UtRegisterTest("AppLayerTest06", AppLayerTest06);
2901 UtRegisterTest("AppLayerTest07", AppLayerTest07);
2902 UtRegisterTest("AppLayerTest09", AppLayerTest09);
2903 UtRegisterTest("AppLayerTest10", AppLayerTest10);
2904 UtRegisterTest("AppLayerTest11", AppLayerTest11);
2905
2906 SCReturn;
2907}
2908
2909#endif /* UNITTESTS */
void AppLayerProtoDetectSupportedAppProtocols(AppProto *alprotos)
AppProto AppLayerProtoDetectGetProto(AppLayerProtoDetectThreadCtx *tctx, Flow *f, const uint8_t *buf, uint32_t buflen, uint8_t ipproto, uint8_t flags, bool *reverse_flow)
Returns the app layer protocol given a buffer.
int AppLayerProtoDetectDeSetup(void)
Cleans up the app layer protocol detection phase.
AppLayerProtoDetectThreadCtx * AppLayerProtoDetectGetCtxThread(void)
Inits and returns an app layer protocol detection thread context.
void AppLayerProtoDetectSupportedIpprotos(AppProto alproto, uint8_t *ipprotos)
void AppLayerProtoDetectReset(Flow *f)
Reset proto detect for flow.
int AppLayerProtoDetectSetup(void)
The first function to be called. This initializes a global protocol detection context.
int AppLayerProtoDetectPrepareState(void)
Prepares the internal state for protocol detection. This needs to be called once all the patterns and...
const char * AppLayerProtoDetectGetProtoName(AppProto alproto)
AppProto AppLayerProtoDetectGetProtoByName(const char *alproto_name)
void AppLayerProtoDetectDestroyCtxThread(AppLayerProtoDetectThreadCtx *alpd_tctx)
Destroys the app layer protocol detection thread context.
void AppLayerDecoderEventsSetEventRaw(AppLayerDecoderEvents **sevents, uint8_t event)
Set an app layer decoder event.
@ APPLAYER_NO_TLS_AFTER_STARTTLS
@ APPLAYER_UNEXPECTED_PROTOCOL
@ APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION
@ APPLAYER_MISMATCH_PROTOCOL_BOTH_DIRECTIONS
@ APPLAYER_PROTO_DETECTION_SKIPPED
@ APPLAYER_WRONG_DIRECTION_FIRST_DATA
void FrameConfigDeInit(void)
void FrameConfigInit(void)
uint64_t FTPMemcapGlobalCounter(void)
uint64_t FTPMemuseGlobalCounter(void)
uint64_t HTPMemuseGlobalCounter(void)
uint64_t HTPMemcapGlobalCounter(void)
uint64_t HTPByteRangeMemcapGlobalCounter(void)
uint64_t HTPByteRangeMemuseGlobalCounter(void)
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
uint32_t AppLayerParserGetStreamDepth(const Flow *f)
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, const uint8_t *input, uint32_t input_len)
uint8_t AppLayerParserGetFirstDataDir(uint8_t ipproto, AppProto alproto)
int AppLayerParserDeSetup(void)
void AppLayerParserStateProtoCleanup(uint8_t protomap, AppProto alproto, void *alstate, AppLayerParserState *pstate)
void AppLayerParserRegisterProtocolParsers(void)
int AppLayerParserSetup(void)
AppProto g_alproto_max
void AppProtoRegisterProtoString(AppProto alproto, const char *proto_name)
const char * AppProtoToString(AppProto alproto)
Maps the ALPROTO_*, to its string equivalent.
uint16_t AppProto
@ ALPROTO_TLS
@ ALPROTO_NFS
@ ALPROTO_RDP
@ ALPROTO_MDNS
@ ALPROTO_MQTT
@ ALPROTO_DCERPC
@ ALPROTO_KRB5
@ ALPROTO_DHCP
@ ALPROTO_IRC
@ ALPROTO_JABBER
@ ALPROTO_HTTP2
@ ALPROTO_SSH
@ ALPROTO_MODBUS
@ ALPROTO_FAILED
@ ALPROTO_FTP
@ ALPROTO_BITTORRENT_DHT
@ ALPROTO_SMTP
@ ALPROTO_WEBSOCKET
@ ALPROTO_HTTP
@ ALPROTO_TELNET
@ ALPROTO_SMB
@ ALPROTO_SIP
@ ALPROTO_NTP
@ ALPROTO_UNKNOWN
@ ALPROTO_DNP3
@ ALPROTO_FTPDATA
@ ALPROTO_IKE
@ ALPROTO_POP3
@ ALPROTO_TEMPLATE
@ ALPROTO_PGSQL
@ ALPROTO_TFTP
@ ALPROTO_QUIC
@ ALPROTO_DOH2
@ ALPROTO_HTTP1
@ ALPROTO_ENIP
@ ALPROTO_IMAP
@ ALPROTO_DNS
@ ALPROTO_RFB
@ ALPROTO_LDAP
#define TEST_START
Definition app-layer.c:1385
struct AppLayerCounters_ AppLayerCounters
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, enum StreamUpdateDir app_update_dir)
handle TCP data for the app-layer.
Definition app-layer.c:711
void AppLayerProfilingStoreInternal(AppLayerThreadCtx *app_tctx, Packet *p)
Definition app-layer.c:1151
AppProto AppLayerGetProtoByName(const char *alproto_name)
Given a protocol string, returns the corresponding internal protocol id.
Definition app-layer.c:1002
void AppLayerListSupportedProtocols(void)
Definition app-layer.c:1016
void AppLayerIncInternalErrorCounter(ThreadVars *tv, Flow *f)
Definition app-layer.c:187
AppLayerCounters(* applayer_counters)[FLOW_PROTO_APPLAYER_MAX]
Definition app-layer.c:102
int AppLayerSetup(void)
Setup the app layer.
Definition app-layer.c:1078
enum ExceptionPolicy g_applayerparser_error_policy
struct AppLayerCounterNames_ AppLayerCounterNames
void AppLayerRegisterGlobalCounters(void)
HACK to work around our broken unix manager (re)init loop.
Definition app-layer.c:1159
#define FLOW_PROTO_CHANGE_MAX_DEPTH
Definition app-layer.c:76
AppLayerCounterNames(* applayer_counter_names)[FLOW_PROTO_APPLAYER_MAX]
Definition app-layer.c:100
void AppLayerDeSetupCounters(void)
Definition app-layer.c:1371
#define TEST_END
Definition app-layer.c:1467
ExceptionPolicyCounters eps_error_summary
Definition app-layer.c:104
void AppLayerSetupCounters(void)
Definition app-layer.c:1198
void AppLayerRegisterThreadCounters(ThreadVars *tv)
Registers per flow counters for all protocols.
Definition app-layer.c:1307
ExceptionPolicyStatsSetts app_layer_error_eps_stats
Definition app-layer.c:108
void AppLayerIncAllocErrorCounter(ThreadVars *tv, Flow *f)
Definition app-layer.c:171
const char * AppLayerGetProtoName(AppProto alproto)
Given the internal protocol id, returns a string representation of the protocol.
Definition app-layer.c:1009
void AppLayerIncGapErrorCounter(ThreadVars *tv, Flow *f)
Definition app-layer.c:163
void AppLayerIncParserErrorCounter(ThreadVars *tv, Flow *f)
Definition app-layer.c:179
void AppLayerIncTxCounter(ThreadVars *tv, Flow *f, uint64_t step)
Definition app-layer.c:155
bool g_stats_eps_per_app_proto_errors
Definition suricata.c:220
void AppLayerDestroyCtxThread(AppLayerThreadCtx *app_tctx)
Destroys the context created by AppLayerGetCtxThread().
Definition app-layer.c:1129
int AppLayerDeSetup(void)
De initializes the app layer.
Definition app-layer.c:1095
void AppLayerUnittestsRegister(void)
Definition app-layer.c:2891
AppLayerThreadCtx * AppLayerGetCtxThread(void)
Creates a new app layer thread context.
Definition app-layer.c:1108
void AppLayerProfilingResetInternal(AppLayerThreadCtx *app_tctx)
Definition app-layer.c:1146
int AppLayerHandleUdp(ThreadVars *tv, AppLayerThreadCtx *tctx, Packet *p, Flow *f)
Handle a app layer UDP message.
Definition app-layer.c:878
#define MAX_COUNTER_SIZE
Definition app-layer.c:78
#define AppLayerProfilingReset(app_tctx)
Definition app-layer.h:127
#define APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER
Definition app-layer.h:40
uint16_t StatsRegisterGlobalCounter(const char *name, uint64_t(*Func)(void))
Registers a counter, which represents a global value.
Definition counters.c:1010
uint16_t StatsRegisterCounter(const char *name, struct ThreadVars_ *tv)
Registers a normal, unqualified counter.
Definition counters.c:952
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition counters.c:166
void StatsAddUI64(ThreadVars *tv, uint16_t id, uint64_t x)
Adds a value of type uint64_t to the local counter.
Definition counters.c:146
uint8_t flags
Definition decode-gre.h:0
#define TH_ACK
Definition decode-tcp.h:38
#define TH_PUSH
Definition decode-tcp.h:37
@ PKT_DROP_REASON_APPLAYER_ERROR
Definition decode.h:387
#define PKT_PROTO_DETECT_TS_DONE
Definition decode.h:1299
#define PKT_PROTO_DETECT_TC_DONE
Definition decode.h:1300
TcpStreamCnf stream_config
Definition stream-tcp.c:219
#define FLOW_PROTO_APPLAYER_MAX
uint8_t FlowGetProtoMapping(uint8_t proto)
Function to map the protocol to the defined FLOW_PROTO_* enumeration.
Definition flow-util.c:99
void FlowUnsetChangeProtoFlag(Flow *f)
Unset flag to indicate to change proto for the flow.
Definition flow.c:186
void FlowCleanupAppLayer(Flow *f)
Definition flow.c:139
int FlowChangeProto(Flow *f)
Check if change proto flag is set for flow.
Definition flow.c:196
void FlowSwap(Flow *f)
swap the flow's direction
Definition flow.c:246
#define FLOW_RESET_PE_DONE(f, dir)
Definition flow.h:288
#define FLOW_PKT_TOSERVER
Definition flow.h:233
#define FLOW_IS_PP_DONE(f, dir)
Definition flow.h:279
#define FLOW_PROTO_DETECT_TS_DONE
Definition flow.h:104
#define FLOW_RESET_PM_DONE(f, dir)
Definition flow.h:286
#define FLOW_RESET_PP_DONE(f, dir)
Definition flow.h:287
#define FLOW_IS_PM_DONE(f, dir)
Definition flow.h:278
#define FLOW_PROTO_DETECT_TC_DONE
Definition flow.h:105
#define FLOW_PKT_TOCLIENT
Definition flow.h:234
ThreadVars * tv
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
#define PASS
Pass the test.
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
uint64_t ExpectationGetCounter(void)
void PacketSwap(Packet *p)
switch direction of a packet
Definition decode.c:577
uint64_t HostGetMemcap(void)
Return memcap value.
Definition host.c:83
uint64_t HostGetMemuse(void)
Return memuse value.
Definition host.c:94
uint64_t IPPairGetMemuse(void)
Return memuse value.
Definition ippair.c:92
#define STREAMTCP_STREAM_FLAG_NOREASSEMBLY
#define StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(stream)
@ TCP_ESTABLISHED
#define StreamTcpSetStreamFlagAppProtoDetectionCompleted(stream)
#define STREAMTCP_FLAG_MIDSTREAM
#define StreamTcpResetStreamFlagAppProtoDetectionCompleted(stream)
#define STREAMTCP_FLAG_MIDSTREAM_SYNACK
#define STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED
#define STREAMTCP_FLAG_APP_LAYER_DISABLED
void StreamTcpDisableAppLayer(Flow *f)
int StreamTcpReassembleAppLayer(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpSession *ssn, TcpStream *stream, Packet *p, enum StreamUpdateDir app_update_dir)
Update the stream reassembly upon receiving a packet.
uint32_t StreamDataAvailableForProtoDetect(TcpStream *stream)
@ UPDATE_DIR_OPPOSING
@ UPDATE_DIR_PACKET
bool StreamTcpInlineMode(void)
See if stream engine is operating in inline mode.
void TcpSessionSetReassemblyDepth(TcpSession *ssn, uint32_t size)
int StreamTcpPacket(ThreadVars *tv, Packet *p, StreamTcpThread *stt, PacketQueueNoLock *pq)
void StreamTcpUpdateAppLayerProgress(TcpSession *ssn, char direction, const uint32_t progress)
update reassembly progress
char eps_name[EXCEPTION_POLICY_MAX][MAX_COUNTER_SIZE]
Definition app-layer.c:86
char name[MAX_COUNTER_SIZE]
Definition app-layer.c:80
char tx_name[MAX_COUNTER_SIZE]
Definition app-layer.c:81
char gap_error[MAX_COUNTER_SIZE]
Definition app-layer.c:82
char parser_error[MAX_COUNTER_SIZE]
Definition app-layer.c:83
char alloc_error[MAX_COUNTER_SIZE]
Definition app-layer.c:85
char internal_error[MAX_COUNTER_SIZE]
Definition app-layer.c:84
uint16_t gap_error_id
Definition app-layer.c:92
uint16_t counter_id
Definition app-layer.c:90
ExceptionPolicyCounters eps_error
Definition app-layer.c:96
uint16_t counter_tx_id
Definition app-layer.c:91
uint16_t parser_error_id
Definition app-layer.c:93
uint16_t alloc_error_id
Definition app-layer.c:95
uint16_t internal_error_id
Definition app-layer.c:94
The app layer protocol detection thread context.
This is for the app layer in general and it contains per thread context relevant to both the alpd and...
Definition app-layer.c:59
uint64_t ticks_spent
Definition app-layer.c:68
uint64_t proto_detect_ticks_end
Definition app-layer.c:71
AppLayerParserThreadCtx * alp_tctx
Definition app-layer.c:63
uint64_t proto_detect_ticks_start
Definition app-layer.c:70
uint64_t ticks_start
Definition app-layer.c:66
AppLayerProtoDetectThreadCtx * alpd_tctx
Definition app-layer.c:61
uint64_t proto_detect_ticks_spent
Definition app-layer.c:72
uint64_t ticks_end
Definition app-layer.c:67
uint16_t eps_id[EXCEPTION_POLICY_MAX]
bool valid_settings_ips[EXCEPTION_POLICY_MAX]
bool valid_settings_ids[EXCEPTION_POLICY_MAX]
char eps_name[EXCEPTION_POLICY_MAX][EXCEPTION_POLICY_COUNTER_MAX_LEN]
Flow data structure.
Definition flow.h:356
AppProto alproto_ts
Definition flow.h:451
AppProto alproto_tc
Definition flow.h:452
uint8_t proto
Definition flow.h:378
uint32_t flags
Definition flow.h:421
uint32_t de_ctx_version
Definition flow.h:464
AppProto alproto_expect
Definition flow.h:459
AppProto alproto
application level protocol
Definition flow.h:450
void * alstate
Definition flow.h:479
AppProto alproto_orig
Definition flow.h:456
void * protoctx
Definition flow.h:441
AppLayerParserState * alparser
Definition flow.h:478
uint8_t protomap
Definition flow.h:445
uint8_t flowflags
Definition decode.h:532
uint64_t pcap_cnt
Definition decode.h:626
uint8_t app_update_direction
Definition decode.h:535
AppLayerDecoderEvents * app_layer_events
Definition decode.h:632
uint8_t * payload
Definition decode.h:605
uint16_t payload_len
Definition decode.h:606
uint32_t flags
Definition decode.h:544
uint8_t proto
Definition decode.h:523
uint32_t reassembly_depth
Definition stream-tcp.h:75
Per thread variable structure.
Definition threadvars.h:58
#define MIN(x, y)
#define MAX(x, y)
#define str(s)
#define SWAP_FLAGS(flags, a, b)
int EngineModeIsIPS(void)
Definition suricata.c:242
const char * name
#define SCEnter(...)
Definition util-debug.h:277
#define FatalError(...)
Definition util-debug.h:510
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCReturnInt(x)
Definition util-debug.h:281
#define SCReturnCT(x, type)
Definition util-debug.h:291
#define SCReturnPtr(x, type)
Definition util-debug.h:293
#define SCReturn
Definition util-debug.h:279
#define EXCEPTION_POLICY_MAX
const char * ExceptionPolicyEnumToString(enum ExceptionPolicy policy, bool is_json)
void ExceptionPolicyApply(Packet *p, enum ExceptionPolicy policy, enum PacketDropReason drop_reason)
#define SCFree(p)
Definition util-mem.h:61
#define SCCalloc(nm, sz)
Definition util-mem.h:53
#define likely(expr)
#define unlikely(expr)
void PrintRawDataFp(FILE *fp, const uint8_t *buf, uint32_t buflen)
Definition util-print.c:112
#define PACKET_PROFILING_APP_PD_START(dp)
#define PACKET_PROFILING_APP_START(dp, id)
#define PACKET_PROFILING_APP_RESET(dp)
#define PACKET_PROFILING_APP_STORE(dp, p)
#define PACKET_PROFILING_APP_PD_END(dp)
#define PACKET_PROFILING_APP_END(dp)
#define DEBUG_VALIDATE_BUG_ON(exp)
#define DEBUG_ASSERT_FLOW_LOCKED(f)