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-htp-range.h"
35 #include "app-layer-detect-proto.h"
36 #include "app-layer-frames.h"
37 #include "stream-tcp-reassemble.h"
38 #include "stream-tcp-private.h"
39 #include "stream-tcp-inline.h"
40 #include "stream-tcp.h"
41 #include "flow.h"
42 #include "flow-util.h"
43 #include "flow-private.h"
44 #include "ippair.h"
45 #include "util-debug.h"
46 #include "util-print.h"
47 #include "util-profiling.h"
48 #include "util-validate.h"
49 #include "decode-events.h"
50 #include "app-layer-htp-mem.h"
51 #include "util-exception-policy.h"
52 
54 /**
55  * \brief This is for the app layer in general and it contains per thread
56  * context relevant to both the alpd and alp.
57  */
59  /* App layer protocol detection thread context, from AppLayerProtoDetectGetCtxThread(). */
61  /* App layer parser thread context, from AppLayerParserThreadCtxAlloc(). */
63 
64 #ifdef PROFILING
65  uint64_t ticks_start;
66  uint64_t ticks_end;
67  uint64_t ticks_spent;
72 #endif
73 };
74 
75 #define FLOW_PROTO_CHANGE_MAX_DEPTH 4096
76 
77 #define MAX_COUNTER_SIZE 64
78 typedef struct AppLayerCounterNames_ {
87 
88 typedef struct AppLayerCounters_ {
89  uint16_t counter_id;
90  uint16_t counter_tx_id;
91  uint16_t gap_error_id;
92  uint16_t parser_error_id;
94  uint16_t alloc_error_id;
97 
98 /* counter names. Only used at init. */
100 /* counter id's. Used that runtime. */
102 /* Exception policy global counters ids */
104 
105 /* Settings order as in the enum */
106 // clang-format off
108  .valid_settings_ids = {
109  /* EXCEPTION_POLICY_NOT_SET */ false,
110  /* EXCEPTION_POLICY_AUTO */ false,
111  /* EXCEPTION_POLICY_PASS_PACKET */ true,
112  /* EXCEPTION_POLICY_PASS_FLOW */ true,
113  /* EXCEPTION_POLICY_BYPASS_FLOW */ true,
114  /* EXCEPTION_POLICY_DROP_PACKET */ false,
115  /* EXCEPTION_POLICY_DROP_FLOW */ false,
116  /* EXCEPTION_POLICY_REJECT */ true,
117  },
118  .valid_settings_ips = {
119  /* EXCEPTION_POLICY_NOT_SET */ false,
120  /* EXCEPTION_POLICY_AUTO */ false,
121  /* EXCEPTION_POLICY_PASS_PACKET */ true,
122  /* EXCEPTION_POLICY_PASS_FLOW */ true,
123  /* EXCEPTION_POLICY_BYPASS_FLOW */ true,
124  /* EXCEPTION_POLICY_DROP_PACKET */ true,
125  /* EXCEPTION_POLICY_DROP_FLOW */ true,
126  /* EXCEPTION_POLICY_REJECT */ true,
127  },
128 };
129 // clang-format on
130 
131 void AppLayerSetupCounters(void);
132 void AppLayerDeSetupCounters(void);
133 
134 /***** L7 layer dispatchers *****/
135 
136 static inline int ProtoDetectDone(const Flow *f, const TcpSession *ssn, uint8_t direction) {
137  const TcpStream *stream = (direction & STREAM_TOSERVER) ? &ssn->client : &ssn->server;
139  (FLOW_IS_PM_DONE(f, direction) && FLOW_IS_PP_DONE(f, direction)));
140 }
141 
142 /**
143  * \note id can be 0 if protocol parser is disabled but detection
144  * is enabled.
145  */
146 static void AppLayerIncFlowCounter(ThreadVars *tv, Flow *f)
147 {
148  const uint16_t id = applayer_counters[f->protomap][f->alproto].counter_id;
149  if (likely(tv && id > 0)) {
150  StatsIncr(tv, id);
151  }
152 }
153 
154 void AppLayerIncTxCounter(ThreadVars *tv, Flow *f, uint64_t step)
155 {
156  const uint16_t id = applayer_counters[f->protomap][f->alproto].counter_tx_id;
157  if (likely(tv && id > 0)) {
158  StatsAddUI64(tv, id, step);
159  }
160 }
161 
163 {
164  const uint16_t id = applayer_counters[f->protomap][f->alproto].gap_error_id;
165  if (likely(tv && id > 0)) {
166  StatsIncr(tv, id);
167  }
168 }
169 
171 {
172  const uint16_t id = applayer_counters[f->protomap][f->alproto].alloc_error_id;
173  if (likely(tv && id > 0)) {
174  StatsIncr(tv, id);
175  }
176 }
177 
179 {
180  const uint16_t id = applayer_counters[f->protomap][f->alproto].parser_error_id;
181  if (likely(tv && id > 0)) {
182  StatsIncr(tv, id);
183  }
184 }
185 
187 {
188  const uint16_t id = applayer_counters[f->protomap][f->alproto].internal_error_id;
189  if (likely(tv && id > 0)) {
190  StatsIncr(tv, id);
191  }
192 }
193 
194 static void AppLayerIncrErrorExcPolicyCounter(ThreadVars *tv, Flow *f, enum ExceptionPolicy policy)
195 {
196 #ifdef UNITTESTS
197  if (tv == NULL) {
198  return;
199  }
200 #endif
201  uint16_t id = applayer_counters[f->protomap][f->alproto].eps_error.eps_id[policy];
202  /* for the summary values */
203  uint16_t g_id = eps_error_summary.eps_id[policy];
204 
205  if (likely(id > 0)) {
206  StatsIncr(tv, id);
207  }
208  if (likely(g_id > 0)) {
209  StatsIncr(tv, g_id);
210  }
211 }
212 
213 /* in IDS mode protocol detection is done in reverse order:
214  * when TCP data is ack'd. We want to flag the correct packet,
215  * so in this case we set a flag in the flow so that the first
216  * packet in the correct direction can be tagged.
217  *
218  * For IPS we update packet and flow. */
219 static inline void FlagPacketFlow(Packet *p, Flow *f, uint8_t flags)
220 {
221  if (p->proto != IPPROTO_TCP || EngineModeIsIPS()) {
222  if (flags & STREAM_TOSERVER) {
223  if (p->flowflags & FLOW_PKT_TOSERVER) {
226  } else {
228  }
229  } else {
230  if (p->flowflags & FLOW_PKT_TOCLIENT) {
233  } else {
235  }
236  }
237  } else {
238  if (flags & STREAM_TOSERVER) {
240  } else {
242  }
243  }
244 }
245 
246 static void DisableAppLayer(ThreadVars *tv, Flow *f, Packet *p)
247 {
248  SCLogDebug("disable app layer for flow %p alproto %u ts %u tc %u",
249  f, f->alproto, f->alproto_ts, f->alproto_tc);
252  TcpSession *ssn = f->protoctx;
254  f->alproto = ALPROTO_FAILED;
255  AppLayerIncFlowCounter(tv, f);
256 
257  if (f->alproto_tc != ALPROTO_FAILED) {
258  if (f->alproto_tc == ALPROTO_UNKNOWN) {
260  }
261  FlagPacketFlow(p, f, STREAM_TOCLIENT);
262  }
263  if (f->alproto_ts != ALPROTO_FAILED) {
264  if (f->alproto_ts == ALPROTO_UNKNOWN) {
266  }
267  FlagPacketFlow(p, f, STREAM_TOSERVER);
268  }
269  SCLogDebug("disabled app layer for flow %p alproto %u ts %u tc %u",
270  f, f->alproto, f->alproto_ts, f->alproto_tc);
271 }
272 
273 /* See if we're going to have to give up:
274  *
275  * If we're getting a lot of data in one direction and the
276  * proto for this direction is unknown, proto detect will
277  * hold up segments in the segment list in the stream.
278  * They are held so that if we detect the protocol on the
279  * opposing stream, we can still parse this side of the stream
280  * as well. However, some sessions are very unbalanced. FTP
281  * data channels, large PUT/POST request and many others, can
282  * lead to cases where we would have to store many megabytes
283  * worth of segments before we see the opposing stream. This
284  * leads to risks of resource starvation.
285  *
286  * Here a cutoff point is enforced. If we've stored 100k in
287  * one direction and we've seen no data in the other direction,
288  * we give up.
289  *
290  * Giving up means we disable applayer an set an applayer event
291  */
292 static void TCPProtoDetectCheckBailConditions(ThreadVars *tv,
293  Flow *f, TcpSession *ssn, Packet *p)
294 {
295  if (ssn->state < TCP_ESTABLISHED) {
296  SCLogDebug("skip as long as TCP is not ESTABLISHED (TCP fast open)");
297  return;
298  }
299 
300  const uint32_t size_ts = StreamDataAvailableForProtoDetect(&ssn->client);
301  const uint32_t size_tc = StreamDataAvailableForProtoDetect(&ssn->server);
302  SCLogDebug("size_ts %" PRIu32 ", size_tc %" PRIu32, size_ts, size_tc);
303 
304  /* at least 100000 whatever the conditions
305  * and can be more if window is bigger and if configuration allows it */
306  const uint32_t size_tc_limit =
308  const uint32_t size_ts_limit =
310 
311  if (ProtoDetectDone(f, ssn, STREAM_TOSERVER) &&
312  ProtoDetectDone(f, ssn, STREAM_TOCLIENT))
313  {
314  goto failure;
315 
316  /* we bail out whatever the pp and pm states if
317  * we received too much data */
318  } else if (size_tc > 2 * size_tc_limit || size_ts > 2 * size_ts_limit) {
320  goto failure;
321 
322  } else if (FLOW_IS_PM_DONE(f, STREAM_TOSERVER) && FLOW_IS_PP_DONE(f, STREAM_TOSERVER) &&
323  size_ts > size_ts_limit && size_tc == 0) {
326  goto failure;
327 
328  } else if (FLOW_IS_PM_DONE(f, STREAM_TOCLIENT) && FLOW_IS_PP_DONE(f, STREAM_TOCLIENT) &&
329  size_tc > size_tc_limit && size_ts == 0) {
332  goto failure;
333 
334  /* little data in ts direction, pp done, pm not done (max
335  * depth not reached), ts direction done, lots of data in
336  * tc direction. */
337  } else if (size_tc > size_tc_limit && FLOW_IS_PP_DONE(f, STREAM_TOSERVER) &&
338  !(FLOW_IS_PM_DONE(f, STREAM_TOSERVER)) && FLOW_IS_PM_DONE(f, STREAM_TOCLIENT) &&
339  FLOW_IS_PP_DONE(f, STREAM_TOCLIENT)) {
342  goto failure;
343 
344  /* little data in tc direction, pp done, pm not done (max
345  * depth not reached), tc direction done, lots of data in
346  * ts direction. */
347  } else if (size_ts > size_ts_limit && FLOW_IS_PP_DONE(f, STREAM_TOCLIENT) &&
348  !(FLOW_IS_PM_DONE(f, STREAM_TOCLIENT)) && FLOW_IS_PM_DONE(f, STREAM_TOSERVER) &&
349  FLOW_IS_PP_DONE(f, STREAM_TOSERVER)) {
352  goto failure;
353  }
354  return;
355 
356 failure:
357  DisableAppLayer(tv, f, p);
358 }
359 
360 static int TCPProtoDetectTriggerOpposingSide(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
361  Packet *p, TcpSession *ssn, const TcpStream *stream)
362 {
363  TcpStream *opposing_stream = NULL;
364  if (stream == &ssn->client) {
365  opposing_stream = &ssn->server;
366  } else {
367  opposing_stream = &ssn->client;
368  }
369 
370  /* if the opposing side is not going to work, then
371  * we just have to give up. */
372  if (opposing_stream->flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY) {
373  SCLogDebug("opposing dir has STREAMTCP_STREAM_FLAG_NOREASSEMBLY set");
374  return -1;
375  }
376 
377  enum StreamUpdateDir dir = StreamTcpInlineMode() ?
380  int ret = StreamTcpReassembleAppLayer(tv, ra_ctx, ssn,
381  opposing_stream, p, dir);
382  return ret;
383 }
384 
386 
387 /** \todo data const
388  * \retval int -1 error
389  * \retval int 0 ok
390  */
391 static int TCPProtoDetect(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
392  AppLayerThreadCtx *app_tctx, Packet *p, Flow *f, TcpSession *ssn, TcpStream **stream,
393  uint8_t *data, uint32_t data_len, uint8_t flags, enum StreamUpdateDir app_update_dir)
394 {
395  AppProto *alproto;
396  AppProto *alproto_otherdir;
397  uint8_t direction = (flags & STREAM_TOSERVER) ? 0 : 1;
398 
399  if (flags & STREAM_TOSERVER) {
400  alproto = &f->alproto_ts;
401  alproto_otherdir = &f->alproto_tc;
402  } else {
403  alproto = &f->alproto_tc;
404  alproto_otherdir = &f->alproto_ts;
405  }
406 
407  SCLogDebug("Stream initializer (len %" PRIu32 ")", data_len);
408 #ifdef PRINT
409  if (data_len > 0) {
410  printf("=> Init Stream Data (app layer) -- start %s%s\n",
411  flags & STREAM_TOCLIENT ? "toclient" : "",
412  flags & STREAM_TOSERVER ? "toserver" : "");
413  PrintRawDataFp(stdout, data, data_len);
414  printf("=> Init Stream Data -- end\n");
415  }
416 #endif
417 
418  bool reverse_flow = false;
419  DEBUG_VALIDATE_BUG_ON(data == NULL && data_len > 0);
421  *alproto = AppLayerProtoDetectGetProto(app_tctx->alpd_tctx,
422  f, data, data_len,
423  IPPROTO_TCP, flags, &reverse_flow);
424  PACKET_PROFILING_APP_PD_END(app_tctx);
425  SCLogDebug("alproto %u rev %s", *alproto, reverse_flow ? "true" : "false");
426 
427  if (*alproto != ALPROTO_UNKNOWN) {
428  if (*alproto_otherdir != ALPROTO_UNKNOWN && *alproto_otherdir != *alproto) {
431 
433  /* if we already invoked the parser, we go with that proto */
434  f->alproto = *alproto_otherdir;
435  } else {
436  /* no data sent to parser yet, we can still choose
437  * we're trusting the server more. */
438  if (flags & STREAM_TOCLIENT)
439  f->alproto = *alproto;
440  else
441  f->alproto = *alproto_otherdir;
442  }
443  } else {
444  f->alproto = *alproto;
445  }
446 
450  FlagPacketFlow(p, f, flags);
451 
452  /* if protocol detection indicated that we need to reverse
453  * the direction of the flow, do it now. We flip the flow,
454  * packet and the direction flags */
455  if (reverse_flow &&
458  /* but only if we didn't already detect it on the other side. */
459  if (*alproto_otherdir == ALPROTO_UNKNOWN) {
460  SCLogDebug("reversing flow after proto detect told us so");
461  PacketSwap(p);
462  FlowSwap(f);
463  SWAP_FLAGS(flags, STREAM_TOSERVER, STREAM_TOCLIENT);
464  if (*stream == &ssn->client) {
465  *stream = &ssn->server;
466  } else {
467  *stream = &ssn->client;
468  }
469  direction = 1 - direction;
470  } else {
471  // TODO event, error?
472  }
473  }
474 
475  /* account flow if we have both sides */
476  if (*alproto_otherdir != ALPROTO_UNKNOWN) {
477  AppLayerIncFlowCounter(tv, f);
478  }
479 
480  /* if we have seen data from the other direction first, send
481  * data for that direction first to the parser. This shouldn't
482  * be an issue, since each stream processing happens
483  * independently of the other stream direction. At this point of
484  * call, you need to know that this function's already being
485  * called by the very same StreamReassembly() function that we
486  * will now call shortly for the opposing direction. */
487  if ((ssn->data_first_seen_dir & (STREAM_TOSERVER | STREAM_TOCLIENT)) &&
488  !(flags & ssn->data_first_seen_dir))
489  {
490  SCLogDebug("protocol %s needs first data in other direction",
491  AppProtoToString(*alproto));
492 
493  if (TCPProtoDetectTriggerOpposingSide(tv, ra_ctx,
494  p, ssn, *stream) != 0)
495  {
496  goto detect_error;
497  }
498  if (FlowChangeProto(f)) {
499  /* We have the first data which requested a protocol change from P1 to P2
500  * even if it was not recognized at first as being P1
501  * As the second data was recognized as P1, the protocol did not change !
502  */
506  }
507  }
508 
509  /* if the parser operates such that it needs to see data from
510  * a particular direction first, we check if we have seen
511  * data from that direction first for the flow. IF it is not
512  * the same, we set an event and exit.
513  *
514  * \todo We need to figure out a more robust solution for this,
515  * as this can lead to easy evasion tactics, where the
516  * attacker can first send some dummy data in the wrong
517  * direction first to mislead our proto detection process.
518  * While doing this we need to update the parsers as well,
519  * since the parsers must be robust to see such wrong
520  * direction data.
521  * Either ways the moment we see the
522  * APPLAYER_WRONG_DIRECTION_FIRST_DATA event set for the
523  * flow, it shows something's fishy.
524  */
526  uint8_t first_data_dir;
527  first_data_dir = AppLayerParserGetFirstDataDir(f->proto, f->alproto);
528 
529  if (first_data_dir && !(first_data_dir & ssn->data_first_seen_dir)) {
532  goto detect_error;
533  }
534  /* This can happen if the current direction is not the
535  * right direction, and the data from the other(also
536  * the right direction) direction is available to be sent
537  * to the app layer, but it is not ack'ed yet and hence
538  * the forced call to STreamTcpAppLayerReassemble still
539  * hasn't managed to send data from the other direction
540  * to the app layer. */
541  if (first_data_dir && !(first_data_dir & flags)) {
547  SCReturnInt(-1);
548  }
549  }
550 
551  /* Set a value that is neither STREAM_TOSERVER, nor STREAM_TOCLIENT */
553 
554  /* finally, invoke the parser */
555  PACKET_PROFILING_APP_START(app_tctx, f->alproto);
556  int r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto,
557  flags, data, data_len);
558  PACKET_PROFILING_APP_END(app_tctx);
559  p->app_update_direction = (uint8_t)app_update_dir;
560  if (r != 1) {
561  StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
562  }
563  if (r == 0) {
564  if (*alproto_otherdir == ALPROTO_UNKNOWN) {
565  TcpStream *opposing_stream;
566  if (*stream == &ssn->client) {
567  opposing_stream = &ssn->server;
568  } else {
569  opposing_stream = &ssn->client;
570  }
572  // can happen in detection-only
573  AppLayerIncFlowCounter(tv, f);
574  }
575  }
576  }
577  if (r < 0) {
578  goto parser_error;
579  }
580  } else {
581  /* if the ssn is midstream, we may end up with a case where the
582  * start of an HTTP request is missing. We won't detect HTTP based
583  * on the request. However, the reply is fine, so we detect
584  * HTTP anyway. This leads to passing the incomplete request to
585  * the htp parser.
586  *
587  * This has been observed, where the http parser then saw many
588  * bogus requests in the incomplete data.
589  *
590  * To counter this case, a midstream session MUST find it's
591  * protocol in the toserver direction. If not, we assume the
592  * start of the request/toserver is incomplete and no reliable
593  * detection and parsing is possible. So we give up.
594  */
595  if ((ssn->flags & STREAMTCP_FLAG_MIDSTREAM) &&
597  {
598  if (FLOW_IS_PM_DONE(f, STREAM_TOSERVER) && FLOW_IS_PP_DONE(f, STREAM_TOSERVER)) {
599  SCLogDebug("midstream end pd %p", ssn);
600  /* midstream and toserver detection failed: give up */
601  DisableAppLayer(tv, f, p);
602  SCReturnInt(0);
603  }
604  }
605 
606  if (*alproto_otherdir != ALPROTO_UNKNOWN) {
607  uint8_t first_data_dir;
608  first_data_dir = AppLayerParserGetFirstDataDir(f->proto, *alproto_otherdir);
609 
610  /* this would handle this test case -
611  * http parser which says it wants to see toserver data first only.
612  * tcp handshake
613  * toclient data first received. - RUBBISH DATA which
614  * we don't detect as http
615  * toserver data next sent - we detect this as http.
616  * at this stage we see that toclient is the first data seen
617  * for this session and we try and redetect the app protocol,
618  * but we are unable to detect the app protocol like before.
619  * But since we have managed to detect the protocol for the
620  * other direction as http, we try to use that. At this
621  * stage we check if the direction of this stream matches
622  * to that acceptable by the app parser. If it is not the
623  * acceptable direction we error out.
624  */
626  (first_data_dir) && !(first_data_dir & flags))
627  {
628  goto detect_error;
629  }
630 
631  /* if protocol detection is marked done for our direction we
632  * pass our data on. We're only succeeded in finding one
633  * direction: the opposing stream
634  *
635  * If PD was not yet complete, we don't do anything.
636  */
637  if (FLOW_IS_PM_DONE(f, flags) && FLOW_IS_PP_DONE(f, flags)) {
638  if (data_len > 0)
640 
641  if (*alproto_otherdir != ALPROTO_FAILED) {
642  PACKET_PROFILING_APP_START(app_tctx, f->alproto);
643  int r = AppLayerParserParse(tv, app_tctx->alp_tctx, f,
644  f->alproto, flags,
645  data, data_len);
646  PACKET_PROFILING_APP_END(app_tctx);
647  p->app_update_direction = (uint8_t)app_update_dir;
648  if (r != 1) {
649  StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
650  }
651 
656 
657  *alproto = *alproto_otherdir;
658  SCLogDebug("packet %"PRIu64": pd done(us %u them %u), parser called (r==%d), APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION set",
659  p->pcap_cnt, *alproto, *alproto_otherdir, r);
660  if (r < 0) {
661  goto parser_error;
662  }
663  }
664  *alproto = ALPROTO_FAILED;
666  AppLayerIncFlowCounter(tv, f);
667  FlagPacketFlow(p, f, flags);
668 
669  } else if (flags & STREAM_EOF) {
670  *alproto = f->alproto;
672  AppLayerIncFlowCounter(tv, f);
673  }
674  } else {
675  /* both sides unknown, let's see if we need to give up */
676  if (FlowChangeProto(f)) {
677  /* TCPProtoDetectCheckBailConditions does not work well because
678  * size_tc from STREAM_RIGHT_EDGE is not reset to zero
679  * so, we set a lower limit to the data we inspect
680  * We could instead have set ssn->server.sb.stream_offset = 0;
681  */
682  if (data_len >= FLOW_PROTO_CHANGE_MAX_DEPTH || (flags & STREAM_EOF)) {
683  DisableAppLayer(tv, f, p);
684  }
685  } else {
686  TCPProtoDetectCheckBailConditions(tv, f, ssn, p);
687  }
688  }
689  }
690  SCReturnInt(0);
691 parser_error:
693  AppLayerIncrErrorExcPolicyCounter(tv, f, g_applayerparser_error_policy);
694  SCReturnInt(-1);
695 detect_error:
696  DisableAppLayer(tv, f, p);
697  SCReturnInt(-2);
698 }
699 
700 /** \brief handle TCP data for the app-layer.
701  *
702  * First run protocol detection and then when the protocol is known invoke
703  * the app layer parser.
704  *
705  * \param stream ptr-to-ptr to stream object. Might change if flow dir is
706  * reversed.
707  */
709  TcpSession *ssn, TcpStream **stream, uint8_t *data, uint32_t data_len, uint8_t flags,
710  enum StreamUpdateDir app_update_dir)
711 {
712  SCEnter();
713 
715  DEBUG_VALIDATE_BUG_ON(data_len > (uint32_t)INT_MAX);
716 
717  AppLayerThreadCtx *app_tctx = ra_ctx->app_tctx;
718  AppProto alproto;
719  int r = 0;
720 
721  SCLogDebug("data_len %u flags %02X", data_len, flags);
723  SCLogDebug("STREAMTCP_FLAG_APP_LAYER_DISABLED is set");
724  goto end;
725  }
726 
727  const uint8_t direction = (flags & STREAM_TOSERVER) ? 0 : 1;
728 
729  if (flags & STREAM_TOSERVER) {
730  alproto = f->alproto_ts;
731  } else {
732  alproto = f->alproto_tc;
733  }
734 
735  /* If a gap notification, relay the notification on to the
736  * app-layer if known. */
737  if (flags & STREAM_GAP) {
738  SCLogDebug("GAP of size %u", data_len);
739  if (alproto == ALPROTO_UNKNOWN) {
741  SCLogDebug("ALPROTO_UNKNOWN flow %p, due to GAP in stream start", f);
742  /* if the other side didn't already find the proto, we're done */
743  if (f->alproto == ALPROTO_UNKNOWN) {
744  goto failure;
745  }
746  AppLayerIncFlowCounter(tv, f);
747  }
748  if (FlowChangeProto(f)) {
750  SCLogDebug("Cannot handle gap while changing protocol");
751  goto failure;
752  }
753  PACKET_PROFILING_APP_START(app_tctx, f->alproto);
754  r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto,
755  flags, data, data_len);
756  PACKET_PROFILING_APP_END(app_tctx);
757  p->app_update_direction = (uint8_t)app_update_dir;
758  /* ignore parser result for gap */
759  StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
760  if (r < 0) {
762  AppLayerIncrErrorExcPolicyCounter(tv, f, g_applayerparser_error_policy);
763  SCReturnInt(-1);
764  }
765  goto end;
766  }
767 
768  /* if we don't know the proto yet and we have received a stream
769  * initializer message, we run proto detection.
770  * We receive 2 stream init msgs (one for each direction), we
771  * only run the proto detection for both and emit an event
772  * in the case protocols mismatch. */
773  if (alproto == ALPROTO_UNKNOWN && (flags & STREAM_START)) {
775  /* run protocol detection */
776  if (TCPProtoDetect(tv, ra_ctx, app_tctx, p, f, ssn, stream, data, data_len, flags,
777  app_update_dir) != 0) {
778  goto failure;
779  }
780  } else if (alproto != ALPROTO_UNKNOWN && FlowChangeProto(f)) {
781  SCLogDebug("protocol change, old %s", AppProtoToString(f->alproto_orig));
782  void *alstate_orig = f->alstate;
783  AppLayerParserState *alparser = f->alparser;
784  // we delay AppLayerParserStateCleanup because we may need previous parser state
788  /* rerun protocol detection */
789  int rd = TCPProtoDetect(
790  tv, ra_ctx, app_tctx, p, f, ssn, stream, data, data_len, flags, app_update_dir);
791  if (f->alproto == ALPROTO_UNKNOWN) {
792  DEBUG_VALIDATE_BUG_ON(alstate_orig != f->alstate);
793  // not enough data, revert AppLayerProtoDetectReset to rerun detection
794  f->alparser = alparser;
795  f->alproto = f->alproto_orig;
796  f->alproto_tc = f->alproto_orig;
797  f->alproto_ts = f->alproto_orig;
798  } else {
800  AppLayerParserStateProtoCleanup(f->protomap, f->alproto_orig, alstate_orig, alparser);
801  if (alstate_orig == f->alstate) {
802  // we just freed it
803  f->alstate = NULL;
804  }
805  }
806  if (rd != 0) {
807  SCLogDebug("proto detect failure");
808  goto failure;
809  }
810  SCLogDebug("protocol change, old %s, new %s",
812 
814  f->alproto != f->alproto_expect) {
817 
818  if (f->alproto_expect == ALPROTO_TLS && f->alproto != ALPROTO_TLS) {
821 
822  }
823  }
824  } else {
825  SCLogDebug("stream data (len %" PRIu32 " alproto "
826  "%"PRIu16" (flow %p)", data_len, f->alproto, f);
827 #ifdef PRINT
828  if (data_len > 0) {
829  printf("=> Stream Data (app layer) -- start %s%s\n",
830  flags & STREAM_TOCLIENT ? "toclient" : "",
831  flags & STREAM_TOSERVER ? "toserver" : "");
832  PrintRawDataFp(stdout, data, data_len);
833  printf("=> Stream Data -- end\n");
834  }
835 #endif
836  /* if we don't have a data object here we are not getting it
837  * a start msg should have gotten us one */
838  if (f->alproto != ALPROTO_UNKNOWN) {
839  PACKET_PROFILING_APP_START(app_tctx, f->alproto);
840  r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto,
841  flags, data, data_len);
842  PACKET_PROFILING_APP_END(app_tctx);
843  p->app_update_direction = (uint8_t)app_update_dir;
844  if (r != 1) {
845  StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
846  if (r < 0) {
849  AppLayerIncrErrorExcPolicyCounter(tv, f, g_applayerparser_error_policy);
850  SCReturnInt(-1);
851  }
852  }
853  }
854  }
855 
856  goto end;
857  failure:
858  r = -1;
859  end:
860  SCReturnInt(r);
861 }
862 
863 /**
864  * \brief Handle a app layer UDP message
865  *
866  * If the protocol is yet unknown, the proto detection code is run first.
867  *
868  * \param dp_ctx Thread app layer detect context
869  * \param f *locked* flow
870  * \param p UDP packet
871  *
872  * \retval 0 ok
873  * \retval -1 error
874  */
876 {
877  SCEnter();
878  AppProto *alproto;
879  AppProto *alproto_otherdir;
880 
881  if (f->alproto_ts == ALPROTO_FAILED && f->alproto_tc == ALPROTO_FAILED) {
882  SCReturnInt(0);
883  }
884 
885  int r = 0;
886  uint8_t flags = 0;
887  if (p->flowflags & FLOW_PKT_TOSERVER) {
888  flags |= STREAM_TOSERVER;
889  alproto = &f->alproto_ts;
890  alproto_otherdir = &f->alproto_tc;
891  } else {
892  flags |= STREAM_TOCLIENT;
893  alproto = &f->alproto_tc;
894  alproto_otherdir = &f->alproto_ts;
895  }
896 
898 
899  /* if the protocol is still unknown, run detection */
900  if (*alproto == ALPROTO_UNKNOWN) {
901  SCLogDebug("Detecting AL proto on udp mesg (len %" PRIu32 ")",
902  p->payload_len);
903 
904  bool reverse_flow = false;
906  *alproto = AppLayerProtoDetectGetProto(
907  tctx->alpd_tctx, f, p->payload, p->payload_len, IPPROTO_UDP, flags, &reverse_flow);
909 
910  switch (*alproto) {
911  case ALPROTO_UNKNOWN:
912  if (*alproto_otherdir != ALPROTO_UNKNOWN) {
913  // Use recognized side
914  f->alproto = *alproto_otherdir;
915  // do not keep ALPROTO_UNKNOWN for this side so as not to loop
916  *alproto = *alproto_otherdir;
917  if (*alproto_otherdir == ALPROTO_FAILED) {
918  SCLogDebug("ALPROTO_UNKNOWN flow %p", f);
919  }
920  } else {
921  // First side of protocol is unknown
922  *alproto = ALPROTO_FAILED;
923  }
924  break;
925  case ALPROTO_FAILED:
926  if (*alproto_otherdir != ALPROTO_UNKNOWN) {
927  // Use recognized side
928  f->alproto = *alproto_otherdir;
929  if (*alproto_otherdir == ALPROTO_FAILED) {
930  SCLogDebug("ALPROTO_UNKNOWN flow %p", f);
931  }
932  }
933  // else wait for second side of protocol
934  break;
935  default:
936  if (*alproto_otherdir != ALPROTO_UNKNOWN && *alproto_otherdir != ALPROTO_FAILED) {
937  if (*alproto_otherdir != *alproto) {
940  // data already sent to parser, we cannot change the protocol to use the one
941  // of the server
942  }
943  } else {
944  f->alproto = *alproto;
945  }
946  }
947  if (*alproto_otherdir == ALPROTO_UNKNOWN) {
948  if (f->alproto == ALPROTO_UNKNOWN) {
949  // so as to increase stat about .app_layer.flow.failed_udp
950  f->alproto = ALPROTO_FAILED;
951  }
952  // If the other side is unknown, this is the first packet of the flow
953  AppLayerIncFlowCounter(tv, f);
954  }
955 
956  // parse the data if we recognized one protocol
957  if (f->alproto != ALPROTO_UNKNOWN && f->alproto != ALPROTO_FAILED) {
958  if (reverse_flow) {
959  SCLogDebug("reversing flow after proto detect told us so");
960  PacketSwap(p);
961  FlowSwap(f);
962  SWAP_FLAGS(flags, STREAM_TOSERVER, STREAM_TOCLIENT);
963  }
964 
966  r = AppLayerParserParse(tv, tctx->alp_tctx, f, f->alproto,
967  flags, p->payload, p->payload_len);
970  }
972  /* we do only inspection in one direction, so flag both
973  * sides as done here */
974  FlagPacketFlow(p, f, STREAM_TOSERVER);
975  FlagPacketFlow(p, f, STREAM_TOCLIENT);
976  } else {
977  SCLogDebug("data (len %" PRIu32 " ), alproto "
978  "%"PRIu16" (flow %p)", p->payload_len, f->alproto, f);
979 
980  /* run the parser */
982  r = AppLayerParserParse(tv, tctx->alp_tctx, f, f->alproto,
983  flags, p->payload, p->payload_len);
987  }
988  if (r < 0) {
990  AppLayerIncrErrorExcPolicyCounter(tv, f, g_applayerparser_error_policy);
991  SCReturnInt(-1);
992  }
993 
994  SCReturnInt(r);
995 }
996 
997 /***** Utility *****/
998 
999 AppProto AppLayerGetProtoByName(char *alproto_name)
1000 {
1001  SCEnter();
1002  AppProto r = AppLayerProtoDetectGetProtoByName(alproto_name);
1003  SCReturnCT(r, "AppProto");
1004 }
1005 
1006 const char *AppLayerGetProtoName(AppProto alproto)
1007 {
1008  SCEnter();
1009  const char * r = AppLayerProtoDetectGetProtoName(alproto);
1010  SCReturnCT(r, "char *");
1011 }
1012 
1014 {
1015  SCEnter();
1016 
1017  AppProto alproto;
1018  AppProto alprotos[ALPROTO_MAX];
1019 
1021 
1022  printf("=========Supported App Layer Protocols=========\n");
1023  for (alproto = 0; alproto < ALPROTO_MAX; alproto++) {
1024  if (alprotos[alproto] == 1)
1025  printf("%s\n", AppLayerGetProtoName(alproto));
1026  }
1027 
1028  SCReturn;
1029 }
1030 
1031 /***** Setup/General Registration *****/
1032 
1033 int AppLayerSetup(void)
1034 {
1035  SCEnter();
1036 
1039 
1042 
1044 
1045  SCReturnInt(0);
1046 }
1047 
1049 {
1050  SCEnter();
1051 
1054 
1056 
1057  SCReturnInt(0);
1058 }
1059 
1061 {
1062  SCEnter();
1063 
1064  AppLayerThreadCtx *app_tctx = SCCalloc(1, sizeof(*app_tctx));
1065  if (app_tctx == NULL)
1066  goto error;
1067 
1068  if ((app_tctx->alpd_tctx = AppLayerProtoDetectGetCtxThread()) == NULL)
1069  goto error;
1070  if ((app_tctx->alp_tctx = AppLayerParserThreadCtxAlloc()) == NULL)
1071  goto error;
1072 
1073  goto done;
1074  error:
1075  AppLayerDestroyCtxThread(app_tctx);
1076  app_tctx = NULL;
1077  done:
1078  SCReturnPtr(app_tctx, "void *");
1079 }
1080 
1082 {
1083  SCEnter();
1084 
1085  if (app_tctx == NULL)
1086  SCReturn;
1087 
1088  if (app_tctx->alpd_tctx != NULL)
1090  if (app_tctx->alp_tctx != NULL)
1092  SCFree(app_tctx);
1093 
1094  SCReturn;
1095 }
1096 
1097 #ifdef PROFILING
1099 {
1100  PACKET_PROFILING_APP_RESET(app_tctx);
1101 }
1102 
1104 {
1105  PACKET_PROFILING_APP_STORE(app_tctx, p);
1106 }
1107 #endif
1108 
1109 /** \brief HACK to work around our broken unix manager (re)init loop
1110  */
1112 {
1117  StatsRegisterGlobalCounter("app_layer.expectations", ExpectationGetCounter);
1120  StatsRegisterGlobalCounter("ippair.memuse", IPPairGetMemuse);
1121  StatsRegisterGlobalCounter("ippair.memcap", IPPairGetMemuse);
1122  StatsRegisterGlobalCounter("host.memuse", HostGetMemuse);
1123  StatsRegisterGlobalCounter("host.memcap", HostGetMemcap);
1124 }
1125 
1126 static bool IsAppLayerErrorExceptionPolicyStatsValid(enum ExceptionPolicy policy)
1127 {
1128  if (EngineModeIsIPS()) {
1130  }
1132 }
1133 
1134 static void AppLayerSetupExceptionPolicyPerProtoCounters(
1135  uint8_t ipproto_map, AppProto alproto, const char *alproto_str, const char *ipproto_suffix)
1136 {
1139  for (enum ExceptionPolicy i = EXCEPTION_POLICY_NOT_SET + 1; i < EXCEPTION_POLICY_MAX; i++) {
1140  if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1141  snprintf(applayer_counter_names[ipproto_map][alproto].eps_name[i],
1142  sizeof(applayer_counter_names[ipproto_map][alproto].eps_name[i]),
1143  "app_layer.error.%s%s.exception_policy.%s", alproto_str, ipproto_suffix,
1144  ExceptionPolicyEnumToString(i, true));
1145  }
1146  }
1147  }
1148 }
1149 
1151 {
1152  const uint8_t ipprotos[] = { IPPROTO_TCP, IPPROTO_UDP };
1153  AppProto alprotos[ALPROTO_MAX];
1154  const char *str = "app_layer.flow.";
1155  const char *estr = "app_layer.error.";
1156 
1157  /* We don't log stats counters if exception policy is `ignore`/`not set` */
1159  /* Register global counters for app layer error exception policy summary */
1160  const char *eps_default_str = "app_layer.error.exception_policy.";
1161  for (enum ExceptionPolicy i = EXCEPTION_POLICY_NOT_SET + 1; i < EXCEPTION_POLICY_MAX; i++) {
1162  if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1163  snprintf(app_layer_error_eps_stats.eps_name[i],
1164  sizeof(app_layer_error_eps_stats.eps_name[i]), "%s%s", eps_default_str,
1165  ExceptionPolicyEnumToString(i, true));
1166  }
1167  }
1168  }
1169 
1171 
1172  for (uint8_t p = 0; p < FLOW_PROTO_APPLAYER_MAX; p++) {
1173  const uint8_t ipproto = ipprotos[p];
1174  const uint8_t ipproto_map = FlowGetProtoMapping(ipproto);
1175  const char *ipproto_suffix = (ipproto == IPPROTO_TCP) ? "_tcp" : "_udp";
1176  uint8_t ipprotos_all[256 / 8];
1177 
1178  for (AppProto alproto = 0; alproto < ALPROTO_MAX; alproto++) {
1179  if (alprotos[alproto] == 1) {
1180  const char *tx_str = "app_layer.tx.";
1181  const char *alproto_str = AppLayerGetProtoName(alproto);
1182 
1183  memset(ipprotos_all, 0, sizeof(ipprotos_all));
1184  AppLayerProtoDetectSupportedIpprotos(alproto, ipprotos_all);
1185  if ((ipprotos_all[IPPROTO_TCP / 8] & (1 << (IPPROTO_TCP % 8))) &&
1186  (ipprotos_all[IPPROTO_UDP / 8] & (1 << (IPPROTO_UDP % 8)))) {
1187  snprintf(applayer_counter_names[ipproto_map][alproto].name,
1188  sizeof(applayer_counter_names[ipproto_map][alproto].name),
1189  "%s%s%s", str, alproto_str, ipproto_suffix);
1190  snprintf(applayer_counter_names[ipproto_map][alproto].tx_name,
1191  sizeof(applayer_counter_names[ipproto_map][alproto].tx_name),
1192  "%s%s%s", tx_str, alproto_str, ipproto_suffix);
1193 
1194  if (ipproto == IPPROTO_TCP) {
1195  snprintf(applayer_counter_names[ipproto_map][alproto].gap_error,
1196  sizeof(applayer_counter_names[ipproto_map][alproto].gap_error),
1197  "%s%s%s.gap", estr, alproto_str, ipproto_suffix);
1198  }
1199  snprintf(applayer_counter_names[ipproto_map][alproto].alloc_error,
1200  sizeof(applayer_counter_names[ipproto_map][alproto].alloc_error),
1201  "%s%s%s.alloc", estr, alproto_str, ipproto_suffix);
1202  snprintf(applayer_counter_names[ipproto_map][alproto].parser_error,
1203  sizeof(applayer_counter_names[ipproto_map][alproto].parser_error),
1204  "%s%s%s.parser", estr, alproto_str, ipproto_suffix);
1205  snprintf(applayer_counter_names[ipproto_map][alproto].internal_error,
1206  sizeof(applayer_counter_names[ipproto_map][alproto].internal_error),
1207  "%s%s%s.internal", estr, alproto_str, ipproto_suffix);
1208 
1209  AppLayerSetupExceptionPolicyPerProtoCounters(
1210  ipproto_map, alproto, alproto_str, ipproto_suffix);
1211  } else {
1212  snprintf(applayer_counter_names[ipproto_map][alproto].name,
1213  sizeof(applayer_counter_names[ipproto_map][alproto].name),
1214  "%s%s", str, alproto_str);
1215  snprintf(applayer_counter_names[ipproto_map][alproto].tx_name,
1216  sizeof(applayer_counter_names[ipproto_map][alproto].tx_name),
1217  "%s%s", tx_str, alproto_str);
1218 
1219  if (ipproto == IPPROTO_TCP) {
1220  snprintf(applayer_counter_names[ipproto_map][alproto].gap_error,
1221  sizeof(applayer_counter_names[ipproto_map][alproto].gap_error),
1222  "%s%s.gap", estr, alproto_str);
1223  }
1224  snprintf(applayer_counter_names[ipproto_map][alproto].alloc_error,
1225  sizeof(applayer_counter_names[ipproto_map][alproto].alloc_error),
1226  "%s%s.alloc", estr, alproto_str);
1227  snprintf(applayer_counter_names[ipproto_map][alproto].parser_error,
1228  sizeof(applayer_counter_names[ipproto_map][alproto].parser_error),
1229  "%s%s.parser", estr, alproto_str);
1230  snprintf(applayer_counter_names[ipproto_map][alproto].internal_error,
1231  sizeof(applayer_counter_names[ipproto_map][alproto].internal_error),
1232  "%s%s.internal", estr, alproto_str);
1233  AppLayerSetupExceptionPolicyPerProtoCounters(
1234  ipproto_map, alproto, alproto_str, "");
1235  }
1236  } else if (alproto == ALPROTO_FAILED) {
1237  snprintf(applayer_counter_names[ipproto_map][alproto].name,
1238  sizeof(applayer_counter_names[ipproto_map][alproto].name),
1239  "%s%s%s", str, "failed", ipproto_suffix);
1240  if (ipproto == IPPROTO_TCP) {
1241  snprintf(applayer_counter_names[ipproto_map][alproto].gap_error,
1242  sizeof(applayer_counter_names[ipproto_map][alproto].gap_error),
1243  "%sfailed%s.gap", estr, ipproto_suffix);
1244  }
1245  }
1246  }
1247  }
1248 }
1249 
1251 {
1252  const uint8_t ipprotos[] = { IPPROTO_TCP, IPPROTO_UDP };
1253  AppProto alprotos[ALPROTO_MAX];
1255 
1256  /* We don't log stats counters if exception policy is `ignore`/`not set` */
1258  /* Register global counters for app layer error exception policy summary */
1259  for (enum ExceptionPolicy i = EXCEPTION_POLICY_NOT_SET + 1; i < EXCEPTION_POLICY_MAX; i++) {
1260  if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1263  }
1264  }
1265  }
1266 
1267  for (uint8_t p = 0; p < FLOW_PROTO_APPLAYER_MAX; p++) {
1268  const uint8_t ipproto = ipprotos[p];
1269  const uint8_t ipproto_map = FlowGetProtoMapping(ipproto);
1270 
1271  for (AppProto alproto = 0; alproto < ALPROTO_MAX; alproto++) {
1272  if (alprotos[alproto] == 1) {
1273  applayer_counters[ipproto_map][alproto].counter_id =
1274  StatsRegisterCounter(applayer_counter_names[ipproto_map][alproto].name, tv);
1275 
1276  applayer_counters[ipproto_map][alproto].counter_tx_id =
1277  StatsRegisterCounter(applayer_counter_names[ipproto_map][alproto].tx_name, tv);
1278 
1279  if (ipproto == IPPROTO_TCP) {
1280  applayer_counters[ipproto_map][alproto].gap_error_id = StatsRegisterCounter(
1281  applayer_counter_names[ipproto_map][alproto].gap_error, tv);
1282  }
1283  applayer_counters[ipproto_map][alproto].alloc_error_id = StatsRegisterCounter(
1284  applayer_counter_names[ipproto_map][alproto].alloc_error, tv);
1285  applayer_counters[ipproto_map][alproto].parser_error_id = StatsRegisterCounter(
1286  applayer_counter_names[ipproto_map][alproto].parser_error, tv);
1288  applayer_counter_names[ipproto_map][alproto].internal_error, tv);
1289  /* We don't log stats counters if exception policy is `ignore`/`not set` */
1292  for (enum ExceptionPolicy i = EXCEPTION_POLICY_NOT_SET + 1;
1293  i < EXCEPTION_POLICY_MAX; i++) {
1294  if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1295  applayer_counters[ipproto_map][alproto]
1297  applayer_counter_names[ipproto_map][alproto].eps_name[i], tv);
1298  }
1299  }
1300  }
1301  } else if (alproto == ALPROTO_FAILED) {
1302  applayer_counters[ipproto_map][alproto].counter_id =
1303  StatsRegisterCounter(applayer_counter_names[ipproto_map][alproto].name, tv);
1304 
1305  if (ipproto == IPPROTO_TCP) {
1306  applayer_counters[ipproto_map][alproto].gap_error_id = StatsRegisterCounter(
1307  applayer_counter_names[ipproto_map][alproto].gap_error, tv);
1308  }
1309  }
1310  }
1311  }
1312 }
1313 
1315 {
1316  memset(applayer_counter_names, 0, sizeof(applayer_counter_names));
1317  memset(applayer_counters, 0, sizeof(applayer_counters));
1318 }
1319 
1320 /***** Unittests *****/
1321 
1322 #ifdef UNITTESTS
1323 #include "pkt-var.h"
1324 #include "stream-tcp-util.h"
1325 #include "stream.h"
1326 #include "util-unittest.h"
1327 
1328 #define TEST_START \
1329  Packet *p = PacketGetFromAlloc(); \
1330  FAIL_IF_NULL(p); \
1331  Flow f; \
1332  ThreadVars tv; \
1333  StreamTcpThread *stt = NULL; \
1334  TCPHdr tcph; \
1335  PacketQueueNoLock pq; \
1336  memset(&pq, 0, sizeof(PacketQueueNoLock)); \
1337  memset(&f, 0, sizeof(Flow)); \
1338  memset(&tv, 0, sizeof(ThreadVars)); \
1339  memset(&tcph, 0, sizeof(TCPHdr)); \
1340  \
1341  FLOW_INITIALIZE(&f); \
1342  f.flags = FLOW_IPV4; \
1343  f.proto = IPPROTO_TCP; \
1344  p->flow = &f; \
1345  PacketSetTCP(p, (uint8_t *)&tcph); \
1346  \
1347  StreamTcpInitConfig(true); \
1348  IPPairInitConfig(true); \
1349  StreamTcpThreadInit(&tv, NULL, (void **)&stt); \
1350  \
1351  /* handshake */ \
1352  tcph.th_win = htons(5480); \
1353  tcph.th_flags = TH_SYN; \
1354  p->flowflags = FLOW_PKT_TOSERVER; \
1355  p->payload_len = 0; \
1356  p->payload = NULL; \
1357  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1); \
1358  TcpSession *ssn = (TcpSession *)f.protoctx; \
1359  \
1360  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); \
1361  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); \
1362  FAIL_IF(f.alproto != ALPROTO_UNKNOWN); \
1363  FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN); \
1364  FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN); \
1365  FAIL_IF(ssn->flags &STREAMTCP_FLAG_APP_LAYER_DISABLED); \
1366  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER)); \
1367  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER)); \
1368  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT)); \
1369  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); \
1370  FAIL_IF(ssn->data_first_seen_dir != 0); \
1371  \
1372  /* handshake */ \
1373  tcph.th_ack = htonl(1); \
1374  tcph.th_flags = TH_SYN | TH_ACK; \
1375  p->flowflags = FLOW_PKT_TOCLIENT; \
1376  p->payload_len = 0; \
1377  p->payload = NULL; \
1378  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1); \
1379  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); \
1380  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); \
1381  FAIL_IF(f.alproto != ALPROTO_UNKNOWN); \
1382  FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN); \
1383  FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN); \
1384  FAIL_IF(ssn->flags &STREAMTCP_FLAG_APP_LAYER_DISABLED); \
1385  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER)); \
1386  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER)); \
1387  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT)); \
1388  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); \
1389  FAIL_IF(ssn->data_first_seen_dir != 0); \
1390  \
1391  /* handshake */ \
1392  tcph.th_ack = htonl(1); \
1393  tcph.th_seq = htonl(1); \
1394  tcph.th_flags = TH_ACK; \
1395  p->flowflags = FLOW_PKT_TOSERVER; \
1396  p->payload_len = 0; \
1397  p->payload = NULL; \
1398  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1); \
1399  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); \
1400  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); \
1401  FAIL_IF(f.alproto != ALPROTO_UNKNOWN); \
1402  FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN); \
1403  FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN); \
1404  FAIL_IF(ssn->flags &STREAMTCP_FLAG_APP_LAYER_DISABLED); \
1405  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER)); \
1406  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER)); \
1407  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT)); \
1408  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); \
1409  FAIL_IF(ssn->data_first_seen_dir != 0);
1410 #define TEST_END \
1411  StreamTcpSessionClear(p->flow->protoctx); \
1412  StreamTcpThreadDeinit(&tv, (void *)stt); \
1413  StreamTcpFreeConfig(true); \
1414  PacketFree(p); \
1415  FLOW_DESTROY(&f); \
1416  StatsThreadCleanup(&tv);
1417 
1418 /**
1419  * \test GET -> HTTP/1.1
1420  */
1421 static int AppLayerTest01(void)
1422 {
1423  TEST_START;
1424 
1425  /* full request */
1426  uint8_t request[] = {
1427  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1428  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1429  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1430  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1431  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1432  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1433  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1434  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1435  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1436  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1437  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1438  tcph.th_ack = htonl(1);
1439  tcph.th_seq = htonl(1);
1440  tcph.th_flags = TH_PUSH | TH_ACK;
1442  p->payload_len = sizeof(request);
1443  p->payload = request;
1444  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1451  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1452  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1453  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1454  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1455  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1456 
1457  /* full response - request ack */
1458  uint8_t response[] = {
1459  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
1460  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1461  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1462  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1463  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1464  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1465  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1466  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1467  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1468  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1469  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1470  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1471  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1472  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1473  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1474  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1475  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1476  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1477  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1478  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1479  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1480  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1481  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1482  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1483  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1484  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1485  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1486  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1487  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1488  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1489  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1490  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1491  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1492  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1493  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1494  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1495  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1496  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1497  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1498  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1499  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1500  tcph.th_ack = htonl(88);
1501  tcph.th_seq = htonl(1);
1502  tcph.th_flags = TH_PUSH | TH_ACK;
1504  p->payload_len = sizeof(response);
1505  p->payload = response;
1506  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1513  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1514  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1515  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1516  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1518 
1519  /* response ack */
1520  tcph.th_ack = htonl(328);
1521  tcph.th_seq = htonl(88);
1522  tcph.th_flags = TH_ACK;
1524  p->payload_len = 0;
1525  p->payload = NULL;
1526  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1533  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1534  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1535  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1536  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1538 
1539  TEST_END;
1540  PASS;
1541 }
1542 
1543 /**
1544  * \test GE -> T -> HTTP/1.1
1545  */
1546 static int AppLayerTest02(void)
1547 {
1548  TEST_START;
1549 
1550  /* partial request */
1551  uint8_t request1[] = { 0x47, 0x45, };
1552  tcph.th_ack = htonl(1);
1553  tcph.th_seq = htonl(1);
1554  tcph.th_flags = TH_PUSH | TH_ACK;
1556  p->payload_len = sizeof(request1);
1557  p->payload = request1;
1558  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1565  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1566  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1567  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1568  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1569  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1570 
1571  /* response ack against partial request */
1572  tcph.th_ack = htonl(3);
1573  tcph.th_seq = htonl(1);
1574  tcph.th_flags = TH_ACK;
1576  p->payload_len = 0;
1577  p->payload = NULL;
1578  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1585  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1586  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1587  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1588  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1589  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1590 
1591  /* complete partial request */
1592  uint8_t request2[] = {
1593  0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1594  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1595  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1596  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1597  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1598  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1599  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1600  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1601  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1602  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1603  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1604  tcph.th_ack = htonl(1);
1605  tcph.th_seq = htonl(3);
1606  tcph.th_flags = TH_PUSH | TH_ACK;
1608  p->payload_len = sizeof(request2);
1609  p->payload = request2;
1610  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1617  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1618  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1619  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1620  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1621  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1622 
1623  /* response - request ack */
1624  uint8_t response[] = {
1625  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
1626  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1627  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1628  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1629  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1630  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1631  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1632  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1633  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1634  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1635  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1636  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1637  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1638  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1639  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1640  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1641  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1642  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1643  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1644  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1645  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1646  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1647  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1648  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1649  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1650  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1651  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1652  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1653  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1654  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1655  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1656  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1657  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1658  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1659  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1660  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1661  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1662  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1663  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1664  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1665  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1666  tcph.th_ack = htonl(88);
1667  tcph.th_seq = htonl(1);
1668  tcph.th_flags = TH_PUSH | TH_ACK;
1670  p->payload_len = sizeof(response);
1671  p->payload = response;
1672  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1679  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1680  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1681  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1682  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1684 
1685  /* response ack */
1686  tcph.th_ack = htonl(328);
1687  tcph.th_seq = htonl(88);
1688  tcph.th_flags = TH_ACK;
1690  p->payload_len = 0;
1691  p->payload = NULL;
1692  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1699  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1700  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1701  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1702  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1704 
1705  TEST_END;
1706  PASS;
1707 }
1708 
1709 /**
1710  * \test GET -> RUBBISH(PM AND PP DONE IN ONE GO)
1711  */
1712 static int AppLayerTest03(void)
1713 {
1714  TEST_START;
1715 
1716  /* request */
1717  uint8_t request[] = {
1718  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1719  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1720  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1721  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1722  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1723  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1724  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1725  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1726  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1727  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1728  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1729  tcph.th_ack = htonl(1);
1730  tcph.th_seq = htonl(1);
1731  tcph.th_flags = TH_PUSH | TH_ACK;
1733  p->payload_len = sizeof(request);
1734  p->payload = request;
1735  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1742  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1743  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1744  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1745  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1746  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1747 
1748  /* rubbish response */
1749  uint8_t response[] = {
1750  0x58, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
1751  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1752  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1753  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1754  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1755  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1756  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1757  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1758  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1759  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1760  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1761  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1762  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1763  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1764  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1765  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1766  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1767  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1768  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1769  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1770  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1771  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1772  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1773  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1774  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1775  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1776  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1777  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1778  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1779  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1780  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1781  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1782  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1783  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1784  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1785  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1786  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1787  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1788  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1789  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1790  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1791  tcph.th_ack = htonl(88);
1792  tcph.th_seq = htonl(1);
1793  tcph.th_flags = TH_PUSH | TH_ACK;
1795  p->payload_len = sizeof(response);
1796  p->payload = response;
1797  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1804  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1805  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1806  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1807  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1809 
1810  /* response ack */
1811  tcph.th_ack = htonl(328);
1812  tcph.th_seq = htonl(88);
1813  tcph.th_flags = TH_ACK;
1815  p->payload_len = 0;
1816  p->payload = NULL;
1817  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1824  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1825  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1826  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1827  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1829 
1830  TEST_END;
1831  PASS;
1832 }
1833 
1834 /**
1835  * \test GE -> RUBBISH(TC - PM AND PP NOT DONE) -> RUBBISH(TC - PM AND PP DONE).
1836  */
1837 static int AppLayerTest04(void)
1838 {
1839  TEST_START;
1840 
1841  /* request */
1842  uint8_t request[] = {
1843  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1844  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1845  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1846  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1847  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1848  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1849  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1850  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1851  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1852  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1853  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1854  PrintRawDataFp(stdout, request, sizeof(request));
1855  tcph.th_ack = htonl(1);
1856  tcph.th_seq = htonl(1);
1857  tcph.th_flags = TH_PUSH | TH_ACK;
1859  p->payload_len = sizeof(request);
1860  p->payload = request;
1861  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1868  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1869  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1870  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1871  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1872  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER); // TOSERVER data now seen
1873 
1874  /* partial response */
1875  uint8_t response1[] = { 0x58, 0x54, 0x54, 0x50, };
1876  PrintRawDataFp(stdout, response1, sizeof(response1));
1877  tcph.th_ack = htonl(88);
1878  tcph.th_seq = htonl(1);
1879  tcph.th_flags = TH_PUSH | TH_ACK;
1881  p->payload_len = sizeof(response1);
1882  p->payload = response1;
1883  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1886  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
1887  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
1890  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1891  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1892  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1893  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1894  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
1895 
1896  /* partial response ack */
1897  tcph.th_ack = htonl(5);
1898  tcph.th_seq = htonl(88);
1899  tcph.th_flags = TH_ACK;
1901  p->payload_len = 0;
1902  p->payload = NULL;
1903  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1906  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
1907  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
1910  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1911  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1912  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1913  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
1914  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
1915 
1916  /* remaining response */
1917  uint8_t response2[] = {
1918  0x2f, 0x31, 0x2e, 0x31,
1919  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1920  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1921  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1922  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1923  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1924  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1925  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1926  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1927  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1928  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1929  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1930  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1931  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1932  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1933  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1934  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1935  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1936  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1937  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1938  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1939  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1940  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1941  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1942  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1943  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1944  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1945  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1946  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1947  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1948  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1949  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1950  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1951  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1952  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1953  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1954  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1955  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1956  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1957  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1958  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1959  PrintRawDataFp(stdout, response2, sizeof(response2));
1960  tcph.th_ack = htonl(88);
1961  tcph.th_seq = htonl(5);
1962  tcph.th_flags = TH_PUSH | TH_ACK;
1964  p->payload_len = sizeof(response2);
1965  p->payload = response2;
1966  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1969  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
1970  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
1973  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1974  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1975  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1976  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
1977  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
1978 
1979  /* response ack */
1980  tcph.th_ack = htonl(328);
1981  tcph.th_seq = htonl(88);
1982  tcph.th_flags = TH_ACK;
1984  p->payload_len = 0;
1985  p->payload = NULL;
1986  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1987  FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); // toclient complete (failed)
1989  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
1990  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
1991  FAIL_IF(f.alproto_tc != ALPROTO_FAILED); // tc failed
1993  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1994  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1995  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1996  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
1997  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
1998 
1999  TEST_END;
2000  PASS;
2001 }
2002 
2003 /**
2004  * \test RUBBISH -> HTTP/1.1
2005  */
2006 static int AppLayerTest05(void)
2007 {
2008  TEST_START;
2009 
2010  /* full request */
2011  uint8_t request[] = {
2012  0x48, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2013  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
2014  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
2015  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
2016  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
2017  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
2018  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
2019  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
2020  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2021  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
2022  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2023  PrintRawDataFp(stdout, request, sizeof(request));
2024  tcph.th_ack = htonl(1);
2025  tcph.th_seq = htonl(1);
2026  tcph.th_flags = TH_PUSH | TH_ACK;
2028  p->payload_len = sizeof(request);
2029  p->payload = request;
2030  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2037  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2038  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2039  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2040  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2041  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2042 
2043  /* full response - request ack */
2044  uint8_t response[] = {
2045  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2046  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2047  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2048  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2049  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2050  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2051  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2052  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2053  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2054  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2055  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2056  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2057  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2058  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2059  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2060  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2061  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2062  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2063  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2064  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2065  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2066  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2067  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2068  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2069  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2070  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2071  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2072  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2073  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2074  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2075  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2076  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2077  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2078  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2079  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2080  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2081  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2082  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2083  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2084  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2085  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2086  PrintRawDataFp(stdout, response, sizeof(response));
2087  tcph.th_ack = htonl(88);
2088  tcph.th_seq = htonl(1);
2089  tcph.th_flags = TH_PUSH | TH_ACK;
2091  p->payload_len = sizeof(response);
2092  p->payload = response;
2093  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2100  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2101  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2102  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2103  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2104  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2105 
2106  /* response ack */
2107  tcph.th_ack = htonl(328);
2108  tcph.th_seq = htonl(88);
2109  tcph.th_flags = TH_ACK;
2111  p->payload_len = 0;
2112  p->payload = NULL;
2113  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2120  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2121  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2122  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2123  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2125 
2126  TEST_END;
2127  PASS;
2128 }
2129 
2130 /**
2131  * \test HTTP/1.1 -> GET
2132  */
2133 static int AppLayerTest06(void)
2134 {
2135  TEST_START;
2136 
2137  /* full response - request ack */
2138  uint8_t response[] = {
2139  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2140  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2141  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2142  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2143  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2144  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2145  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2146  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2147  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2148  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2149  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2150  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2151  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2152  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2153  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2154  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2155  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2156  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2157  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2158  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2159  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2160  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2161  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2162  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2163  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2164  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2165  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2166  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2167  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2168  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2169  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2170  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2171  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2172  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2173  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2174  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2175  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2176  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2177  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2178  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2179  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2180  tcph.th_ack = htonl(1);
2181  tcph.th_seq = htonl(1);
2182  tcph.th_flags = TH_PUSH | TH_ACK;
2184  p->payload_len = sizeof(response);
2185  p->payload = response;
2186  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2193  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2194  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2195  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2196  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2197  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOCLIENT);
2198 
2199  /* full request - response ack*/
2200  uint8_t request[] = {
2201  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2202  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
2203  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
2204  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
2205  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
2206  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
2207  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
2208  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
2209  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2210  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
2211  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2212  tcph.th_ack = htonl(328);
2213  tcph.th_seq = htonl(1);
2214  tcph.th_flags = TH_PUSH | TH_ACK;
2216  p->payload_len = sizeof(request);
2217  p->payload = request;
2218  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2225  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2226  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2227  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2228  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2230 
2231  tcph.th_ack = htonl(1 + sizeof(request));
2232  tcph.th_seq = htonl(328);
2233  tcph.th_flags = TH_PUSH | TH_ACK;
2235  p->payload_len = 0;
2236  p->payload = NULL;
2237  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2244  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2245  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2246  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2247  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2249 
2250  TEST_END;
2251  PASS;
2252 }
2253 
2254 /**
2255  * \test GET -> DCERPC
2256  */
2257 static int AppLayerTest07(void)
2258 {
2259  TEST_START;
2260 
2261  /* full request */
2262  uint8_t request[] = {
2263  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2264  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
2265  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
2266  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
2267  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
2268  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
2269  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
2270  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
2271  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2272  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
2273  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2274  tcph.th_ack = htonl(1);
2275  tcph.th_seq = htonl(1);
2276  tcph.th_flags = TH_PUSH | TH_ACK;
2278  p->payload_len = sizeof(request);
2279  p->payload = request;
2280  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2287  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2288  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2289  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2290  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2291  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2292 
2293  /* full response - request ack */
2294  uint8_t response[] = { 0x05, 0x00, 0x4d, 0x42, 0x00, 0x01, 0x2e, 0x31, 0x20, 0x32, 0x30, 0x30,
2295  0x20, 0x4f, 0x4b, 0x0d, 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, 0x72, 0x69, 0x2c,
2296  0x20, 0x32, 0x33, 0x20, 0x53, 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20, 0x30, 0x36,
2297  0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, 0x72,
2298  0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2299  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69, 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f,
2300  0x32, 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65,
2301  0x64, 0x3a, 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34, 0x20, 0x4e, 0x6f, 0x76, 0x20,
2302  0x32, 0x30, 0x31, 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a, 0x34, 0x36, 0x20, 0x47,
2303  0x4d, 0x54, 0x0d, 0x0a, 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61, 0x62, 0x38, 0x39,
2304  0x36, 0x35, 0x2d, 0x32, 0x63, 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61, 0x37, 0x66,
2305  0x37, 0x66, 0x38, 0x30, 0x22, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x52,
2306  0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2307  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20,
2308  0x34, 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a,
2309  0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
2310  0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d,
2311  0x6c, 0x0d, 0x0a, 0x58, 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64,
2312  0x20, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d, 0x0a, 0x0d,
2313  0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x68,
2314  0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2315  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2316  tcph.th_ack = htonl(88);
2317  tcph.th_seq = htonl(1);
2318  tcph.th_flags = TH_PUSH | TH_ACK;
2320  p->payload_len = sizeof(response);
2321  p->payload = response;
2322  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2329  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2330  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2331  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2332  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2334 
2335  /* response ack */
2336  tcph.th_ack = htonl(328);
2337  tcph.th_seq = htonl(88);
2338  tcph.th_flags = TH_ACK;
2340  p->payload_len = 0;
2341  p->payload = NULL;
2342  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2349  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2350  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2351  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2352  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2354 
2355  TEST_END;
2356  PASS;
2357 }
2358 
2359 /**
2360  * \test SMB -> HTTP/1.1
2361  */
2362 static int AppLayerTest08(void)
2363 {
2364  TEST_START;
2365 
2366  /* full request */
2367  uint8_t request[] = { 0x05, 0x00, 0x54, 0x20, 0x00, 0x01, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68,
2368  0x74, 0x6d, 0x6c, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x0d, 0x0a, 0x48,
2369  0x6f, 0x73, 0x74, 0x3a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x0d,
2370  0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41, 0x70,
2371  0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2372  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2373  tcph.th_ack = htonl(1);
2374  tcph.th_seq = htonl(1);
2375  tcph.th_flags = TH_PUSH | TH_ACK;
2377  p->payload_len = sizeof(request);
2378  p->payload = request;
2379  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2386  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2387  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2388  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2389  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2390  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2391 
2392  /* full response - request ack */
2393  uint8_t response[] = {
2394  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2395  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2396  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2397  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2398  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2399  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2400  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2401  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2402  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2403  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2404  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2405  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2406  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2407  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2408  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2409  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2410  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2411  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2412  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2413  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2414  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2415  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2416  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2417  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2418  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2419  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2420  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2421  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2422  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2423  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2424  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2425  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2426  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2427  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2428  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2429  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2430  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2431  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2432  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2433  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2434  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2435  tcph.th_ack = htonl(88);
2436  tcph.th_seq = htonl(1);
2437  tcph.th_flags = TH_PUSH | TH_ACK;
2439  p->payload_len = sizeof(response);
2440  p->payload = response;
2441  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2448  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2449  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2450  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2451  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2453 
2454  /* response ack */
2455  tcph.th_ack = htonl(328);
2456  tcph.th_seq = htonl(88);
2457  tcph.th_flags = TH_ACK;
2459  p->payload_len = 0;
2460  p->payload = NULL;
2461  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2468  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2469  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2470  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2471  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2473 
2474  TEST_END;
2475  PASS;
2476 }
2477 
2478 /**
2479  * \test RUBBISH(TC - PM and PP NOT DONE) ->
2480  * RUBBISH(TC - PM and PP DONE) ->
2481  * RUBBISH(TS - PM and PP DONE)
2482  */
2483 static int AppLayerTest09(void)
2484 {
2485  TEST_START;
2486 
2487  /* full request */
2488  uint8_t request1[] = {
2489  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64 };
2490  tcph.th_ack = htonl(1);
2491  tcph.th_seq = htonl(1);
2492  tcph.th_flags = TH_PUSH | TH_ACK;
2494  p->payload_len = sizeof(request1);
2495  p->payload = request1;
2496  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2503  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2504  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2505  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2506  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2507  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2508 
2509  /* response - request ack */
2510  tcph.th_ack = htonl(9);
2511  tcph.th_seq = htonl(1);
2512  tcph.th_flags = TH_PUSH | TH_ACK;
2514  p->payload_len = 0;
2515  p->payload = NULL;
2516  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2523  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2524  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2525  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2526  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2527  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2528 
2529  /* full request */
2530  uint8_t request2[] = {
2531  0x44, 0x44, 0x45, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff };
2532  tcph.th_ack = htonl(1);
2533  tcph.th_seq = htonl(9);
2534  tcph.th_flags = TH_PUSH | TH_ACK;
2536  p->payload_len = sizeof(request2);
2537  p->payload = request2;
2538  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2545  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2546  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2547  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2548  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2549  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2550 
2551  /* full response - request ack */
2552  uint8_t response[] = {
2553  0x55, 0x74, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2554  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2555  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2556  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2557  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2558  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2559  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2560  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2561  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2562  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2563  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2564  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2565  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2566  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2567  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2568  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2569  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2570  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2571  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2572  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2573  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2574  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2575  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2576  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2577  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2578  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2579  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2580  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2581  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2582  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2583  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2584  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2585  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2586  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2587  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2588  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2589  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2590  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2591  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2592  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2593  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2594  tcph.th_ack = htonl(18);
2595  tcph.th_seq = htonl(1);
2596  tcph.th_flags = TH_PUSH | TH_ACK;
2598  p->payload_len = sizeof(response);
2599  p->payload = response;
2600  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2607  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2608  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2609  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2610  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2611  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2612 
2613  /* response ack */
2614  tcph.th_ack = htonl(328);
2615  tcph.th_seq = htonl(18);
2616  tcph.th_flags = TH_ACK;
2618  p->payload_len = 0;
2619  p->payload = NULL;
2620  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2627  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2628  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2629  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2630  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2632 
2633  TEST_END;
2634  PASS;
2635 }
2636 
2637 /**
2638  * \test RUBBISH(TC - PM and PP DONE) ->
2639  * RUBBISH(TS - PM and PP DONE)
2640  */
2641 static int AppLayerTest10(void)
2642 {
2643  TEST_START;
2644 
2645  /* full request */
2646  uint8_t request1[] = {
2647  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2648  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff };
2649  tcph.th_ack = htonl(1);
2650  tcph.th_seq = htonl(1);
2651  tcph.th_flags = TH_PUSH | TH_ACK;
2653  p->payload_len = sizeof(request1);
2654  p->payload = request1;
2655  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2662  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2663  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2664  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2665  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2666  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2667 
2668  /* response - request ack */
2669  tcph.th_ack = htonl(18);
2670  tcph.th_seq = htonl(1);
2671  tcph.th_flags = TH_PUSH | TH_ACK;
2673  p->payload_len = 0;
2674  p->payload = NULL;
2675  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2682  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2683  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2684  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2685  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2686  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2687 
2688  /* full response - request ack */
2689  uint8_t response[] = {
2690  0x55, 0x74, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2691  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2692  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2693  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2694  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2695  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2696  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2697  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2698  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2699  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2700  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2701  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2702  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2703  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2704  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2705  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2706  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2707  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2708  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2709  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2710  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2711  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2712  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2713  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2714  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2715  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2716  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2717  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2718  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2719  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2720  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2721  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2722  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2723  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2724  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2725  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2726  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2727  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2728  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2729  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2730  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2731  tcph.th_ack = htonl(18);
2732  tcph.th_seq = htonl(1);
2733  tcph.th_flags = TH_PUSH | TH_ACK;
2735  p->payload_len = sizeof(response);
2736  p->payload = response;
2737  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2744  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2745  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2746  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2747  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2748  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2749 
2750  /* response ack */
2751  tcph.th_ack = htonl(328);
2752  tcph.th_seq = htonl(18);
2753  tcph.th_flags = TH_ACK;
2755  p->payload_len = 0;
2756  p->payload = NULL;
2757  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2764  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2765  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2766  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2767  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2769 
2770  TEST_END;
2771  PASS;
2772 }
2773 
2774 /**
2775  * \test RUBBISH(TC - PM and PP DONE) ->
2776  * RUBBISH(TS - PM and PP NOT DONE) ->
2777  * RUBBISH(TS - PM and PP DONE)
2778  */
2779 static int AppLayerTest11(void)
2780 {
2781  TEST_START;
2782 
2783  /* full request */
2784  uint8_t request1[] = {
2785  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2786  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff };
2787  tcph.th_ack = htonl(1);
2788  tcph.th_seq = htonl(1);
2789  tcph.th_flags = TH_PUSH | TH_ACK;
2791  p->payload_len = sizeof(request1);
2792  p->payload = request1;
2793  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2800  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2801  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2802  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2803  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2804  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2805 
2806  /* response - request ack */
2807  tcph.th_ack = htonl(18);
2808  tcph.th_seq = htonl(1);
2809  tcph.th_flags = TH_PUSH | TH_ACK;
2811  p->payload_len = 0;
2812  p->payload = NULL;
2813  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2820  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2821  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2822  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2823  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2824  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2825 
2826  /* full response - request ack */
2827  uint8_t response1[] = {
2828  0x55, 0x74, 0x54, 0x50, };
2829  tcph.th_ack = htonl(18);
2830  tcph.th_seq = htonl(1);
2831  tcph.th_flags = TH_PUSH | TH_ACK;
2833  p->payload_len = sizeof(response1);
2834  p->payload = response1;
2835  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2842  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2843  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2844  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2845  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2846  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2847 
2848  /* response ack from request */
2849  tcph.th_ack = htonl(5);
2850  tcph.th_seq = htonl(18);
2851  tcph.th_flags = TH_ACK;
2853  p->payload_len = 0;
2854  p->payload = NULL;
2855  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2862  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2863  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2864  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2865  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2866  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2867 
2868  uint8_t response2[] = {
2869  0x2f, 0x31, 0x2e, 0x31,
2870  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2871  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2872  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2873  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2874  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2875  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2876  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2877  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2878  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2879  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2880  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2881  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2882  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2883  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2884  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2885  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2886  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2887  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2888  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2889  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2890  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2891  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2892  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2893  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2894  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2895  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2896  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2897  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2898  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2899  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2900  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2901  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2902  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2903  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2904  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2905  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2906  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2907  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2908  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2909  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2910  tcph.th_ack = htonl(18);
2911  tcph.th_seq = htonl(5);
2912  tcph.th_flags = TH_PUSH | TH_ACK;
2914  p->payload_len = sizeof(response2);
2915  p->payload = response2;
2916  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2923  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2924  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2925  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2926  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2927  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2928 
2929  /* response ack from request */
2930  tcph.th_ack = htonl(328);
2931  tcph.th_seq = htonl(18);
2932  tcph.th_flags = TH_ACK;
2934  p->payload_len = 0;
2935  p->payload = NULL;
2936  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2943  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2944  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2945  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2946  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2948 
2949  TEST_END;
2950  PASS;
2951 }
2952 
2954 {
2955  SCEnter();
2956 
2957  UtRegisterTest("AppLayerTest01", AppLayerTest01);
2958  UtRegisterTest("AppLayerTest02", AppLayerTest02);
2959  UtRegisterTest("AppLayerTest03", AppLayerTest03);
2960  UtRegisterTest("AppLayerTest04", AppLayerTest04);
2961  UtRegisterTest("AppLayerTest05", AppLayerTest05);
2962  UtRegisterTest("AppLayerTest06", AppLayerTest06);
2963  UtRegisterTest("AppLayerTest07", AppLayerTest07);
2964  UtRegisterTest("AppLayerTest08", AppLayerTest08);
2965  UtRegisterTest("AppLayerTest09", AppLayerTest09);
2966  UtRegisterTest("AppLayerTest10", AppLayerTest10);
2967  UtRegisterTest("AppLayerTest11", AppLayerTest11);
2968 
2969  SCReturn;
2970 }
2971 
2972 #endif /* UNITTESTS */
AppLayerCounters_::alloc_error_id
uint16_t alloc_error_id
Definition: app-layer.c:94
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:89
FLOW_RESET_PP_DONE
#define FLOW_RESET_PP_DONE(f, dir)
Definition: flow.h:287
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:194
Packet_::proto
uint8_t proto
Definition: decode.h:498
AppLayerParserDeSetup
int AppLayerParserDeSetup(void)
Definition: app-layer-parser.c:269
TcpStream_
Definition: stream-tcp-private.h:106
APPLAYER_UNEXPECTED_PROTOCOL
@ APPLAYER_UNEXPECTED_PROTOCOL
Definition: app-layer-events.h:54
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:91
AppLayerCounters_
Definition: app-layer.c:88
ippair.h
app-layer-htp-range.h
FlowCleanupAppLayer
void FlowCleanupAppLayer(Flow *f)
Definition: flow.c:137
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:85
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:90
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:101
stream-tcp.h
StreamTcpInlineMode
bool StreamTcpInlineMode(void)
See if stream engine is operating in inline mode.
Definition: stream-tcp.c:7137
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:595
AppLayerCounterNames_::parser_error
char parser_error[MAX_COUNTER_SIZE]
Definition: app-layer.c:82
StatsRegisterGlobalCounter
uint16_t StatsRegisterGlobalCounter(const char *name, uint64_t(*Func)(void))
Registers a counter, which represents a global value.
Definition: counters.c:1009
AppLayerProfilingStoreInternal
void AppLayerProfilingStoreInternal(AppLayerThreadCtx *app_tctx, Packet *p)
Definition: app-layer.c:1103
Flow_::proto
uint8_t proto
Definition: flow.h:378
AppProto
uint16_t AppProto
Definition: app-layer-protos.h:81
Packet_::payload
uint8_t * payload
Definition: decode.h:574
TcpReassemblyThreadCtx_::app_tctx
void * app_tctx
Definition: stream-tcp-reassemble.h:62
Packet_::flags
uint32_t flags
Definition: decode.h:513
AppLayerThreadCtx_::proto_detect_ticks_spent
uint64_t proto_detect_ticks_spent
Definition: app-layer.c:71
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:75
AppLayerThreadCtx_::alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: app-layer.c:62
flow-private.h
Flow_
Flow data structure.
Definition: flow.h:356
AppLayerIncGapErrorCounter
void AppLayerIncGapErrorCounter(ThreadVars *tv, Flow *f)
Definition: app-layer.c:162
AppLayerCounters_::internal_error_id
uint16_t internal_error_id
Definition: app-layer.c:93
Flow_::protomap
uint8_t protomap
Definition: flow.h:450
AppProtoToString
const char * AppProtoToString(AppProto alproto)
Maps the ALPROTO_*, to its string equivalent.
Definition: app-layer-protos.c:75
AppLayerThreadCtx_::ticks_spent
uint64_t ticks_spent
Definition: app-layer.c:67
ExceptionPolicyStatsSetts_
Definition: util-exception-policy-types.h:48
AppLayerParserGetFirstDataDir
uint8_t AppLayerParserGetFirstDataDir(uint8_t ipproto, AppProto alproto)
Definition: app-layer-parser.c:1130
g_stats_eps_per_app_proto_errors
bool g_stats_eps_per_app_proto_errors
Definition: suricata.c:213
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:1398
StreamTcpResetStreamFlagAppProtoDetectionCompleted
#define StreamTcpResetStreamFlagAppProtoDetectionCompleted(stream)
Definition: stream-tcp-private.h:305
AppLayerRegisterThreadCounters
void AppLayerRegisterThreadCounters(ThreadVars *tv)
Registers per flow counters for all protocols.
Definition: app-layer.c:1250
Flow_::alproto_orig
AppProto alproto_orig
Definition: flow.h:461
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:1098
AppLayerCounterNames_
Definition: app-layer.c:78
AppLayerParserStateProtoCleanup
void AppLayerParserStateProtoCleanup(uint8_t protomap, AppProto alproto, void *alstate, AppLayerParserState *pstate)
Definition: app-layer-parser.c:1599
AppLayerParserThreadCtxFree
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
Definition: app-layer-parser.c:300
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:708
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:6708
app_layer_error_eps_stats
ExceptionPolicyStatsSetts app_layer_error_eps_stats
Definition: app-layer.c:107
stream-tcp-reassemble.h
AppLayerThreadCtx_::proto_detect_ticks_end
uint64_t proto_detect_ticks_end
Definition: app-layer.c:70
TcpStream_::flags
uint16_t flags
Definition: stream-tcp-private.h:107
AppLayerUnittestsRegister
void AppLayerUnittestsRegister(void)
Definition: app-layer.c:2953
APPLAYER_PROTO_DETECTION_SKIPPED
@ APPLAYER_PROTO_DETECTION_SKIPPED
Definition: app-layer-events.h:52
HTPMemuseGlobalCounter
uint64_t HTPMemuseGlobalCounter(void)
Definition: app-layer-htp-mem.c:81
AppLayerListSupportedProtocols
void AppLayerListSupportedProtocols(void)
Definition: app-layer.c:1013
AppLayerSetupCounters
void AppLayerSetupCounters(void)
Definition: app-layer.c:1150
app-layer-ftp.h
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:507
AppLayerThreadCtx_::alproto
AppProto alproto
Definition: app-layer.c:68
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:76
Flow_::protoctx
void * protoctx
Definition: flow.h:446
AppLayerCounterNames_::tx_name
char tx_name[MAX_COUNTER_SIZE]
Definition: app-layer.c:80
AppLayerIncAllocErrorCounter
void AppLayerIncAllocErrorCounter(ThreadVars *tv, Flow *f)
Definition: app-layer.c:170
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:575
Packet_::app_layer_events
AppLayerDecoderEvents * app_layer_events
Definition: decode.h:601
util-unittest.h
AppLayerGetProtoByName
AppProto AppLayerGetProtoByName(char *alproto_name)
Given a protocol string, returns the corresponding internal protocol id.
Definition: app-layer.c:999
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:92
AppLayerDeSetup
int AppLayerDeSetup(void)
De initializes the app layer.
Definition: app-layer.c:1048
HostGetMemcap
uint64_t HostGetMemcap(void)
Return memcap value.
Definition: host.c:83
PKT_PROTO_DETECT_TS_DONE
#define PKT_PROTO_DETECT_TS_DONE
Definition: decode.h:1301
MAX_COUNTER_SIZE
#define MAX_COUNTER_SIZE
Definition: app-layer.c:77
STREAMTCP_FLAG_MIDSTREAM
#define STREAMTCP_FLAG_MIDSTREAM
Definition: stream-tcp-private.h:170
TcpSession_::flags
uint32_t flags
Definition: stream-tcp-private.h:294
FLOW_IS_PM_DONE
#define FLOW_IS_PM_DONE(f, dir)
Definition: flow.h:278
APPLAYER_NO_TLS_AFTER_STARTTLS
@ APPLAYER_NO_TLS_AFTER_STARTTLS
Definition: app-layer-events.h:53
Flow_::alparser
AppLayerParserState * alparser
Definition: flow.h:480
EXCEPTION_POLICY_MAX
#define EXCEPTION_POLICY_MAX
Definition: util-exception-policy-types.h:36
AppLayerParserRegisterProtocolParsers
void AppLayerParserRegisterProtocolParsers(void)
Definition: app-layer-parser.c:1701
AppLayerThreadCtx_::proto_detect_ticks_start
uint64_t proto_detect_ticks_start
Definition: app-layer.c:69
AppLayerSetup
int AppLayerSetup(void)
Setup the app layer.
Definition: app-layer.c:1033
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:129
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:49
FLOW_IS_PP_DONE
#define FLOW_IS_PP_DONE(f, dir)
Definition: flow.h:279
AppLayerRegisterGlobalCounters
void AppLayerRegisterGlobalCounters(void)
HACK to work around our broken unix manager (re)init loop.
Definition: app-layer.c:1111
PKT_DROP_REASON_APPLAYER_ERROR
@ PKT_DROP_REASON_APPLAYER_ERROR
Definition: decode.h:366
AppLayerThreadCtx_::ticks_end
uint64_t ticks_end
Definition: app-layer.c:66
PacketSwap
void PacketSwap(Packet *p)
switch direction of a packet
Definition: decode.c:551
util-exception-policy.h
HTPByteRangeMemuseGlobalCounter
uint64_t HTPByteRangeMemuseGlobalCounter(void)
Definition: app-layer-htp-range.c:61
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:58
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:58
pkt-var.h
StreamTcpPacket
int StreamTcpPacket(ThreadVars *tv, Packet *p, StreamTcpThread *stt, PacketQueueNoLock *pq)
Definition: stream-tcp.c:5567
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:1328
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
HostGetMemuse
uint64_t HostGetMemuse(void)
Return memuse value.
Definition: host.c:94
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:111
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:248
SCReturn
#define SCReturn
Definition: util-debug.h:273
FLOW_RESET_PM_DONE
#define FLOW_RESET_PM_DONE(f, dir)
Definition: flow.h:286
stream.h
FlowGetProtoMapping
uint8_t FlowGetProtoMapping(uint8_t proto)
Function to map the protocol to the defined FLOW_PROTO_* enumeration.
Definition: flow-util.c:98
StreamTcpIsSetStreamFlagAppProtoDetectionCompleted
#define StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(stream)
Definition: stream-tcp-private.h:303
Packet_
Definition: decode.h:476
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:875
DEBUG_ASSERT_FLOW_LOCKED
#define DEBUG_ASSERT_FLOW_LOCKED(f)
Definition: util-validate.h:99
StreamTcpSetStreamFlagAppProtoDetectionCompleted
#define StreamTcpSetStreamFlagAppProtoDetectionCompleted(stream)
Definition: stream-tcp-private.h:301
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:60
StreamDataAvailableForProtoDetect
uint32_t StreamDataAvailableForProtoDetect(TcpStream *stream)
Definition: stream-tcp-reassemble.c:723
AppLayerGetCtxThread
AppLayerThreadCtx * AppLayerGetCtxThread(void)
Creates a new app layer thread context.
Definition: app-layer.c:1060
AppLayerThreadCtx_::ticks_start
uint64_t ticks_start
Definition: app-layer.c:65
AppLayerIncParserErrorCounter
void AppLayerIncParserErrorCounter(ThreadVars *tv, Flow *f)
Definition: app-layer.c:178
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:464
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:279
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:1272
StreamTcpDisableAppLayer
void StreamTcpDisableAppLayer(Flow *f)
Definition: stream-tcp-reassemble.c:448
suricata-common.h
FLOW_RESET_PE_DONE
#define FLOW_RESET_PE_DONE(f, dir)
Definition: flow.h:288
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:94
IPPairGetMemuse
uint64_t IPPairGetMemuse(void)
Return memuse value.
Definition: ippair.c:92
Packet_::app_update_direction
uint8_t app_update_direction
Definition: decode.h:510
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:186
eps_error_summary
ExceptionPolicyCounters eps_error_summary
Definition: app-layer.c:103
APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION
@ APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION
Definition: app-layer-events.h:51
STREAMTCP_FLAG_MIDSTREAM_SYNACK
#define STREAMTCP_FLAG_MIDSTREAM_SYNACK
Definition: stream-tcp-private.h:174
TcpSession_::client
TcpStream client
Definition: stream-tcp-private.h:297
PKT_PROTO_DETECT_TC_DONE
#define PKT_PROTO_DETECT_TC_DONE
Definition: decode.h:1302
AppLayerParserGetStreamDepth
uint32_t AppLayerParserGetStreamDepth(const Flow *f)
Definition: app-layer-parser.c:1560
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
util-validate.h
FlowSwap
void FlowSwap(Flow *f)
swap the flow's direction
Definition: flow.c:255
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:296
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:81
Flow_::alproto_ts
AppProto alproto_ts
Definition: flow.h:456
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:7143
Flow_::alstate
void * alstate
Definition: flow.h:481
AppLayerDestroyCtxThread
void AppLayerDestroyCtxThread(AppLayerThreadCtx *app_tctx)
Destroys the context created by AppLayerGetCtxThread().
Definition: app-layer.c:1081
PACKET_PROFILING_APP_START
#define PACKET_PROFILING_APP_START(dp, id)
Definition: util-profiling.h:167
HTPByteRangeMemcapGlobalCounter
uint64_t HTPByteRangeMemcapGlobalCounter(void)
Definition: app-layer-htp-range.c:55
Flow_::flags
uint32_t flags
Definition: flow.h:426
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:1006
g_applayerparser_error_policy
enum ExceptionPolicy g_applayerparser_error_policy
Definition: app-layer-parser.c:149
AppLayerCounters_::eps_error
ExceptionPolicyCounters eps_error
Definition: app-layer.c:95
AppLayerIncTxCounter
void AppLayerIncTxCounter(ThreadVars *tv, Flow *f, uint64_t step)
Definition: app-layer.c:154
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:83
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:228
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:1410
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:99
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:58
AppLayerCounterNames_::name
char name[MAX_COUNTER_SIZE]
Definition: app-layer.c:79
FlowChangeProto
int FlowChangeProto(Flow *f)
Check if change proto flag is set for flow.
Definition: flow.c:204
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:457
FLOW_PROTO_CHANGE_MAX_DEPTH
#define FLOW_PROTO_CHANGE_MAX_DEPTH
Definition: app-layer.c:75
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:455
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:951
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
AppLayerCounterNames_::alloc_error
char alloc_error[MAX_COUNTER_SIZE]
Definition: app-layer.c:84
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:50
AppLayerDeSetupCounters
void AppLayerDeSetupCounters(void)
Definition: app-layer.c:1314
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