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->alproto][f->protomap].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->alproto][f->protomap].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->alproto][f->protomap].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->alproto][f->protomap].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->alproto][f->protomap].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->alproto][f->protomap].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->alproto][f->protomap].eps_error.eps_id[policy];
202  /* for the summary values */
203  uint16_t g_id = eps_error_summary.eps_id[policy];
204 
205  if (likely(id > 0)) {
206  StatsIncr(tv, id);
207  }
208  if (likely(g_id > 0)) {
209  StatsIncr(tv, g_id);
210  }
211 }
212 
213 /* in IDS mode protocol detection is done in reverse order:
214  * when TCP data is ack'd. We want to flag the correct packet,
215  * so in this case we set a flag in the flow so that the first
216  * packet in the correct direction can be tagged.
217  *
218  * For IPS we update packet and flow. */
219 static inline void FlagPacketFlow(Packet *p, Flow *f, uint8_t flags)
220 {
221  if (p->proto != IPPROTO_TCP || EngineModeIsIPS()) {
222  if (flags & STREAM_TOSERVER) {
223  if (p->flowflags & FLOW_PKT_TOSERVER) {
226  } else {
228  }
229  } else {
230  if (p->flowflags & FLOW_PKT_TOCLIENT) {
233  } else {
235  }
236  }
237  } else {
238  if (flags & STREAM_TOSERVER) {
240  } else {
242  }
243  }
244 }
245 
246 static void DisableAppLayer(ThreadVars *tv, Flow *f, Packet *p)
247 {
248  SCLogDebug("disable app layer for flow %p alproto %u ts %u tc %u",
249  f, f->alproto, f->alproto_ts, f->alproto_tc);
252  TcpSession *ssn = f->protoctx;
254  f->alproto = ALPROTO_FAILED;
255  AppLayerIncFlowCounter(tv, f);
256 
257  if (f->alproto_tc != ALPROTO_FAILED) {
258  if (f->alproto_tc == ALPROTO_UNKNOWN) {
260  }
261  FlagPacketFlow(p, f, STREAM_TOCLIENT);
262  }
263  if (f->alproto_ts != ALPROTO_FAILED) {
264  if (f->alproto_ts == ALPROTO_UNKNOWN) {
266  }
267  FlagPacketFlow(p, f, STREAM_TOSERVER);
268  }
269  SCLogDebug("disabled app layer for flow %p alproto %u ts %u tc %u",
270  f, f->alproto, f->alproto_ts, f->alproto_tc);
271 }
272 
273 /* See if we're going to have to give up:
274  *
275  * If we're getting a lot of data in one direction and the
276  * proto for this direction is unknown, proto detect will
277  * hold up segments in the segment list in the stream.
278  * They are held so that if we detect the protocol on the
279  * opposing stream, we can still parse this side of the stream
280  * as well. However, some sessions are very unbalanced. FTP
281  * data channels, large PUT/POST request and many others, can
282  * lead to cases where we would have to store many megabytes
283  * worth of segments before we see the opposing stream. This
284  * leads to risks of resource starvation.
285  *
286  * Here a cutoff point is enforced. If we've stored 100k in
287  * one direction and we've seen no data in the other direction,
288  * we give up.
289  *
290  * Giving up means we disable applayer an set an applayer event
291  */
292 static void TCPProtoDetectCheckBailConditions(ThreadVars *tv,
293  Flow *f, TcpSession *ssn, Packet *p)
294 {
295  if (ssn->state < TCP_ESTABLISHED) {
296  SCLogDebug("skip as long as TCP is not ESTABLISHED (TCP fast open)");
297  return;
298  }
299 
300  const uint32_t size_ts = StreamDataAvailableForProtoDetect(&ssn->client);
301  const uint32_t size_tc = StreamDataAvailableForProtoDetect(&ssn->server);
302  SCLogDebug("size_ts %" PRIu32 ", size_tc %" PRIu32, size_ts, size_tc);
303 
304  /* at least 100000 whatever the conditions
305  * and can be more if window is bigger and if configuration allows it */
306  const uint32_t size_tc_limit =
308  const uint32_t size_ts_limit =
310 
311  if (ProtoDetectDone(f, ssn, STREAM_TOSERVER) &&
312  ProtoDetectDone(f, ssn, STREAM_TOCLIENT))
313  {
314  goto failure;
315 
316  /* we bail out whatever the pp and pm states if
317  * we received too much data */
318  } else if (size_tc > 2 * size_tc_limit || size_ts > 2 * size_ts_limit) {
320  goto failure;
321 
322  } else if (FLOW_IS_PM_DONE(f, STREAM_TOSERVER) && FLOW_IS_PP_DONE(f, STREAM_TOSERVER) &&
323  size_ts > size_ts_limit && size_tc == 0) {
326  goto failure;
327 
328  } else if (FLOW_IS_PM_DONE(f, STREAM_TOCLIENT) && FLOW_IS_PP_DONE(f, STREAM_TOCLIENT) &&
329  size_tc > size_tc_limit && size_ts == 0) {
332  goto failure;
333 
334  /* little data in ts direction, pp done, pm not done (max
335  * depth not reached), ts direction done, lots of data in
336  * tc direction. */
337  } else if (size_tc > size_tc_limit && FLOW_IS_PP_DONE(f, STREAM_TOSERVER) &&
338  !(FLOW_IS_PM_DONE(f, STREAM_TOSERVER)) && FLOW_IS_PM_DONE(f, STREAM_TOCLIENT) &&
339  FLOW_IS_PP_DONE(f, STREAM_TOCLIENT)) {
342  goto failure;
343 
344  /* little data in tc direction, pp done, pm not done (max
345  * depth not reached), tc direction done, lots of data in
346  * ts direction. */
347  } else if (size_ts > size_ts_limit && FLOW_IS_PP_DONE(f, STREAM_TOCLIENT) &&
348  !(FLOW_IS_PM_DONE(f, STREAM_TOCLIENT)) && FLOW_IS_PM_DONE(f, STREAM_TOSERVER) &&
349  FLOW_IS_PP_DONE(f, STREAM_TOSERVER)) {
352  goto failure;
353  }
354  return;
355 
356 failure:
357  DisableAppLayer(tv, f, p);
358 }
359 
360 static int TCPProtoDetectTriggerOpposingSide(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
361  Packet *p, TcpSession *ssn, const TcpStream *stream)
362 {
363  TcpStream *opposing_stream = NULL;
364  if (stream == &ssn->client) {
365  opposing_stream = &ssn->server;
366  } else {
367  opposing_stream = &ssn->client;
368  }
369 
370  /* if the opposing side is not going to work, then
371  * we just have to give up. */
372  if (opposing_stream->flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY) {
373  SCLogDebug("opposing dir has STREAMTCP_STREAM_FLAG_NOREASSEMBLY set");
374  return -1;
375  }
376 
377  enum StreamUpdateDir dir = StreamTcpInlineMode() ?
380  int ret = StreamTcpReassembleAppLayer(tv, ra_ctx, ssn,
381  opposing_stream, p, dir);
382  return ret;
383 }
384 
386 
387 /** \todo data const
388  * \retval int -1 error
389  * \retval int 0 ok
390  */
391 static int TCPProtoDetect(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
392  AppLayerThreadCtx *app_tctx, Packet *p, Flow *f, TcpSession *ssn, TcpStream **stream,
393  uint8_t *data, uint32_t data_len, uint8_t flags, enum StreamUpdateDir app_update_dir)
394 {
395  AppProto *alproto;
396  AppProto *alproto_otherdir;
397  uint8_t direction = (flags & STREAM_TOSERVER) ? 0 : 1;
398 
399  if (flags & STREAM_TOSERVER) {
400  alproto = &f->alproto_ts;
401  alproto_otherdir = &f->alproto_tc;
402  } else {
403  alproto = &f->alproto_tc;
404  alproto_otherdir = &f->alproto_ts;
405  }
406 
407  SCLogDebug("Stream initializer (len %" PRIu32 ")", data_len);
408 #ifdef PRINT
409  if (data_len > 0) {
410  printf("=> Init Stream Data (app layer) -- start %s%s\n",
411  flags & STREAM_TOCLIENT ? "toclient" : "",
412  flags & STREAM_TOSERVER ? "toserver" : "");
413  PrintRawDataFp(stdout, data, data_len);
414  printf("=> Init Stream Data -- end\n");
415  }
416 #endif
417 
418  bool reverse_flow = false;
419  DEBUG_VALIDATE_BUG_ON(data == NULL && data_len > 0);
421  *alproto = AppLayerProtoDetectGetProto(app_tctx->alpd_tctx,
422  f, data, data_len,
423  IPPROTO_TCP, flags, &reverse_flow);
424  PACKET_PROFILING_APP_PD_END(app_tctx);
425  SCLogDebug("alproto %u rev %s", *alproto, reverse_flow ? "true" : "false");
426 
427  if (*alproto != ALPROTO_UNKNOWN) {
428  if (*alproto_otherdir != ALPROTO_UNKNOWN && *alproto_otherdir != *alproto) {
431 
433  /* if we already invoked the parser, we go with that proto */
434  f->alproto = *alproto_otherdir;
435  } else {
436  /* no data sent to parser yet, we can still choose
437  * we're trusting the server more. */
438  if (flags & STREAM_TOCLIENT)
439  f->alproto = *alproto;
440  else
441  f->alproto = *alproto_otherdir;
442  }
443  } else {
444  f->alproto = *alproto;
445  }
446 
450  FlagPacketFlow(p, f, flags);
451 
452  /* if protocol detection indicated that we need to reverse
453  * the direction of the flow, do it now. We flip the flow,
454  * packet and the direction flags */
455  if (reverse_flow &&
458  /* but only if we didn't already detect it on the other side. */
459  if (*alproto_otherdir == ALPROTO_UNKNOWN) {
460  SCLogDebug("reversing flow after proto detect told us so");
461  PacketSwap(p);
462  FlowSwap(f);
463  SWAP_FLAGS(flags, STREAM_TOSERVER, STREAM_TOCLIENT);
464  if (*stream == &ssn->client) {
465  *stream = &ssn->server;
466  } else {
467  *stream = &ssn->client;
468  }
469  direction = 1 - direction;
470  } else {
471  // TODO event, error?
472  }
473  }
474 
475  /* account flow if we have both sides */
476  if (*alproto_otherdir != ALPROTO_UNKNOWN) {
477  AppLayerIncFlowCounter(tv, f);
478  }
479 
480  /* if we have seen data from the other direction first, send
481  * data for that direction first to the parser. This shouldn't
482  * be an issue, since each stream processing happens
483  * independently of the other stream direction. At this point of
484  * call, you need to know that this function's already being
485  * called by the very same StreamReassembly() function that we
486  * will now call shortly for the opposing direction. */
487  if ((ssn->data_first_seen_dir & (STREAM_TOSERVER | STREAM_TOCLIENT)) &&
488  !(flags & ssn->data_first_seen_dir))
489  {
490  SCLogDebug("protocol %s needs first data in other direction",
491  AppProtoToString(*alproto));
492 
493  if (TCPProtoDetectTriggerOpposingSide(tv, ra_ctx,
494  p, ssn, *stream) != 0)
495  {
496  goto detect_error;
497  }
498  if (FlowChangeProto(f)) {
499  /* We have the first data which requested a protocol change from P1 to P2
500  * even if it was not recognized at first as being P1
501  * As the second data was recognized as P1, the protocol did not change !
502  */
506  }
507  }
508 
509  /* if the parser operates such that it needs to see data from
510  * a particular direction first, we check if we have seen
511  * data from that direction first for the flow. IF it is not
512  * the same, we set an event and exit.
513  *
514  * \todo We need to figure out a more robust solution for this,
515  * as this can lead to easy evasion tactics, where the
516  * attacker can first send some dummy data in the wrong
517  * direction first to mislead our proto detection process.
518  * While doing this we need to update the parsers as well,
519  * since the parsers must be robust to see such wrong
520  * direction data.
521  * Either ways the moment we see the
522  * APPLAYER_WRONG_DIRECTION_FIRST_DATA event set for the
523  * flow, it shows something's fishy.
524  */
526  uint8_t first_data_dir;
527  first_data_dir = AppLayerParserGetFirstDataDir(f->proto, f->alproto);
528 
529  if (first_data_dir && !(first_data_dir & ssn->data_first_seen_dir)) {
532  goto detect_error;
533  }
534  /* This can happen if the current direction is not the
535  * right direction, and the data from the other(also
536  * the right direction) direction is available to be sent
537  * to the app layer, but it is not ack'ed yet and hence
538  * the forced call to STreamTcpAppLayerReassemble still
539  * hasn't managed to send data from the other direction
540  * to the app layer. */
541  if (first_data_dir && !(first_data_dir & flags)) {
547  SCReturnInt(-1);
548  }
549  }
550 
551  /* Set a value that is neither STREAM_TOSERVER, nor STREAM_TOCLIENT */
553 
554  /* finally, invoke the parser */
555  PACKET_PROFILING_APP_START(app_tctx, f->alproto);
556  int r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto,
557  flags, data, data_len);
558  PACKET_PROFILING_APP_END(app_tctx);
559  p->app_update_direction = (uint8_t)app_update_dir;
560  if (r != 1) {
561  StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
562  }
563  if (r == 0) {
564  if (*alproto_otherdir == ALPROTO_UNKNOWN) {
565  TcpStream *opposing_stream;
566  if (*stream == &ssn->client) {
567  opposing_stream = &ssn->server;
568  } else {
569  opposing_stream = &ssn->client;
570  }
572  // can happen in detection-only
573  AppLayerIncFlowCounter(tv, f);
574  }
575  }
576  }
577  if (r < 0) {
578  goto parser_error;
579  }
580  } else {
581  /* if the ssn is midstream, we may end up with a case where the
582  * start of an HTTP request is missing. We won't detect HTTP based
583  * on the request. However, the reply is fine, so we detect
584  * HTTP anyway. This leads to passing the incomplete request to
585  * the htp parser.
586  *
587  * This has been observed, where the http parser then saw many
588  * bogus requests in the incomplete data.
589  *
590  * To counter this case, a midstream session MUST find it's
591  * protocol in the toserver direction. If not, we assume the
592  * start of the request/toserver is incomplete and no reliable
593  * detection and parsing is possible. So we give up.
594  */
595  if ((ssn->flags & STREAMTCP_FLAG_MIDSTREAM) &&
597  {
598  if (FLOW_IS_PM_DONE(f, STREAM_TOSERVER) && FLOW_IS_PP_DONE(f, STREAM_TOSERVER)) {
599  SCLogDebug("midstream end pd %p", ssn);
600  /* midstream and toserver detection failed: give up */
601  DisableAppLayer(tv, f, p);
602  SCReturnInt(0);
603  }
604  }
605 
606  if (*alproto_otherdir != ALPROTO_UNKNOWN) {
607  uint8_t first_data_dir;
608  first_data_dir = AppLayerParserGetFirstDataDir(f->proto, *alproto_otherdir);
609 
610  /* this would handle this test case -
611  * http parser which says it wants to see toserver data first only.
612  * tcp handshake
613  * toclient data first received. - RUBBISH DATA which
614  * we don't detect as http
615  * toserver data next sent - we detect this as http.
616  * at this stage we see that toclient is the first data seen
617  * for this session and we try and redetect the app protocol,
618  * but we are unable to detect the app protocol like before.
619  * But since we have managed to detect the protocol for the
620  * other direction as http, we try to use that. At this
621  * stage we check if the direction of this stream matches
622  * to that acceptable by the app parser. If it is not the
623  * acceptable direction we error out.
624  */
626  (first_data_dir) && !(first_data_dir & flags))
627  {
628  goto detect_error;
629  }
630 
631  /* if protocol detection is marked done for our direction we
632  * pass our data on. We're only succeeded in finding one
633  * direction: the opposing stream
634  *
635  * If PD was not yet complete, we don't do anything.
636  */
637  if (FLOW_IS_PM_DONE(f, flags) && FLOW_IS_PP_DONE(f, flags)) {
638  if (data_len > 0)
640 
641  if (*alproto_otherdir != ALPROTO_FAILED) {
642  PACKET_PROFILING_APP_START(app_tctx, f->alproto);
643  int r = AppLayerParserParse(tv, app_tctx->alp_tctx, f,
644  f->alproto, flags,
645  data, data_len);
646  PACKET_PROFILING_APP_END(app_tctx);
647  p->app_update_direction = (uint8_t)app_update_dir;
648  if (r != 1) {
649  StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
650  }
651 
656 
657  *alproto = *alproto_otherdir;
658  SCLogDebug("packet %"PRIu64": pd done(us %u them %u), parser called (r==%d), APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION set",
659  p->pcap_cnt, *alproto, *alproto_otherdir, r);
660  if (r < 0) {
661  goto parser_error;
662  }
663  }
664  *alproto = ALPROTO_FAILED;
666  AppLayerIncFlowCounter(tv, f);
667  FlagPacketFlow(p, f, flags);
668 
669  } else if (flags & STREAM_EOF) {
670  *alproto = f->alproto;
672  AppLayerIncFlowCounter(tv, f);
673  }
674  } else {
675  /* both sides unknown, let's see if we need to give up */
676  if (FlowChangeProto(f)) {
677  /* TCPProtoDetectCheckBailConditions does not work well because
678  * size_tc from STREAM_RIGHT_EDGE is not reset to zero
679  * so, we set a lower limit to the data we inspect
680  * We could instead have set ssn->server.sb.stream_offset = 0;
681  */
682  if (data_len >= FLOW_PROTO_CHANGE_MAX_DEPTH || (flags & STREAM_EOF)) {
683  DisableAppLayer(tv, f, p);
684  }
685  } else {
686  TCPProtoDetectCheckBailConditions(tv, f, ssn, p);
687  }
688  }
689  }
690  SCReturnInt(0);
691 parser_error:
693  AppLayerIncrErrorExcPolicyCounter(tv, f, g_applayerparser_error_policy);
694  SCReturnInt(-1);
695 detect_error:
696  DisableAppLayer(tv, f, p);
697  SCReturnInt(-2);
698 }
699 
700 /** \brief handle TCP data for the app-layer.
701  *
702  * First run protocol detection and then when the protocol is known invoke
703  * the app layer parser.
704  *
705  * \param stream ptr-to-ptr to stream object. Might change if flow dir is
706  * reversed.
707  */
709  TcpSession *ssn, TcpStream **stream, uint8_t *data, uint32_t data_len, uint8_t flags,
710  enum StreamUpdateDir app_update_dir)
711 {
712  SCEnter();
713 
715  DEBUG_VALIDATE_BUG_ON(data_len > (uint32_t)INT_MAX);
716 
717  AppLayerThreadCtx *app_tctx = ra_ctx->app_tctx;
718  AppProto alproto;
719  int r = 0;
720 
721  SCLogDebug("data_len %u flags %02X", data_len, flags);
723  SCLogDebug("STREAMTCP_FLAG_APP_LAYER_DISABLED is set");
724  goto end;
725  }
726 
727  const uint8_t direction = (flags & STREAM_TOSERVER) ? 0 : 1;
728 
729  if (flags & STREAM_TOSERVER) {
730  alproto = f->alproto_ts;
731  } else {
732  alproto = f->alproto_tc;
733  }
734 
735  /* If a gap notification, relay the notification on to the
736  * app-layer if known. */
737  if (flags & STREAM_GAP) {
738  SCLogDebug("GAP of size %u", data_len);
739  if (alproto == ALPROTO_UNKNOWN) {
741  SCLogDebug("ALPROTO_UNKNOWN flow %p, due to GAP in stream start", f);
742  /* if the other side didn't already find the proto, we're done */
743  if (f->alproto == ALPROTO_UNKNOWN) {
744  goto failure;
745  }
746  AppLayerIncFlowCounter(tv, f);
747  }
748  if (FlowChangeProto(f)) {
750  SCLogDebug("Cannot handle gap while changing protocol");
751  goto failure;
752  }
753  PACKET_PROFILING_APP_START(app_tctx, f->alproto);
754  r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto,
755  flags, data, data_len);
756  PACKET_PROFILING_APP_END(app_tctx);
757  p->app_update_direction = (uint8_t)app_update_dir;
758  /* ignore parser result for gap */
759  StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
760  if (r < 0) {
762  AppLayerIncrErrorExcPolicyCounter(tv, f, g_applayerparser_error_policy);
763  SCReturnInt(-1);
764  }
765  goto end;
766  }
767 
768  /* if we don't know the proto yet and we have received a stream
769  * initializer message, we run proto detection.
770  * We receive 2 stream init msgs (one for each direction), we
771  * only run the proto detection for both and emit an event
772  * in the case protocols mismatch. */
773  if (alproto == ALPROTO_UNKNOWN && (flags & STREAM_START)) {
775  /* run protocol detection */
776  if (TCPProtoDetect(tv, ra_ctx, app_tctx, p, f, ssn, stream, data, data_len, flags,
777  app_update_dir) != 0) {
778  goto failure;
779  }
780  } else if (alproto != ALPROTO_UNKNOWN && FlowChangeProto(f)) {
781  SCLogDebug("protocol change, old %s", AppProtoToString(f->alproto_orig));
782  void *alstate_orig = f->alstate;
783  AppLayerParserState *alparser = f->alparser;
784  // we delay AppLayerParserStateCleanup because we may need previous parser state
788  /* rerun protocol detection */
789  int rd = TCPProtoDetect(
790  tv, ra_ctx, app_tctx, p, f, ssn, stream, data, data_len, flags, app_update_dir);
791  if (f->alproto == ALPROTO_UNKNOWN) {
792  DEBUG_VALIDATE_BUG_ON(alstate_orig != f->alstate);
793  // not enough data, revert AppLayerProtoDetectReset to rerun detection
794  f->alparser = alparser;
795  f->alproto = f->alproto_orig;
796  f->alproto_tc = f->alproto_orig;
797  f->alproto_ts = f->alproto_orig;
798  } else {
800  AppLayerParserStateProtoCleanup(f->protomap, f->alproto_orig, alstate_orig, alparser);
801  if (alstate_orig == f->alstate) {
802  // we just freed it
803  f->alstate = NULL;
804  }
805  }
806  if (rd != 0) {
807  SCLogDebug("proto detect failure");
808  goto failure;
809  }
810  SCLogDebug("protocol change, old %s, new %s",
812 
814  f->alproto != f->alproto_expect) {
817 
818  if (f->alproto_expect == ALPROTO_TLS && f->alproto != ALPROTO_TLS) {
821 
822  }
823  }
824  } else {
825  SCLogDebug("stream data (len %" PRIu32 " alproto "
826  "%"PRIu16" (flow %p)", data_len, f->alproto, f);
827 #ifdef PRINT
828  if (data_len > 0) {
829  printf("=> Stream Data (app layer) -- start %s%s\n",
830  flags & STREAM_TOCLIENT ? "toclient" : "",
831  flags & STREAM_TOSERVER ? "toserver" : "");
832  PrintRawDataFp(stdout, data, data_len);
833  printf("=> Stream Data -- end\n");
834  }
835 #endif
836  /* if we don't have a data object here we are not getting it
837  * a start msg should have gotten us one */
838  if (f->alproto != ALPROTO_UNKNOWN) {
839  PACKET_PROFILING_APP_START(app_tctx, f->alproto);
840  r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto,
841  flags, data, data_len);
842  PACKET_PROFILING_APP_END(app_tctx);
843  p->app_update_direction = (uint8_t)app_update_dir;
844  if (r != 1) {
845  StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
846  if (r < 0) {
849  AppLayerIncrErrorExcPolicyCounter(tv, f, g_applayerparser_error_policy);
850  SCReturnInt(-1);
851  }
852  }
853  }
854  }
855 
856  goto end;
857  failure:
858  r = -1;
859  end:
860  SCReturnInt(r);
861 }
862 
863 /**
864  * \brief Handle a app layer UDP message
865  *
866  * If the protocol is yet unknown, the proto detection code is run first.
867  *
868  * \param dp_ctx Thread app layer detect context
869  * \param f *locked* flow
870  * \param p UDP packet
871  *
872  * \retval 0 ok
873  * \retval -1 error
874  */
876 {
877  SCEnter();
878  AppProto *alproto;
879  AppProto *alproto_otherdir;
880 
881  if (f->alproto_ts == ALPROTO_FAILED && f->alproto_tc == ALPROTO_FAILED) {
882  SCReturnInt(0);
883  }
884 
885  int r = 0;
886  uint8_t flags = 0;
887  if (p->flowflags & FLOW_PKT_TOSERVER) {
888  flags |= STREAM_TOSERVER;
889  alproto = &f->alproto_ts;
890  alproto_otherdir = &f->alproto_tc;
891  } else {
892  flags |= STREAM_TOCLIENT;
893  alproto = &f->alproto_tc;
894  alproto_otherdir = &f->alproto_ts;
895  }
896 
898 
899  /* if the protocol is still unknown, run detection */
900  if (*alproto == ALPROTO_UNKNOWN) {
901  SCLogDebug("Detecting AL proto on udp mesg (len %" PRIu32 ")",
902  p->payload_len);
903 
904  bool reverse_flow = false;
906  *alproto = AppLayerProtoDetectGetProto(
907  tctx->alpd_tctx, f, p->payload, p->payload_len, IPPROTO_UDP, flags, &reverse_flow);
909 
910  switch (*alproto) {
911  case ALPROTO_UNKNOWN:
912  if (*alproto_otherdir != ALPROTO_UNKNOWN) {
913  // Use recognized side
914  f->alproto = *alproto_otherdir;
915  // do not keep ALPROTO_UNKNOWN for this side so as not to loop
916  *alproto = *alproto_otherdir;
917  if (*alproto_otherdir == ALPROTO_FAILED) {
918  SCLogDebug("ALPROTO_UNKNOWN flow %p", f);
919  }
920  } else {
921  // First side of protocol is unknown
922  *alproto = ALPROTO_FAILED;
923  }
924  break;
925  case ALPROTO_FAILED:
926  if (*alproto_otherdir != ALPROTO_UNKNOWN) {
927  // Use recognized side
928  f->alproto = *alproto_otherdir;
929  if (*alproto_otherdir == ALPROTO_FAILED) {
930  SCLogDebug("ALPROTO_UNKNOWN flow %p", f);
931  }
932  }
933  // else wait for second side of protocol
934  break;
935  default:
936  if (*alproto_otherdir != ALPROTO_UNKNOWN && *alproto_otherdir != ALPROTO_FAILED) {
937  if (*alproto_otherdir != *alproto) {
940  // data already sent to parser, we cannot change the protocol to use the one
941  // of the server
942  }
943  } else {
944  f->alproto = *alproto;
945  }
946  }
947  if (*alproto_otherdir == ALPROTO_UNKNOWN) {
948  if (f->alproto == ALPROTO_UNKNOWN) {
949  // so as to increase stat about .app_layer.flow.failed_udp
950  f->alproto = ALPROTO_FAILED;
951  }
952  // If the other side is unknown, this is the first packet of the flow
953  AppLayerIncFlowCounter(tv, f);
954  }
955 
956  // parse the data if we recognized one protocol
957  if (f->alproto != ALPROTO_UNKNOWN && f->alproto != ALPROTO_FAILED) {
958  if (reverse_flow) {
959  SCLogDebug("reversing flow after proto detect told us so");
960  PacketSwap(p);
961  FlowSwap(f);
962  SWAP_FLAGS(flags, STREAM_TOSERVER, STREAM_TOCLIENT);
963  }
964 
966  r = AppLayerParserParse(tv, tctx->alp_tctx, f, f->alproto,
967  flags, p->payload, p->payload_len);
970  }
972  /* we do only inspection in one direction, so flag both
973  * sides as done here */
974  FlagPacketFlow(p, f, STREAM_TOSERVER);
975  FlagPacketFlow(p, f, STREAM_TOCLIENT);
976  } else {
977  SCLogDebug("data (len %" PRIu32 " ), alproto "
978  "%"PRIu16" (flow %p)", p->payload_len, f->alproto, f);
979 
980  /* run the parser */
982  r = AppLayerParserParse(tv, tctx->alp_tctx, f, f->alproto,
983  flags, p->payload, p->payload_len);
987  }
988  if (r < 0) {
990  AppLayerIncrErrorExcPolicyCounter(tv, f, g_applayerparser_error_policy);
991  SCReturnInt(-1);
992  }
993 
994  SCReturnInt(r);
995 }
996 
997 /***** Utility *****/
998 
999 AppProto AppLayerGetProtoByName(char *alproto_name)
1000 {
1001  SCEnter();
1002  AppProto r = AppLayerProtoDetectGetProtoByName(alproto_name);
1003  SCReturnCT(r, "AppProto");
1004 }
1005 
1006 const char *AppLayerGetProtoName(AppProto alproto)
1007 {
1008  SCEnter();
1009  const char * r = AppLayerProtoDetectGetProtoName(alproto);
1010  SCReturnCT(r, "char *");
1011 }
1012 
1014 {
1015  SCEnter();
1016 
1017  AppProto alproto;
1018  AppProto alprotos[g_alproto_max];
1019 
1021 
1022  printf("=========Supported App Layer Protocols=========\n");
1023  for (alproto = 0; alproto < g_alproto_max; alproto++) {
1024  if (alprotos[alproto] == 1)
1025  printf("%s\n", AppLayerGetProtoName(alproto));
1026  }
1027 
1028  SCReturn;
1029 }
1030 
1031 /***** Setup/General Registration *****/
1032 static void AppLayerNamesSetup(void)
1033 {
1073 }
1074 
1075 int AppLayerSetup(void)
1076 {
1077  SCEnter();
1078 
1079  AppLayerNamesSetup();
1082 
1085 
1087  FrameConfigInit();
1088 
1089  SCReturnInt(0);
1090 }
1091 
1093 {
1094  SCEnter();
1095 
1098 
1101 
1102  SCReturnInt(0);
1103 }
1104 
1106 {
1107  SCEnter();
1108 
1109  AppLayerThreadCtx *app_tctx = SCCalloc(1, sizeof(*app_tctx));
1110  if (app_tctx == NULL)
1111  goto error;
1112 
1113  if ((app_tctx->alpd_tctx = AppLayerProtoDetectGetCtxThread()) == NULL)
1114  goto error;
1115  if ((app_tctx->alp_tctx = AppLayerParserThreadCtxAlloc()) == NULL)
1116  goto error;
1117 
1118  goto done;
1119  error:
1120  AppLayerDestroyCtxThread(app_tctx);
1121  app_tctx = NULL;
1122  done:
1123  SCReturnPtr(app_tctx, "void *");
1124 }
1125 
1127 {
1128  SCEnter();
1129 
1130  if (app_tctx == NULL)
1131  SCReturn;
1132 
1133  if (app_tctx->alpd_tctx != NULL)
1135  if (app_tctx->alp_tctx != NULL)
1137  SCFree(app_tctx);
1138 
1139  SCReturn;
1140 }
1141 
1142 #ifdef PROFILING
1144 {
1145  PACKET_PROFILING_APP_RESET(app_tctx);
1146 }
1147 
1149 {
1150  PACKET_PROFILING_APP_STORE(app_tctx, p);
1151 }
1152 #endif
1153 
1154 /** \brief HACK to work around our broken unix manager (re)init loop
1155  */
1157 {
1162  StatsRegisterGlobalCounter("app_layer.expectations", ExpectationGetCounter);
1165  StatsRegisterGlobalCounter("ippair.memuse", IPPairGetMemuse);
1166  StatsRegisterGlobalCounter("ippair.memcap", IPPairGetMemuse);
1167  StatsRegisterGlobalCounter("host.memuse", HostGetMemuse);
1168  StatsRegisterGlobalCounter("host.memcap", HostGetMemcap);
1169 }
1170 
1171 static bool IsAppLayerErrorExceptionPolicyStatsValid(enum ExceptionPolicy policy)
1172 {
1173  if (EngineModeIsIPS()) {
1175  }
1177 }
1178 
1179 static void AppLayerSetupExceptionPolicyPerProtoCounters(
1180  uint8_t ipproto_map, AppProto alproto, const char *alproto_str, const char *ipproto_suffix)
1181 {
1184  for (enum ExceptionPolicy i = EXCEPTION_POLICY_NOT_SET + 1; i < EXCEPTION_POLICY_MAX; i++) {
1185  if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1186  snprintf(applayer_counter_names[alproto][ipproto_map].eps_name[i],
1187  sizeof(applayer_counter_names[alproto][ipproto_map].eps_name[i]),
1188  "app_layer.error.%s%s.exception_policy.%s", alproto_str, ipproto_suffix,
1189  ExceptionPolicyEnumToString(i, true));
1190  }
1191  }
1192  }
1193 }
1194 
1196 {
1197  const uint8_t ipprotos[] = { IPPROTO_TCP, IPPROTO_UDP };
1198  AppProto alprotos[g_alproto_max];
1199  const char *str = "app_layer.flow.";
1200  const char *estr = "app_layer.error.";
1201 
1204  if (unlikely(applayer_counter_names == NULL)) {
1205  FatalError("Unable to alloc applayer_counter_names.");
1206  }
1208  if (unlikely(applayer_counters == NULL)) {
1209  FatalError("Unable to alloc applayer_counters.");
1210  }
1211  /* We don't log stats counters if exception policy is `ignore`/`not set` */
1213  /* Register global counters for app layer error exception policy summary */
1214  const char *eps_default_str = "app_layer.error.exception_policy.";
1215  for (enum ExceptionPolicy i = EXCEPTION_POLICY_NOT_SET + 1; i < EXCEPTION_POLICY_MAX; i++) {
1216  if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1217  snprintf(app_layer_error_eps_stats.eps_name[i],
1218  sizeof(app_layer_error_eps_stats.eps_name[i]), "%s%s", eps_default_str,
1219  ExceptionPolicyEnumToString(i, true));
1220  }
1221  }
1222  }
1223 
1225 
1226  for (uint8_t p = 0; p < FLOW_PROTO_APPLAYER_MAX; p++) {
1227  const uint8_t ipproto = ipprotos[p];
1228  const uint8_t ipproto_map = FlowGetProtoMapping(ipproto);
1229  const char *ipproto_suffix = (ipproto == IPPROTO_TCP) ? "_tcp" : "_udp";
1230  uint8_t ipprotos_all[256 / 8];
1231 
1232  for (AppProto alproto = 0; alproto < g_alproto_max; alproto++) {
1233  if (alprotos[alproto] == 1) {
1234  const char *tx_str = "app_layer.tx.";
1235  const char *alproto_str = AppLayerGetProtoName(alproto);
1236 
1237  memset(ipprotos_all, 0, sizeof(ipprotos_all));
1238  AppLayerProtoDetectSupportedIpprotos(alproto, ipprotos_all);
1239  if ((ipprotos_all[IPPROTO_TCP / 8] & (1 << (IPPROTO_TCP % 8))) &&
1240  (ipprotos_all[IPPROTO_UDP / 8] & (1 << (IPPROTO_UDP % 8)))) {
1241  snprintf(applayer_counter_names[alproto][ipproto_map].name,
1242  sizeof(applayer_counter_names[alproto][ipproto_map].name), "%s%s%s",
1243  str, alproto_str, ipproto_suffix);
1244  snprintf(applayer_counter_names[alproto][ipproto_map].tx_name,
1245  sizeof(applayer_counter_names[alproto][ipproto_map].tx_name), "%s%s%s",
1246  tx_str, alproto_str, ipproto_suffix);
1247 
1248  if (ipproto == IPPROTO_TCP) {
1249  snprintf(applayer_counter_names[alproto][ipproto_map].gap_error,
1250  sizeof(applayer_counter_names[alproto][ipproto_map].gap_error),
1251  "%s%s%s.gap", estr, alproto_str, ipproto_suffix);
1252  }
1253  snprintf(applayer_counter_names[alproto][ipproto_map].alloc_error,
1254  sizeof(applayer_counter_names[alproto][ipproto_map].alloc_error),
1255  "%s%s%s.alloc", estr, alproto_str, ipproto_suffix);
1256  snprintf(applayer_counter_names[alproto][ipproto_map].parser_error,
1257  sizeof(applayer_counter_names[alproto][ipproto_map].parser_error),
1258  "%s%s%s.parser", estr, alproto_str, ipproto_suffix);
1259  snprintf(applayer_counter_names[alproto][ipproto_map].internal_error,
1260  sizeof(applayer_counter_names[alproto][ipproto_map].internal_error),
1261  "%s%s%s.internal", estr, alproto_str, ipproto_suffix);
1262 
1263  AppLayerSetupExceptionPolicyPerProtoCounters(
1264  ipproto_map, alproto, alproto_str, ipproto_suffix);
1265  } else {
1266  snprintf(applayer_counter_names[alproto][ipproto_map].name,
1267  sizeof(applayer_counter_names[alproto][ipproto_map].name), "%s%s", str,
1268  alproto_str);
1269  snprintf(applayer_counter_names[alproto][ipproto_map].tx_name,
1270  sizeof(applayer_counter_names[alproto][ipproto_map].tx_name), "%s%s",
1271  tx_str, alproto_str);
1272 
1273  if (ipproto == IPPROTO_TCP) {
1274  snprintf(applayer_counter_names[alproto][ipproto_map].gap_error,
1275  sizeof(applayer_counter_names[alproto][ipproto_map].gap_error),
1276  "%s%s.gap", estr, alproto_str);
1277  }
1278  snprintf(applayer_counter_names[alproto][ipproto_map].alloc_error,
1279  sizeof(applayer_counter_names[alproto][ipproto_map].alloc_error),
1280  "%s%s.alloc", estr, alproto_str);
1281  snprintf(applayer_counter_names[alproto][ipproto_map].parser_error,
1282  sizeof(applayer_counter_names[alproto][ipproto_map].parser_error),
1283  "%s%s.parser", estr, alproto_str);
1284  snprintf(applayer_counter_names[alproto][ipproto_map].internal_error,
1285  sizeof(applayer_counter_names[alproto][ipproto_map].internal_error),
1286  "%s%s.internal", estr, alproto_str);
1287  AppLayerSetupExceptionPolicyPerProtoCounters(
1288  ipproto_map, alproto, alproto_str, "");
1289  }
1290  } else if (alproto == ALPROTO_FAILED) {
1291  snprintf(applayer_counter_names[alproto][ipproto_map].name,
1292  sizeof(applayer_counter_names[alproto][ipproto_map].name), "%s%s%s", str,
1293  "failed", ipproto_suffix);
1294  if (ipproto == IPPROTO_TCP) {
1295  snprintf(applayer_counter_names[alproto][ipproto_map].gap_error,
1296  sizeof(applayer_counter_names[alproto][ipproto_map].gap_error),
1297  "%sfailed%s.gap", estr, ipproto_suffix);
1298  }
1299  }
1300  }
1301  }
1302 }
1303 
1305 {
1306  const uint8_t ipprotos[] = { IPPROTO_TCP, IPPROTO_UDP };
1307  AppProto alprotos[g_alproto_max];
1309 
1310  /* We don't log stats counters if exception policy is `ignore`/`not set` */
1312  /* Register global counters for app layer error exception policy summary */
1313  for (enum ExceptionPolicy i = EXCEPTION_POLICY_NOT_SET + 1; i < EXCEPTION_POLICY_MAX; i++) {
1314  if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1317  }
1318  }
1319  }
1320 
1321  for (uint8_t p = 0; p < FLOW_PROTO_APPLAYER_MAX; p++) {
1322  const uint8_t ipproto = ipprotos[p];
1323  const uint8_t ipproto_map = FlowGetProtoMapping(ipproto);
1324 
1325  for (AppProto alproto = 0; alproto < g_alproto_max; alproto++) {
1326  if (alprotos[alproto] == 1) {
1327  applayer_counters[alproto][ipproto_map].counter_id =
1328  StatsRegisterCounter(applayer_counter_names[alproto][ipproto_map].name, tv);
1329 
1330  applayer_counters[alproto][ipproto_map].counter_tx_id = StatsRegisterCounter(
1331  applayer_counter_names[alproto][ipproto_map].tx_name, tv);
1332 
1333  if (ipproto == IPPROTO_TCP) {
1334  applayer_counters[alproto][ipproto_map].gap_error_id = StatsRegisterCounter(
1335  applayer_counter_names[alproto][ipproto_map].gap_error, tv);
1336  }
1337  applayer_counters[alproto][ipproto_map].alloc_error_id = StatsRegisterCounter(
1338  applayer_counter_names[alproto][ipproto_map].alloc_error, tv);
1339  applayer_counters[alproto][ipproto_map].parser_error_id = StatsRegisterCounter(
1340  applayer_counter_names[alproto][ipproto_map].parser_error, tv);
1342  applayer_counter_names[alproto][ipproto_map].internal_error, tv);
1343  /* We don't log stats counters if exception policy is `ignore`/`not set` */
1346  for (enum ExceptionPolicy i = EXCEPTION_POLICY_NOT_SET + 1;
1347  i < EXCEPTION_POLICY_MAX; i++) {
1348  if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1349  applayer_counters[alproto][ipproto_map]
1351  applayer_counter_names[alproto][ipproto_map].eps_name[i], tv);
1352  }
1353  }
1354  }
1355  } else if (alproto == ALPROTO_FAILED) {
1356  applayer_counters[alproto][ipproto_map].counter_id =
1357  StatsRegisterCounter(applayer_counter_names[alproto][ipproto_map].name, tv);
1358 
1359  if (ipproto == IPPROTO_TCP) {
1360  applayer_counters[alproto][ipproto_map].gap_error_id = StatsRegisterCounter(
1361  applayer_counter_names[alproto][ipproto_map].gap_error, tv);
1362  }
1363  }
1364  }
1365  }
1366 }
1367 
1369 {
1372 }
1373 
1374 /***** Unittests *****/
1375 
1376 #ifdef UNITTESTS
1377 #include "pkt-var.h"
1378 #include "stream-tcp-util.h"
1379 #include "stream.h"
1380 #include "util-unittest.h"
1381 
1382 #define TEST_START \
1383  Packet *p = PacketGetFromAlloc(); \
1384  FAIL_IF_NULL(p); \
1385  Flow f; \
1386  ThreadVars tv; \
1387  StreamTcpThread *stt = NULL; \
1388  TCPHdr tcph; \
1389  PacketQueueNoLock pq; \
1390  memset(&pq, 0, sizeof(PacketQueueNoLock)); \
1391  memset(&f, 0, sizeof(Flow)); \
1392  memset(&tv, 0, sizeof(ThreadVars)); \
1393  memset(&tcph, 0, sizeof(TCPHdr)); \
1394  \
1395  FLOW_INITIALIZE(&f); \
1396  f.flags = FLOW_IPV4; \
1397  f.proto = IPPROTO_TCP; \
1398  p->flow = &f; \
1399  PacketSetTCP(p, (uint8_t *)&tcph); \
1400  \
1401  StreamTcpInitConfig(true); \
1402  IPPairInitConfig(true); \
1403  StreamTcpThreadInit(&tv, NULL, (void **)&stt); \
1404  \
1405  /* handshake */ \
1406  tcph.th_win = htons(5480); \
1407  tcph.th_flags = TH_SYN; \
1408  p->flowflags = FLOW_PKT_TOSERVER; \
1409  p->payload_len = 0; \
1410  p->payload = NULL; \
1411  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1); \
1412  TcpSession *ssn = (TcpSession *)f.protoctx; \
1413  \
1414  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); \
1415  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); \
1416  FAIL_IF(f.alproto != ALPROTO_UNKNOWN); \
1417  FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN); \
1418  FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN); \
1419  FAIL_IF(ssn->flags &STREAMTCP_FLAG_APP_LAYER_DISABLED); \
1420  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER)); \
1421  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER)); \
1422  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT)); \
1423  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); \
1424  FAIL_IF(ssn->data_first_seen_dir != 0); \
1425  \
1426  /* handshake */ \
1427  tcph.th_ack = htonl(1); \
1428  tcph.th_flags = TH_SYN | TH_ACK; \
1429  p->flowflags = FLOW_PKT_TOCLIENT; \
1430  p->payload_len = 0; \
1431  p->payload = NULL; \
1432  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1); \
1433  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); \
1434  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); \
1435  FAIL_IF(f.alproto != ALPROTO_UNKNOWN); \
1436  FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN); \
1437  FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN); \
1438  FAIL_IF(ssn->flags &STREAMTCP_FLAG_APP_LAYER_DISABLED); \
1439  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER)); \
1440  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER)); \
1441  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT)); \
1442  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); \
1443  FAIL_IF(ssn->data_first_seen_dir != 0); \
1444  \
1445  /* handshake */ \
1446  tcph.th_ack = htonl(1); \
1447  tcph.th_seq = htonl(1); \
1448  tcph.th_flags = TH_ACK; \
1449  p->flowflags = FLOW_PKT_TOSERVER; \
1450  p->payload_len = 0; \
1451  p->payload = NULL; \
1452  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1); \
1453  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); \
1454  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); \
1455  FAIL_IF(f.alproto != ALPROTO_UNKNOWN); \
1456  FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN); \
1457  FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN); \
1458  FAIL_IF(ssn->flags &STREAMTCP_FLAG_APP_LAYER_DISABLED); \
1459  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER)); \
1460  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER)); \
1461  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT)); \
1462  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); \
1463  FAIL_IF(ssn->data_first_seen_dir != 0);
1464 #define TEST_END \
1465  StreamTcpSessionClear(p->flow->protoctx); \
1466  StreamTcpThreadDeinit(&tv, (void *)stt); \
1467  StreamTcpFreeConfig(true); \
1468  PacketFree(p); \
1469  FLOW_DESTROY(&f); \
1470  StatsThreadCleanup(&tv);
1471 
1472 /**
1473  * \test GET -> HTTP/1.1
1474  */
1475 static int AppLayerTest01(void)
1476 {
1477  TEST_START;
1478 
1479  /* full request */
1480  uint8_t request[] = {
1481  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1482  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1483  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1484  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1485  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1486  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1487  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1488  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1489  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1490  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1491  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1492  tcph.th_ack = htonl(1);
1493  tcph.th_seq = htonl(1);
1494  tcph.th_flags = TH_PUSH | TH_ACK;
1496  p->payload_len = sizeof(request);
1497  p->payload = request;
1498  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1505  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1506  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1507  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1508  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1509  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1510 
1511  /* full response - request ack */
1512  uint8_t response[] = {
1513  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
1514  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1515  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1516  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1517  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1518  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1519  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1520  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1521  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1522  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1523  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1524  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1525  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1526  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1527  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1528  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1529  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1530  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1531  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1532  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1533  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1534  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1535  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1536  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1537  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1538  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1539  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1540  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1541  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1542  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1543  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1544  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1545  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1546  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1547  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1548  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1549  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1550  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1551  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1552  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1553  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1554  tcph.th_ack = htonl(88);
1555  tcph.th_seq = htonl(1);
1556  tcph.th_flags = TH_PUSH | TH_ACK;
1558  p->payload_len = sizeof(response);
1559  p->payload = response;
1560  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1567  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1568  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1569  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1570  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1572 
1573  /* response ack */
1574  tcph.th_ack = htonl(328);
1575  tcph.th_seq = htonl(88);
1576  tcph.th_flags = TH_ACK;
1578  p->payload_len = 0;
1579  p->payload = NULL;
1580  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1587  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1588  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1589  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1590  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1592 
1593  TEST_END;
1594  PASS;
1595 }
1596 
1597 /**
1598  * \test GE -> T -> HTTP/1.1
1599  */
1600 static int AppLayerTest02(void)
1601 {
1602  TEST_START;
1603 
1604  /* partial request */
1605  uint8_t request1[] = { 0x47, 0x45, };
1606  tcph.th_ack = htonl(1);
1607  tcph.th_seq = htonl(1);
1608  tcph.th_flags = TH_PUSH | TH_ACK;
1610  p->payload_len = sizeof(request1);
1611  p->payload = request1;
1612  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1619  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1620  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1621  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1622  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1623  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1624 
1625  /* response ack against partial request */
1626  tcph.th_ack = htonl(3);
1627  tcph.th_seq = htonl(1);
1628  tcph.th_flags = TH_ACK;
1630  p->payload_len = 0;
1631  p->payload = NULL;
1632  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1639  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1640  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1641  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1642  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1643  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1644 
1645  /* complete partial request */
1646  uint8_t request2[] = {
1647  0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1648  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1649  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1650  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1651  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1652  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1653  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1654  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1655  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1656  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1657  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1658  tcph.th_ack = htonl(1);
1659  tcph.th_seq = htonl(3);
1660  tcph.th_flags = TH_PUSH | TH_ACK;
1662  p->payload_len = sizeof(request2);
1663  p->payload = request2;
1664  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1671  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1672  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1673  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1674  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1675  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1676 
1677  /* response - request ack */
1678  uint8_t response[] = {
1679  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
1680  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1681  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1682  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1683  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1684  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1685  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1686  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1687  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1688  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1689  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1690  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1691  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1692  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1693  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1694  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1695  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1696  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1697  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1698  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1699  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1700  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1701  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1702  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1703  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1704  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1705  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1706  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1707  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1708  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1709  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1710  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1711  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1712  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1713  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1714  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1715  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1716  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1717  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1718  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1719  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1720  tcph.th_ack = htonl(88);
1721  tcph.th_seq = htonl(1);
1722  tcph.th_flags = TH_PUSH | TH_ACK;
1724  p->payload_len = sizeof(response);
1725  p->payload = response;
1726  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1733  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1734  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1735  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1736  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1738 
1739  /* response ack */
1740  tcph.th_ack = htonl(328);
1741  tcph.th_seq = htonl(88);
1742  tcph.th_flags = TH_ACK;
1744  p->payload_len = 0;
1745  p->payload = NULL;
1746  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1753  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1754  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1755  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1756  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1758 
1759  TEST_END;
1760  PASS;
1761 }
1762 
1763 /**
1764  * \test GET -> RUBBISH(PM AND PP DONE IN ONE GO)
1765  */
1766 static int AppLayerTest03(void)
1767 {
1768  TEST_START;
1769 
1770  /* request */
1771  uint8_t request[] = {
1772  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1773  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1774  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1775  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1776  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1777  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1778  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1779  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1780  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1781  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1782  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1783  tcph.th_ack = htonl(1);
1784  tcph.th_seq = htonl(1);
1785  tcph.th_flags = TH_PUSH | TH_ACK;
1787  p->payload_len = sizeof(request);
1788  p->payload = request;
1789  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1796  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1797  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1798  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1799  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1800  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1801 
1802  /* rubbish response */
1803  uint8_t response[] = {
1804  0x58, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
1805  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1806  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1807  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1808  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1809  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1810  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1811  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1812  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1813  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1814  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1815  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1816  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1817  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1818  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1819  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1820  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1821  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1822  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1823  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1824  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1825  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1826  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1827  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1828  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1829  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1830  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1831  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1832  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1833  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1834  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1835  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1836  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1837  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1838  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1839  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1840  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1841  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1842  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1843  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1844  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1845  tcph.th_ack = htonl(88);
1846  tcph.th_seq = htonl(1);
1847  tcph.th_flags = TH_PUSH | TH_ACK;
1849  p->payload_len = sizeof(response);
1850  p->payload = response;
1851  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1858  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1859  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1860  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1861  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1863 
1864  /* response ack */
1865  tcph.th_ack = htonl(328);
1866  tcph.th_seq = htonl(88);
1867  tcph.th_flags = TH_ACK;
1869  p->payload_len = 0;
1870  p->payload = NULL;
1871  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1878  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1879  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1880  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1881  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1883 
1884  TEST_END;
1885  PASS;
1886 }
1887 
1888 /**
1889  * \test GE -> RUBBISH(TC - PM AND PP NOT DONE) -> RUBBISH(TC - PM AND PP DONE).
1890  */
1891 static int AppLayerTest04(void)
1892 {
1893  TEST_START;
1894 
1895  /* request */
1896  uint8_t request[] = {
1897  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1898  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1899  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1900  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1901  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1902  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1903  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1904  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1905  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1906  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1907  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1908  PrintRawDataFp(stdout, request, sizeof(request));
1909  tcph.th_ack = htonl(1);
1910  tcph.th_seq = htonl(1);
1911  tcph.th_flags = TH_PUSH | TH_ACK;
1913  p->payload_len = sizeof(request);
1914  p->payload = request;
1915  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1922  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1923  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1924  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1925  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1926  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER); // TOSERVER data now seen
1927 
1928  /* partial response */
1929  uint8_t response1[] = { 0x58, 0x54, 0x54, 0x50, };
1930  PrintRawDataFp(stdout, response1, sizeof(response1));
1931  tcph.th_ack = htonl(88);
1932  tcph.th_seq = htonl(1);
1933  tcph.th_flags = TH_PUSH | TH_ACK;
1935  p->payload_len = sizeof(response1);
1936  p->payload = response1;
1937  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1940  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
1941  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
1944  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1945  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1946  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1947  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1948  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
1949 
1950  /* partial response ack */
1951  tcph.th_ack = htonl(5);
1952  tcph.th_seq = htonl(88);
1953  tcph.th_flags = TH_ACK;
1955  p->payload_len = 0;
1956  p->payload = NULL;
1957  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1960  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
1961  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
1964  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1965  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1966  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1967  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
1968  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
1969 
1970  /* remaining response */
1971  uint8_t response2[] = {
1972  0x2f, 0x31, 0x2e, 0x31,
1973  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1974  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1975  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1976  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1977  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1978  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1979  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1980  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1981  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1982  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1983  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1984  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1985  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1986  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1987  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1988  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1989  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1990  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1991  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1992  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1993  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1994  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1995  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1996  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1997  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1998  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1999  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2000  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2001  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2002  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2003  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2004  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2005  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2006  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2007  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2008  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2009  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2010  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2011  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2012  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2013  PrintRawDataFp(stdout, response2, sizeof(response2));
2014  tcph.th_ack = htonl(88);
2015  tcph.th_seq = htonl(5);
2016  tcph.th_flags = TH_PUSH | TH_ACK;
2018  p->payload_len = sizeof(response2);
2019  p->payload = response2;
2020  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2023  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
2024  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
2027  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2028  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2029  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2030  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
2031  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
2032 
2033  /* response ack */
2034  tcph.th_ack = htonl(328);
2035  tcph.th_seq = htonl(88);
2036  tcph.th_flags = TH_ACK;
2038  p->payload_len = 0;
2039  p->payload = NULL;
2040  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2041  FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); // toclient complete (failed)
2043  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
2044  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
2045  FAIL_IF(f.alproto_tc != ALPROTO_FAILED); // tc failed
2047  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2048  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2049  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2050  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
2051  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
2052 
2053  TEST_END;
2054  PASS;
2055 }
2056 
2057 /**
2058  * \test RUBBISH -> HTTP/1.1
2059  */
2060 static int AppLayerTest05(void)
2061 {
2062  TEST_START;
2063 
2064  /* full request */
2065  uint8_t request[] = {
2066  0x48, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2067  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
2068  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
2069  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
2070  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
2071  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
2072  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
2073  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
2074  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2075  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
2076  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2077  PrintRawDataFp(stdout, request, sizeof(request));
2078  tcph.th_ack = htonl(1);
2079  tcph.th_seq = htonl(1);
2080  tcph.th_flags = TH_PUSH | TH_ACK;
2082  p->payload_len = sizeof(request);
2083  p->payload = request;
2084  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2091  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2092  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2093  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2094  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2095  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2096 
2097  /* full response - request ack */
2098  uint8_t response[] = {
2099  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2100  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2101  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2102  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2103  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2104  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2105  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2106  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2107  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2108  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2109  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2110  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2111  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2112  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2113  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2114  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2115  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2116  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2117  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2118  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2119  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2120  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2121  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2122  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2123  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2124  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2125  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2126  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2127  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2128  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2129  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2130  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2131  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2132  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2133  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2134  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2135  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2136  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2137  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2138  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2139  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2140  PrintRawDataFp(stdout, response, sizeof(response));
2141  tcph.th_ack = htonl(88);
2142  tcph.th_seq = htonl(1);
2143  tcph.th_flags = TH_PUSH | TH_ACK;
2145  p->payload_len = sizeof(response);
2146  p->payload = response;
2147  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2154  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2155  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2156  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2157  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2158  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2159 
2160  /* response ack */
2161  tcph.th_ack = htonl(328);
2162  tcph.th_seq = htonl(88);
2163  tcph.th_flags = TH_ACK;
2165  p->payload_len = 0;
2166  p->payload = NULL;
2167  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2174  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2175  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2176  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2177  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2179 
2180  TEST_END;
2181  PASS;
2182 }
2183 
2184 /**
2185  * \test HTTP/1.1 -> GET
2186  */
2187 static int AppLayerTest06(void)
2188 {
2189  TEST_START;
2190 
2191  /* full response - request ack */
2192  uint8_t response[] = {
2193  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2194  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2195  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2196  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2197  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2198  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2199  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2200  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2201  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2202  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2203  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2204  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2205  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2206  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2207  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2208  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2209  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2210  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2211  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2212  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2213  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2214  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2215  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2216  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2217  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2218  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2219  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2220  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2221  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2222  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2223  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2224  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2225  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2226  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2227  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2228  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2229  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2230  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2231  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2232  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2233  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2234  tcph.th_ack = htonl(1);
2235  tcph.th_seq = htonl(1);
2236  tcph.th_flags = TH_PUSH | TH_ACK;
2238  p->payload_len = sizeof(response);
2239  p->payload = response;
2240  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2247  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2248  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2249  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2250  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2251  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOCLIENT);
2252 
2253  /* full request - response ack*/
2254  uint8_t request[] = {
2255  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2256  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
2257  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
2258  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
2259  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
2260  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
2261  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
2262  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
2263  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2264  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
2265  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2266  tcph.th_ack = htonl(328);
2267  tcph.th_seq = htonl(1);
2268  tcph.th_flags = TH_PUSH | TH_ACK;
2270  p->payload_len = sizeof(request);
2271  p->payload = request;
2272  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2279  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2280  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2281  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2282  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2284 
2285  tcph.th_ack = htonl(1 + sizeof(request));
2286  tcph.th_seq = htonl(328);
2287  tcph.th_flags = TH_PUSH | TH_ACK;
2289  p->payload_len = 0;
2290  p->payload = NULL;
2291  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2298  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2299  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2300  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2301  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2303 
2304  TEST_END;
2305  PASS;
2306 }
2307 
2308 /**
2309  * \test GET -> DCERPC
2310  */
2311 static int AppLayerTest07(void)
2312 {
2313  TEST_START;
2314 
2315  /* full request */
2316  uint8_t request[] = {
2317  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2318  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
2319  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
2320  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
2321  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
2322  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
2323  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
2324  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
2325  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2326  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
2327  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2328  tcph.th_ack = htonl(1);
2329  tcph.th_seq = htonl(1);
2330  tcph.th_flags = TH_PUSH | TH_ACK;
2332  p->payload_len = sizeof(request);
2333  p->payload = request;
2334  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2341  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2342  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2343  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2344  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2345  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2346 
2347  /* full response - request ack */
2348  uint8_t response[] = { 0x05, 0x00, 0x4d, 0x42, 0x00, 0x01, 0x2e, 0x31, 0x20, 0x32, 0x30, 0x30,
2349  0x20, 0x4f, 0x4b, 0x0d, 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, 0x72, 0x69, 0x2c,
2350  0x20, 0x32, 0x33, 0x20, 0x53, 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20, 0x30, 0x36,
2351  0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, 0x72,
2352  0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2353  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69, 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f,
2354  0x32, 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65,
2355  0x64, 0x3a, 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34, 0x20, 0x4e, 0x6f, 0x76, 0x20,
2356  0x32, 0x30, 0x31, 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a, 0x34, 0x36, 0x20, 0x47,
2357  0x4d, 0x54, 0x0d, 0x0a, 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61, 0x62, 0x38, 0x39,
2358  0x36, 0x35, 0x2d, 0x32, 0x63, 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61, 0x37, 0x66,
2359  0x37, 0x66, 0x38, 0x30, 0x22, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x52,
2360  0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2361  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20,
2362  0x34, 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a,
2363  0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
2364  0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d,
2365  0x6c, 0x0d, 0x0a, 0x58, 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64,
2366  0x20, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d, 0x0a, 0x0d,
2367  0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x68,
2368  0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2369  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2370  tcph.th_ack = htonl(88);
2371  tcph.th_seq = htonl(1);
2372  tcph.th_flags = TH_PUSH | TH_ACK;
2374  p->payload_len = sizeof(response);
2375  p->payload = response;
2376  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2383  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2384  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2385  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2386  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2388 
2389  /* response ack */
2390  tcph.th_ack = htonl(328);
2391  tcph.th_seq = htonl(88);
2392  tcph.th_flags = TH_ACK;
2394  p->payload_len = 0;
2395  p->payload = NULL;
2396  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2403  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2404  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2405  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2406  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2408 
2409  TEST_END;
2410  PASS;
2411 }
2412 
2413 /**
2414  * \test SMB -> HTTP/1.1
2415  */
2416 static int AppLayerTest08(void)
2417 {
2418  TEST_START;
2419 
2420  /* full request */
2421  uint8_t request[] = { 0x05, 0x00, 0x54, 0x20, 0x00, 0x01, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68,
2422  0x74, 0x6d, 0x6c, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x0d, 0x0a, 0x48,
2423  0x6f, 0x73, 0x74, 0x3a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x0d,
2424  0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41, 0x70,
2425  0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2426  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2427  tcph.th_ack = htonl(1);
2428  tcph.th_seq = htonl(1);
2429  tcph.th_flags = TH_PUSH | TH_ACK;
2431  p->payload_len = sizeof(request);
2432  p->payload = request;
2433  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2440  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2441  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2442  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2443  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2444  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2445 
2446  /* full response - request ack */
2447  uint8_t response[] = {
2448  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2449  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2450  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2451  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2452  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2453  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2454  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2455  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2456  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2457  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2458  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2459  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2460  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2461  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2462  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2463  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2464  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2465  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2466  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2467  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2468  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2469  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2470  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2471  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2472  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2473  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2474  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2475  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2476  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2477  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2478  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2479  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2480  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2481  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2482  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2483  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2484  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2485  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2486  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2487  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2488  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2489  tcph.th_ack = htonl(88);
2490  tcph.th_seq = htonl(1);
2491  tcph.th_flags = TH_PUSH | TH_ACK;
2493  p->payload_len = sizeof(response);
2494  p->payload = response;
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));
2507 
2508  /* response ack */
2509  tcph.th_ack = htonl(328);
2510  tcph.th_seq = htonl(88);
2511  tcph.th_flags = 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));
2527 
2528  TEST_END;
2529  PASS;
2530 }
2531 
2532 /**
2533  * \test RUBBISH(TC - PM and PP NOT DONE) ->
2534  * RUBBISH(TC - PM and PP DONE) ->
2535  * RUBBISH(TS - PM and PP DONE)
2536  */
2537 static int AppLayerTest09(void)
2538 {
2539  TEST_START;
2540 
2541  /* full request */
2542  uint8_t request1[] = {
2543  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64 };
2544  tcph.th_ack = htonl(1);
2545  tcph.th_seq = htonl(1);
2546  tcph.th_flags = TH_PUSH | TH_ACK;
2548  p->payload_len = sizeof(request1);
2549  p->payload = request1;
2550  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2557  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2558  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2559  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2560  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2561  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2562 
2563  /* response - request ack */
2564  tcph.th_ack = htonl(9);
2565  tcph.th_seq = htonl(1);
2566  tcph.th_flags = TH_PUSH | TH_ACK;
2568  p->payload_len = 0;
2569  p->payload = NULL;
2570  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2577  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2578  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2579  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2580  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2581  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2582 
2583  /* full request */
2584  uint8_t request2[] = {
2585  0x44, 0x44, 0x45, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff };
2586  tcph.th_ack = htonl(1);
2587  tcph.th_seq = htonl(9);
2588  tcph.th_flags = TH_PUSH | TH_ACK;
2590  p->payload_len = sizeof(request2);
2591  p->payload = request2;
2592  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2599  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2600  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2601  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2602  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2603  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2604 
2605  /* full response - request ack */
2606  uint8_t response[] = {
2607  0x55, 0x74, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2608  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2609  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2610  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2611  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2612  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2613  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2614  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2615  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2616  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2617  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2618  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2619  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2620  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2621  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2622  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2623  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2624  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2625  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2626  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2627  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2628  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2629  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2630  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2631  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2632  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2633  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2634  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2635  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2636  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2637  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2638  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2639  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2640  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2641  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2642  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2643  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2644  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2645  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2646  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2647  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2648  tcph.th_ack = htonl(18);
2649  tcph.th_seq = htonl(1);
2650  tcph.th_flags = TH_PUSH | TH_ACK;
2652  p->payload_len = sizeof(response);
2653  p->payload = response;
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 ack */
2668  tcph.th_ack = htonl(328);
2669  tcph.th_seq = htonl(18);
2670  tcph.th_flags = 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));
2686 
2687  TEST_END;
2688  PASS;
2689 }
2690 
2691 /**
2692  * \test RUBBISH(TC - PM and PP DONE) ->
2693  * RUBBISH(TS - PM and PP DONE)
2694  */
2695 static int AppLayerTest10(void)
2696 {
2697  TEST_START;
2698 
2699  /* full request */
2700  uint8_t request1[] = {
2701  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2702  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff };
2703  tcph.th_ack = htonl(1);
2704  tcph.th_seq = htonl(1);
2705  tcph.th_flags = TH_PUSH | TH_ACK;
2707  p->payload_len = sizeof(request1);
2708  p->payload = request1;
2709  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2716  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2717  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2718  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2719  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2720  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2721 
2722  /* response - request ack */
2723  tcph.th_ack = htonl(18);
2724  tcph.th_seq = htonl(1);
2725  tcph.th_flags = TH_PUSH | TH_ACK;
2727  p->payload_len = 0;
2728  p->payload = NULL;
2729  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2736  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2737  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2738  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2739  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2740  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2741 
2742  /* full response - request ack */
2743  uint8_t response[] = {
2744  0x55, 0x74, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2745  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2746  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2747  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2748  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2749  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2750  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2751  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2752  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2753  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2754  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2755  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2756  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2757  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2758  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2759  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2760  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2761  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2762  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2763  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2764  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2765  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2766  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2767  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2768  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2769  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2770  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2771  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2772  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2773  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2774  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2775  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2776  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2777  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2778  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2779  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2780  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2781  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2782  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2783  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2784  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2785  tcph.th_ack = htonl(18);
2786  tcph.th_seq = htonl(1);
2787  tcph.th_flags = TH_PUSH | TH_ACK;
2789  p->payload_len = sizeof(response);
2790  p->payload = response;
2791  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2798  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2799  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2800  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2801  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2802  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2803 
2804  /* response ack */
2805  tcph.th_ack = htonl(328);
2806  tcph.th_seq = htonl(18);
2807  tcph.th_flags = TH_ACK;
2809  p->payload_len = 0;
2810  p->payload = NULL;
2811  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2818  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2819  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2820  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2821  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2823 
2824  TEST_END;
2825  PASS;
2826 }
2827 
2828 /**
2829  * \test RUBBISH(TC - PM and PP DONE) ->
2830  * RUBBISH(TS - PM and PP NOT DONE) ->
2831  * RUBBISH(TS - PM and PP DONE)
2832  */
2833 static int AppLayerTest11(void)
2834 {
2835  TEST_START;
2836 
2837  /* full request */
2838  uint8_t request1[] = {
2839  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2840  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff };
2841  tcph.th_ack = htonl(1);
2842  tcph.th_seq = htonl(1);
2843  tcph.th_flags = TH_PUSH | TH_ACK;
2845  p->payload_len = sizeof(request1);
2846  p->payload = request1;
2847  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2854  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2855  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2856  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2857  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2858  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2859 
2860  /* response - request ack */
2861  tcph.th_ack = htonl(18);
2862  tcph.th_seq = htonl(1);
2863  tcph.th_flags = TH_PUSH | TH_ACK;
2865  p->payload_len = 0;
2866  p->payload = NULL;
2867  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2874  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2875  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2876  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2877  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2878  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2879 
2880  /* full response - request ack */
2881  uint8_t response1[] = {
2882  0x55, 0x74, 0x54, 0x50, };
2883  tcph.th_ack = htonl(18);
2884  tcph.th_seq = htonl(1);
2885  tcph.th_flags = TH_PUSH | TH_ACK;
2887  p->payload_len = sizeof(response1);
2888  p->payload = response1;
2889  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2896  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2897  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2898  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2899  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2900  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2901 
2902  /* response ack from request */
2903  tcph.th_ack = htonl(5);
2904  tcph.th_seq = htonl(18);
2905  tcph.th_flags = TH_ACK;
2907  p->payload_len = 0;
2908  p->payload = NULL;
2909  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2916  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2917  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2918  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2919  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2920  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2921 
2922  uint8_t response2[] = {
2923  0x2f, 0x31, 0x2e, 0x31,
2924  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2925  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2926  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2927  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2928  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2929  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2930  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2931  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2932  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2933  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2934  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2935  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2936  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2937  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2938  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2939  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2940  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2941  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2942  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2943  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2944  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2945  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2946  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2947  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2948  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2949  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2950  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2951  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2952  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2953  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2954  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2955  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2956  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2957  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2958  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2959  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2960  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2961  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2962  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2963  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2964  tcph.th_ack = htonl(18);
2965  tcph.th_seq = htonl(5);
2966  tcph.th_flags = TH_PUSH | TH_ACK;
2968  p->payload_len = sizeof(response2);
2969  p->payload = response2;
2970  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2977  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2978  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2979  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2980  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2981  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2982 
2983  /* response ack from request */
2984  tcph.th_ack = htonl(328);
2985  tcph.th_seq = htonl(18);
2986  tcph.th_flags = TH_ACK;
2988  p->payload_len = 0;
2989  p->payload = NULL;
2990  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2997  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2998  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2999  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
3000  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
3002 
3003  TEST_END;
3004  PASS;
3005 }
3006 
3008 {
3009  SCEnter();
3010 
3011  UtRegisterTest("AppLayerTest01", AppLayerTest01);
3012  UtRegisterTest("AppLayerTest02", AppLayerTest02);
3013  UtRegisterTest("AppLayerTest03", AppLayerTest03);
3014  UtRegisterTest("AppLayerTest04", AppLayerTest04);
3015  UtRegisterTest("AppLayerTest05", AppLayerTest05);
3016  UtRegisterTest("AppLayerTest06", AppLayerTest06);
3017  UtRegisterTest("AppLayerTest07", AppLayerTest07);
3018  UtRegisterTest("AppLayerTest08", AppLayerTest08);
3019  UtRegisterTest("AppLayerTest09", AppLayerTest09);
3020  UtRegisterTest("AppLayerTest10", AppLayerTest10);
3021  UtRegisterTest("AppLayerTest11", AppLayerTest11);
3022 
3023  SCReturn;
3024 }
3025 
3026 #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:288
UPDATE_DIR_PACKET
@ UPDATE_DIR_PACKET
Definition: stream-tcp-reassemble.h:56
FlowUnsetChangeProtoFlag
void FlowUnsetChangeProtoFlag(Flow *f)
Unset flag to indicate to change proto for the flow.
Definition: flow.c:194
Packet_::proto
uint8_t proto
Definition: decode.h:498
AppLayerParserDeSetup
int AppLayerParserDeSetup(void)
Definition: app-layer-parser.c:273
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:1706
ALPROTO_IKE
@ ALPROTO_IKE
Definition: app-layer-protos.h:55
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:44
flow-util.h
ALPROTO_DNS
@ ALPROTO_DNS
Definition: app-layer-protos.h:47
stream-tcp.h
ALPROTO_ENIP
@ ALPROTO_ENIP
Definition: app-layer-protos.h:49
StreamTcpInlineMode
bool StreamTcpInlineMode(void)
See if stream engine is operating in inline mode.
Definition: stream-tcp.c:7096
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
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:39
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
Packet_::pcap_cnt
uint64_t pcap_cnt
Definition: decode.h:595
AppLayerCounterNames_::parser_error
char parser_error[MAX_COUNTER_SIZE]
Definition: app-layer.c:82
StatsRegisterGlobalCounter
uint16_t StatsRegisterGlobalCounter(const char *name, uint64_t(*Func)(void))
Registers a counter, which represents a global value.
Definition: counters.c:1009
ALPROTO_MODBUS
@ ALPROTO_MODBUS
Definition: app-layer-protos.h:48
AppLayerProfilingStoreInternal
void AppLayerProfilingStoreInternal(AppLayerThreadCtx *app_tctx, Packet *p)
Definition: app-layer.c:1148
Flow_::proto
uint8_t proto
Definition: flow.h:379
AppProto
uint16_t AppProto
Definition: app-layer-protos.h:85
ALPROTO_QUIC
@ ALPROTO_QUIC
Definition: app-layer-protos.h:57
Packet_::payload
uint8_t * payload
Definition: decode.h:574
ALPROTO_POP3
@ ALPROTO_POP3
Definition: app-layer-protos.h:72
TcpReassemblyThreadCtx_::app_tctx
void * app_tctx
Definition: stream-tcp-reassemble.h:62
Packet_::flags
uint32_t flags
Definition: decode.h:513
AppLayerThreadCtx_::proto_detect_ticks_spent
uint64_t proto_detect_ticks_spent
Definition: app-layer.c:71
PACKET_PROFILING_APP_PD_END
#define PACKET_PROFILING_APP_PD_END(dp)
Definition: util-profiling.h:186
ALPROTO_JABBER
@ ALPROTO_JABBER
Definition: app-layer-protos.h:42
TcpStreamCnf_::reassembly_depth
uint32_t reassembly_depth
Definition: stream-tcp.h:75
AppLayerThreadCtx_::alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: app-layer.c:62
flow-private.h
Flow_
Flow data structure.
Definition: flow.h:357
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:446
AppProtoToString
const char * AppProtoToString(AppProto alproto)
Maps the ALPROTO_*, to its string equivalent.
Definition: app-layer-protos.c:40
AppLayerThreadCtx_::ticks_spent
uint64_t ticks_spent
Definition: app-layer.c:67
ALPROTO_IRC
@ ALPROTO_IRC
Definition: app-layer-protos.h:45
ExceptionPolicyStatsSetts_
Definition: util-exception-policy-types.h:48
AppLayerParserGetFirstDataDir
uint8_t AppLayerParserGetFirstDataDir(uint8_t ipproto, AppProto alproto)
Definition: app-layer-parser.c:1132
g_stats_eps_per_app_proto_errors
bool g_stats_eps_per_app_proto_errors
Definition: suricata.c:213
StreamTcpReassembleAppLayer
int StreamTcpReassembleAppLayer(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpSession *ssn, TcpStream *stream, Packet *p, enum StreamUpdateDir app_update_dir)
Update the stream reassembly upon receiving a packet.
Definition: stream-tcp-reassemble.c:1398
StreamTcpResetStreamFlagAppProtoDetectionCompleted
#define StreamTcpResetStreamFlagAppProtoDetectionCompleted(stream)
Definition: stream-tcp-private.h:305
AppLayerRegisterThreadCounters
void AppLayerRegisterThreadCounters(ThreadVars *tv)
Registers per flow counters for all protocols.
Definition: app-layer.c:1304
Flow_::alproto_orig
AppProto alproto_orig
Definition: flow.h:457
AppLayerProtoDetectSupportedIpprotos
void AppLayerProtoDetectSupportedIpprotos(AppProto alproto, uint8_t *ipprotos)
Definition: app-layer-detect-proto.c:2058
FTPMemuseGlobalCounter
uint64_t FTPMemuseGlobalCounter(void)
Definition: app-layer-ftp.c:165
ALPROTO_SIP
@ ALPROTO_SIP
Definition: app-layer-protos.h:60
AppLayerProfilingResetInternal
void AppLayerProfilingResetInternal(AppLayerThreadCtx *app_tctx)
Definition: app-layer.c:1143
AppLayerCounterNames_
Definition: app-layer.c:78
AppLayerParserStateProtoCleanup
void AppLayerParserStateProtoCleanup(uint8_t protomap, AppProto alproto, void *alstate, AppLayerParserState *pstate)
Definition: app-layer-parser.c:1601
AppLayerParserThreadCtxFree
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
Definition: app-layer-parser.c:312
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
ALPROTO_LDAP
@ ALPROTO_LDAP
Definition: app-layer-protos.h:66
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:6667
ALPROTO_FTP
@ ALPROTO_FTP
Definition: app-layer-protos.h:37
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:3007
APPLAYER_PROTO_DETECTION_SKIPPED
@ APPLAYER_PROTO_DETECTION_SKIPPED
Definition: app-layer-events.h:52
HTPMemuseGlobalCounter
uint64_t HTPMemuseGlobalCounter(void)
Definition: app-layer-htp-mem.c:81
AppLayerListSupportedProtocols
void AppLayerListSupportedProtocols(void)
Definition: app-layer.c:1013
AppLayerSetupCounters
void AppLayerSetupCounters(void)
Definition: app-layer.c:1195
ALPROTO_SSH
@ ALPROTO_SSH
Definition: app-layer-protos.h:40
app-layer-ftp.h
ALPROTO_DHCP
@ ALPROTO_DHCP
Definition: app-layer-protos.h:58
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:507
AppLayerThreadCtx_::alproto
AppProto alproto
Definition: app-layer.c:68
stream_config
TcpStreamCnf stream_config
Definition: stream-tcp.c:219
MAX
#define MAX(x, y)
Definition: suricata-common.h:395
Flow_::protoctx
void * protoctx
Definition: flow.h:442
AppLayerCounterNames_::tx_name
char tx_name[MAX_COUNTER_SIZE]
Definition: app-layer.c:80
AppLayerIncAllocErrorCounter
void AppLayerIncAllocErrorCounter(ThreadVars *tv, Flow *f)
Definition: app-layer.c:170
EXCEPTION_POLICY_NOT_SET
@ EXCEPTION_POLICY_NOT_SET
Definition: util-exception-policy-types.h:26
Packet_::payload_len
uint16_t payload_len
Definition: decode.h:575
Packet_::app_layer_events
AppLayerDecoderEvents * app_layer_events
Definition: decode.h:601
util-unittest.h
AppLayerGetProtoByName
AppProto AppLayerGetProtoByName(char *alproto_name)
Given a protocol string, returns the corresponding internal protocol id.
Definition: app-layer.c:999
PACKET_PROFILING_APP_PD_START
#define PACKET_PROFILING_APP_PD_START(dp)
Definition: util-profiling.h:181
AppLayerCounters_::parser_error_id
uint16_t parser_error_id
Definition: app-layer.c:92
AppLayerDeSetup
int AppLayerDeSetup(void)
De initializes the app layer.
Definition: app-layer.c:1092
HostGetMemcap
uint64_t HostGetMemcap(void)
Return memcap value.
Definition: host.c:83
PKT_PROTO_DETECT_TS_DONE
#define PKT_PROTO_DETECT_TS_DONE
Definition: decode.h:1301
MAX_COUNTER_SIZE
#define MAX_COUNTER_SIZE
Definition: app-layer.c:77
ALPROTO_KRB5
@ ALPROTO_KRB5
Definition: app-layer-protos.h:56
STREAMTCP_FLAG_MIDSTREAM
#define STREAMTCP_FLAG_MIDSTREAM
Definition: stream-tcp-private.h:170
TcpSession_::flags
uint32_t flags
Definition: stream-tcp-private.h:294
ALPROTO_SNMP
@ ALPROTO_SNMP
Definition: app-layer-protos.h:59
FLOW_IS_PM_DONE
#define FLOW_IS_PM_DONE(f, dir)
Definition: flow.h:279
APPLAYER_NO_TLS_AFTER_STARTTLS
@ APPLAYER_NO_TLS_AFTER_STARTTLS
Definition: app-layer-events.h:53
Flow_::alparser
AppLayerParserState * alparser
Definition: flow.h:476
EXCEPTION_POLICY_MAX
#define EXCEPTION_POLICY_MAX
Definition: util-exception-policy-types.h:36
AppLayerParserRegisterProtocolParsers
void AppLayerParserRegisterProtocolParsers(void)
Definition: app-layer-parser.c:1724
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:1075
app-layer-expectation.h
app-layer-detect-proto.h
AppLayerProtoDetectThreadCtx_
The app layer protocol detection thread context.
Definition: app-layer-detect-proto.c:181
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
g_alproto_max
AppProto g_alproto_max
Definition: app-layer-protos.c:29
FLOW_IS_PP_DONE
#define FLOW_IS_PP_DONE(f, dir)
Definition: flow.h:280
AppLayerRegisterGlobalCounters
void AppLayerRegisterGlobalCounters(void)
HACK to work around our broken unix manager (re)init loop.
Definition: app-layer.c:1156
ALPROTO_DNP3
@ ALPROTO_DNP3
Definition: app-layer-protos.h:50
PKT_DROP_REASON_APPLAYER_ERROR
@ PKT_DROP_REASON_APPLAYER_ERROR
Definition: decode.h:366
AppLayerThreadCtx_::ticks_end
uint64_t ticks_end
Definition: app-layer.c:66
PacketSwap
void PacketSwap(Packet *p)
switch direction of a packet
Definition: decode.c:551
util-exception-policy.h
ALPROTO_SMTP
@ ALPROTO_SMTP
Definition: app-layer-protos.h:38
AppProtoRegisterProtoString
void AppProtoRegisterProtoString(AppProto alproto, const char *proto_name)
Definition: app-layer-protos.c:74
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:5527
AppLayerProtoDetectReset
void AppLayerProtoDetectReset(Flow *f)
Reset proto detect for flow.
Definition: app-layer-detect-proto.c:1885
TcpSession_::state
uint8_t state
Definition: stream-tcp-private.h:285
TEST_START
#define TEST_START
Definition: app-layer.c:1382
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:287
stream.h
FlowGetProtoMapping
uint8_t FlowGetProtoMapping(uint8_t proto)
Function to map the protocol to the defined FLOW_PROTO_* enumeration.
Definition: flow-util.c:98
StreamTcpIsSetStreamFlagAppProtoDetectionCompleted
#define StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(stream)
Definition: stream-tcp-private.h:303
Packet_
Definition: decode.h:476
ALPROTO_IMAP
@ ALPROTO_IMAP
Definition: app-layer-protos.h:41
stream-tcp-private.h
ALPROTO_RDP
@ ALPROTO_RDP
Definition: app-layer-protos.h:69
FLOW_PROTO_APPLAYER_MAX
#define FLOW_PROTO_APPLAYER_MAX
Definition: flow-private.h:77
applayer_counters
AppLayerCounters(* applayer_counters)[FLOW_PROTO_APPLAYER_MAX]
Definition: app-layer.c:101
AppLayerHandleUdp
int AppLayerHandleUdp(ThreadVars *tv, AppLayerThreadCtx *tctx, Packet *p, Flow *f)
Handle a app layer UDP message.
Definition: app-layer.c:875
DEBUG_ASSERT_FLOW_LOCKED
#define DEBUG_ASSERT_FLOW_LOCKED(f)
Definition: util-validate.h:99
StreamTcpSetStreamFlagAppProtoDetectionCompleted
#define StreamTcpSetStreamFlagAppProtoDetectionCompleted(stream)
Definition: stream-tcp-private.h:301
PACKET_PROFILING_APP_END
#define PACKET_PROFILING_APP_END(dp)
Definition: util-profiling.h:173
TcpStream_::window
uint32_t window
Definition: stream-tcp-private.h:117
ALPROTO_TELNET
@ ALPROTO_TELNET
Definition: app-layer-protos.h:64
ALPROTO_DOH2
@ ALPROTO_DOH2
Definition: app-layer-protos.h:67
name
const char * name
Definition: tm-threads.c:2081
SCReturnPtr
#define SCReturnPtr(x, type)
Definition: util-debug.h:287
AppLayerThreadCtx_::alpd_tctx
AppLayerProtoDetectThreadCtx * alpd_tctx
Definition: app-layer.c:60
StreamDataAvailableForProtoDetect
uint32_t StreamDataAvailableForProtoDetect(TcpStream *stream)
Definition: stream-tcp-reassemble.c:723
AppLayerGetCtxThread
AppLayerThreadCtx * AppLayerGetCtxThread(void)
Creates a new app layer thread context.
Definition: app-layer.c:1105
ALPROTO_TFTP
@ ALPROTO_TFTP
Definition: app-layer-protos.h:54
AppLayerThreadCtx_::ticks_start
uint64_t ticks_start
Definition: app-layer.c:65
AppLayerIncParserErrorCounter
void AppLayerIncParserErrorCounter(ThreadVars *tv, Flow *f)
Definition: app-layer.c:178
ALPROTO_HTTP2
@ ALPROTO_HTTP2
Definition: app-layer-protos.h:70
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:460
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:285
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:1274
StreamTcpDisableAppLayer
void StreamTcpDisableAppLayer(Flow *f)
Definition: stream-tcp-reassemble.c:448
suricata-common.h
FLOW_RESET_PE_DONE
#define FLOW_RESET_PE_DONE(f, dir)
Definition: flow.h:289
AppLayerProtoDetectDeSetup
int AppLayerProtoDetectDeSetup(void)
Cleans up the app layer protocol detection phase.
Definition: app-layer-detect-proto.c:1745
ALPROTO_HTTP1
@ ALPROTO_HTTP1
Definition: app-layer-protos.h:36
AppLayerDecoderEventsSetEventRaw
void AppLayerDecoderEventsSetEventRaw(AppLayerDecoderEvents **sevents, uint8_t event)
Set an app layer decoder event.
Definition: app-layer-events.c:94
ALPROTO_PGSQL
@ ALPROTO_PGSQL
Definition: app-layer-protos.h:63
IPPairGetMemuse
uint64_t IPPairGetMemuse(void)
Return memuse value.
Definition: ippair.c:92
Packet_::app_update_direction
uint8_t app_update_direction
Definition: decode.h:510
FLOW_PROTO_DETECT_TS_DONE
#define FLOW_PROTO_DETECT_TS_DONE
Definition: flow.h:103
ALPROTO_FTPDATA
@ ALPROTO_FTPDATA
Definition: app-layer-protos.h:53
AppLayerIncInternalErrorCounter
void AppLayerIncInternalErrorCounter(ThreadVars *tv, Flow *f)
Definition: app-layer.c:186
eps_error_summary
ExceptionPolicyCounters eps_error_summary
Definition: app-layer.c:103
FatalError
#define FatalError(...)
Definition: util-debug.h:502
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
applayer_counter_names
AppLayerCounterNames(* applayer_counter_names)[FLOW_PROTO_APPLAYER_MAX]
Definition: app-layer.c:99
ALPROTO_WEBSOCKET
@ ALPROTO_WEBSOCKET
Definition: app-layer-protos.h:65
TcpSession_::client
TcpStream client
Definition: stream-tcp-private.h:297
PKT_PROTO_DETECT_TC_DONE
#define PKT_PROTO_DETECT_TC_DONE
Definition: decode.h:1302
FrameConfigInit
void FrameConfigInit(void)
Definition: app-layer-frames.c:39
AppLayerParserGetStreamDepth
uint32_t AppLayerParserGetStreamDepth(const Flow *f)
Definition: app-layer-parser.c:1562
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:2120
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:1403
AppLayerProtoDetectGetCtxThread
AppLayerProtoDetectThreadCtx * AppLayerProtoDetectGetCtxThread(void)
Inits and returns an app layer protocol detection thread context.
Definition: app-layer-detect-proto.c:1979
TcpSession_::server
TcpStream server
Definition: stream-tcp-private.h:296
AppLayerProtoDetectGetProtoByName
AppProto AppLayerProtoDetectGetProtoByName(const char *alproto_name)
Definition: app-layer-detect-proto.c:2078
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:452
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:7102
Flow_::alstate
void * alstate
Definition: flow.h:477
AppLayerDestroyCtxThread
void AppLayerDestroyCtxThread(AppLayerThreadCtx *app_tctx)
Destroys the context created by AppLayerGetCtxThread().
Definition: app-layer.c:1126
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:422
HTPMemcapGlobalCounter
uint64_t HTPMemcapGlobalCounter(void)
Definition: app-layer-htp-mem.c:87
ALPROTO_MQTT
@ ALPROTO_MQTT
Definition: app-layer-protos.h:62
AppLayerGetProtoName
const char * AppLayerGetProtoName(AppProto alproto)
Given the internal protocol id, returns a string representation of the protocol.
Definition: app-layer.c:1006
g_applayerparser_error_policy
enum ExceptionPolicy g_applayerparser_error_policy
Definition: app-layer-parser.c:149
ALPROTO_HTTP
@ ALPROTO_HTTP
Definition: app-layer-protos.h:76
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:33
ALPROTO_TEMPLATE
@ ALPROTO_TEMPLATE
Definition: app-layer-protos.h:68
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
ALPROTO_RFB
@ ALPROTO_RFB
Definition: app-layer-protos.h:61
TEST_END
#define TEST_END
Definition: app-layer.c:1464
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:2032
ALPROTO_BITTORRENT_DHT
@ ALPROTO_BITTORRENT_DHT
Definition: app-layer-protos.h:71
ALPROTO_NTP
@ ALPROTO_NTP
Definition: app-layer-protos.h:52
ALPROTO_SMB
@ ALPROTO_SMB
Definition: app-layer-protos.h:43
likely
#define likely(expr)
Definition: util-optimize.h:32
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
FrameConfigDeInit
void FrameConfigDeInit(void)
Definition: app-layer-frames.c:50
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:453
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:1506
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:451
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:1368
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:102
ALPROTO_NFS
@ ALPROTO_NFS
Definition: app-layer-protos.h:51
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:2103
app-layer.h