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  if (alproto == ALPROTO_UNKNOWN) {
740  SCLogDebug("ALPROTO_UNKNOWN flow %p, due to GAP in stream start", f);
741  /* if the other side didn't already find the proto, we're done */
742  if (f->alproto == ALPROTO_UNKNOWN) {
743  goto failure;
744  }
745  AppLayerIncFlowCounter(tv, f);
746  }
747  if (FlowChangeProto(f)) {
749  SCLogDebug("Cannot handle gap while changing protocol");
750  goto failure;
751  }
752  PACKET_PROFILING_APP_START(app_tctx, f->alproto);
753  r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto,
754  flags, data, data_len);
755  PACKET_PROFILING_APP_END(app_tctx);
756  p->app_update_direction = (uint8_t)app_update_dir;
757  /* ignore parser result for gap */
758  StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
759  if (r < 0) {
761  AppLayerIncrErrorExcPolicyCounter(tv, f, g_applayerparser_error_policy);
762  SCReturnInt(-1);
763  }
764  goto end;
765  }
766 
767  /* if we don't know the proto yet and we have received a stream
768  * initializer message, we run proto detection.
769  * We receive 2 stream init msgs (one for each direction), we
770  * only run the proto detection for both and emit an event
771  * in the case protocols mismatch. */
772  if (alproto == ALPROTO_UNKNOWN && (flags & STREAM_START)) {
774  /* run protocol detection */
775  if (TCPProtoDetect(tv, ra_ctx, app_tctx, p, f, ssn, stream, data, data_len, flags,
776  app_update_dir) != 0) {
777  goto failure;
778  }
779  } else if (alproto != ALPROTO_UNKNOWN && FlowChangeProto(f)) {
780  SCLogDebug("protocol change, old %s", AppProtoToString(f->alproto_orig));
781  void *alstate_orig = f->alstate;
782  AppLayerParserState *alparser = f->alparser;
783  // we delay AppLayerParserStateCleanup because we may need previous parser state
787  /* rerun protocol detection */
788  int rd = TCPProtoDetect(
789  tv, ra_ctx, app_tctx, p, f, ssn, stream, data, data_len, flags, app_update_dir);
790  if (f->alproto == ALPROTO_UNKNOWN) {
791  DEBUG_VALIDATE_BUG_ON(alstate_orig != f->alstate);
792  // not enough data, revert AppLayerProtoDetectReset to rerun detection
793  f->alparser = alparser;
794  f->alproto = f->alproto_orig;
795  f->alproto_tc = f->alproto_orig;
796  f->alproto_ts = f->alproto_orig;
797  } else {
799  AppLayerParserStateProtoCleanup(f->protomap, f->alproto_orig, alstate_orig, alparser);
800  if (alstate_orig == f->alstate) {
801  // we just freed it
802  f->alstate = NULL;
803  }
804  }
805  if (rd != 0) {
806  SCLogDebug("proto detect failure");
807  goto failure;
808  }
809  SCLogDebug("protocol change, old %s, new %s",
811 
813  f->alproto != f->alproto_expect) {
816 
817  if (f->alproto_expect == ALPROTO_TLS && f->alproto != ALPROTO_TLS) {
820 
821  }
822  }
823  } else {
824  SCLogDebug("stream data (len %" PRIu32 " alproto "
825  "%"PRIu16" (flow %p)", data_len, f->alproto, f);
826 #ifdef PRINT
827  if (data_len > 0) {
828  printf("=> Stream Data (app layer) -- start %s%s\n",
829  flags & STREAM_TOCLIENT ? "toclient" : "",
830  flags & STREAM_TOSERVER ? "toserver" : "");
831  PrintRawDataFp(stdout, data, data_len);
832  printf("=> Stream Data -- end\n");
833  }
834 #endif
835  /* if we don't have a data object here we are not getting it
836  * a start msg should have gotten us one */
837  if (f->alproto != ALPROTO_UNKNOWN) {
838  PACKET_PROFILING_APP_START(app_tctx, f->alproto);
839  r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto,
840  flags, data, data_len);
841  PACKET_PROFILING_APP_END(app_tctx);
842  p->app_update_direction = (uint8_t)app_update_dir;
843  if (r != 1) {
844  StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
845  if (r < 0) {
848  AppLayerIncrErrorExcPolicyCounter(tv, f, g_applayerparser_error_policy);
849  SCReturnInt(-1);
850  }
851  }
852  }
853  }
854 
855  goto end;
856  failure:
857  r = -1;
858  end:
859  SCReturnInt(r);
860 }
861 
862 /**
863  * \brief Handle a app layer UDP message
864  *
865  * If the protocol is yet unknown, the proto detection code is run first.
866  *
867  * \param dp_ctx Thread app layer detect context
868  * \param f *locked* flow
869  * \param p UDP packet
870  *
871  * \retval 0 ok
872  * \retval -1 error
873  */
875 {
876  SCEnter();
877  AppProto *alproto;
878  AppProto *alproto_otherdir;
879 
880  if (f->alproto_ts == ALPROTO_FAILED && f->alproto_tc == ALPROTO_FAILED) {
881  SCReturnInt(0);
882  }
883 
884  int r = 0;
885  uint8_t flags = 0;
886  if (p->flowflags & FLOW_PKT_TOSERVER) {
887  flags |= STREAM_TOSERVER;
888  alproto = &f->alproto_ts;
889  alproto_otherdir = &f->alproto_tc;
890  } else {
891  flags |= STREAM_TOCLIENT;
892  alproto = &f->alproto_tc;
893  alproto_otherdir = &f->alproto_ts;
894  }
895 
897 
898  /* if the protocol is still unknown, run detection */
899  if (*alproto == ALPROTO_UNKNOWN) {
900  SCLogDebug("Detecting AL proto on udp mesg (len %" PRIu32 ")",
901  p->payload_len);
902 
903  bool reverse_flow = false;
905  *alproto = AppLayerProtoDetectGetProto(
906  tctx->alpd_tctx, f, p->payload, p->payload_len, IPPROTO_UDP, flags, &reverse_flow);
908 
909  switch (*alproto) {
910  case ALPROTO_UNKNOWN:
911  if (*alproto_otherdir != ALPROTO_UNKNOWN) {
912  // Use recognized side
913  f->alproto = *alproto_otherdir;
914  // do not keep ALPROTO_UNKNOWN for this side so as not to loop
915  *alproto = *alproto_otherdir;
916  if (*alproto_otherdir == ALPROTO_FAILED) {
917  SCLogDebug("ALPROTO_UNKNOWN flow %p", f);
918  }
919  } else {
920  // First side of protocol is unknown
921  *alproto = ALPROTO_FAILED;
922  }
923  break;
924  case ALPROTO_FAILED:
925  if (*alproto_otherdir != ALPROTO_UNKNOWN) {
926  // Use recognized side
927  f->alproto = *alproto_otherdir;
928  if (*alproto_otherdir == ALPROTO_FAILED) {
929  SCLogDebug("ALPROTO_UNKNOWN flow %p", f);
930  }
931  }
932  // else wait for second side of protocol
933  break;
934  default:
935  if (*alproto_otherdir != ALPROTO_UNKNOWN && *alproto_otherdir != ALPROTO_FAILED) {
936  if (*alproto_otherdir != *alproto) {
939  // data already sent to parser, we cannot change the protocol to use the one
940  // of the server
941  }
942  } else {
943  f->alproto = *alproto;
944  }
945  }
946  if (*alproto_otherdir == ALPROTO_UNKNOWN) {
947  if (f->alproto == ALPROTO_UNKNOWN) {
948  // so as to increase stat about .app_layer.flow.failed_udp
949  f->alproto = ALPROTO_FAILED;
950  }
951  // If the other side is unknown, this is the first packet of the flow
952  AppLayerIncFlowCounter(tv, f);
953  }
954 
955  // parse the data if we recognized one protocol
956  if (f->alproto != ALPROTO_UNKNOWN && f->alproto != ALPROTO_FAILED) {
957  if (reverse_flow) {
958  SCLogDebug("reversing flow after proto detect told us so");
959  PacketSwap(p);
960  FlowSwap(f);
961  SWAP_FLAGS(flags, STREAM_TOSERVER, STREAM_TOCLIENT);
962  }
963 
965  r = AppLayerParserParse(tv, tctx->alp_tctx, f, f->alproto,
966  flags, p->payload, p->payload_len);
969  }
971  /* we do only inspection in one direction, so flag both
972  * sides as done here */
973  FlagPacketFlow(p, f, STREAM_TOSERVER);
974  FlagPacketFlow(p, f, STREAM_TOCLIENT);
975  } else {
976  SCLogDebug("data (len %" PRIu32 " ), alproto "
977  "%"PRIu16" (flow %p)", p->payload_len, f->alproto, f);
978 
979  /* run the parser */
981  r = AppLayerParserParse(tv, tctx->alp_tctx, f, f->alproto,
982  flags, p->payload, p->payload_len);
986  }
987  if (r < 0) {
989  AppLayerIncrErrorExcPolicyCounter(tv, f, g_applayerparser_error_policy);
990  SCReturnInt(-1);
991  }
992 
993  SCReturnInt(r);
994 }
995 
996 /***** Utility *****/
997 
998 AppProto AppLayerGetProtoByName(char *alproto_name)
999 {
1000  SCEnter();
1001  AppProto r = AppLayerProtoDetectGetProtoByName(alproto_name);
1002  SCReturnCT(r, "AppProto");
1003 }
1004 
1005 const char *AppLayerGetProtoName(AppProto alproto)
1006 {
1007  SCEnter();
1008  const char * r = AppLayerProtoDetectGetProtoName(alproto);
1009  SCReturnCT(r, "char *");
1010 }
1011 
1013 {
1014  SCEnter();
1015 
1016  AppProto alproto;
1017  AppProto alprotos[ALPROTO_MAX];
1018 
1020 
1021  printf("=========Supported App Layer Protocols=========\n");
1022  for (alproto = 0; alproto < ALPROTO_MAX; alproto++) {
1023  if (alprotos[alproto] == 1)
1024  printf("%s\n", AppLayerGetProtoName(alproto));
1025  }
1026 
1027  SCReturn;
1028 }
1029 
1030 /***** Setup/General Registration *****/
1031 
1032 int AppLayerSetup(void)
1033 {
1034  SCEnter();
1035 
1038 
1041 
1043 
1044  SCReturnInt(0);
1045 }
1046 
1048 {
1049  SCEnter();
1050 
1053 
1055 
1056  SCReturnInt(0);
1057 }
1058 
1060 {
1061  SCEnter();
1062 
1063  AppLayerThreadCtx *app_tctx = SCCalloc(1, sizeof(*app_tctx));
1064  if (app_tctx == NULL)
1065  goto error;
1066 
1067  if ((app_tctx->alpd_tctx = AppLayerProtoDetectGetCtxThread()) == NULL)
1068  goto error;
1069  if ((app_tctx->alp_tctx = AppLayerParserThreadCtxAlloc()) == NULL)
1070  goto error;
1071 
1072  goto done;
1073  error:
1074  AppLayerDestroyCtxThread(app_tctx);
1075  app_tctx = NULL;
1076  done:
1077  SCReturnPtr(app_tctx, "void *");
1078 }
1079 
1081 {
1082  SCEnter();
1083 
1084  if (app_tctx == NULL)
1085  SCReturn;
1086 
1087  if (app_tctx->alpd_tctx != NULL)
1089  if (app_tctx->alp_tctx != NULL)
1091  SCFree(app_tctx);
1092 
1093  SCReturn;
1094 }
1095 
1096 #ifdef PROFILING
1098 {
1099  PACKET_PROFILING_APP_RESET(app_tctx);
1100 }
1101 
1103 {
1104  PACKET_PROFILING_APP_STORE(app_tctx, p);
1105 }
1106 #endif
1107 
1108 /** \brief HACK to work around our broken unix manager (re)init loop
1109  */
1111 {
1116  StatsRegisterGlobalCounter("app_layer.expectations", ExpectationGetCounter);
1119  StatsRegisterGlobalCounter("ippair.memuse", IPPairGetMemuse);
1120  StatsRegisterGlobalCounter("ippair.memcap", IPPairGetMemuse);
1121  StatsRegisterGlobalCounter("host.memuse", HostGetMemuse);
1122  StatsRegisterGlobalCounter("host.memcap", HostGetMemcap);
1123 }
1124 
1125 static bool IsAppLayerErrorExceptionPolicyStatsValid(enum ExceptionPolicy policy)
1126 {
1127  if (EngineModeIsIPS()) {
1129  }
1131 }
1132 
1133 static void AppLayerSetupExceptionPolicyPerProtoCounters(
1134  uint8_t ipproto_map, AppProto alproto, const char *alproto_str, const char *ipproto_suffix)
1135 {
1138  for (enum ExceptionPolicy i = EXCEPTION_POLICY_NOT_SET + 1; i < EXCEPTION_POLICY_MAX; i++) {
1139  if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1140  snprintf(applayer_counter_names[ipproto_map][alproto].eps_name[i],
1141  sizeof(applayer_counter_names[ipproto_map][alproto].eps_name[i]),
1142  "app_layer.error.%s%s.exception_policy.%s", alproto_str, ipproto_suffix,
1143  ExceptionPolicyEnumToString(i, true));
1144  }
1145  }
1146  }
1147 }
1148 
1150 {
1151  const uint8_t ipprotos[] = { IPPROTO_TCP, IPPROTO_UDP };
1152  AppProto alprotos[ALPROTO_MAX];
1153  const char *str = "app_layer.flow.";
1154  const char *estr = "app_layer.error.";
1155 
1156  /* We don't log stats counters if exception policy is `ignore`/`not set` */
1158  /* Register global counters for app layer error exception policy summary */
1159  const char *eps_default_str = "app_layer.error.exception_policy.";
1160  for (enum ExceptionPolicy i = EXCEPTION_POLICY_NOT_SET + 1; i < EXCEPTION_POLICY_MAX; i++) {
1161  if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1162  snprintf(app_layer_error_eps_stats.eps_name[i],
1163  sizeof(app_layer_error_eps_stats.eps_name[i]), "%s%s", eps_default_str,
1164  ExceptionPolicyEnumToString(i, true));
1165  }
1166  }
1167  }
1168 
1170 
1171  for (uint8_t p = 0; p < FLOW_PROTO_APPLAYER_MAX; p++) {
1172  const uint8_t ipproto = ipprotos[p];
1173  const uint8_t ipproto_map = FlowGetProtoMapping(ipproto);
1174  const char *ipproto_suffix = (ipproto == IPPROTO_TCP) ? "_tcp" : "_udp";
1175  uint8_t ipprotos_all[256 / 8];
1176 
1177  for (AppProto alproto = 0; alproto < ALPROTO_MAX; alproto++) {
1178  if (alprotos[alproto] == 1) {
1179  const char *tx_str = "app_layer.tx.";
1180  const char *alproto_str = AppLayerGetProtoName(alproto);
1181 
1182  memset(ipprotos_all, 0, sizeof(ipprotos_all));
1183  AppLayerProtoDetectSupportedIpprotos(alproto, ipprotos_all);
1184  if ((ipprotos_all[IPPROTO_TCP / 8] & (1 << (IPPROTO_TCP % 8))) &&
1185  (ipprotos_all[IPPROTO_UDP / 8] & (1 << (IPPROTO_UDP % 8)))) {
1186  snprintf(applayer_counter_names[ipproto_map][alproto].name,
1187  sizeof(applayer_counter_names[ipproto_map][alproto].name),
1188  "%s%s%s", str, alproto_str, ipproto_suffix);
1189  snprintf(applayer_counter_names[ipproto_map][alproto].tx_name,
1190  sizeof(applayer_counter_names[ipproto_map][alproto].tx_name),
1191  "%s%s%s", tx_str, alproto_str, ipproto_suffix);
1192 
1193  if (ipproto == IPPROTO_TCP) {
1194  snprintf(applayer_counter_names[ipproto_map][alproto].gap_error,
1195  sizeof(applayer_counter_names[ipproto_map][alproto].gap_error),
1196  "%s%s%s.gap", estr, alproto_str, ipproto_suffix);
1197  }
1198  snprintf(applayer_counter_names[ipproto_map][alproto].alloc_error,
1199  sizeof(applayer_counter_names[ipproto_map][alproto].alloc_error),
1200  "%s%s%s.alloc", estr, alproto_str, ipproto_suffix);
1201  snprintf(applayer_counter_names[ipproto_map][alproto].parser_error,
1202  sizeof(applayer_counter_names[ipproto_map][alproto].parser_error),
1203  "%s%s%s.parser", estr, alproto_str, ipproto_suffix);
1204  snprintf(applayer_counter_names[ipproto_map][alproto].internal_error,
1205  sizeof(applayer_counter_names[ipproto_map][alproto].internal_error),
1206  "%s%s%s.internal", estr, alproto_str, ipproto_suffix);
1207 
1208  AppLayerSetupExceptionPolicyPerProtoCounters(
1209  ipproto_map, alproto, alproto_str, ipproto_suffix);
1210  } else {
1211  snprintf(applayer_counter_names[ipproto_map][alproto].name,
1212  sizeof(applayer_counter_names[ipproto_map][alproto].name),
1213  "%s%s", str, alproto_str);
1214  snprintf(applayer_counter_names[ipproto_map][alproto].tx_name,
1215  sizeof(applayer_counter_names[ipproto_map][alproto].tx_name),
1216  "%s%s", tx_str, alproto_str);
1217 
1218  if (ipproto == IPPROTO_TCP) {
1219  snprintf(applayer_counter_names[ipproto_map][alproto].gap_error,
1220  sizeof(applayer_counter_names[ipproto_map][alproto].gap_error),
1221  "%s%s.gap", estr, alproto_str);
1222  }
1223  snprintf(applayer_counter_names[ipproto_map][alproto].alloc_error,
1224  sizeof(applayer_counter_names[ipproto_map][alproto].alloc_error),
1225  "%s%s.alloc", estr, alproto_str);
1226  snprintf(applayer_counter_names[ipproto_map][alproto].parser_error,
1227  sizeof(applayer_counter_names[ipproto_map][alproto].parser_error),
1228  "%s%s.parser", estr, alproto_str);
1229  snprintf(applayer_counter_names[ipproto_map][alproto].internal_error,
1230  sizeof(applayer_counter_names[ipproto_map][alproto].internal_error),
1231  "%s%s.internal", estr, alproto_str);
1232  AppLayerSetupExceptionPolicyPerProtoCounters(
1233  ipproto_map, alproto, alproto_str, "");
1234  }
1235  } else if (alproto == ALPROTO_FAILED) {
1236  snprintf(applayer_counter_names[ipproto_map][alproto].name,
1237  sizeof(applayer_counter_names[ipproto_map][alproto].name),
1238  "%s%s%s", str, "failed", ipproto_suffix);
1239  if (ipproto == IPPROTO_TCP) {
1240  snprintf(applayer_counter_names[ipproto_map][alproto].gap_error,
1241  sizeof(applayer_counter_names[ipproto_map][alproto].gap_error),
1242  "%sfailed%s.gap", estr, ipproto_suffix);
1243  }
1244  }
1245  }
1246  }
1247 }
1248 
1250 {
1251  const uint8_t ipprotos[] = { IPPROTO_TCP, IPPROTO_UDP };
1252  AppProto alprotos[ALPROTO_MAX];
1254 
1255  /* We don't log stats counters if exception policy is `ignore`/`not set` */
1257  /* Register global counters for app layer error exception policy summary */
1258  for (enum ExceptionPolicy i = EXCEPTION_POLICY_NOT_SET + 1; i < EXCEPTION_POLICY_MAX; i++) {
1259  if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1262  }
1263  }
1264  }
1265 
1266  for (uint8_t p = 0; p < FLOW_PROTO_APPLAYER_MAX; p++) {
1267  const uint8_t ipproto = ipprotos[p];
1268  const uint8_t ipproto_map = FlowGetProtoMapping(ipproto);
1269 
1270  for (AppProto alproto = 0; alproto < ALPROTO_MAX; alproto++) {
1271  if (alprotos[alproto] == 1) {
1272  applayer_counters[ipproto_map][alproto].counter_id =
1273  StatsRegisterCounter(applayer_counter_names[ipproto_map][alproto].name, tv);
1274 
1275  applayer_counters[ipproto_map][alproto].counter_tx_id =
1276  StatsRegisterCounter(applayer_counter_names[ipproto_map][alproto].tx_name, tv);
1277 
1278  if (ipproto == IPPROTO_TCP) {
1279  applayer_counters[ipproto_map][alproto].gap_error_id = StatsRegisterCounter(
1280  applayer_counter_names[ipproto_map][alproto].gap_error, tv);
1281  }
1282  applayer_counters[ipproto_map][alproto].alloc_error_id = StatsRegisterCounter(
1283  applayer_counter_names[ipproto_map][alproto].alloc_error, tv);
1284  applayer_counters[ipproto_map][alproto].parser_error_id = StatsRegisterCounter(
1285  applayer_counter_names[ipproto_map][alproto].parser_error, tv);
1287  applayer_counter_names[ipproto_map][alproto].internal_error, tv);
1288  /* We don't log stats counters if exception policy is `ignore`/`not set` */
1291  for (enum ExceptionPolicy i = EXCEPTION_POLICY_NOT_SET + 1;
1292  i < EXCEPTION_POLICY_MAX; i++) {
1293  if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1294  applayer_counters[ipproto_map][alproto]
1296  applayer_counter_names[ipproto_map][alproto].eps_name[i], tv);
1297  }
1298  }
1299  }
1300  } else if (alproto == ALPROTO_FAILED) {
1301  applayer_counters[ipproto_map][alproto].counter_id =
1302  StatsRegisterCounter(applayer_counter_names[ipproto_map][alproto].name, tv);
1303 
1304  if (ipproto == IPPROTO_TCP) {
1305  applayer_counters[ipproto_map][alproto].gap_error_id = StatsRegisterCounter(
1306  applayer_counter_names[ipproto_map][alproto].gap_error, tv);
1307  }
1308  }
1309  }
1310  }
1311 }
1312 
1314 {
1315  memset(applayer_counter_names, 0, sizeof(applayer_counter_names));
1316  memset(applayer_counters, 0, sizeof(applayer_counters));
1317 }
1318 
1319 /***** Unittests *****/
1320 
1321 #ifdef UNITTESTS
1322 #include "pkt-var.h"
1323 #include "stream-tcp-util.h"
1324 #include "stream.h"
1325 #include "util-unittest.h"
1326 
1327 #define TEST_START \
1328  Packet *p = PacketGetFromAlloc(); \
1329  FAIL_IF_NULL(p); \
1330  Flow f; \
1331  ThreadVars tv; \
1332  StreamTcpThread *stt = NULL; \
1333  TCPHdr tcph; \
1334  PacketQueueNoLock pq; \
1335  memset(&pq, 0, sizeof(PacketQueueNoLock)); \
1336  memset(&f, 0, sizeof(Flow)); \
1337  memset(&tv, 0, sizeof(ThreadVars)); \
1338  memset(&tcph, 0, sizeof(TCPHdr)); \
1339  \
1340  FLOW_INITIALIZE(&f); \
1341  f.flags = FLOW_IPV4; \
1342  f.proto = IPPROTO_TCP; \
1343  p->flow = &f; \
1344  PacketSetTCP(p, (uint8_t *)&tcph); \
1345  \
1346  StreamTcpInitConfig(true); \
1347  IPPairInitConfig(true); \
1348  StreamTcpThreadInit(&tv, NULL, (void **)&stt); \
1349  \
1350  /* handshake */ \
1351  tcph.th_win = htons(5480); \
1352  tcph.th_flags = TH_SYN; \
1353  p->flowflags = FLOW_PKT_TOSERVER; \
1354  p->payload_len = 0; \
1355  p->payload = NULL; \
1356  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1); \
1357  TcpSession *ssn = (TcpSession *)f.protoctx; \
1358  \
1359  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); \
1360  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); \
1361  FAIL_IF(f.alproto != ALPROTO_UNKNOWN); \
1362  FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN); \
1363  FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN); \
1364  FAIL_IF(ssn->flags &STREAMTCP_FLAG_APP_LAYER_DISABLED); \
1365  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER)); \
1366  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER)); \
1367  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT)); \
1368  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); \
1369  FAIL_IF(ssn->data_first_seen_dir != 0); \
1370  \
1371  /* handshake */ \
1372  tcph.th_ack = htonl(1); \
1373  tcph.th_flags = TH_SYN | TH_ACK; \
1374  p->flowflags = FLOW_PKT_TOCLIENT; \
1375  p->payload_len = 0; \
1376  p->payload = NULL; \
1377  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1); \
1378  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); \
1379  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); \
1380  FAIL_IF(f.alproto != ALPROTO_UNKNOWN); \
1381  FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN); \
1382  FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN); \
1383  FAIL_IF(ssn->flags &STREAMTCP_FLAG_APP_LAYER_DISABLED); \
1384  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER)); \
1385  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER)); \
1386  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT)); \
1387  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); \
1388  FAIL_IF(ssn->data_first_seen_dir != 0); \
1389  \
1390  /* handshake */ \
1391  tcph.th_ack = htonl(1); \
1392  tcph.th_seq = htonl(1); \
1393  tcph.th_flags = TH_ACK; \
1394  p->flowflags = FLOW_PKT_TOSERVER; \
1395  p->payload_len = 0; \
1396  p->payload = NULL; \
1397  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1); \
1398  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); \
1399  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); \
1400  FAIL_IF(f.alproto != ALPROTO_UNKNOWN); \
1401  FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN); \
1402  FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN); \
1403  FAIL_IF(ssn->flags &STREAMTCP_FLAG_APP_LAYER_DISABLED); \
1404  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER)); \
1405  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER)); \
1406  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT)); \
1407  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); \
1408  FAIL_IF(ssn->data_first_seen_dir != 0);
1409 #define TEST_END \
1410  StreamTcpSessionClear(p->flow->protoctx); \
1411  StreamTcpThreadDeinit(&tv, (void *)stt); \
1412  StreamTcpFreeConfig(true); \
1413  PacketFree(p); \
1414  FLOW_DESTROY(&f); \
1415  StatsThreadCleanup(&tv);
1416 
1417 /**
1418  * \test GET -> HTTP/1.1
1419  */
1420 static int AppLayerTest01(void)
1421 {
1422  TEST_START;
1423 
1424  /* full request */
1425  uint8_t request[] = {
1426  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1427  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1428  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1429  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1430  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1431  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1432  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1433  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1434  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1435  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1436  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1437  tcph.th_ack = htonl(1);
1438  tcph.th_seq = htonl(1);
1439  tcph.th_flags = TH_PUSH | TH_ACK;
1441  p->payload_len = sizeof(request);
1442  p->payload = request;
1443  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1450  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1451  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1452  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1453  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1454  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1455 
1456  /* full response - request ack */
1457  uint8_t response[] = {
1458  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
1459  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1460  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1461  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1462  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1463  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1464  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1465  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1466  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1467  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1468  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1469  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1470  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1471  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1472  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1473  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1474  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1475  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1476  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1477  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1478  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1479  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1480  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1481  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1482  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1483  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1484  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1485  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1486  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1487  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1488  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1489  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1490  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1491  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1492  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1493  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1494  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1495  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1496  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1497  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1498  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1499  tcph.th_ack = htonl(88);
1500  tcph.th_seq = htonl(1);
1501  tcph.th_flags = TH_PUSH | TH_ACK;
1503  p->payload_len = sizeof(response);
1504  p->payload = response;
1505  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1512  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1513  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1514  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1515  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1517 
1518  /* response ack */
1519  tcph.th_ack = htonl(328);
1520  tcph.th_seq = htonl(88);
1521  tcph.th_flags = TH_ACK;
1523  p->payload_len = 0;
1524  p->payload = NULL;
1525  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1532  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1533  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1534  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1535  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1537 
1538  TEST_END;
1539  PASS;
1540 }
1541 
1542 /**
1543  * \test GE -> T -> HTTP/1.1
1544  */
1545 static int AppLayerTest02(void)
1546 {
1547  TEST_START;
1548 
1549  /* partial request */
1550  uint8_t request1[] = { 0x47, 0x45, };
1551  tcph.th_ack = htonl(1);
1552  tcph.th_seq = htonl(1);
1553  tcph.th_flags = TH_PUSH | TH_ACK;
1555  p->payload_len = sizeof(request1);
1556  p->payload = request1;
1557  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1564  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1565  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1566  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1567  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1568  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1569 
1570  /* response ack against partial request */
1571  tcph.th_ack = htonl(3);
1572  tcph.th_seq = htonl(1);
1573  tcph.th_flags = TH_ACK;
1575  p->payload_len = 0;
1576  p->payload = NULL;
1577  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1584  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1585  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1586  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1587  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1588  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1589 
1590  /* complete partial request */
1591  uint8_t request2[] = {
1592  0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1593  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1594  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1595  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1596  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1597  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1598  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1599  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1600  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1601  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1602  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1603  tcph.th_ack = htonl(1);
1604  tcph.th_seq = htonl(3);
1605  tcph.th_flags = TH_PUSH | TH_ACK;
1607  p->payload_len = sizeof(request2);
1608  p->payload = request2;
1609  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1616  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1617  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1618  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1619  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1620  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1621 
1622  /* response - request ack */
1623  uint8_t response[] = {
1624  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
1625  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1626  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1627  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1628  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1629  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1630  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1631  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1632  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1633  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1634  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1635  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1636  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1637  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1638  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1639  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1640  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1641  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1642  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1643  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1644  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1645  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1646  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1647  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1648  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1649  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1650  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1651  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1652  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1653  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1654  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1655  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1656  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1657  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1658  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1659  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1660  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1661  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1662  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1663  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1664  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1665  tcph.th_ack = htonl(88);
1666  tcph.th_seq = htonl(1);
1667  tcph.th_flags = TH_PUSH | TH_ACK;
1669  p->payload_len = sizeof(response);
1670  p->payload = response;
1671  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1678  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1679  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1680  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1681  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1683 
1684  /* response ack */
1685  tcph.th_ack = htonl(328);
1686  tcph.th_seq = htonl(88);
1687  tcph.th_flags = TH_ACK;
1689  p->payload_len = 0;
1690  p->payload = NULL;
1691  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1698  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1699  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1700  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1701  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1703 
1704  TEST_END;
1705  PASS;
1706 }
1707 
1708 /**
1709  * \test GET -> RUBBISH(PM AND PP DONE IN ONE GO)
1710  */
1711 static int AppLayerTest03(void)
1712 {
1713  TEST_START;
1714 
1715  /* request */
1716  uint8_t request[] = {
1717  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1718  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1719  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1720  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1721  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1722  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1723  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1724  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1725  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1726  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1727  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1728  tcph.th_ack = htonl(1);
1729  tcph.th_seq = htonl(1);
1730  tcph.th_flags = TH_PUSH | TH_ACK;
1732  p->payload_len = sizeof(request);
1733  p->payload = request;
1734  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1741  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1742  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1743  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1744  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1745  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1746 
1747  /* rubbish response */
1748  uint8_t response[] = {
1749  0x58, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
1750  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1751  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1752  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1753  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1754  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1755  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1756  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1757  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1758  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1759  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1760  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1761  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1762  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1763  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1764  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1765  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1766  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1767  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1768  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1769  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1770  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1771  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1772  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1773  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1774  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1775  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1776  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1777  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1778  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1779  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1780  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1781  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1782  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1783  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1784  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1785  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1786  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1787  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1788  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1789  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1790  tcph.th_ack = htonl(88);
1791  tcph.th_seq = htonl(1);
1792  tcph.th_flags = TH_PUSH | TH_ACK;
1794  p->payload_len = sizeof(response);
1795  p->payload = response;
1796  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1803  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1804  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1805  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1806  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1808 
1809  /* response ack */
1810  tcph.th_ack = htonl(328);
1811  tcph.th_seq = htonl(88);
1812  tcph.th_flags = TH_ACK;
1814  p->payload_len = 0;
1815  p->payload = NULL;
1816  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1823  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1824  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1825  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1826  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1828 
1829  TEST_END;
1830  PASS;
1831 }
1832 
1833 /**
1834  * \test GE -> RUBBISH(TC - PM AND PP NOT DONE) -> RUBBISH(TC - PM AND PP DONE).
1835  */
1836 static int AppLayerTest04(void)
1837 {
1838  TEST_START;
1839 
1840  /* request */
1841  uint8_t request[] = {
1842  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1843  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1844  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1845  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1846  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1847  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1848  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1849  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1850  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1851  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1852  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1853  PrintRawDataFp(stdout, request, sizeof(request));
1854  tcph.th_ack = htonl(1);
1855  tcph.th_seq = htonl(1);
1856  tcph.th_flags = TH_PUSH | TH_ACK;
1858  p->payload_len = sizeof(request);
1859  p->payload = request;
1860  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1867  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1868  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1869  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1870  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1871  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER); // TOSERVER data now seen
1872 
1873  /* partial response */
1874  uint8_t response1[] = { 0x58, 0x54, 0x54, 0x50, };
1875  PrintRawDataFp(stdout, response1, sizeof(response1));
1876  tcph.th_ack = htonl(88);
1877  tcph.th_seq = htonl(1);
1878  tcph.th_flags = TH_PUSH | TH_ACK;
1880  p->payload_len = sizeof(response1);
1881  p->payload = response1;
1882  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1885  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
1886  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
1889  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1890  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1891  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1892  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1893  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
1894 
1895  /* partial response ack */
1896  tcph.th_ack = htonl(5);
1897  tcph.th_seq = htonl(88);
1898  tcph.th_flags = TH_ACK;
1900  p->payload_len = 0;
1901  p->payload = NULL;
1902  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1905  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
1906  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
1909  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1910  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1911  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1912  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
1913  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
1914 
1915  /* remaining response */
1916  uint8_t response2[] = {
1917  0x2f, 0x31, 0x2e, 0x31,
1918  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1919  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1920  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1921  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1922  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1923  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1924  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1925  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1926  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1927  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1928  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1929  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1930  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1931  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1932  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1933  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1934  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1935  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1936  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1937  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1938  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1939  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1940  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1941  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1942  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1943  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1944  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1945  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1946  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1947  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1948  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1949  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1950  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1951  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1952  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1953  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1954  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1955  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1956  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1957  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1958  PrintRawDataFp(stdout, response2, sizeof(response2));
1959  tcph.th_ack = htonl(88);
1960  tcph.th_seq = htonl(5);
1961  tcph.th_flags = TH_PUSH | TH_ACK;
1963  p->payload_len = sizeof(response2);
1964  p->payload = response2;
1965  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1968  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
1969  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
1972  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1973  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1974  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1975  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
1976  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
1977 
1978  /* response ack */
1979  tcph.th_ack = htonl(328);
1980  tcph.th_seq = htonl(88);
1981  tcph.th_flags = TH_ACK;
1983  p->payload_len = 0;
1984  p->payload = NULL;
1985  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1986  FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); // toclient complete (failed)
1988  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
1989  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
1990  FAIL_IF(f.alproto_tc != ALPROTO_FAILED); // tc failed
1992  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1993  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1994  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1995  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
1996  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
1997 
1998  TEST_END;
1999  PASS;
2000 }
2001 
2002 /**
2003  * \test RUBBISH -> HTTP/1.1
2004  */
2005 static int AppLayerTest05(void)
2006 {
2007  TEST_START;
2008 
2009  /* full request */
2010  uint8_t request[] = {
2011  0x48, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2012  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
2013  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
2014  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
2015  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
2016  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
2017  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
2018  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
2019  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2020  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
2021  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2022  PrintRawDataFp(stdout, request, sizeof(request));
2023  tcph.th_ack = htonl(1);
2024  tcph.th_seq = htonl(1);
2025  tcph.th_flags = TH_PUSH | TH_ACK;
2027  p->payload_len = sizeof(request);
2028  p->payload = request;
2029  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2036  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2037  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2038  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2039  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2040  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2041 
2042  /* full response - request ack */
2043  uint8_t response[] = {
2044  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2045  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2046  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2047  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2048  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2049  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2050  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2051  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2052  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2053  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2054  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2055  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2056  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2057  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2058  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2059  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2060  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2061  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2062  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2063  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2064  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2065  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2066  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2067  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2068  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2069  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2070  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2071  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2072  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2073  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2074  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2075  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2076  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2077  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2078  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2079  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2080  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2081  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2082  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2083  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2084  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2085  PrintRawDataFp(stdout, response, sizeof(response));
2086  tcph.th_ack = htonl(88);
2087  tcph.th_seq = htonl(1);
2088  tcph.th_flags = TH_PUSH | TH_ACK;
2090  p->payload_len = sizeof(response);
2091  p->payload = response;
2092  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2099  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2100  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2101  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2102  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2103  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2104 
2105  /* response ack */
2106  tcph.th_ack = htonl(328);
2107  tcph.th_seq = htonl(88);
2108  tcph.th_flags = TH_ACK;
2110  p->payload_len = 0;
2111  p->payload = NULL;
2112  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2119  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2120  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2121  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2122  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2124 
2125  TEST_END;
2126  PASS;
2127 }
2128 
2129 /**
2130  * \test HTTP/1.1 -> GET
2131  */
2132 static int AppLayerTest06(void)
2133 {
2134  TEST_START;
2135 
2136  /* full response - request ack */
2137  uint8_t response[] = {
2138  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2139  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2140  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2141  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2142  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2143  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2144  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2145  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2146  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2147  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2148  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2149  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2150  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2151  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2152  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2153  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2154  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2155  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2156  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2157  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2158  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2159  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2160  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2161  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2162  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2163  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2164  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2165  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2166  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2167  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2168  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2169  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2170  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2171  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2172  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2173  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2174  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2175  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2176  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2177  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2178  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2179  tcph.th_ack = htonl(1);
2180  tcph.th_seq = htonl(1);
2181  tcph.th_flags = TH_PUSH | TH_ACK;
2183  p->payload_len = sizeof(response);
2184  p->payload = response;
2185  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2192  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2193  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2194  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2195  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2196  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOCLIENT);
2197 
2198  /* full request - response ack*/
2199  uint8_t request[] = {
2200  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2201  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
2202  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
2203  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
2204  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
2205  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
2206  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
2207  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
2208  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2209  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
2210  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2211  tcph.th_ack = htonl(328);
2212  tcph.th_seq = htonl(1);
2213  tcph.th_flags = TH_PUSH | TH_ACK;
2215  p->payload_len = sizeof(request);
2216  p->payload = request;
2217  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2224  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2225  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2226  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2227  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2229 
2230  tcph.th_ack = htonl(1 + sizeof(request));
2231  tcph.th_seq = htonl(328);
2232  tcph.th_flags = TH_PUSH | TH_ACK;
2234  p->payload_len = 0;
2235  p->payload = NULL;
2236  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2243  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2244  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2245  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2246  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2248 
2249  TEST_END;
2250  PASS;
2251 }
2252 
2253 /**
2254  * \test GET -> DCERPC
2255  */
2256 static int AppLayerTest07(void)
2257 {
2258  TEST_START;
2259 
2260  /* full request */
2261  uint8_t request[] = {
2262  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2263  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
2264  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
2265  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
2266  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
2267  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
2268  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
2269  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
2270  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2271  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
2272  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2273  tcph.th_ack = htonl(1);
2274  tcph.th_seq = htonl(1);
2275  tcph.th_flags = TH_PUSH | TH_ACK;
2277  p->payload_len = sizeof(request);
2278  p->payload = request;
2279  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2286  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2287  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2288  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2289  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2290  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2291 
2292  /* full response - request ack */
2293  uint8_t response[] = { 0x05, 0x00, 0x4d, 0x42, 0x00, 0x01, 0x2e, 0x31, 0x20, 0x32, 0x30, 0x30,
2294  0x20, 0x4f, 0x4b, 0x0d, 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, 0x72, 0x69, 0x2c,
2295  0x20, 0x32, 0x33, 0x20, 0x53, 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20, 0x30, 0x36,
2296  0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, 0x72,
2297  0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2298  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69, 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f,
2299  0x32, 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65,
2300  0x64, 0x3a, 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34, 0x20, 0x4e, 0x6f, 0x76, 0x20,
2301  0x32, 0x30, 0x31, 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a, 0x34, 0x36, 0x20, 0x47,
2302  0x4d, 0x54, 0x0d, 0x0a, 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61, 0x62, 0x38, 0x39,
2303  0x36, 0x35, 0x2d, 0x32, 0x63, 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61, 0x37, 0x66,
2304  0x37, 0x66, 0x38, 0x30, 0x22, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x52,
2305  0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2306  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20,
2307  0x34, 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a,
2308  0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
2309  0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d,
2310  0x6c, 0x0d, 0x0a, 0x58, 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64,
2311  0x20, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d, 0x0a, 0x0d,
2312  0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x68,
2313  0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2314  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2315  tcph.th_ack = htonl(88);
2316  tcph.th_seq = htonl(1);
2317  tcph.th_flags = TH_PUSH | TH_ACK;
2319  p->payload_len = sizeof(response);
2320  p->payload = response;
2321  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2328  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2329  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2330  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2331  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2333 
2334  /* response ack */
2335  tcph.th_ack = htonl(328);
2336  tcph.th_seq = htonl(88);
2337  tcph.th_flags = TH_ACK;
2339  p->payload_len = 0;
2340  p->payload = NULL;
2341  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2348  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2349  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2350  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2351  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2353 
2354  TEST_END;
2355  PASS;
2356 }
2357 
2358 /**
2359  * \test SMB -> HTTP/1.1
2360  */
2361 static int AppLayerTest08(void)
2362 {
2363  TEST_START;
2364 
2365  /* full request */
2366  uint8_t request[] = { 0x05, 0x00, 0x54, 0x20, 0x00, 0x01, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68,
2367  0x74, 0x6d, 0x6c, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x0d, 0x0a, 0x48,
2368  0x6f, 0x73, 0x74, 0x3a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x0d,
2369  0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41, 0x70,
2370  0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2371  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2372  tcph.th_ack = htonl(1);
2373  tcph.th_seq = htonl(1);
2374  tcph.th_flags = TH_PUSH | TH_ACK;
2376  p->payload_len = sizeof(request);
2377  p->payload = request;
2378  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2385  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2386  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2387  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2388  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2389  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2390 
2391  /* full response - request ack */
2392  uint8_t response[] = {
2393  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2394  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2395  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2396  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2397  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2398  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2399  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2400  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2401  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2402  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2403  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2404  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2405  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2406  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2407  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2408  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2409  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2410  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2411  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2412  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2413  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2414  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2415  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2416  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2417  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2418  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2419  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2420  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2421  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2422  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2423  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2424  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2425  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2426  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2427  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2428  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2429  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2430  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2431  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2432  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2433  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2434  tcph.th_ack = htonl(88);
2435  tcph.th_seq = htonl(1);
2436  tcph.th_flags = TH_PUSH | TH_ACK;
2438  p->payload_len = sizeof(response);
2439  p->payload = response;
2440  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2447  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2448  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2449  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2450  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2452 
2453  /* response ack */
2454  tcph.th_ack = htonl(328);
2455  tcph.th_seq = htonl(88);
2456  tcph.th_flags = TH_ACK;
2458  p->payload_len = 0;
2459  p->payload = NULL;
2460  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2467  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2468  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2469  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2470  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2472 
2473  TEST_END;
2474  PASS;
2475 }
2476 
2477 /**
2478  * \test RUBBISH(TC - PM and PP NOT DONE) ->
2479  * RUBBISH(TC - PM and PP DONE) ->
2480  * RUBBISH(TS - PM and PP DONE)
2481  */
2482 static int AppLayerTest09(void)
2483 {
2484  TEST_START;
2485 
2486  /* full request */
2487  uint8_t request1[] = {
2488  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64 };
2489  tcph.th_ack = htonl(1);
2490  tcph.th_seq = htonl(1);
2491  tcph.th_flags = TH_PUSH | TH_ACK;
2493  p->payload_len = sizeof(request1);
2494  p->payload = request1;
2495  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2502  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2503  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2504  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2505  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2506  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2507 
2508  /* response - request ack */
2509  tcph.th_ack = htonl(9);
2510  tcph.th_seq = htonl(1);
2511  tcph.th_flags = TH_PUSH | TH_ACK;
2513  p->payload_len = 0;
2514  p->payload = NULL;
2515  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2522  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2523  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2524  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2525  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2526  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2527 
2528  /* full request */
2529  uint8_t request2[] = {
2530  0x44, 0x44, 0x45, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff };
2531  tcph.th_ack = htonl(1);
2532  tcph.th_seq = htonl(9);
2533  tcph.th_flags = TH_PUSH | TH_ACK;
2535  p->payload_len = sizeof(request2);
2536  p->payload = request2;
2537  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2544  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2545  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2546  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2547  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2548  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2549 
2550  /* full response - request ack */
2551  uint8_t response[] = {
2552  0x55, 0x74, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2553  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2554  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2555  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2556  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2557  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2558  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2559  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2560  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2561  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2562  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2563  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2564  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2565  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2566  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2567  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2568  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2569  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2570  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2571  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2572  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2573  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2574  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2575  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2576  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2577  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2578  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2579  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2580  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2581  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2582  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2583  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2584  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2585  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2586  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2587  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2588  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2589  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2590  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2591  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2592  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2593  tcph.th_ack = htonl(18);
2594  tcph.th_seq = htonl(1);
2595  tcph.th_flags = TH_PUSH | TH_ACK;
2597  p->payload_len = sizeof(response);
2598  p->payload = response;
2599  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2606  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2607  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2608  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2609  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2610  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2611 
2612  /* response ack */
2613  tcph.th_ack = htonl(328);
2614  tcph.th_seq = htonl(18);
2615  tcph.th_flags = TH_ACK;
2617  p->payload_len = 0;
2618  p->payload = NULL;
2619  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2626  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2627  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2628  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2629  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2631 
2632  TEST_END;
2633  PASS;
2634 }
2635 
2636 /**
2637  * \test RUBBISH(TC - PM and PP DONE) ->
2638  * RUBBISH(TS - PM and PP DONE)
2639  */
2640 static int AppLayerTest10(void)
2641 {
2642  TEST_START;
2643 
2644  /* full request */
2645  uint8_t request1[] = {
2646  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2647  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff };
2648  tcph.th_ack = htonl(1);
2649  tcph.th_seq = htonl(1);
2650  tcph.th_flags = TH_PUSH | TH_ACK;
2652  p->payload_len = sizeof(request1);
2653  p->payload = request1;
2654  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2661  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2662  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2663  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2664  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2665  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2666 
2667  /* response - request ack */
2668  tcph.th_ack = htonl(18);
2669  tcph.th_seq = htonl(1);
2670  tcph.th_flags = TH_PUSH | TH_ACK;
2672  p->payload_len = 0;
2673  p->payload = NULL;
2674  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2681  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2682  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2683  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2684  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2685  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2686 
2687  /* full response - request ack */
2688  uint8_t response[] = {
2689  0x55, 0x74, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2690  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2691  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2692  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2693  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2694  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2695  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2696  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2697  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2698  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2699  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2700  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2701  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2702  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2703  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2704  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2705  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2706  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2707  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2708  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2709  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2710  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2711  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2712  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2713  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2714  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2715  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2716  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2717  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2718  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2719  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2720  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2721  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2722  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2723  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2724  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2725  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2726  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2727  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2728  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2729  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2730  tcph.th_ack = htonl(18);
2731  tcph.th_seq = htonl(1);
2732  tcph.th_flags = TH_PUSH | TH_ACK;
2734  p->payload_len = sizeof(response);
2735  p->payload = response;
2736  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2743  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2744  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2745  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2746  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2747  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2748 
2749  /* response ack */
2750  tcph.th_ack = htonl(328);
2751  tcph.th_seq = htonl(18);
2752  tcph.th_flags = TH_ACK;
2754  p->payload_len = 0;
2755  p->payload = NULL;
2756  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2763  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2764  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2765  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2766  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2768 
2769  TEST_END;
2770  PASS;
2771 }
2772 
2773 /**
2774  * \test RUBBISH(TC - PM and PP DONE) ->
2775  * RUBBISH(TS - PM and PP NOT DONE) ->
2776  * RUBBISH(TS - PM and PP DONE)
2777  */
2778 static int AppLayerTest11(void)
2779 {
2780  TEST_START;
2781 
2782  /* full request */
2783  uint8_t request1[] = {
2784  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2785  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff };
2786  tcph.th_ack = htonl(1);
2787  tcph.th_seq = htonl(1);
2788  tcph.th_flags = TH_PUSH | TH_ACK;
2790  p->payload_len = sizeof(request1);
2791  p->payload = request1;
2792  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2799  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2800  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2801  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2802  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2803  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2804 
2805  /* response - request ack */
2806  tcph.th_ack = htonl(18);
2807  tcph.th_seq = htonl(1);
2808  tcph.th_flags = TH_PUSH | TH_ACK;
2810  p->payload_len = 0;
2811  p->payload = NULL;
2812  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2819  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2820  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2821  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2822  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2823  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2824 
2825  /* full response - request ack */
2826  uint8_t response1[] = {
2827  0x55, 0x74, 0x54, 0x50, };
2828  tcph.th_ack = htonl(18);
2829  tcph.th_seq = htonl(1);
2830  tcph.th_flags = TH_PUSH | TH_ACK;
2832  p->payload_len = sizeof(response1);
2833  p->payload = response1;
2834  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2841  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2842  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2843  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2844  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2845  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2846 
2847  /* response ack from request */
2848  tcph.th_ack = htonl(5);
2849  tcph.th_seq = htonl(18);
2850  tcph.th_flags = TH_ACK;
2852  p->payload_len = 0;
2853  p->payload = NULL;
2854  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2861  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2862  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2863  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2864  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2865  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2866 
2867  uint8_t response2[] = {
2868  0x2f, 0x31, 0x2e, 0x31,
2869  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2870  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2871  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2872  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2873  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2874  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2875  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2876  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2877  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2878  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2879  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2880  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2881  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2882  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2883  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2884  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2885  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2886  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2887  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2888  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2889  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2890  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2891  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2892  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2893  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2894  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2895  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2896  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2897  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2898  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2899  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2900  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2901  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2902  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2903  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2904  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2905  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2906  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2907  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2908  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2909  tcph.th_ack = htonl(18);
2910  tcph.th_seq = htonl(5);
2911  tcph.th_flags = TH_PUSH | TH_ACK;
2913  p->payload_len = sizeof(response2);
2914  p->payload = response2;
2915  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2922  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2923  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2924  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2925  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2926  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2927 
2928  /* response ack from request */
2929  tcph.th_ack = htonl(328);
2930  tcph.th_seq = htonl(18);
2931  tcph.th_flags = TH_ACK;
2933  p->payload_len = 0;
2934  p->payload = NULL;
2935  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2942  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2943  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2944  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2945  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2947 
2948  TEST_END;
2949  PASS;
2950 }
2951 
2953 {
2954  SCEnter();
2955 
2956  UtRegisterTest("AppLayerTest01", AppLayerTest01);
2957  UtRegisterTest("AppLayerTest02", AppLayerTest02);
2958  UtRegisterTest("AppLayerTest03", AppLayerTest03);
2959  UtRegisterTest("AppLayerTest04", AppLayerTest04);
2960  UtRegisterTest("AppLayerTest05", AppLayerTest05);
2961  UtRegisterTest("AppLayerTest06", AppLayerTest06);
2962  UtRegisterTest("AppLayerTest07", AppLayerTest07);
2963  UtRegisterTest("AppLayerTest08", AppLayerTest08);
2964  UtRegisterTest("AppLayerTest09", AppLayerTest09);
2965  UtRegisterTest("AppLayerTest10", AppLayerTest10);
2966  UtRegisterTest("AppLayerTest11", AppLayerTest11);
2967 
2968  SCReturn;
2969 }
2970 
2971 #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:495
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:7063
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:592
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:1102
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:571
TcpReassemblyThreadCtx_::app_tctx
void * app_tctx
Definition: stream-tcp-reassemble.h:62
Packet_::flags
uint32_t flags
Definition: decode.h:510
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:65
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:1123
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:1334
StreamTcpResetStreamFlagAppProtoDetectionCompleted
#define StreamTcpResetStreamFlagAppProtoDetectionCompleted(stream)
Definition: stream-tcp-private.h:303
AppLayerRegisterThreadCounters
void AppLayerRegisterThreadCounters(ThreadVars *tv)
Registers per flow counters for all protocols.
Definition: app-layer.c:1249
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:1097
AppLayerCounterNames_
Definition: app-layer.c:78
AppLayerParserStateProtoCleanup
void AppLayerParserStateProtoCleanup(uint8_t protomap, AppProto alproto, void *alstate, AppLayerParserState *pstate)
Definition: app-layer-parser.c:1592
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:6634
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:2952
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:1012
AppLayerSetupCounters
void AppLayerSetupCounters(void)
Definition: app-layer.c:1149
app-layer-ftp.h
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:504
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:572
Packet_::app_layer_events
AppLayerDecoderEvents * app_layer_events
Definition: decode.h:598
util-unittest.h
AppLayerGetProtoByName
AppProto AppLayerGetProtoByName(char *alproto_name)
Given a protocol string, returns the corresponding internal protocol id.
Definition: app-layer.c:998
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:1047
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:1297
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:292
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:1694
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:1032
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:1110
PKT_DROP_REASON_APPLAYER_ERROR
@ PKT_DROP_REASON_APPLAYER_ERROR
Definition: decode.h:364
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:5500
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:1327
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:301
Packet_
Definition: decode.h:473
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:874
DEBUG_ASSERT_FLOW_LOCKED
#define DEBUG_ASSERT_FLOW_LOCKED(f)
Definition: util-validate.h:99
StreamTcpSetStreamFlagAppProtoDetectionCompleted
#define StreamTcpSetStreamFlagAppProtoDetectionCompleted(stream)
Definition: stream-tcp-private.h:299
PACKET_PROFILING_APP_END
#define PACKET_PROFILING_APP_END(dp)
Definition: util-profiling.h:173
TcpStream_::window
uint32_t window
Definition: stream-tcp-private.h:117
SCReturnPtr
#define SCReturnPtr(x, type)
Definition: util-debug.h:287
AppLayerThreadCtx_::alpd_tctx
AppLayerProtoDetectThreadCtx * alpd_tctx
Definition: app-layer.c:60
StreamDataAvailableForProtoDetect
uint32_t StreamDataAvailableForProtoDetect(TcpStream *stream)
Definition: stream-tcp-reassemble.c:712
AppLayerGetCtxThread
AppLayerThreadCtx * AppLayerGetCtxThread(void)
Creates a new app layer thread context.
Definition: app-layer.c:1059
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:1265
StreamTcpDisableAppLayer
void StreamTcpDisableAppLayer(Flow *f)
Definition: stream-tcp-reassemble.c:446
suricata-common.h
FLOW_RESET_PE_DONE
#define FLOW_RESET_PE_DONE(f, dir)
Definition: flow.h: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:507
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:295
PKT_PROTO_DETECT_TC_DONE
#define PKT_PROTO_DETECT_TC_DONE
Definition: decode.h:1298
AppLayerParserGetStreamDepth
uint32_t AppLayerParserGetStreamDepth(const Flow *f)
Definition: app-layer-parser.c:1553
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:294
AppLayerProtoDetectGetProtoByName
AppProto AppLayerProtoDetectGetProtoByName(const char *alproto_name)
Definition: app-layer-detect-proto.c:2056
str
#define str(s)
Definition: suricata-common.h:291
SWAP_FLAGS
#define SWAP_FLAGS(flags, a, b)
Definition: suricata-common.h:417
ExceptionPolicyEnumToString
const char * ExceptionPolicyEnumToString(enum ExceptionPolicy policy, bool is_json)
Definition: util-exception-policy.c:35
SCFree
#define SCFree(p)
Definition: util-mem.h:61
AppLayerCounterNames_::gap_error
char gap_error[MAX_COUNTER_SIZE]
Definition: app-layer.c: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:7069
Flow_::alstate
void * alstate
Definition: flow.h:481
AppLayerDestroyCtxThread
void AppLayerDestroyCtxThread(AppLayerThreadCtx *app_tctx)
Destroys the context created by AppLayerGetCtxThread().
Definition: app-layer.c:1080
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:1005
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:1409
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:1313
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