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"
32 #include "app-layer-expectation.h"
33 #include "app-layer-ftp.h"
34 #include "app-layer-detect-proto.h"
35 #include "app-layer-frames.h"
36 #include "stream-tcp-reassemble.h"
37 #include "stream-tcp-private.h"
38 #include "stream-tcp-inline.h"
39 #include "stream-tcp.h"
40 #include "flow.h"
41 #include "flow-util.h"
42 #include "flow-private.h"
43 #include "ippair.h"
44 #include "util-debug.h"
45 #include "util-print.h"
46 #include "util-profiling.h"
47 #include "util-validate.h"
48 #include "decode-events.h"
49 #include "app-layer-htp-mem.h"
50 #include "util-exception-policy.h"
51 
53 /**
54  * \brief This is for the app layer in general and it contains per thread
55  * context relevant to both the alpd and alp.
56  */
58  /* App layer protocol detection thread context, from AppLayerProtoDetectGetCtxThread(). */
60  /* App layer parser thread context, from AppLayerParserThreadCtxAlloc(). */
62 
63 #ifdef PROFILING
64  uint64_t ticks_start;
65  uint64_t ticks_end;
66  uint64_t ticks_spent;
71 #endif
72 };
73 
74 #define FLOW_PROTO_CHANGE_MAX_DEPTH 4096
75 
76 #define MAX_COUNTER_SIZE 64
77 typedef struct AppLayerCounterNames_ {
86 
87 typedef struct AppLayerCounters_ {
88  uint16_t counter_id;
89  uint16_t counter_tx_id;
90  uint16_t gap_error_id;
91  uint16_t parser_error_id;
93  uint16_t alloc_error_id;
96 
97 /* counter names. Only used at init. */
99 /* counter id's. Used that runtime. */
101 /* Exception policy global counters ids */
103 
104 /* Settings order as in the enum */
105 // clang-format off
107  .valid_settings_ids = {
108  /* EXCEPTION_POLICY_NOT_SET */ false,
109  /* EXCEPTION_POLICY_AUTO */ false,
110  /* EXCEPTION_POLICY_PASS_PACKET */ true,
111  /* EXCEPTION_POLICY_PASS_FLOW */ true,
112  /* EXCEPTION_POLICY_BYPASS_FLOW */ true,
113  /* EXCEPTION_POLICY_DROP_PACKET */ false,
114  /* EXCEPTION_POLICY_DROP_FLOW */ false,
115  /* EXCEPTION_POLICY_REJECT */ true,
116  },
117  .valid_settings_ips = {
118  /* EXCEPTION_POLICY_NOT_SET */ false,
119  /* EXCEPTION_POLICY_AUTO */ false,
120  /* EXCEPTION_POLICY_PASS_PACKET */ true,
121  /* EXCEPTION_POLICY_PASS_FLOW */ true,
122  /* EXCEPTION_POLICY_BYPASS_FLOW */ true,
123  /* EXCEPTION_POLICY_DROP_PACKET */ true,
124  /* EXCEPTION_POLICY_DROP_FLOW */ true,
125  /* EXCEPTION_POLICY_REJECT */ true,
126  },
127 };
128 // clang-format on
129 
130 void AppLayerSetupCounters(void);
131 void AppLayerDeSetupCounters(void);
132 
133 /***** L7 layer dispatchers *****/
134 
135 static inline int ProtoDetectDone(const Flow *f, const TcpSession *ssn, uint8_t direction) {
136  const TcpStream *stream = (direction & STREAM_TOSERVER) ? &ssn->client : &ssn->server;
138  (FLOW_IS_PM_DONE(f, direction) && FLOW_IS_PP_DONE(f, direction)));
139 }
140 
141 /**
142  * \note id can be 0 if protocol parser is disabled but detection
143  * is enabled.
144  */
145 static void AppLayerIncFlowCounter(ThreadVars *tv, Flow *f)
146 {
147  const uint16_t id = applayer_counters[f->protomap][f->alproto].counter_id;
148  if (likely(tv && id > 0)) {
149  StatsIncr(tv, id);
150  }
151 }
152 
153 void AppLayerIncTxCounter(ThreadVars *tv, Flow *f, uint64_t step)
154 {
155  const uint16_t id = applayer_counters[f->protomap][f->alproto].counter_tx_id;
156  if (likely(tv && id > 0)) {
157  StatsAddUI64(tv, id, step);
158  }
159 }
160 
162 {
163  const uint16_t id = applayer_counters[f->protomap][f->alproto].gap_error_id;
164  if (likely(tv && id > 0)) {
165  StatsIncr(tv, id);
166  }
167 }
168 
170 {
171  const uint16_t id = applayer_counters[f->protomap][f->alproto].alloc_error_id;
172  if (likely(tv && id > 0)) {
173  StatsIncr(tv, id);
174  }
175 }
176 
178 {
179  const uint16_t id = applayer_counters[f->protomap][f->alproto].parser_error_id;
180  if (likely(tv && id > 0)) {
181  StatsIncr(tv, id);
182  }
183 }
184 
186 {
187  const uint16_t id = applayer_counters[f->protomap][f->alproto].internal_error_id;
188  if (likely(tv && id > 0)) {
189  StatsIncr(tv, id);
190  }
191 }
192 
193 static void AppLayerIncrErrorExcPolicyCounter(ThreadVars *tv, Flow *f, enum ExceptionPolicy policy)
194 {
195 #ifdef UNITTESTS
196  if (tv == NULL) {
197  return;
198  }
199 #endif
200  uint16_t id = applayer_counters[f->protomap][f->alproto].eps_error.eps_id[policy];
201  /* for the summary values */
202  uint16_t g_id = eps_error_summary.eps_id[policy];
203 
204  if (likely(id > 0)) {
205  StatsIncr(tv, id);
206  }
207  if (likely(g_id > 0)) {
208  StatsIncr(tv, g_id);
209  }
210 }
211 
212 /* in IDS mode protocol detection is done in reverse order:
213  * when TCP data is ack'd. We want to flag the correct packet,
214  * so in this case we set a flag in the flow so that the first
215  * packet in the correct direction can be tagged.
216  *
217  * For IPS we update packet and flow. */
218 static inline void FlagPacketFlow(Packet *p, Flow *f, uint8_t flags)
219 {
220  if (p->proto != IPPROTO_TCP || EngineModeIsIPS()) {
221  if (flags & STREAM_TOSERVER) {
222  if (p->flowflags & FLOW_PKT_TOSERVER) {
225  } else {
227  }
228  } else {
229  if (p->flowflags & FLOW_PKT_TOCLIENT) {
232  } else {
234  }
235  }
236  } else {
237  if (flags & STREAM_TOSERVER) {
239  } else {
241  }
242  }
243 }
244 
245 static void DisableAppLayer(ThreadVars *tv, Flow *f, Packet *p)
246 {
247  SCLogDebug("disable app layer for flow %p alproto %u ts %u tc %u",
248  f, f->alproto, f->alproto_ts, f->alproto_tc);
251  TcpSession *ssn = f->protoctx;
253  f->alproto = ALPROTO_FAILED;
254  AppLayerIncFlowCounter(tv, f);
255 
256  if (f->alproto_tc != ALPROTO_FAILED) {
257  if (f->alproto_tc == ALPROTO_UNKNOWN) {
259  }
260  FlagPacketFlow(p, f, STREAM_TOCLIENT);
261  }
262  if (f->alproto_ts != ALPROTO_FAILED) {
263  if (f->alproto_ts == ALPROTO_UNKNOWN) {
265  }
266  FlagPacketFlow(p, f, STREAM_TOSERVER);
267  }
268  SCLogDebug("disabled app layer for flow %p alproto %u ts %u tc %u",
269  f, f->alproto, f->alproto_ts, f->alproto_tc);
270 }
271 
272 /* See if we're going to have to give up:
273  *
274  * If we're getting a lot of data in one direction and the
275  * proto for this direction is unknown, proto detect will
276  * hold up segments in the segment list in the stream.
277  * They are held so that if we detect the protocol on the
278  * opposing stream, we can still parse this side of the stream
279  * as well. However, some sessions are very unbalanced. FTP
280  * data channels, large PUT/POST request and many others, can
281  * lead to cases where we would have to store many megabytes
282  * worth of segments before we see the opposing stream. This
283  * leads to risks of resource starvation.
284  *
285  * Here a cutoff point is enforced. If we've stored 100k in
286  * one direction and we've seen no data in the other direction,
287  * we give up.
288  *
289  * Giving up means we disable applayer an set an applayer event
290  */
291 static void TCPProtoDetectCheckBailConditions(ThreadVars *tv,
292  Flow *f, TcpSession *ssn, Packet *p)
293 {
294  if (ssn->state < TCP_ESTABLISHED) {
295  SCLogDebug("skip as long as TCP is not ESTABLISHED (TCP fast open)");
296  return;
297  }
298 
299  const uint32_t size_ts = StreamDataAvailableForProtoDetect(&ssn->client);
300  const uint32_t size_tc = StreamDataAvailableForProtoDetect(&ssn->server);
301  SCLogDebug("size_ts %" PRIu32 ", size_tc %" PRIu32, size_ts, size_tc);
302 
303  /* at least 100000 whatever the conditions
304  * and can be more if window is bigger and if configuration allows it */
305  const uint32_t size_tc_limit =
307  const uint32_t size_ts_limit =
309 
310  if (ProtoDetectDone(f, ssn, STREAM_TOSERVER) &&
311  ProtoDetectDone(f, ssn, STREAM_TOCLIENT))
312  {
313  goto failure;
314 
315  /* we bail out whatever the pp and pm states if
316  * we received too much data */
317  } else if (size_tc > 2 * size_tc_limit || size_ts > 2 * size_ts_limit) {
319  goto failure;
320 
321  } else if (FLOW_IS_PM_DONE(f, STREAM_TOSERVER) && FLOW_IS_PP_DONE(f, STREAM_TOSERVER) &&
322  size_ts > size_ts_limit && size_tc == 0) {
325  goto failure;
326 
327  } else if (FLOW_IS_PM_DONE(f, STREAM_TOCLIENT) && FLOW_IS_PP_DONE(f, STREAM_TOCLIENT) &&
328  size_tc > size_tc_limit && size_ts == 0) {
331  goto failure;
332 
333  /* little data in ts direction, pp done, pm not done (max
334  * depth not reached), ts direction done, lots of data in
335  * tc direction. */
336  } else if (size_tc > size_tc_limit && FLOW_IS_PP_DONE(f, STREAM_TOSERVER) &&
337  !(FLOW_IS_PM_DONE(f, STREAM_TOSERVER)) && FLOW_IS_PM_DONE(f, STREAM_TOCLIENT) &&
338  FLOW_IS_PP_DONE(f, STREAM_TOCLIENT)) {
341  goto failure;
342 
343  /* little data in tc direction, pp done, pm not done (max
344  * depth not reached), tc direction done, lots of data in
345  * ts direction. */
346  } else if (size_ts > size_ts_limit && FLOW_IS_PP_DONE(f, STREAM_TOCLIENT) &&
347  !(FLOW_IS_PM_DONE(f, STREAM_TOCLIENT)) && FLOW_IS_PM_DONE(f, STREAM_TOSERVER) &&
348  FLOW_IS_PP_DONE(f, STREAM_TOSERVER)) {
351  goto failure;
352  }
353  return;
354 
355 failure:
356  DisableAppLayer(tv, f, p);
357 }
358 
359 static int TCPProtoDetectTriggerOpposingSide(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
360  Packet *p, TcpSession *ssn, const TcpStream *stream)
361 {
362  TcpStream *opposing_stream = NULL;
363  if (stream == &ssn->client) {
364  opposing_stream = &ssn->server;
365  } else {
366  opposing_stream = &ssn->client;
367  }
368 
369  /* if the opposing side is not going to work, then
370  * we just have to give up. */
371  if (opposing_stream->flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY) {
372  SCLogDebug("opposing dir has STREAMTCP_STREAM_FLAG_NOREASSEMBLY set");
373  return -1;
374  }
375 
376  enum StreamUpdateDir dir = StreamTcpInlineMode() ?
379  int ret = StreamTcpReassembleAppLayer(tv, ra_ctx, ssn,
380  opposing_stream, p, dir);
381  return ret;
382 }
383 
385 
386 /** \todo data const
387  * \retval int -1 error
388  * \retval int 0 ok
389  */
390 static int TCPProtoDetect(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
391  AppLayerThreadCtx *app_tctx, Packet *p, Flow *f, TcpSession *ssn, TcpStream **stream,
392  uint8_t *data, uint32_t data_len, uint8_t flags, enum StreamUpdateDir app_update_dir)
393 {
394  AppProto *alproto;
395  AppProto *alproto_otherdir;
396  uint8_t direction = (flags & STREAM_TOSERVER) ? 0 : 1;
397 
398  if (flags & STREAM_TOSERVER) {
399  alproto = &f->alproto_ts;
400  alproto_otherdir = &f->alproto_tc;
401  } else {
402  alproto = &f->alproto_tc;
403  alproto_otherdir = &f->alproto_ts;
404  }
405 
406  SCLogDebug("Stream initializer (len %" PRIu32 ")", data_len);
407 #ifdef PRINT
408  if (data_len > 0) {
409  printf("=> Init Stream Data (app layer) -- start %s%s\n",
410  flags & STREAM_TOCLIENT ? "toclient" : "",
411  flags & STREAM_TOSERVER ? "toserver" : "");
412  PrintRawDataFp(stdout, data, data_len);
413  printf("=> Init Stream Data -- end\n");
414  }
415 #endif
416 
417  bool reverse_flow = false;
418  DEBUG_VALIDATE_BUG_ON(data == NULL && data_len > 0);
420  *alproto = AppLayerProtoDetectGetProto(app_tctx->alpd_tctx,
421  f, data, data_len,
422  IPPROTO_TCP, flags, &reverse_flow);
423  PACKET_PROFILING_APP_PD_END(app_tctx);
424  SCLogDebug("alproto %u rev %s", *alproto, reverse_flow ? "true" : "false");
425 
426  if (*alproto != ALPROTO_UNKNOWN) {
427  if (*alproto_otherdir != ALPROTO_UNKNOWN && *alproto_otherdir != *alproto) {
430 
432  /* if we already invoked the parser, we go with that proto */
433  f->alproto = *alproto_otherdir;
434  } else {
435  /* no data sent to parser yet, we can still choose
436  * we're trusting the server more. */
437  if (flags & STREAM_TOCLIENT)
438  f->alproto = *alproto;
439  else
440  f->alproto = *alproto_otherdir;
441  }
442  } else {
443  f->alproto = *alproto;
444  }
445 
449  FlagPacketFlow(p, f, flags);
450 
451  /* if protocol detection indicated that we need to reverse
452  * the direction of the flow, do it now. We flip the flow,
453  * packet and the direction flags */
454  if (reverse_flow &&
457  /* but only if we didn't already detect it on the other side. */
458  if (*alproto_otherdir == ALPROTO_UNKNOWN) {
459  SCLogDebug("reversing flow after proto detect told us so");
460  PacketSwap(p);
461  FlowSwap(f);
462  SWAP_FLAGS(flags, STREAM_TOSERVER, STREAM_TOCLIENT);
463  if (*stream == &ssn->client) {
464  *stream = &ssn->server;
465  } else {
466  *stream = &ssn->client;
467  }
468  direction = 1 - direction;
469  } else {
470  // TODO event, error?
471  }
472  }
473 
474  /* account flow if we have both sides */
475  if (*alproto_otherdir != ALPROTO_UNKNOWN) {
476  AppLayerIncFlowCounter(tv, f);
477  }
478 
479  /* if we have seen data from the other direction first, send
480  * data for that direction first to the parser. This shouldn't
481  * be an issue, since each stream processing happens
482  * independently of the other stream direction. At this point of
483  * call, you need to know that this function's already being
484  * called by the very same StreamReassembly() function that we
485  * will now call shortly for the opposing direction. */
486  if ((ssn->data_first_seen_dir & (STREAM_TOSERVER | STREAM_TOCLIENT)) &&
487  !(flags & ssn->data_first_seen_dir))
488  {
489  SCLogDebug("protocol %s needs first data in other direction",
490  AppProtoToString(*alproto));
491 
492  if (TCPProtoDetectTriggerOpposingSide(tv, ra_ctx,
493  p, ssn, *stream) != 0)
494  {
495  goto detect_error;
496  }
497  if (FlowChangeProto(f)) {
498  /* We have the first data which requested a protocol change from P1 to P2
499  * even if it was not recognized at first as being P1
500  * As the second data was recognized as P1, the protocol did not change !
501  */
505  }
506  }
507 
508  /* if the parser operates such that it needs to see data from
509  * a particular direction first, we check if we have seen
510  * data from that direction first for the flow. IF it is not
511  * the same, we set an event and exit.
512  *
513  * \todo We need to figure out a more robust solution for this,
514  * as this can lead to easy evasion tactics, where the
515  * attacker can first send some dummy data in the wrong
516  * direction first to mislead our proto detection process.
517  * While doing this we need to update the parsers as well,
518  * since the parsers must be robust to see such wrong
519  * direction data.
520  * Either ways the moment we see the
521  * APPLAYER_WRONG_DIRECTION_FIRST_DATA event set for the
522  * flow, it shows something's fishy.
523  */
525  uint8_t first_data_dir;
526  first_data_dir = AppLayerParserGetFirstDataDir(f->proto, f->alproto);
527 
528  if (first_data_dir && !(first_data_dir & ssn->data_first_seen_dir)) {
531  goto detect_error;
532  }
533  /* This can happen if the current direction is not the
534  * right direction, and the data from the other(also
535  * the right direction) direction is available to be sent
536  * to the app layer, but it is not ack'ed yet and hence
537  * the forced call to STreamTcpAppLayerReassemble still
538  * hasn't managed to send data from the other direction
539  * to the app layer. */
540  if (first_data_dir && !(first_data_dir & flags)) {
546  SCReturnInt(-1);
547  }
548  }
549 
550  /* Set a value that is neither STREAM_TOSERVER, nor STREAM_TOCLIENT */
552 
553  /* finally, invoke the parser */
554  PACKET_PROFILING_APP_START(app_tctx, f->alproto);
555  int r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto,
556  flags, data, data_len);
557  PACKET_PROFILING_APP_END(app_tctx);
558  p->app_update_direction = (uint8_t)app_update_dir;
559  if (r != 1) {
560  StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
561  }
562  if (r == 0) {
563  if (*alproto_otherdir == ALPROTO_UNKNOWN) {
564  TcpStream *opposing_stream;
565  if (*stream == &ssn->client) {
566  opposing_stream = &ssn->server;
567  } else {
568  opposing_stream = &ssn->client;
569  }
571  // can happen in detection-only
572  AppLayerIncFlowCounter(tv, f);
573  }
574  }
575  }
576  if (r < 0) {
577  goto parser_error;
578  }
579  } else {
580  /* if the ssn is midstream, we may end up with a case where the
581  * start of an HTTP request is missing. We won't detect HTTP based
582  * on the request. However, the reply is fine, so we detect
583  * HTTP anyway. This leads to passing the incomplete request to
584  * the htp parser.
585  *
586  * This has been observed, where the http parser then saw many
587  * bogus requests in the incomplete data.
588  *
589  * To counter this case, a midstream session MUST find it's
590  * protocol in the toserver direction. If not, we assume the
591  * start of the request/toserver is incomplete and no reliable
592  * detection and parsing is possible. So we give up.
593  */
594  if ((ssn->flags & STREAMTCP_FLAG_MIDSTREAM) &&
596  {
597  if (FLOW_IS_PM_DONE(f, STREAM_TOSERVER) && FLOW_IS_PP_DONE(f, STREAM_TOSERVER)) {
598  SCLogDebug("midstream end pd %p", ssn);
599  /* midstream and toserver detection failed: give up */
600  DisableAppLayer(tv, f, p);
601  SCReturnInt(0);
602  }
603  }
604 
605  if (*alproto_otherdir != ALPROTO_UNKNOWN) {
606  uint8_t first_data_dir;
607  first_data_dir = AppLayerParserGetFirstDataDir(f->proto, *alproto_otherdir);
608 
609  /* this would handle this test case -
610  * http parser which says it wants to see toserver data first only.
611  * tcp handshake
612  * toclient data first received. - RUBBISH DATA which
613  * we don't detect as http
614  * toserver data next sent - we detect this as http.
615  * at this stage we see that toclient is the first data seen
616  * for this session and we try and redetect the app protocol,
617  * but we are unable to detect the app protocol like before.
618  * But since we have managed to detect the protocol for the
619  * other direction as http, we try to use that. At this
620  * stage we check if the direction of this stream matches
621  * to that acceptable by the app parser. If it is not the
622  * acceptable direction we error out.
623  */
625  (first_data_dir) && !(first_data_dir & flags))
626  {
627  goto detect_error;
628  }
629 
630  /* if protocol detection is marked done for our direction we
631  * pass our data on. We're only succeeded in finding one
632  * direction: the opposing stream
633  *
634  * If PD was not yet complete, we don't do anything.
635  */
636  if (FLOW_IS_PM_DONE(f, flags) && FLOW_IS_PP_DONE(f, flags)) {
637  if (data_len > 0)
639 
640  if (*alproto_otherdir != ALPROTO_FAILED) {
641  PACKET_PROFILING_APP_START(app_tctx, f->alproto);
642  int r = AppLayerParserParse(tv, app_tctx->alp_tctx, f,
643  f->alproto, flags,
644  data, data_len);
645  PACKET_PROFILING_APP_END(app_tctx);
646  p->app_update_direction = (uint8_t)app_update_dir;
647  if (r != 1) {
648  StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
649  }
650 
655 
656  *alproto = *alproto_otherdir;
657  SCLogDebug("packet %"PRIu64": pd done(us %u them %u), parser called (r==%d), APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION set",
658  p->pcap_cnt, *alproto, *alproto_otherdir, r);
659  if (r < 0) {
660  goto parser_error;
661  }
662  }
663  *alproto = ALPROTO_FAILED;
665  AppLayerIncFlowCounter(tv, f);
666  FlagPacketFlow(p, f, flags);
667 
668  } else if (flags & STREAM_EOF) {
669  *alproto = f->alproto;
671  AppLayerIncFlowCounter(tv, f);
672  }
673  } else {
674  /* both sides unknown, let's see if we need to give up */
675  if (FlowChangeProto(f)) {
676  /* TCPProtoDetectCheckBailConditions does not work well because
677  * size_tc from STREAM_RIGHT_EDGE is not reset to zero
678  * so, we set a lower limit to the data we inspect
679  * We could instead have set ssn->server.sb.stream_offset = 0;
680  */
681  if (data_len >= FLOW_PROTO_CHANGE_MAX_DEPTH || (flags & STREAM_EOF)) {
682  DisableAppLayer(tv, f, p);
683  }
684  } else {
685  TCPProtoDetectCheckBailConditions(tv, f, ssn, p);
686  }
687  }
688  }
689  SCReturnInt(0);
690 parser_error:
692  AppLayerIncrErrorExcPolicyCounter(tv, f, g_applayerparser_error_policy);
693  SCReturnInt(-1);
694 detect_error:
695  DisableAppLayer(tv, f, p);
696  SCReturnInt(-2);
697 }
698 
699 /** \brief handle TCP data for the app-layer.
700  *
701  * First run protocol detection and then when the protocol is known invoke
702  * the app layer parser.
703  *
704  * \param stream ptr-to-ptr to stream object. Might change if flow dir is
705  * reversed.
706  */
708  TcpSession *ssn, TcpStream **stream, uint8_t *data, uint32_t data_len, uint8_t flags,
709  enum StreamUpdateDir app_update_dir)
710 {
711  SCEnter();
712 
714  DEBUG_VALIDATE_BUG_ON(data_len > (uint32_t)INT_MAX);
715 
716  AppLayerThreadCtx *app_tctx = ra_ctx->app_tctx;
717  AppProto alproto;
718  int r = 0;
719 
720  SCLogDebug("data_len %u flags %02X", data_len, flags);
722  SCLogDebug("STREAMTCP_FLAG_APP_LAYER_DISABLED is set");
723  goto end;
724  }
725 
726  const uint8_t direction = (flags & STREAM_TOSERVER) ? 0 : 1;
727 
728  if (flags & STREAM_TOSERVER) {
729  alproto = f->alproto_ts;
730  } else {
731  alproto = f->alproto_tc;
732  }
733 
734  /* If a gap notification, relay the notification on to the
735  * app-layer if known. */
736  if (flags & STREAM_GAP) {
737  if (alproto == ALPROTO_UNKNOWN) {
739  SCLogDebug("ALPROTO_UNKNOWN flow %p, due to GAP in stream start", f);
740  /* if the other side didn't already find the proto, we're done */
741  if (f->alproto == ALPROTO_UNKNOWN) {
742  goto failure;
743  }
744  AppLayerIncFlowCounter(tv, f);
745  }
746  if (FlowChangeProto(f)) {
748  SCLogDebug("Cannot handle gap while changing protocol");
749  goto failure;
750  }
751  PACKET_PROFILING_APP_START(app_tctx, f->alproto);
752  r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto,
753  flags, data, data_len);
754  PACKET_PROFILING_APP_END(app_tctx);
755  p->app_update_direction = (uint8_t)app_update_dir;
756  /* ignore parser result for gap */
757  StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
758  if (r < 0) {
760  AppLayerIncrErrorExcPolicyCounter(tv, f, g_applayerparser_error_policy);
761  SCReturnInt(-1);
762  }
763  goto end;
764  }
765 
766  /* if we don't know the proto yet and we have received a stream
767  * initializer message, we run proto detection.
768  * We receive 2 stream init msgs (one for each direction), we
769  * only run the proto detection for both and emit an event
770  * in the case protocols mismatch. */
771  if (alproto == ALPROTO_UNKNOWN && (flags & STREAM_START)) {
773  /* run protocol detection */
774  if (TCPProtoDetect(tv, ra_ctx, app_tctx, p, f, ssn, stream, data, data_len, flags,
775  app_update_dir) != 0) {
776  goto failure;
777  }
778  } else if (alproto != ALPROTO_UNKNOWN && FlowChangeProto(f)) {
779  SCLogDebug("protocol change, old %s", AppProtoToString(f->alproto_orig));
780  void *alstate_orig = f->alstate;
781  AppLayerParserState *alparser = f->alparser;
782  // we delay AppLayerParserStateCleanup because we may need previous parser state
786  /* rerun protocol detection */
787  int rd = TCPProtoDetect(
788  tv, ra_ctx, app_tctx, p, f, ssn, stream, data, data_len, flags, app_update_dir);
789  if (f->alproto == ALPROTO_UNKNOWN) {
790  DEBUG_VALIDATE_BUG_ON(alstate_orig != f->alstate);
791  // not enough data, revert AppLayerProtoDetectReset to rerun detection
792  f->alparser = alparser;
793  f->alproto = f->alproto_orig;
794  f->alproto_tc = f->alproto_orig;
795  f->alproto_ts = f->alproto_orig;
796  } else {
798  AppLayerParserStateProtoCleanup(f->protomap, f->alproto_orig, alstate_orig, alparser);
799  if (alstate_orig == f->alstate) {
800  // we just freed it
801  f->alstate = NULL;
802  }
803  }
804  if (rd != 0) {
805  SCLogDebug("proto detect failure");
806  goto failure;
807  }
808  SCLogDebug("protocol change, old %s, new %s",
810 
812  f->alproto != f->alproto_expect) {
815 
816  if (f->alproto_expect == ALPROTO_TLS && f->alproto != ALPROTO_TLS) {
819 
820  }
821  }
822  } else {
823  SCLogDebug("stream data (len %" PRIu32 " alproto "
824  "%"PRIu16" (flow %p)", data_len, f->alproto, f);
825 #ifdef PRINT
826  if (data_len > 0) {
827  printf("=> Stream Data (app layer) -- start %s%s\n",
828  flags & STREAM_TOCLIENT ? "toclient" : "",
829  flags & STREAM_TOSERVER ? "toserver" : "");
830  PrintRawDataFp(stdout, data, data_len);
831  printf("=> Stream Data -- end\n");
832  }
833 #endif
834  /* if we don't have a data object here we are not getting it
835  * a start msg should have gotten us one */
836  if (f->alproto != ALPROTO_UNKNOWN) {
837  PACKET_PROFILING_APP_START(app_tctx, f->alproto);
838  r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto,
839  flags, data, data_len);
840  PACKET_PROFILING_APP_END(app_tctx);
841  p->app_update_direction = (uint8_t)app_update_dir;
842  if (r != 1) {
843  StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
844  if (r < 0) {
847  AppLayerIncrErrorExcPolicyCounter(tv, f, g_applayerparser_error_policy);
848  SCReturnInt(-1);
849  }
850  }
851  }
852  }
853 
854  goto end;
855  failure:
856  r = -1;
857  end:
858  SCReturnInt(r);
859 }
860 
861 /**
862  * \brief Handle a app layer UDP message
863  *
864  * If the protocol is yet unknown, the proto detection code is run first.
865  *
866  * \param dp_ctx Thread app layer detect context
867  * \param f *locked* flow
868  * \param p UDP packet
869  *
870  * \retval 0 ok
871  * \retval -1 error
872  */
874 {
875  SCEnter();
876  AppProto *alproto;
877  AppProto *alproto_otherdir;
878 
879  if (f->alproto_ts == ALPROTO_FAILED && f->alproto_tc == ALPROTO_FAILED) {
880  SCReturnInt(0);
881  }
882 
883  int r = 0;
884  uint8_t flags = 0;
885  if (p->flowflags & FLOW_PKT_TOSERVER) {
886  flags |= STREAM_TOSERVER;
887  alproto = &f->alproto_ts;
888  alproto_otherdir = &f->alproto_tc;
889  } else {
890  flags |= STREAM_TOCLIENT;
891  alproto = &f->alproto_tc;
892  alproto_otherdir = &f->alproto_ts;
893  }
894 
896 
897  /* if the protocol is still unknown, run detection */
898  if (*alproto == ALPROTO_UNKNOWN) {
899  SCLogDebug("Detecting AL proto on udp mesg (len %" PRIu32 ")",
900  p->payload_len);
901 
902  bool reverse_flow = false;
904  *alproto = AppLayerProtoDetectGetProto(
905  tctx->alpd_tctx, f, p->payload, p->payload_len, IPPROTO_UDP, flags, &reverse_flow);
907 
908  switch (*alproto) {
909  case ALPROTO_UNKNOWN:
910  if (*alproto_otherdir != ALPROTO_UNKNOWN) {
911  // Use recognized side
912  f->alproto = *alproto_otherdir;
913  // do not keep ALPROTO_UNKNOWN for this side so as not to loop
914  *alproto = *alproto_otherdir;
915  if (*alproto_otherdir == ALPROTO_FAILED) {
916  SCLogDebug("ALPROTO_UNKNOWN flow %p", f);
917  }
918  } else {
919  // First side of protocol is unknown
920  *alproto = ALPROTO_FAILED;
921  }
922  break;
923  case ALPROTO_FAILED:
924  if (*alproto_otherdir != ALPROTO_UNKNOWN) {
925  // Use recognized side
926  f->alproto = *alproto_otherdir;
927  if (*alproto_otherdir == ALPROTO_FAILED) {
928  SCLogDebug("ALPROTO_UNKNOWN flow %p", f);
929  }
930  }
931  // else wait for second side of protocol
932  break;
933  default:
934  if (*alproto_otherdir != ALPROTO_UNKNOWN && *alproto_otherdir != ALPROTO_FAILED) {
935  if (*alproto_otherdir != *alproto) {
938  // data already sent to parser, we cannot change the protocol to use the one
939  // of the server
940  }
941  } else {
942  f->alproto = *alproto;
943  }
944  }
945  if (*alproto_otherdir == ALPROTO_UNKNOWN) {
946  if (f->alproto == ALPROTO_UNKNOWN) {
947  // so as to increase stat about .app_layer.flow.failed_udp
948  f->alproto = ALPROTO_FAILED;
949  }
950  // If the other side is unknown, this is the first packet of the flow
951  AppLayerIncFlowCounter(tv, f);
952  }
953 
954  // parse the data if we recognized one protocol
955  if (f->alproto != ALPROTO_UNKNOWN && f->alproto != ALPROTO_FAILED) {
956  if (reverse_flow) {
957  SCLogDebug("reversing flow after proto detect told us so");
958  PacketSwap(p);
959  FlowSwap(f);
960  SWAP_FLAGS(flags, STREAM_TOSERVER, STREAM_TOCLIENT);
961  }
962 
964  r = AppLayerParserParse(tv, tctx->alp_tctx, f, f->alproto,
965  flags, p->payload, p->payload_len);
968  }
970  /* we do only inspection in one direction, so flag both
971  * sides as done here */
972  FlagPacketFlow(p, f, STREAM_TOSERVER);
973  FlagPacketFlow(p, f, STREAM_TOCLIENT);
974  } else {
975  SCLogDebug("data (len %" PRIu32 " ), alproto "
976  "%"PRIu16" (flow %p)", p->payload_len, f->alproto, f);
977 
978  /* run the parser */
980  r = AppLayerParserParse(tv, tctx->alp_tctx, f, f->alproto,
981  flags, p->payload, p->payload_len);
985  }
986  if (r < 0) {
988  AppLayerIncrErrorExcPolicyCounter(tv, f, g_applayerparser_error_policy);
989  SCReturnInt(-1);
990  }
991 
992  SCReturnInt(r);
993 }
994 
995 /***** Utility *****/
996 
997 AppProto AppLayerGetProtoByName(char *alproto_name)
998 {
999  SCEnter();
1000  AppProto r = AppLayerProtoDetectGetProtoByName(alproto_name);
1001  SCReturnCT(r, "AppProto");
1002 }
1003 
1004 const char *AppLayerGetProtoName(AppProto alproto)
1005 {
1006  SCEnter();
1007  const char * r = AppLayerProtoDetectGetProtoName(alproto);
1008  SCReturnCT(r, "char *");
1009 }
1010 
1012 {
1013  SCEnter();
1014 
1015  AppProto alproto;
1016  AppProto alprotos[ALPROTO_MAX];
1017 
1019 
1020  printf("=========Supported App Layer Protocols=========\n");
1021  for (alproto = 0; alproto < ALPROTO_MAX; alproto++) {
1022  if (alprotos[alproto] == 1)
1023  printf("%s\n", AppLayerGetProtoName(alproto));
1024  }
1025 
1026  SCReturn;
1027 }
1028 
1029 /***** Setup/General Registration *****/
1030 
1031 int AppLayerSetup(void)
1032 {
1033  SCEnter();
1034 
1037 
1040 
1042 
1043  SCReturnInt(0);
1044 }
1045 
1047 {
1048  SCEnter();
1049 
1052 
1054 
1055  SCReturnInt(0);
1056 }
1057 
1059 {
1060  SCEnter();
1061 
1062  AppLayerThreadCtx *app_tctx = SCCalloc(1, sizeof(*app_tctx));
1063  if (app_tctx == NULL)
1064  goto error;
1065 
1066  if ((app_tctx->alpd_tctx = AppLayerProtoDetectGetCtxThread()) == NULL)
1067  goto error;
1068  if ((app_tctx->alp_tctx = AppLayerParserThreadCtxAlloc()) == NULL)
1069  goto error;
1070 
1071  goto done;
1072  error:
1073  AppLayerDestroyCtxThread(app_tctx);
1074  app_tctx = NULL;
1075  done:
1076  SCReturnPtr(app_tctx, "void *");
1077 }
1078 
1080 {
1081  SCEnter();
1082 
1083  if (app_tctx == NULL)
1084  SCReturn;
1085 
1086  if (app_tctx->alpd_tctx != NULL)
1088  if (app_tctx->alp_tctx != NULL)
1090  SCFree(app_tctx);
1091 
1092  SCReturn;
1093 }
1094 
1095 #ifdef PROFILING
1097 {
1098  PACKET_PROFILING_APP_RESET(app_tctx);
1099 }
1100 
1102 {
1103  PACKET_PROFILING_APP_STORE(app_tctx, p);
1104 }
1105 #endif
1106 
1107 /** \brief HACK to work around our broken unix manager (re)init loop
1108  */
1110 {
1115  StatsRegisterGlobalCounter("app_layer.expectations", ExpectationGetCounter);
1116 }
1117 
1118 static bool IsAppLayerErrorExceptionPolicyStatsValid(enum ExceptionPolicy policy)
1119 {
1120  if (EngineModeIsIPS()) {
1122  }
1124 }
1125 
1126 static void AppLayerSetupExceptionPolicyPerProtoCounters(
1127  uint8_t ipproto_map, AppProto alproto, const char *alproto_str, const char *ipproto_suffix)
1128 {
1131  for (enum ExceptionPolicy i = EXCEPTION_POLICY_NOT_SET + 1; i < EXCEPTION_POLICY_MAX; i++) {
1132  if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1133  snprintf(applayer_counter_names[ipproto_map][alproto].eps_name[i],
1134  sizeof(applayer_counter_names[ipproto_map][alproto].eps_name[i]),
1135  "app_layer.error.%s%s.exception_policy.%s", alproto_str, ipproto_suffix,
1136  ExceptionPolicyEnumToString(i, true));
1137  }
1138  }
1139  }
1140 }
1141 
1143 {
1144  const uint8_t ipprotos[] = { IPPROTO_TCP, IPPROTO_UDP };
1145  AppProto alprotos[ALPROTO_MAX];
1146  const char *str = "app_layer.flow.";
1147  const char *estr = "app_layer.error.";
1148 
1149  /* We don't log stats counters if exception policy is `ignore`/`not set` */
1151  /* Register global counters for app layer error exception policy summary */
1152  const char *eps_default_str = "app_layer.error.exception_policy.";
1153  for (enum ExceptionPolicy i = EXCEPTION_POLICY_NOT_SET + 1; i < EXCEPTION_POLICY_MAX; i++) {
1154  if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1155  snprintf(app_layer_error_eps_stats.eps_name[i],
1156  sizeof(app_layer_error_eps_stats.eps_name[i]), "%s%s", eps_default_str,
1157  ExceptionPolicyEnumToString(i, true));
1158  }
1159  }
1160  }
1161 
1163 
1164  for (uint8_t p = 0; p < FLOW_PROTO_APPLAYER_MAX; p++) {
1165  const uint8_t ipproto = ipprotos[p];
1166  const uint8_t ipproto_map = FlowGetProtoMapping(ipproto);
1167  const char *ipproto_suffix = (ipproto == IPPROTO_TCP) ? "_tcp" : "_udp";
1168  uint8_t ipprotos_all[256 / 8];
1169 
1170  for (AppProto alproto = 0; alproto < ALPROTO_MAX; alproto++) {
1171  if (alprotos[alproto] == 1) {
1172  const char *tx_str = "app_layer.tx.";
1173  const char *alproto_str = AppLayerGetProtoName(alproto);
1174 
1175  memset(ipprotos_all, 0, sizeof(ipprotos_all));
1176  AppLayerProtoDetectSupportedIpprotos(alproto, ipprotos_all);
1177  if ((ipprotos_all[IPPROTO_TCP / 8] & (1 << (IPPROTO_TCP % 8))) &&
1178  (ipprotos_all[IPPROTO_UDP / 8] & (1 << (IPPROTO_UDP % 8)))) {
1179  snprintf(applayer_counter_names[ipproto_map][alproto].name,
1180  sizeof(applayer_counter_names[ipproto_map][alproto].name),
1181  "%s%s%s", str, alproto_str, ipproto_suffix);
1182  snprintf(applayer_counter_names[ipproto_map][alproto].tx_name,
1183  sizeof(applayer_counter_names[ipproto_map][alproto].tx_name),
1184  "%s%s%s", tx_str, alproto_str, ipproto_suffix);
1185 
1186  if (ipproto == IPPROTO_TCP) {
1187  snprintf(applayer_counter_names[ipproto_map][alproto].gap_error,
1188  sizeof(applayer_counter_names[ipproto_map][alproto].gap_error),
1189  "%s%s%s.gap", estr, alproto_str, ipproto_suffix);
1190  }
1191  snprintf(applayer_counter_names[ipproto_map][alproto].alloc_error,
1192  sizeof(applayer_counter_names[ipproto_map][alproto].alloc_error),
1193  "%s%s%s.alloc", estr, alproto_str, ipproto_suffix);
1194  snprintf(applayer_counter_names[ipproto_map][alproto].parser_error,
1195  sizeof(applayer_counter_names[ipproto_map][alproto].parser_error),
1196  "%s%s%s.parser", estr, alproto_str, ipproto_suffix);
1197  snprintf(applayer_counter_names[ipproto_map][alproto].internal_error,
1198  sizeof(applayer_counter_names[ipproto_map][alproto].internal_error),
1199  "%s%s%s.internal", estr, alproto_str, ipproto_suffix);
1200 
1201  AppLayerSetupExceptionPolicyPerProtoCounters(
1202  ipproto_map, alproto, alproto_str, ipproto_suffix);
1203  } else {
1204  snprintf(applayer_counter_names[ipproto_map][alproto].name,
1205  sizeof(applayer_counter_names[ipproto_map][alproto].name),
1206  "%s%s", str, alproto_str);
1207  snprintf(applayer_counter_names[ipproto_map][alproto].tx_name,
1208  sizeof(applayer_counter_names[ipproto_map][alproto].tx_name),
1209  "%s%s", tx_str, alproto_str);
1210 
1211  if (ipproto == IPPROTO_TCP) {
1212  snprintf(applayer_counter_names[ipproto_map][alproto].gap_error,
1213  sizeof(applayer_counter_names[ipproto_map][alproto].gap_error),
1214  "%s%s.gap", estr, alproto_str);
1215  }
1216  snprintf(applayer_counter_names[ipproto_map][alproto].alloc_error,
1217  sizeof(applayer_counter_names[ipproto_map][alproto].alloc_error),
1218  "%s%s.alloc", estr, alproto_str);
1219  snprintf(applayer_counter_names[ipproto_map][alproto].parser_error,
1220  sizeof(applayer_counter_names[ipproto_map][alproto].parser_error),
1221  "%s%s.parser", estr, alproto_str);
1222  snprintf(applayer_counter_names[ipproto_map][alproto].internal_error,
1223  sizeof(applayer_counter_names[ipproto_map][alproto].internal_error),
1224  "%s%s.internal", estr, alproto_str);
1225  AppLayerSetupExceptionPolicyPerProtoCounters(
1226  ipproto_map, alproto, alproto_str, "");
1227  }
1228  } else if (alproto == ALPROTO_FAILED) {
1229  snprintf(applayer_counter_names[ipproto_map][alproto].name,
1230  sizeof(applayer_counter_names[ipproto_map][alproto].name),
1231  "%s%s%s", str, "failed", ipproto_suffix);
1232  if (ipproto == IPPROTO_TCP) {
1233  snprintf(applayer_counter_names[ipproto_map][alproto].gap_error,
1234  sizeof(applayer_counter_names[ipproto_map][alproto].gap_error),
1235  "%sfailed%s.gap", estr, ipproto_suffix);
1236  }
1237  }
1238  }
1239  }
1240 }
1241 
1243 {
1244  const uint8_t ipprotos[] = { IPPROTO_TCP, IPPROTO_UDP };
1245  AppProto alprotos[ALPROTO_MAX];
1247 
1248  /* We don't log stats counters if exception policy is `ignore`/`not set` */
1250  /* Register global counters for app layer error exception policy summary */
1251  for (enum ExceptionPolicy i = EXCEPTION_POLICY_NOT_SET + 1; i < EXCEPTION_POLICY_MAX; i++) {
1252  if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1255  }
1256  }
1257  }
1258 
1259  for (uint8_t p = 0; p < FLOW_PROTO_APPLAYER_MAX; p++) {
1260  const uint8_t ipproto = ipprotos[p];
1261  const uint8_t ipproto_map = FlowGetProtoMapping(ipproto);
1262 
1263  for (AppProto alproto = 0; alproto < ALPROTO_MAX; alproto++) {
1264  if (alprotos[alproto] == 1) {
1265  applayer_counters[ipproto_map][alproto].counter_id =
1266  StatsRegisterCounter(applayer_counter_names[ipproto_map][alproto].name, tv);
1267 
1268  applayer_counters[ipproto_map][alproto].counter_tx_id =
1269  StatsRegisterCounter(applayer_counter_names[ipproto_map][alproto].tx_name, tv);
1270 
1271  if (ipproto == IPPROTO_TCP) {
1272  applayer_counters[ipproto_map][alproto].gap_error_id = StatsRegisterCounter(
1273  applayer_counter_names[ipproto_map][alproto].gap_error, tv);
1274  }
1275  applayer_counters[ipproto_map][alproto].alloc_error_id = StatsRegisterCounter(
1276  applayer_counter_names[ipproto_map][alproto].alloc_error, tv);
1277  applayer_counters[ipproto_map][alproto].parser_error_id = StatsRegisterCounter(
1278  applayer_counter_names[ipproto_map][alproto].parser_error, tv);
1280  applayer_counter_names[ipproto_map][alproto].internal_error, tv);
1281  /* We don't log stats counters if exception policy is `ignore`/`not set` */
1284  for (enum ExceptionPolicy i = EXCEPTION_POLICY_NOT_SET + 1;
1285  i < EXCEPTION_POLICY_MAX; i++) {
1286  if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1287  applayer_counters[ipproto_map][alproto]
1289  applayer_counter_names[ipproto_map][alproto].eps_name[i], tv);
1290  }
1291  }
1292  }
1293  } else if (alproto == ALPROTO_FAILED) {
1294  applayer_counters[ipproto_map][alproto].counter_id =
1295  StatsRegisterCounter(applayer_counter_names[ipproto_map][alproto].name, tv);
1296 
1297  if (ipproto == IPPROTO_TCP) {
1298  applayer_counters[ipproto_map][alproto].gap_error_id = StatsRegisterCounter(
1299  applayer_counter_names[ipproto_map][alproto].gap_error, tv);
1300  }
1301  }
1302  }
1303  }
1304 }
1305 
1307 {
1308  memset(applayer_counter_names, 0, sizeof(applayer_counter_names));
1309  memset(applayer_counters, 0, sizeof(applayer_counters));
1310 }
1311 
1312 /***** Unittests *****/
1313 
1314 #ifdef UNITTESTS
1315 #include "pkt-var.h"
1316 #include "stream-tcp-util.h"
1317 #include "stream.h"
1318 #include "util-unittest.h"
1319 
1320 #define TEST_START \
1321  Packet *p = PacketGetFromAlloc(); \
1322  FAIL_IF_NULL(p); \
1323  Flow f; \
1324  ThreadVars tv; \
1325  StreamTcpThread *stt = NULL; \
1326  TCPHdr tcph; \
1327  PacketQueueNoLock pq; \
1328  memset(&pq, 0, sizeof(PacketQueueNoLock)); \
1329  memset(&f, 0, sizeof(Flow)); \
1330  memset(&tv, 0, sizeof(ThreadVars)); \
1331  memset(&tcph, 0, sizeof(TCPHdr)); \
1332  \
1333  FLOW_INITIALIZE(&f); \
1334  f.flags = FLOW_IPV4; \
1335  f.proto = IPPROTO_TCP; \
1336  p->flow = &f; \
1337  PacketSetTCP(p, (uint8_t *)&tcph); \
1338  \
1339  StreamTcpInitConfig(true); \
1340  IPPairInitConfig(true); \
1341  StreamTcpThreadInit(&tv, NULL, (void **)&stt); \
1342  \
1343  /* handshake */ \
1344  tcph.th_win = htons(5480); \
1345  tcph.th_flags = TH_SYN; \
1346  p->flowflags = FLOW_PKT_TOSERVER; \
1347  p->payload_len = 0; \
1348  p->payload = NULL; \
1349  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1); \
1350  TcpSession *ssn = (TcpSession *)f.protoctx; \
1351  \
1352  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); \
1353  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); \
1354  FAIL_IF(f.alproto != ALPROTO_UNKNOWN); \
1355  FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN); \
1356  FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN); \
1357  FAIL_IF(ssn->flags &STREAMTCP_FLAG_APP_LAYER_DISABLED); \
1358  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER)); \
1359  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER)); \
1360  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT)); \
1361  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); \
1362  FAIL_IF(ssn->data_first_seen_dir != 0); \
1363  \
1364  /* handshake */ \
1365  tcph.th_ack = htonl(1); \
1366  tcph.th_flags = TH_SYN | TH_ACK; \
1367  p->flowflags = FLOW_PKT_TOCLIENT; \
1368  p->payload_len = 0; \
1369  p->payload = NULL; \
1370  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1); \
1371  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); \
1372  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); \
1373  FAIL_IF(f.alproto != ALPROTO_UNKNOWN); \
1374  FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN); \
1375  FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN); \
1376  FAIL_IF(ssn->flags &STREAMTCP_FLAG_APP_LAYER_DISABLED); \
1377  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER)); \
1378  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER)); \
1379  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT)); \
1380  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); \
1381  FAIL_IF(ssn->data_first_seen_dir != 0); \
1382  \
1383  /* handshake */ \
1384  tcph.th_ack = htonl(1); \
1385  tcph.th_seq = htonl(1); \
1386  tcph.th_flags = TH_ACK; \
1387  p->flowflags = FLOW_PKT_TOSERVER; \
1388  p->payload_len = 0; \
1389  p->payload = NULL; \
1390  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1); \
1391  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); \
1392  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); \
1393  FAIL_IF(f.alproto != ALPROTO_UNKNOWN); \
1394  FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN); \
1395  FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN); \
1396  FAIL_IF(ssn->flags &STREAMTCP_FLAG_APP_LAYER_DISABLED); \
1397  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER)); \
1398  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER)); \
1399  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT)); \
1400  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); \
1401  FAIL_IF(ssn->data_first_seen_dir != 0);
1402 #define TEST_END \
1403  StreamTcpSessionClear(p->flow->protoctx); \
1404  StreamTcpThreadDeinit(&tv, (void *)stt); \
1405  StreamTcpFreeConfig(true); \
1406  PacketFree(p); \
1407  FLOW_DESTROY(&f); \
1408  StatsThreadCleanup(&tv);
1409 
1410 /**
1411  * \test GET -> HTTP/1.1
1412  */
1413 static int AppLayerTest01(void)
1414 {
1415  TEST_START;
1416 
1417  /* full request */
1418  uint8_t request[] = {
1419  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1420  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1421  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1422  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1423  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1424  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1425  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1426  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1427  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1428  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1429  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1430  tcph.th_ack = htonl(1);
1431  tcph.th_seq = htonl(1);
1432  tcph.th_flags = TH_PUSH | TH_ACK;
1434  p->payload_len = sizeof(request);
1435  p->payload = request;
1436  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1443  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1444  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1445  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1446  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1447  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1448 
1449  /* full response - request ack */
1450  uint8_t response[] = {
1451  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
1452  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1453  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1454  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1455  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1456  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1457  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1458  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1459  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1460  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1461  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1462  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1463  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1464  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1465  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1466  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1467  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1468  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1469  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1470  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1471  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1472  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1473  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1474  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1475  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1476  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1477  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1478  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1479  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1480  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1481  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1482  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1483  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1484  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1485  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1486  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1487  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1488  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1489  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1490  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1491  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1492  tcph.th_ack = htonl(88);
1493  tcph.th_seq = htonl(1);
1494  tcph.th_flags = TH_PUSH | TH_ACK;
1496  p->payload_len = sizeof(response);
1497  p->payload = response;
1498  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1505  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1506  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1507  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1508  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1510 
1511  /* response ack */
1512  tcph.th_ack = htonl(328);
1513  tcph.th_seq = htonl(88);
1514  tcph.th_flags = TH_ACK;
1516  p->payload_len = 0;
1517  p->payload = NULL;
1518  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1525  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1526  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1527  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1528  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1530 
1531  TEST_END;
1532  PASS;
1533 }
1534 
1535 /**
1536  * \test GE -> T -> HTTP/1.1
1537  */
1538 static int AppLayerTest02(void)
1539 {
1540  TEST_START;
1541 
1542  /* partial request */
1543  uint8_t request1[] = { 0x47, 0x45, };
1544  tcph.th_ack = htonl(1);
1545  tcph.th_seq = htonl(1);
1546  tcph.th_flags = TH_PUSH | TH_ACK;
1548  p->payload_len = sizeof(request1);
1549  p->payload = request1;
1550  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1557  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1558  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1559  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1560  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1561  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1562 
1563  /* response ack against partial request */
1564  tcph.th_ack = htonl(3);
1565  tcph.th_seq = htonl(1);
1566  tcph.th_flags = TH_ACK;
1568  p->payload_len = 0;
1569  p->payload = NULL;
1570  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1577  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1578  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1579  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1580  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1581  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1582 
1583  /* complete partial request */
1584  uint8_t request2[] = {
1585  0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1586  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1587  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1588  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1589  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1590  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1591  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1592  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1593  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1594  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1595  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1596  tcph.th_ack = htonl(1);
1597  tcph.th_seq = htonl(3);
1598  tcph.th_flags = TH_PUSH | TH_ACK;
1600  p->payload_len = sizeof(request2);
1601  p->payload = request2;
1602  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1609  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1610  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1611  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1612  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1613  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1614 
1615  /* response - request ack */
1616  uint8_t response[] = {
1617  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
1618  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1619  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1620  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1621  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1622  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1623  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1624  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1625  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1626  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1627  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1628  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1629  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1630  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1631  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1632  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1633  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1634  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1635  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1636  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1637  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1638  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1639  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1640  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1641  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1642  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1643  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1644  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1645  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1646  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1647  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1648  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1649  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1650  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1651  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1652  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1653  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1654  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1655  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1656  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1657  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1658  tcph.th_ack = htonl(88);
1659  tcph.th_seq = htonl(1);
1660  tcph.th_flags = TH_PUSH | TH_ACK;
1662  p->payload_len = sizeof(response);
1663  p->payload = response;
1664  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1671  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1672  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1673  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1674  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1676 
1677  /* response ack */
1678  tcph.th_ack = htonl(328);
1679  tcph.th_seq = htonl(88);
1680  tcph.th_flags = TH_ACK;
1682  p->payload_len = 0;
1683  p->payload = NULL;
1684  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1691  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1692  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1693  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1694  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1696 
1697  TEST_END;
1698  PASS;
1699 }
1700 
1701 /**
1702  * \test GET -> RUBBISH(PM AND PP DONE IN ONE GO)
1703  */
1704 static int AppLayerTest03(void)
1705 {
1706  TEST_START;
1707 
1708  /* request */
1709  uint8_t request[] = {
1710  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1711  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1712  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1713  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1714  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1715  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1716  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1717  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1718  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1719  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1720  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1721  tcph.th_ack = htonl(1);
1722  tcph.th_seq = htonl(1);
1723  tcph.th_flags = TH_PUSH | TH_ACK;
1725  p->payload_len = sizeof(request);
1726  p->payload = request;
1727  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1734  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1735  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1736  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1737  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1738  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1739 
1740  /* rubbish response */
1741  uint8_t response[] = {
1742  0x58, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
1743  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1744  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1745  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1746  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1747  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1748  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1749  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1750  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1751  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1752  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1753  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1754  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1755  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1756  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1757  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1758  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1759  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1760  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1761  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1762  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1763  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1764  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1765  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1766  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1767  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1768  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1769  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1770  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1771  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1772  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1773  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1774  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1775  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1776  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1777  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1778  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1779  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1780  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1781  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1782  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1783  tcph.th_ack = htonl(88);
1784  tcph.th_seq = htonl(1);
1785  tcph.th_flags = TH_PUSH | TH_ACK;
1787  p->payload_len = sizeof(response);
1788  p->payload = response;
1789  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1796  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1797  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1798  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1799  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1801 
1802  /* response ack */
1803  tcph.th_ack = htonl(328);
1804  tcph.th_seq = htonl(88);
1805  tcph.th_flags = TH_ACK;
1807  p->payload_len = 0;
1808  p->payload = NULL;
1809  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1816  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1817  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1818  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1819  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1821 
1822  TEST_END;
1823  PASS;
1824 }
1825 
1826 /**
1827  * \test GE -> RUBBISH(TC - PM AND PP NOT DONE) -> RUBBISH(TC - PM AND PP DONE).
1828  */
1829 static int AppLayerTest04(void)
1830 {
1831  TEST_START;
1832 
1833  /* request */
1834  uint8_t request[] = {
1835  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1836  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1837  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1838  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1839  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1840  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1841  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1842  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1843  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1844  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1845  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1846  PrintRawDataFp(stdout, request, sizeof(request));
1847  tcph.th_ack = htonl(1);
1848  tcph.th_seq = htonl(1);
1849  tcph.th_flags = TH_PUSH | TH_ACK;
1851  p->payload_len = sizeof(request);
1852  p->payload = request;
1853  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1860  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1861  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1862  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1863  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1864  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER); // TOSERVER data now seen
1865 
1866  /* partial response */
1867  uint8_t response1[] = { 0x58, 0x54, 0x54, 0x50, };
1868  PrintRawDataFp(stdout, response1, sizeof(response1));
1869  tcph.th_ack = htonl(88);
1870  tcph.th_seq = htonl(1);
1871  tcph.th_flags = TH_PUSH | TH_ACK;
1873  p->payload_len = sizeof(response1);
1874  p->payload = response1;
1875  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1878  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
1879  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
1882  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1883  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1884  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1885  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1886  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
1887 
1888  /* partial response ack */
1889  tcph.th_ack = htonl(5);
1890  tcph.th_seq = htonl(88);
1891  tcph.th_flags = TH_ACK;
1893  p->payload_len = 0;
1894  p->payload = NULL;
1895  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1898  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
1899  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
1902  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1903  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1904  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1905  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
1906  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
1907 
1908  /* remaining response */
1909  uint8_t response2[] = {
1910  0x2f, 0x31, 0x2e, 0x31,
1911  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1912  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1913  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1914  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1915  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1916  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1917  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1918  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1919  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1920  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1921  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1922  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1923  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1924  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1925  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1926  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1927  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1928  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1929  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1930  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1931  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1932  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1933  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1934  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1935  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1936  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1937  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1938  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1939  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1940  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1941  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1942  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1943  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1944  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1945  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1946  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1947  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1948  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1949  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1950  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1951  PrintRawDataFp(stdout, response2, sizeof(response2));
1952  tcph.th_ack = htonl(88);
1953  tcph.th_seq = htonl(5);
1954  tcph.th_flags = TH_PUSH | TH_ACK;
1956  p->payload_len = sizeof(response2);
1957  p->payload = response2;
1958  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1961  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
1962  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
1965  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1966  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1967  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1968  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
1969  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
1970 
1971  /* response ack */
1972  tcph.th_ack = htonl(328);
1973  tcph.th_seq = htonl(88);
1974  tcph.th_flags = TH_ACK;
1976  p->payload_len = 0;
1977  p->payload = NULL;
1978  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1979  FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); // toclient complete (failed)
1981  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
1982  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
1983  FAIL_IF(f.alproto_tc != ALPROTO_FAILED); // tc failed
1985  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1986  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1987  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1988  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
1989  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
1990 
1991  TEST_END;
1992  PASS;
1993 }
1994 
1995 /**
1996  * \test RUBBISH -> HTTP/1.1
1997  */
1998 static int AppLayerTest05(void)
1999 {
2000  TEST_START;
2001 
2002  /* full request */
2003  uint8_t request[] = {
2004  0x48, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2005  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
2006  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
2007  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
2008  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
2009  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
2010  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
2011  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
2012  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2013  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
2014  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2015  PrintRawDataFp(stdout, request, sizeof(request));
2016  tcph.th_ack = htonl(1);
2017  tcph.th_seq = htonl(1);
2018  tcph.th_flags = TH_PUSH | TH_ACK;
2020  p->payload_len = sizeof(request);
2021  p->payload = request;
2022  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2029  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2030  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2031  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2032  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2033  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2034 
2035  /* full response - request ack */
2036  uint8_t response[] = {
2037  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2038  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2039  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2040  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2041  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2042  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2043  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2044  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2045  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2046  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2047  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2048  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2049  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2050  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2051  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2052  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2053  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2054  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2055  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2056  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2057  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2058  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2059  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2060  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2061  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2062  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2063  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2064  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2065  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2066  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2067  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2068  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2069  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2070  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2071  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2072  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2073  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2074  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2075  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2076  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2077  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2078  PrintRawDataFp(stdout, response, sizeof(response));
2079  tcph.th_ack = htonl(88);
2080  tcph.th_seq = htonl(1);
2081  tcph.th_flags = TH_PUSH | TH_ACK;
2083  p->payload_len = sizeof(response);
2084  p->payload = response;
2085  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2092  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2093  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2094  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2095  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2096  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2097 
2098  /* response ack */
2099  tcph.th_ack = htonl(328);
2100  tcph.th_seq = htonl(88);
2101  tcph.th_flags = TH_ACK;
2103  p->payload_len = 0;
2104  p->payload = NULL;
2105  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2112  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2113  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2114  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2115  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2117 
2118  TEST_END;
2119  PASS;
2120 }
2121 
2122 /**
2123  * \test HTTP/1.1 -> GET
2124  */
2125 static int AppLayerTest06(void)
2126 {
2127  TEST_START;
2128 
2129  /* full response - request ack */
2130  uint8_t response[] = {
2131  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2132  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2133  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2134  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2135  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2136  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2137  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2138  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2139  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2140  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2141  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2142  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2143  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2144  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2145  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2146  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2147  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2148  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2149  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2150  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2151  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2152  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2153  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2154  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2155  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2156  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2157  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2158  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2159  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2160  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2161  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2162  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2163  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2164  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2165  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2166  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2167  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2168  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2169  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2170  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2171  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2172  tcph.th_ack = htonl(1);
2173  tcph.th_seq = htonl(1);
2174  tcph.th_flags = TH_PUSH | TH_ACK;
2176  p->payload_len = sizeof(response);
2177  p->payload = response;
2178  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2185  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2186  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2187  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2188  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2189  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOCLIENT);
2190 
2191  /* full request - response ack*/
2192  uint8_t request[] = {
2193  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2194  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
2195  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
2196  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
2197  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
2198  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
2199  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
2200  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
2201  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2202  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
2203  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2204  tcph.th_ack = htonl(328);
2205  tcph.th_seq = htonl(1);
2206  tcph.th_flags = TH_PUSH | TH_ACK;
2208  p->payload_len = sizeof(request);
2209  p->payload = request;
2210  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2217  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2218  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2219  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2220  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2222 
2223  tcph.th_ack = htonl(1 + sizeof(request));
2224  tcph.th_seq = htonl(328);
2225  tcph.th_flags = TH_PUSH | TH_ACK;
2227  p->payload_len = 0;
2228  p->payload = NULL;
2229  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2236  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2237  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2238  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2239  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2241 
2242  TEST_END;
2243  PASS;
2244 }
2245 
2246 /**
2247  * \test GET -> DCERPC
2248  */
2249 static int AppLayerTest07(void)
2250 {
2251  TEST_START;
2252 
2253  /* full request */
2254  uint8_t request[] = {
2255  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2256  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
2257  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
2258  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
2259  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
2260  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
2261  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
2262  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
2263  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2264  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
2265  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2266  tcph.th_ack = htonl(1);
2267  tcph.th_seq = htonl(1);
2268  tcph.th_flags = TH_PUSH | TH_ACK;
2270  p->payload_len = sizeof(request);
2271  p->payload = request;
2272  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2279  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2280  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2281  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2282  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2283  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2284 
2285  /* full response - request ack */
2286  uint8_t response[] = { 0x05, 0x00, 0x4d, 0x42, 0x00, 0x01, 0x2e, 0x31, 0x20, 0x32, 0x30, 0x30,
2287  0x20, 0x4f, 0x4b, 0x0d, 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, 0x72, 0x69, 0x2c,
2288  0x20, 0x32, 0x33, 0x20, 0x53, 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20, 0x30, 0x36,
2289  0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, 0x72,
2290  0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2291  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69, 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f,
2292  0x32, 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65,
2293  0x64, 0x3a, 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34, 0x20, 0x4e, 0x6f, 0x76, 0x20,
2294  0x32, 0x30, 0x31, 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a, 0x34, 0x36, 0x20, 0x47,
2295  0x4d, 0x54, 0x0d, 0x0a, 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61, 0x62, 0x38, 0x39,
2296  0x36, 0x35, 0x2d, 0x32, 0x63, 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61, 0x37, 0x66,
2297  0x37, 0x66, 0x38, 0x30, 0x22, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x52,
2298  0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2299  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20,
2300  0x34, 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a,
2301  0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
2302  0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d,
2303  0x6c, 0x0d, 0x0a, 0x58, 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64,
2304  0x20, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d, 0x0a, 0x0d,
2305  0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x68,
2306  0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2307  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2308  tcph.th_ack = htonl(88);
2309  tcph.th_seq = htonl(1);
2310  tcph.th_flags = TH_PUSH | TH_ACK;
2312  p->payload_len = sizeof(response);
2313  p->payload = response;
2314  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2321  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2322  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2323  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2324  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2326 
2327  /* response ack */
2328  tcph.th_ack = htonl(328);
2329  tcph.th_seq = htonl(88);
2330  tcph.th_flags = TH_ACK;
2332  p->payload_len = 0;
2333  p->payload = NULL;
2334  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2341  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2342  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2343  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2344  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2346 
2347  TEST_END;
2348  PASS;
2349 }
2350 
2351 /**
2352  * \test SMB -> HTTP/1.1
2353  */
2354 static int AppLayerTest08(void)
2355 {
2356  TEST_START;
2357 
2358  /* full request */
2359  uint8_t request[] = { 0x05, 0x00, 0x54, 0x20, 0x00, 0x01, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68,
2360  0x74, 0x6d, 0x6c, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x0d, 0x0a, 0x48,
2361  0x6f, 0x73, 0x74, 0x3a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x0d,
2362  0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41, 0x70,
2363  0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2364  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2365  tcph.th_ack = htonl(1);
2366  tcph.th_seq = htonl(1);
2367  tcph.th_flags = TH_PUSH | TH_ACK;
2369  p->payload_len = sizeof(request);
2370  p->payload = request;
2371  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2378  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2379  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2380  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2381  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2382  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2383 
2384  /* full response - request ack */
2385  uint8_t response[] = {
2386  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2387  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2388  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2389  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2390  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2391  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2392  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2393  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2394  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2395  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2396  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2397  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2398  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2399  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2400  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2401  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2402  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2403  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2404  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2405  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2406  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2407  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2408  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2409  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2410  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2411  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2412  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2413  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2414  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2415  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2416  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2417  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2418  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2419  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2420  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2421  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2422  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2423  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2424  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2425  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2426  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2427  tcph.th_ack = htonl(88);
2428  tcph.th_seq = htonl(1);
2429  tcph.th_flags = TH_PUSH | TH_ACK;
2431  p->payload_len = sizeof(response);
2432  p->payload = response;
2433  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2440  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2441  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2442  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2443  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2445 
2446  /* response ack */
2447  tcph.th_ack = htonl(328);
2448  tcph.th_seq = htonl(88);
2449  tcph.th_flags = TH_ACK;
2451  p->payload_len = 0;
2452  p->payload = NULL;
2453  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2460  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2461  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2462  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2463  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2465 
2466  TEST_END;
2467  PASS;
2468 }
2469 
2470 /**
2471  * \test RUBBISH(TC - PM and PP NOT DONE) ->
2472  * RUBBISH(TC - PM and PP DONE) ->
2473  * RUBBISH(TS - PM and PP DONE)
2474  */
2475 static int AppLayerTest09(void)
2476 {
2477  TEST_START;
2478 
2479  /* full request */
2480  uint8_t request1[] = {
2481  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64 };
2482  tcph.th_ack = htonl(1);
2483  tcph.th_seq = htonl(1);
2484  tcph.th_flags = TH_PUSH | TH_ACK;
2486  p->payload_len = sizeof(request1);
2487  p->payload = request1;
2488  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2495  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2496  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2497  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2498  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2499  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2500 
2501  /* response - request ack */
2502  tcph.th_ack = htonl(9);
2503  tcph.th_seq = htonl(1);
2504  tcph.th_flags = TH_PUSH | TH_ACK;
2506  p->payload_len = 0;
2507  p->payload = NULL;
2508  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2515  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2516  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2517  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2518  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2519  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2520 
2521  /* full request */
2522  uint8_t request2[] = {
2523  0x44, 0x44, 0x45, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff };
2524  tcph.th_ack = htonl(1);
2525  tcph.th_seq = htonl(9);
2526  tcph.th_flags = TH_PUSH | TH_ACK;
2528  p->payload_len = sizeof(request2);
2529  p->payload = request2;
2530  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2537  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2538  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2539  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2540  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2541  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2542 
2543  /* full response - request ack */
2544  uint8_t response[] = {
2545  0x55, 0x74, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2546  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2547  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2548  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2549  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2550  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2551  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2552  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2553  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2554  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2555  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2556  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2557  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2558  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2559  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2560  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2561  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2562  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2563  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2564  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2565  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2566  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2567  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2568  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2569  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2570  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2571  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2572  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2573  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2574  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2575  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2576  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2577  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2578  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2579  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2580  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2581  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2582  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2583  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2584  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2585  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2586  tcph.th_ack = htonl(18);
2587  tcph.th_seq = htonl(1);
2588  tcph.th_flags = TH_PUSH | TH_ACK;
2590  p->payload_len = sizeof(response);
2591  p->payload = response;
2592  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2599  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2600  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2601  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2602  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2603  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2604 
2605  /* response ack */
2606  tcph.th_ack = htonl(328);
2607  tcph.th_seq = htonl(18);
2608  tcph.th_flags = TH_ACK;
2610  p->payload_len = 0;
2611  p->payload = NULL;
2612  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2619  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2620  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2621  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2622  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2624 
2625  TEST_END;
2626  PASS;
2627 }
2628 
2629 /**
2630  * \test RUBBISH(TC - PM and PP DONE) ->
2631  * RUBBISH(TS - PM and PP DONE)
2632  */
2633 static int AppLayerTest10(void)
2634 {
2635  TEST_START;
2636 
2637  /* full request */
2638  uint8_t request1[] = {
2639  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2640  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff };
2641  tcph.th_ack = htonl(1);
2642  tcph.th_seq = htonl(1);
2643  tcph.th_flags = TH_PUSH | TH_ACK;
2645  p->payload_len = sizeof(request1);
2646  p->payload = request1;
2647  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2654  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2655  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2656  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2657  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2658  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2659 
2660  /* response - request ack */
2661  tcph.th_ack = htonl(18);
2662  tcph.th_seq = htonl(1);
2663  tcph.th_flags = TH_PUSH | TH_ACK;
2665  p->payload_len = 0;
2666  p->payload = NULL;
2667  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2674  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2675  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2676  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2677  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2678  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2679 
2680  /* full response - request ack */
2681  uint8_t response[] = {
2682  0x55, 0x74, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2683  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2684  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2685  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2686  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2687  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2688  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2689  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2690  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2691  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2692  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2693  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2694  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2695  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2696  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2697  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2698  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2699  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2700  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2701  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2702  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2703  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2704  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2705  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2706  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2707  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2708  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2709  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2710  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2711  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2712  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2713  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2714  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2715  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2716  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2717  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2718  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2719  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2720  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2721  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2722  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2723  tcph.th_ack = htonl(18);
2724  tcph.th_seq = htonl(1);
2725  tcph.th_flags = TH_PUSH | TH_ACK;
2727  p->payload_len = sizeof(response);
2728  p->payload = response;
2729  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2736  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2737  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2738  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2739  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2740  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2741 
2742  /* response ack */
2743  tcph.th_ack = htonl(328);
2744  tcph.th_seq = htonl(18);
2745  tcph.th_flags = TH_ACK;
2747  p->payload_len = 0;
2748  p->payload = NULL;
2749  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2756  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2757  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2758  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2759  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2761 
2762  TEST_END;
2763  PASS;
2764 }
2765 
2766 /**
2767  * \test RUBBISH(TC - PM and PP DONE) ->
2768  * RUBBISH(TS - PM and PP NOT DONE) ->
2769  * RUBBISH(TS - PM and PP DONE)
2770  */
2771 static int AppLayerTest11(void)
2772 {
2773  TEST_START;
2774 
2775  /* full request */
2776  uint8_t request1[] = {
2777  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2778  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff };
2779  tcph.th_ack = htonl(1);
2780  tcph.th_seq = htonl(1);
2781  tcph.th_flags = TH_PUSH | TH_ACK;
2783  p->payload_len = sizeof(request1);
2784  p->payload = request1;
2785  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2792  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2793  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2794  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2795  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2796  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2797 
2798  /* response - request ack */
2799  tcph.th_ack = htonl(18);
2800  tcph.th_seq = htonl(1);
2801  tcph.th_flags = TH_PUSH | TH_ACK;
2803  p->payload_len = 0;
2804  p->payload = NULL;
2805  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2812  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2813  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2814  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2815  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2816  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2817 
2818  /* full response - request ack */
2819  uint8_t response1[] = {
2820  0x55, 0x74, 0x54, 0x50, };
2821  tcph.th_ack = htonl(18);
2822  tcph.th_seq = htonl(1);
2823  tcph.th_flags = TH_PUSH | TH_ACK;
2825  p->payload_len = sizeof(response1);
2826  p->payload = response1;
2827  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2834  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2835  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2836  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2837  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2838  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2839 
2840  /* response ack from request */
2841  tcph.th_ack = htonl(5);
2842  tcph.th_seq = htonl(18);
2843  tcph.th_flags = TH_ACK;
2845  p->payload_len = 0;
2846  p->payload = NULL;
2847  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2854  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2855  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2856  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2857  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2858  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2859 
2860  uint8_t response2[] = {
2861  0x2f, 0x31, 0x2e, 0x31,
2862  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2863  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2864  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2865  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2866  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2867  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2868  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2869  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2870  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2871  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2872  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2873  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2874  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2875  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2876  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2877  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2878  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2879  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2880  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2881  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2882  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2883  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2884  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2885  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2886  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2887  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2888  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2889  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2890  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2891  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2892  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2893  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2894  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2895  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2896  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2897  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2898  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2899  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2900  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2901  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2902  tcph.th_ack = htonl(18);
2903  tcph.th_seq = htonl(5);
2904  tcph.th_flags = TH_PUSH | TH_ACK;
2906  p->payload_len = sizeof(response2);
2907  p->payload = response2;
2908  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2915  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2916  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2917  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2918  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2919  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2920 
2921  /* response ack from request */
2922  tcph.th_ack = htonl(328);
2923  tcph.th_seq = htonl(18);
2924  tcph.th_flags = TH_ACK;
2926  p->payload_len = 0;
2927  p->payload = NULL;
2928  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2935  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2936  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2937  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2938  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2940 
2941  TEST_END;
2942  PASS;
2943 }
2944 
2946 {
2947  SCEnter();
2948 
2949  UtRegisterTest("AppLayerTest01", AppLayerTest01);
2950  UtRegisterTest("AppLayerTest02", AppLayerTest02);
2951  UtRegisterTest("AppLayerTest03", AppLayerTest03);
2952  UtRegisterTest("AppLayerTest04", AppLayerTest04);
2953  UtRegisterTest("AppLayerTest05", AppLayerTest05);
2954  UtRegisterTest("AppLayerTest06", AppLayerTest06);
2955  UtRegisterTest("AppLayerTest07", AppLayerTest07);
2956  UtRegisterTest("AppLayerTest08", AppLayerTest08);
2957  UtRegisterTest("AppLayerTest09", AppLayerTest09);
2958  UtRegisterTest("AppLayerTest10", AppLayerTest10);
2959  UtRegisterTest("AppLayerTest11", AppLayerTest11);
2960 
2961  SCReturn;
2962 }
2963 
2964 #endif /* UNITTESTS */
AppLayerCounters_::alloc_error_id
uint16_t alloc_error_id
Definition: app-layer.c:93
APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER
#define APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER
Definition: app-layer.h:40
AppLayerCounters_::counter_id
uint16_t counter_id
Definition: app-layer.c:88
FLOW_RESET_PP_DONE
#define FLOW_RESET_PP_DONE(f, dir)
Definition: flow.h:291
UPDATE_DIR_PACKET
@ UPDATE_DIR_PACKET
Definition: stream-tcp-reassemble.h:56
FlowUnsetChangeProtoFlag
void FlowUnsetChangeProtoFlag(Flow *f)
Unset flag to indicate to change proto for the flow.
Definition: flow.c:193
Packet_::proto
uint8_t proto
Definition: decode.h:501
AppLayerParserDeSetup
int AppLayerParserDeSetup(void)
Definition: app-layer-parser.c:270
TcpStream_
Definition: stream-tcp-private.h:106
APPLAYER_UNEXPECTED_PROTOCOL
@ APPLAYER_UNEXPECTED_PROTOCOL
Definition: app-layer-events.h:53
ExceptionPolicyApply
void ExceptionPolicyApply(Packet *p, enum ExceptionPolicy policy, enum PacketDropReason drop_reason)
Definition: util-exception-policy.c:69
AppLayerCounters_::gap_error_id
uint16_t gap_error_id
Definition: app-layer.c:90
AppLayerCounters_
Definition: app-layer.c:87
ippair.h
FlowCleanupAppLayer
void FlowCleanupAppLayer(Flow *f)
Definition: flow.c:136
AppLayerProtoDetectSetup
int AppLayerProtoDetectSetup(void)
The first function to be called. This initializes a global protocol detection context.
Definition: app-layer-detect-proto.c:1699
ExpectationGetCounter
uint64_t ExpectationGetCounter(void)
Definition: app-layer-expectation.c:140
AppLayerCounterNames_::eps_name
char eps_name[EXCEPTION_POLICY_MAX][MAX_COUNTER_SIZE]
Definition: app-layer.c:84
StatsIncr
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:166
AppLayerCounters_::counter_tx_id
uint16_t counter_tx_id
Definition: app-layer.c:89
AppLayerCounters
struct AppLayerCounters_ AppLayerCounters
stream-tcp-inline.h
ALPROTO_DCERPC
@ ALPROTO_DCERPC
Definition: app-layer-protos.h:38
flow-util.h
applayer_counters
AppLayerCounters applayer_counters[FLOW_PROTO_APPLAYER_MAX][ALPROTO_MAX]
Definition: app-layer.c:100
stream-tcp.h
StreamTcpInlineMode
bool StreamTcpInlineMode(void)
See if stream engine is operating in inline mode.
Definition: stream-tcp.c:7055
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
ALPROTO_TLS
@ ALPROTO_TLS
Definition: app-layer-protos.h:33
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
Packet_::pcap_cnt
uint64_t pcap_cnt
Definition: decode.h:601
AppLayerCounterNames_::parser_error
char parser_error[MAX_COUNTER_SIZE]
Definition: app-layer.c:81
StatsRegisterGlobalCounter
uint16_t StatsRegisterGlobalCounter(const char *name, uint64_t(*Func)(void))
Registers a counter, which represents a global value.
Definition: counters.c:1019
AppLayerProfilingStoreInternal
void AppLayerProfilingStoreInternal(AppLayerThreadCtx *app_tctx, Packet *p)
Definition: app-layer.c:1101
Flow_::proto
uint8_t proto
Definition: flow.h:382
AppProto
uint16_t AppProto
Definition: app-layer-protos.h:84
Packet_::payload
uint8_t * payload
Definition: decode.h:580
TcpReassemblyThreadCtx_::app_tctx
void * app_tctx
Definition: stream-tcp-reassemble.h:62
Packet_::flags
uint32_t flags
Definition: decode.h:516
AppLayerThreadCtx_::proto_detect_ticks_spent
uint64_t proto_detect_ticks_spent
Definition: app-layer.c:70
PACKET_PROFILING_APP_PD_END
#define PACKET_PROFILING_APP_PD_END(dp)
Definition: util-profiling.h:186
TcpStreamCnf_::reassembly_depth
uint32_t reassembly_depth
Definition: stream-tcp.h:65
AppLayerThreadCtx_::alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: app-layer.c:61
flow-private.h
Flow_
Flow data structure.
Definition: flow.h:360
AppLayerIncGapErrorCounter
void AppLayerIncGapErrorCounter(ThreadVars *tv, Flow *f)
Definition: app-layer.c:161
AppLayerCounters_::internal_error_id
uint16_t internal_error_id
Definition: app-layer.c:92
Flow_::protomap
uint8_t protomap
Definition: flow.h:454
AppProtoToString
const char * AppProtoToString(AppProto alproto)
Maps the ALPROTO_*, to its string equivalent.
Definition: app-layer-protos.c:78
AppLayerThreadCtx_::ticks_spent
uint64_t ticks_spent
Definition: app-layer.c:66
ExceptionPolicyStatsSetts_
Definition: util-exception-policy-types.h:48
AppLayerParserGetFirstDataDir
uint8_t AppLayerParserGetFirstDataDir(uint8_t ipproto, AppProto alproto)
Definition: app-layer-parser.c:1125
g_stats_eps_per_app_proto_errors
bool g_stats_eps_per_app_proto_errors
Definition: suricata.c:214
StreamTcpReassembleAppLayer
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.
Definition: stream-tcp-reassemble.c:1349
StreamTcpResetStreamFlagAppProtoDetectionCompleted
#define StreamTcpResetStreamFlagAppProtoDetectionCompleted(stream)
Definition: stream-tcp-private.h:303
AppLayerRegisterThreadCounters
void AppLayerRegisterThreadCounters(ThreadVars *tv)
Registers per flow counters for all protocols.
Definition: app-layer.c:1242
Flow_::alproto_orig
AppProto alproto_orig
Definition: flow.h:465
AppLayerProtoDetectSupportedIpprotos
void AppLayerProtoDetectSupportedIpprotos(AppProto alproto, uint8_t *ipprotos)
Definition: app-layer-detect-proto.c:2036
FTPMemuseGlobalCounter
uint64_t FTPMemuseGlobalCounter(void)
Definition: app-layer-ftp.c:165
AppLayerProfilingResetInternal
void AppLayerProfilingResetInternal(AppLayerThreadCtx *app_tctx)
Definition: app-layer.c:1096
AppLayerCounterNames_
Definition: app-layer.c:77
AppLayerParserStateProtoCleanup
void AppLayerParserStateProtoCleanup(uint8_t protomap, AppProto alproto, void *alstate, AppLayerParserState *pstate)
Definition: app-layer-parser.c:1594
AppLayerParserThreadCtxFree
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
Definition: app-layer-parser.c:301
AppLayerHandleTCPData
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:707
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:232
TCP_ESTABLISHED
@ TCP_ESTABLISHED
Definition: stream-tcp-private.h:155
MIN
#define MIN(x, y)
Definition: suricata-common.h:391
StreamTcpUpdateAppLayerProgress
void StreamTcpUpdateAppLayerProgress(TcpSession *ssn, char direction, const uint32_t progress)
update reassembly progress
Definition: stream-tcp.c:6626
app_layer_error_eps_stats
ExceptionPolicyStatsSetts app_layer_error_eps_stats
Definition: app-layer.c:106
stream-tcp-reassemble.h
AppLayerThreadCtx_::proto_detect_ticks_end
uint64_t proto_detect_ticks_end
Definition: app-layer.c:69
TcpStream_::flags
uint16_t flags
Definition: stream-tcp-private.h:107
AppLayerUnittestsRegister
void AppLayerUnittestsRegister(void)
Definition: app-layer.c:2945
APPLAYER_PROTO_DETECTION_SKIPPED
@ APPLAYER_PROTO_DETECTION_SKIPPED
Definition: app-layer-events.h:51
HTPMemuseGlobalCounter
uint64_t HTPMemuseGlobalCounter(void)
Definition: app-layer-htp-mem.c:81
AppLayerListSupportedProtocols
void AppLayerListSupportedProtocols(void)
Definition: app-layer.c:1011
AppLayerSetupCounters
void AppLayerSetupCounters(void)
Definition: app-layer.c:1142
app-layer-ftp.h
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:510
AppLayerThreadCtx_::alproto
AppProto alproto
Definition: app-layer.c:67
stream_config
TcpStreamCnf stream_config
Definition: stream-tcp.c:219
MAX
#define MAX(x, y)
Definition: suricata-common.h:395
ALPROTO_MAX
@ ALPROTO_MAX
Definition: app-layer-protos.h:79
Flow_::protoctx
void * protoctx
Definition: flow.h:450
AppLayerCounterNames_::tx_name
char tx_name[MAX_COUNTER_SIZE]
Definition: app-layer.c:79
AppLayerIncAllocErrorCounter
void AppLayerIncAllocErrorCounter(ThreadVars *tv, Flow *f)
Definition: app-layer.c:169
EXCEPTION_POLICY_NOT_SET
@ EXCEPTION_POLICY_NOT_SET
Definition: util-exception-policy-types.h:26
Packet_::payload_len
uint16_t payload_len
Definition: decode.h:581
Packet_::app_layer_events
AppLayerDecoderEvents * app_layer_events
Definition: decode.h:607
util-unittest.h
AppLayerGetProtoByName
AppProto AppLayerGetProtoByName(char *alproto_name)
Given a protocol string, returns the corresponding internal protocol id.
Definition: app-layer.c:997
PACKET_PROFILING_APP_PD_START
#define PACKET_PROFILING_APP_PD_START(dp)
Definition: util-profiling.h:181
AppLayerCounters_::parser_error_id
uint16_t parser_error_id
Definition: app-layer.c:91
AppLayerDeSetup
int AppLayerDeSetup(void)
De initializes the app layer.
Definition: app-layer.c:1046
PKT_PROTO_DETECT_TS_DONE
#define PKT_PROTO_DETECT_TS_DONE
Definition: decode.h:1306
MAX_COUNTER_SIZE
#define MAX_COUNTER_SIZE
Definition: app-layer.c:76
STREAMTCP_FLAG_MIDSTREAM
#define STREAMTCP_FLAG_MIDSTREAM
Definition: stream-tcp-private.h:170
TcpSession_::flags
uint32_t flags
Definition: stream-tcp-private.h:292
FLOW_IS_PM_DONE
#define FLOW_IS_PM_DONE(f, dir)
Definition: flow.h:282
APPLAYER_NO_TLS_AFTER_STARTTLS
@ APPLAYER_NO_TLS_AFTER_STARTTLS
Definition: app-layer-events.h:52
Flow_::alparser
AppLayerParserState * alparser
Definition: flow.h:484
EXCEPTION_POLICY_MAX
#define EXCEPTION_POLICY_MAX
Definition: util-exception-policy-types.h:36
AppLayerParserRegisterProtocolParsers
void AppLayerParserRegisterProtocolParsers(void)
Definition: app-layer-parser.c:1696
AppLayerThreadCtx_::proto_detect_ticks_start
uint64_t proto_detect_ticks_start
Definition: app-layer.c:68
AppLayerSetup
int AppLayerSetup(void)
Setup the app layer.
Definition: app-layer.c:1031
app-layer-expectation.h
app-layer-detect-proto.h
AppLayerProtoDetectThreadCtx_
The app layer protocol detection thread context.
Definition: app-layer-detect-proto.c:174
util-debug.h
AppLayerParserState_
Definition: app-layer-parser.c:130
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
ExceptionPolicyCounters_
Definition: util-exception-policy-types.h:43
APPLAYER_MISMATCH_PROTOCOL_BOTH_DIRECTIONS
@ APPLAYER_MISMATCH_PROTOCOL_BOTH_DIRECTIONS
Definition: app-layer-events.h:48
FLOW_IS_PP_DONE
#define FLOW_IS_PP_DONE(f, dir)
Definition: flow.h:283
AppLayerRegisterGlobalCounters
void AppLayerRegisterGlobalCounters(void)
HACK to work around our broken unix manager (re)init loop.
Definition: app-layer.c:1109
PKT_DROP_REASON_APPLAYER_ERROR
@ PKT_DROP_REASON_APPLAYER_ERROR
Definition: decode.h:370
AppLayerThreadCtx_::ticks_end
uint64_t ticks_end
Definition: app-layer.c:65
PacketSwap
void PacketSwap(Packet *p)
switch direction of a packet
Definition: decode.c:551
util-exception-policy.h
AppLayerThreadCtx_
This is for the app layer in general and it contains per thread context relevant to both the alpd and...
Definition: app-layer.c:57
ExceptionPolicyCounters_::eps_id
uint16_t eps_id[EXCEPTION_POLICY_MAX]
Definition: util-exception-policy-types.h:45
util-print.h
SCEnter
#define SCEnter(...)
Definition: util-debug.h:271
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
pkt-var.h
StreamTcpPacket
int StreamTcpPacket(ThreadVars *tv, Packet *p, StreamTcpThread *stt, PacketQueueNoLock *pq)
Definition: stream-tcp.c:5492
AppLayerProtoDetectReset
void AppLayerProtoDetectReset(Flow *f)
Reset proto detect for flow.
Definition: app-layer-detect-proto.c:1863
TcpSession_::state
uint8_t state
Definition: stream-tcp-private.h:285
TEST_START
#define TEST_START
Definition: app-layer.c:1320
ExceptionPolicyStatsSetts_::valid_settings_ids
bool valid_settings_ids[EXCEPTION_POLICY_MAX]
Definition: util-exception-policy-types.h:50
TH_ACK
#define TH_ACK
Definition: decode-tcp.h:38
PACKET_PROFILING_APP_STORE
#define PACKET_PROFILING_APP_STORE(dp, p)
Definition: util-profiling.h:206
PrintRawDataFp
void PrintRawDataFp(FILE *fp, const uint8_t *buf, uint32_t buflen)
Definition: util-print.c:112
app-layer-parser.h
FLOW_PROTO_DETECT_TC_DONE
#define FLOW_PROTO_DETECT_TC_DONE
Definition: flow.h:104
AppLayerCounterNames
struct AppLayerCounterNames_ AppLayerCounterNames
util-profiling.h
AppLayerParserSetup
int AppLayerParserSetup(void)
Definition: app-layer-parser.c:249
SCReturn
#define SCReturn
Definition: util-debug.h:273
FLOW_RESET_PM_DONE
#define FLOW_RESET_PM_DONE(f, dir)
Definition: flow.h:290
stream.h
FlowGetProtoMapping
uint8_t FlowGetProtoMapping(uint8_t proto)
Function to map the protocol to the defined FLOW_PROTO_* enumeration.
Definition: flow-util.c:97
StreamTcpIsSetStreamFlagAppProtoDetectionCompleted
#define StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(stream)
Definition: stream-tcp-private.h:301
Packet_
Definition: decode.h:479
stream-tcp-private.h
FLOW_PROTO_APPLAYER_MAX
#define FLOW_PROTO_APPLAYER_MAX
Definition: flow-private.h:77
AppLayerHandleUdp
int AppLayerHandleUdp(ThreadVars *tv, AppLayerThreadCtx *tctx, Packet *p, Flow *f)
Handle a app layer UDP message.
Definition: app-layer.c:873
DEBUG_ASSERT_FLOW_LOCKED
#define DEBUG_ASSERT_FLOW_LOCKED(f)
Definition: util-validate.h:99
StreamTcpSetStreamFlagAppProtoDetectionCompleted
#define StreamTcpSetStreamFlagAppProtoDetectionCompleted(stream)
Definition: stream-tcp-private.h:299
PACKET_PROFILING_APP_END
#define PACKET_PROFILING_APP_END(dp)
Definition: util-profiling.h:173
TcpStream_::window
uint32_t window
Definition: stream-tcp-private.h:117
SCReturnPtr
#define SCReturnPtr(x, type)
Definition: util-debug.h:287
AppLayerThreadCtx_::alpd_tctx
AppLayerProtoDetectThreadCtx * alpd_tctx
Definition: app-layer.c:59
StreamDataAvailableForProtoDetect
uint32_t StreamDataAvailableForProtoDetect(TcpStream *stream)
Definition: stream-tcp-reassemble.c:712
AppLayerGetCtxThread
AppLayerThreadCtx * AppLayerGetCtxThread(void)
Creates a new app layer thread context.
Definition: app-layer.c:1058
AppLayerThreadCtx_::ticks_start
uint64_t ticks_start
Definition: app-layer.c:64
AppLayerIncParserErrorCounter
void AppLayerIncParserErrorCounter(ThreadVars *tv, Flow *f)
Definition: app-layer.c:177
FTPMemcapGlobalCounter
uint64_t FTPMemcapGlobalCounter(void)
Definition: app-layer-ftp.c:171
FLOW_PKT_TOCLIENT
#define FLOW_PKT_TOCLIENT
Definition: flow.h:233
Flow_::alproto_expect
AppProto alproto_expect
Definition: flow.h:468
decode-events.h
UPDATE_DIR_OPPOSING
@ UPDATE_DIR_OPPOSING
Definition: stream-tcp-reassemble.h:57
AppLayerParserThreadCtxAlloc
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
Definition: app-layer-parser.c:280
TH_PUSH
#define TH_PUSH
Definition: decode-tcp.h:37
app-layer-frames.h
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
flags
uint8_t flags
Definition: decode-gre.h:0
AppLayerParserParse
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, const uint8_t *input, uint32_t input_len)
Definition: app-layer-parser.c:1267
StreamTcpDisableAppLayer
void StreamTcpDisableAppLayer(Flow *f)
Definition: stream-tcp-reassemble.c:446
suricata-common.h
FLOW_RESET_PE_DONE
#define FLOW_RESET_PE_DONE(f, dir)
Definition: flow.h:292
AppLayerProtoDetectDeSetup
int AppLayerProtoDetectDeSetup(void)
Cleans up the app layer protocol detection phase.
Definition: app-layer-detect-proto.c:1729
ALPROTO_HTTP1
@ ALPROTO_HTTP1
Definition: app-layer-protos.h:30
AppLayerDecoderEventsSetEventRaw
void AppLayerDecoderEventsSetEventRaw(AppLayerDecoderEvents **sevents, uint8_t event)
Set an app layer decoder event.
Definition: app-layer-events.c:91
Packet_::app_update_direction
uint8_t app_update_direction
Definition: decode.h:513
FLOW_PROTO_DETECT_TS_DONE
#define FLOW_PROTO_DETECT_TS_DONE
Definition: flow.h:103
AppLayerIncInternalErrorCounter
void AppLayerIncInternalErrorCounter(ThreadVars *tv, Flow *f)
Definition: app-layer.c:185
eps_error_summary
ExceptionPolicyCounters eps_error_summary
Definition: app-layer.c:102
APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION
@ APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION
Definition: app-layer-events.h:50
STREAMTCP_FLAG_MIDSTREAM_SYNACK
#define STREAMTCP_FLAG_MIDSTREAM_SYNACK
Definition: stream-tcp-private.h:174
TcpSession_::client
TcpStream client
Definition: stream-tcp-private.h:295
PKT_PROTO_DETECT_TC_DONE
#define PKT_PROTO_DETECT_TC_DONE
Definition: decode.h:1307
AppLayerParserGetStreamDepth
uint32_t AppLayerParserGetStreamDepth(const Flow *f)
Definition: app-layer-parser.c:1555
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
util-validate.h
FlowSwap
void FlowSwap(Flow *f)
swap the flow's direction
Definition: flow.c:254
StatsAddUI64
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
AppLayerProtoDetectSupportedAppProtocols
void AppLayerProtoDetectSupportedAppProtocols(AppProto *alprotos)
Definition: app-layer-detect-proto.c:2098
AppLayerProtoDetectGetProto
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.
Definition: app-layer-detect-proto.c:1396
AppLayerProtoDetectGetCtxThread
AppLayerProtoDetectThreadCtx * AppLayerProtoDetectGetCtxThread(void)
Inits and returns an app layer protocol detection thread context.
Definition: app-layer-detect-proto.c:1957
TcpSession_::server
TcpStream server
Definition: stream-tcp-private.h:294
AppLayerProtoDetectGetProtoByName
AppProto AppLayerProtoDetectGetProtoByName(const char *alproto_name)
Definition: app-layer-detect-proto.c:2056
str
#define str(s)
Definition: suricata-common.h:291
SWAP_FLAGS
#define SWAP_FLAGS(flags, a, b)
Definition: suricata-common.h:417
ExceptionPolicyEnumToString
const char * ExceptionPolicyEnumToString(enum ExceptionPolicy policy, bool is_json)
Definition: util-exception-policy.c:35
SCFree
#define SCFree(p)
Definition: util-mem.h:61
AppLayerCounterNames_::gap_error
char gap_error[MAX_COUNTER_SIZE]
Definition: app-layer.c:80
Flow_::alproto_ts
AppProto alproto_ts
Definition: flow.h:460
ExceptionPolicyStatsSetts_::valid_settings_ips
bool valid_settings_ips[EXCEPTION_POLICY_MAX]
Definition: util-exception-policy-types.h:51
TcpSessionSetReassemblyDepth
void TcpSessionSetReassemblyDepth(TcpSession *ssn, uint32_t size)
Definition: stream-tcp.c:7061
Flow_::alstate
void * alstate
Definition: flow.h:485
AppLayerDestroyCtxThread
void AppLayerDestroyCtxThread(AppLayerThreadCtx *app_tctx)
Destroys the context created by AppLayerGetCtxThread().
Definition: app-layer.c:1079
PACKET_PROFILING_APP_START
#define PACKET_PROFILING_APP_START(dp, id)
Definition: util-profiling.h:167
Flow_::flags
uint32_t flags
Definition: flow.h:430
HTPMemcapGlobalCounter
uint64_t HTPMemcapGlobalCounter(void)
Definition: app-layer-htp-mem.c:87
AppLayerGetProtoName
const char * AppLayerGetProtoName(AppProto alproto)
Given the internal protocol id, returns a string representation of the protocol.
Definition: app-layer.c:1004
g_applayerparser_error_policy
enum ExceptionPolicy g_applayerparser_error_policy
Definition: app-layer-parser.c:150
AppLayerCounters_::eps_error
ExceptionPolicyCounters eps_error
Definition: app-layer.c:94
AppLayerIncTxCounter
void AppLayerIncTxCounter(ThreadVars *tv, Flow *f, uint64_t step)
Definition: app-layer.c:153
stream-tcp-util.h
ALPROTO_UNKNOWN
@ ALPROTO_UNKNOWN
Definition: app-layer-protos.h:29
ALPROTO_FAILED
@ ALPROTO_FAILED
Definition: app-layer-protos.h:74
AppLayerCounterNames_::internal_error
char internal_error[MAX_COUNTER_SIZE]
Definition: app-layer.c:82
TcpReassemblyThreadCtx_
Definition: stream-tcp-reassemble.h:61
SCReturnCT
#define SCReturnCT(x, type)
Definition: util-debug.h:285
app-layer-protos.h
AppLayerProfilingReset
#define AppLayerProfilingReset(app_tctx)
Definition: app-layer.h:127
app-layer-htp-mem.h
EngineModeIsIPS
int EngineModeIsIPS(void)
Definition: suricata.c:229
STREAMTCP_FLAG_APP_LAYER_DISABLED
#define STREAMTCP_FLAG_APP_LAYER_DISABLED
Definition: stream-tcp-private.h:201
STREAMTCP_STREAM_FLAG_NOREASSEMBLY
#define STREAMTCP_STREAM_FLAG_NOREASSEMBLY
Definition: stream-tcp-private.h:219
suricata.h
TEST_END
#define TEST_END
Definition: app-layer.c:1402
StreamUpdateDir
StreamUpdateDir
Definition: stream-tcp-reassemble.h:54
AppLayerProtoDetectDestroyCtxThread
void AppLayerProtoDetectDestroyCtxThread(AppLayerProtoDetectThreadCtx *alpd_tctx)
Destroys the app layer protocol detection thread context.
Definition: app-layer-detect-proto.c:2010
likely
#define likely(expr)
Definition: util-optimize.h:32
applayer_counter_names
AppLayerCounterNames applayer_counter_names[FLOW_PROTO_APPLAYER_MAX][ALPROTO_MAX]
Definition: app-layer.c:98
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:59
AppLayerCounterNames_::name
char name[MAX_COUNTER_SIZE]
Definition: app-layer.c:78
FlowChangeProto
int FlowChangeProto(Flow *f)
Check if change proto flag is set for flow.
Definition: flow.c:203
TcpSession_
Definition: stream-tcp-private.h:283
TcpSession_::data_first_seen_dir
int8_t data_first_seen_dir
Definition: stream-tcp-private.h:288
flow.h
Flow_::alproto_tc
AppProto alproto_tc
Definition: flow.h:461
FLOW_PROTO_CHANGE_MAX_DEPTH
#define FLOW_PROTO_CHANGE_MAX_DEPTH
Definition: app-layer.c:74
AppLayerProtoDetectPrepareState
int AppLayerProtoDetectPrepareState(void)
Prepares the internal state for protocol detection. This needs to be called once all the patterns and...
Definition: app-layer-detect-proto.c:1499
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:459
ExceptionPolicy
ExceptionPolicy
Definition: util-exception-policy-types.h:25
StatsRegisterCounter
uint16_t StatsRegisterCounter(const char *name, struct ThreadVars_ *tv)
Registers a normal, unqualified counter.
Definition: counters.c:961
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
AppLayerCounterNames_::alloc_error
char alloc_error[MAX_COUNTER_SIZE]
Definition: app-layer.c:83
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:275
PACKET_PROFILING_APP_RESET
#define PACKET_PROFILING_APP_RESET(dp)
Definition: util-profiling.h:195
APPLAYER_WRONG_DIRECTION_FIRST_DATA
@ APPLAYER_WRONG_DIRECTION_FIRST_DATA
Definition: app-layer-events.h:49
AppLayerDeSetupCounters
void AppLayerDeSetupCounters(void)
Definition: app-layer.c:1306
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:102
ExceptionPolicyStatsSetts_::eps_name
char eps_name[EXCEPTION_POLICY_MAX][EXCEPTION_POLICY_COUNTER_MAX_LEN]
Definition: util-exception-policy-types.h:49
STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED
#define STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED
Definition: stream-tcp-private.h:232
AppLayerProtoDetectGetProtoName
const char * AppLayerProtoDetectGetProtoName(AppProto alproto)
Definition: app-layer-detect-proto.c:2081
app-layer.h