suricata
app-layer.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2024 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Victor Julien <victor@inliniac.net>
22  * \author Anoop Saldanha <anoopsaldanha@gmail.com>
23  *
24  * Generic App-layer functions
25  */
26 
27 #include "suricata-common.h"
28 #include "suricata.h"
29 #include "app-layer.h"
30 #include "app-layer-parser.h"
31 #include "app-layer-protos.h"
32 #include "app-layer-expectation.h"
33 #include "app-layer-ftp.h"
34 #include "app-layer-detect-proto.h"
35 #include "app-layer-frames.h"
36 #include "stream-tcp-reassemble.h"
37 #include "stream-tcp-private.h"
38 #include "stream-tcp-inline.h"
39 #include "stream-tcp.h"
40 #include "flow.h"
41 #include "flow-util.h"
42 #include "flow-private.h"
43 #include "ippair.h"
44 #include "util-debug.h"
45 #include "util-print.h"
46 #include "util-profiling.h"
47 #include "util-validate.h"
48 #include "decode-events.h"
49 #include "app-layer-htp-mem.h"
50 #include "util-exception-policy.h"
51 
53 /**
54  * \brief This is for the app layer in general and it contains per thread
55  * context relevant to both the alpd and alp.
56  */
58  /* App layer protocol detection thread context, from AppLayerProtoDetectGetCtxThread(). */
60  /* App layer parser thread context, from AppLayerParserThreadCtxAlloc(). */
62 
63 #ifdef PROFILING
64  uint64_t ticks_start;
65  uint64_t ticks_end;
66  uint64_t ticks_spent;
71 #endif
72 };
73 
74 #define FLOW_PROTO_CHANGE_MAX_DEPTH 4096
75 
76 #define MAX_COUNTER_SIZE 64
77 typedef struct AppLayerCounterNames_ {
86 
87 typedef struct AppLayerCounters_ {
88  uint16_t counter_id;
89  uint16_t counter_tx_id;
90  uint16_t gap_error_id;
91  uint16_t parser_error_id;
93  uint16_t alloc_error_id;
96 
97 /* counter names. Only used at init. */
99 /* counter id's. Used that runtime. */
101 /* Exception policy global counters ids */
103 
104 /* Settings order as in the enum */
105 // clang-format off
107  .valid_settings_ids = {
108  /* EXCEPTION_POLICY_NOT_SET */ false,
109  /* EXCEPTION_POLICY_AUTO */ false,
110  /* EXCEPTION_POLICY_PASS_PACKET */ true,
111  /* EXCEPTION_POLICY_PASS_FLOW */ true,
112  /* EXCEPTION_POLICY_BYPASS_FLOW */ true,
113  /* EXCEPTION_POLICY_DROP_PACKET */ false,
114  /* EXCEPTION_POLICY_DROP_FLOW */ false,
115  /* EXCEPTION_POLICY_REJECT */ true,
116  },
117  .valid_settings_ips = {
118  /* EXCEPTION_POLICY_NOT_SET */ false,
119  /* EXCEPTION_POLICY_AUTO */ false,
120  /* EXCEPTION_POLICY_PASS_PACKET */ true,
121  /* EXCEPTION_POLICY_PASS_FLOW */ true,
122  /* EXCEPTION_POLICY_BYPASS_FLOW */ true,
123  /* EXCEPTION_POLICY_DROP_PACKET */ true,
124  /* EXCEPTION_POLICY_DROP_FLOW */ true,
125  /* EXCEPTION_POLICY_REJECT */ true,
126  },
127 };
128 // clang-format on
129 
130 void AppLayerSetupCounters(void);
131 void AppLayerDeSetupCounters(void);
132 
133 /***** L7 layer dispatchers *****/
134 
135 static inline int ProtoDetectDone(const Flow *f, const TcpSession *ssn, uint8_t direction) {
136  const TcpStream *stream = (direction & STREAM_TOSERVER) ? &ssn->client : &ssn->server;
138  (FLOW_IS_PM_DONE(f, direction) && FLOW_IS_PP_DONE(f, direction)));
139 }
140 
141 /**
142  * \note id can be 0 if protocol parser is disabled but detection
143  * is enabled.
144  */
145 static void AppLayerIncFlowCounter(ThreadVars *tv, Flow *f)
146 {
147  const uint16_t id = applayer_counters[f->protomap][f->alproto].counter_id;
148  if (likely(tv && id > 0)) {
149  StatsIncr(tv, id);
150  }
151 }
152 
153 void AppLayerIncTxCounter(ThreadVars *tv, Flow *f, uint64_t step)
154 {
155  const uint16_t id = applayer_counters[f->protomap][f->alproto].counter_tx_id;
156  if (likely(tv && id > 0)) {
157  StatsAddUI64(tv, id, step);
158  }
159 }
160 
162 {
163  const uint16_t id = applayer_counters[f->protomap][f->alproto].gap_error_id;
164  if (likely(tv && id > 0)) {
165  StatsIncr(tv, id);
166  }
167 }
168 
170 {
171  const uint16_t id = applayer_counters[f->protomap][f->alproto].alloc_error_id;
172  if (likely(tv && id > 0)) {
173  StatsIncr(tv, id);
174  }
175 }
176 
178 {
179  const uint16_t id = applayer_counters[f->protomap][f->alproto].parser_error_id;
180  if (likely(tv && id > 0)) {
181  StatsIncr(tv, id);
182  }
183 }
184 
186 {
187  const uint16_t id = applayer_counters[f->protomap][f->alproto].internal_error_id;
188  if (likely(tv && id > 0)) {
189  StatsIncr(tv, id);
190  }
191 }
192 
193 static void AppLayerIncrErrorExcPolicyCounter(ThreadVars *tv, Flow *f, enum ExceptionPolicy policy)
194 {
195 #ifdef UNITTESTS
196  if (tv == NULL) {
197  return;
198  }
199 #endif
200  uint16_t id = applayer_counters[f->protomap][f->alproto].eps_error.eps_id[policy];
201  /* for the summary values */
202  uint16_t g_id = eps_error_summary.eps_id[policy];
203 
204  if (likely(id > 0)) {
205  StatsIncr(tv, id);
206  }
207  if (likely(g_id > 0)) {
208  StatsIncr(tv, g_id);
209  }
210 }
211 
212 /* in IDS mode protocol detection is done in reverse order:
213  * when TCP data is ack'd. We want to flag the correct packet,
214  * so in this case we set a flag in the flow so that the first
215  * packet in the correct direction can be tagged.
216  *
217  * For IPS we update packet and flow. */
218 static inline void FlagPacketFlow(Packet *p, Flow *f, uint8_t flags)
219 {
220  if (p->proto != IPPROTO_TCP || EngineModeIsIPS()) {
221  if (flags & STREAM_TOSERVER) {
222  if (p->flowflags & FLOW_PKT_TOSERVER) {
225  } else {
227  }
228  } else {
229  if (p->flowflags & FLOW_PKT_TOCLIENT) {
232  } else {
234  }
235  }
236  } else {
237  if (flags & STREAM_TOSERVER) {
239  } else {
241  }
242  }
243 }
244 
245 static void DisableAppLayer(ThreadVars *tv, Flow *f, Packet *p)
246 {
247  SCLogDebug("disable app layer for flow %p alproto %u ts %u tc %u",
248  f, f->alproto, f->alproto_ts, f->alproto_tc);
251  TcpSession *ssn = f->protoctx;
253  f->alproto = ALPROTO_FAILED;
254  AppLayerIncFlowCounter(tv, f);
255 
256  if (f->alproto_tc != ALPROTO_FAILED) {
257  if (f->alproto_tc == ALPROTO_UNKNOWN) {
259  }
260  FlagPacketFlow(p, f, STREAM_TOCLIENT);
261  }
262  if (f->alproto_ts != ALPROTO_FAILED) {
263  if (f->alproto_ts == ALPROTO_UNKNOWN) {
265  }
266  FlagPacketFlow(p, f, STREAM_TOSERVER);
267  }
268  SCLogDebug("disabled app layer for flow %p alproto %u ts %u tc %u",
269  f, f->alproto, f->alproto_ts, f->alproto_tc);
270 }
271 
272 /* See if we're going to have to give up:
273  *
274  * If we're getting a lot of data in one direction and the
275  * proto for this direction is unknown, proto detect will
276  * hold up segments in the segment list in the stream.
277  * They are held so that if we detect the protocol on the
278  * opposing stream, we can still parse this side of the stream
279  * as well. However, some sessions are very unbalanced. FTP
280  * data channels, large PUT/POST request and many others, can
281  * lead to cases where we would have to store many megabytes
282  * worth of segments before we see the opposing stream. This
283  * leads to risks of resource starvation.
284  *
285  * Here a cutoff point is enforced. If we've stored 100k in
286  * one direction and we've seen no data in the other direction,
287  * we give up.
288  *
289  * Giving up means we disable applayer an set an applayer event
290  */
291 static void TCPProtoDetectCheckBailConditions(ThreadVars *tv,
292  Flow *f, TcpSession *ssn, Packet *p)
293 {
294  if (ssn->state < TCP_ESTABLISHED) {
295  SCLogDebug("skip as long as TCP is not ESTABLISHED (TCP fast open)");
296  return;
297  }
298 
299  const uint32_t size_ts = StreamDataAvailableForProtoDetect(&ssn->client);
300  const uint32_t size_tc = StreamDataAvailableForProtoDetect(&ssn->server);
301  SCLogDebug("size_ts %" PRIu32 ", size_tc %" PRIu32, size_ts, size_tc);
302 
303  /* at least 100000 whatever the conditions
304  * and can be more if window is bigger and if configuration allows it */
305  const uint32_t size_tc_limit =
307  const uint32_t size_ts_limit =
309 
310  if (ProtoDetectDone(f, ssn, STREAM_TOSERVER) &&
311  ProtoDetectDone(f, ssn, STREAM_TOCLIENT))
312  {
313  goto failure;
314 
315  /* we bail out whatever the pp and pm states if
316  * we received too much data */
317  } else if (size_tc > 2 * size_tc_limit || size_ts > 2 * size_ts_limit) {
319  goto failure;
320 
321  } else if (FLOW_IS_PM_DONE(f, STREAM_TOSERVER) && FLOW_IS_PP_DONE(f, STREAM_TOSERVER) &&
322  size_ts > size_ts_limit && size_tc == 0) {
325  goto failure;
326 
327  } else if (FLOW_IS_PM_DONE(f, STREAM_TOCLIENT) && FLOW_IS_PP_DONE(f, STREAM_TOCLIENT) &&
328  size_tc > size_tc_limit && size_ts == 0) {
331  goto failure;
332 
333  /* little data in ts direction, pp done, pm not done (max
334  * depth not reached), ts direction done, lots of data in
335  * tc direction. */
336  } else if (size_tc > size_tc_limit && FLOW_IS_PP_DONE(f, STREAM_TOSERVER) &&
337  !(FLOW_IS_PM_DONE(f, STREAM_TOSERVER)) && FLOW_IS_PM_DONE(f, STREAM_TOCLIENT) &&
338  FLOW_IS_PP_DONE(f, STREAM_TOCLIENT)) {
341  goto failure;
342 
343  /* little data in tc direction, pp done, pm not done (max
344  * depth not reached), tc direction done, lots of data in
345  * ts direction. */
346  } else if (size_ts > size_ts_limit && FLOW_IS_PP_DONE(f, STREAM_TOCLIENT) &&
347  !(FLOW_IS_PM_DONE(f, STREAM_TOCLIENT)) && FLOW_IS_PM_DONE(f, STREAM_TOSERVER) &&
348  FLOW_IS_PP_DONE(f, STREAM_TOSERVER)) {
351  goto failure;
352  }
353  return;
354 
355 failure:
356  DisableAppLayer(tv, f, p);
357  return;
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 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, f->alproto);
559  p->app_update_direction = (uint8_t)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, f->alproto);
647  p->app_update_direction = (uint8_t)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 dir)
711 {
712  SCEnter();
713 
715  DEBUG_VALIDATE_BUG_ON(data_len > (uint32_t)INT_MAX);
716 
717  AppLayerThreadCtx *app_tctx = ra_ctx->app_tctx;
718  AppProto alproto;
719  int r = 0;
720 
721  SCLogDebug("data_len %u flags %02X", data_len, flags);
723  SCLogDebug("STREAMTCP_FLAG_APP_LAYER_DISABLED is set");
724  goto end;
725  }
726 
727  const uint8_t direction = (flags & STREAM_TOSERVER) ? 0 : 1;
728 
729  if (flags & STREAM_TOSERVER) {
730  alproto = f->alproto_ts;
731  } else {
732  alproto = f->alproto_tc;
733  }
734 
735  /* If a gap notification, relay the notification on to the
736  * app-layer if known. */
737  if (flags & STREAM_GAP) {
738  if (alproto == ALPROTO_UNKNOWN) {
740  SCLogDebug("ALPROTO_UNKNOWN flow %p, due to GAP in stream start", f);
741  /* if the other side didn't already find the proto, we're done */
742  if (f->alproto == ALPROTO_UNKNOWN) {
743  goto failure;
744  }
745  AppLayerIncFlowCounter(tv, f);
746  }
747  if (FlowChangeProto(f)) {
749  SCLogDebug("Cannot handle gap while changing protocol");
750  goto failure;
751  }
752  PACKET_PROFILING_APP_START(app_tctx, f->alproto);
753  r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto,
754  flags, data, data_len);
755  PACKET_PROFILING_APP_END(app_tctx, f->alproto);
756  p->app_update_direction = (uint8_t)dir;
757  /* ignore parser result for gap */
758  StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
759  if (r < 0) {
761  AppLayerIncrErrorExcPolicyCounter(tv, f, g_applayerparser_error_policy);
762  SCReturnInt(-1);
763  }
764  goto end;
765  }
766 
767  /* if we don't know the proto yet and we have received a stream
768  * initializer message, we run proto detection.
769  * We receive 2 stream init msgs (one for each direction), we
770  * only run the proto detection for both and emit an event
771  * in the case protocols mismatch. */
772  if (alproto == ALPROTO_UNKNOWN && (flags & STREAM_START)) {
774  /* run protocol detection */
775  if (TCPProtoDetect(tv, ra_ctx, app_tctx, p, f, ssn, stream, data, data_len, flags, dir) !=
776  0) {
777  goto failure;
778  }
779  } else if (alproto != ALPROTO_UNKNOWN && FlowChangeProto(f)) {
780  SCLogDebug("protocol change, old %s", AppProtoToString(f->alproto_orig));
781  void *alstate_orig = f->alstate;
782  AppLayerParserState *alparser = f->alparser;
783  // we delay AppLayerParserStateCleanup because we may need previous parser state
787  /* rerun protocol detection */
788  int rd =
789  TCPProtoDetect(tv, ra_ctx, app_tctx, p, f, ssn, stream, data, data_len, flags, dir);
790  if (f->alproto == ALPROTO_UNKNOWN) {
791  DEBUG_VALIDATE_BUG_ON(alstate_orig != f->alstate);
792  // not enough data, revert AppLayerProtoDetectReset to rerun detection
793  f->alparser = alparser;
794  f->alproto = f->alproto_orig;
795  f->alproto_tc = f->alproto_orig;
796  f->alproto_ts = f->alproto_orig;
797  } else {
799  AppLayerParserStateProtoCleanup(f->protomap, f->alproto_orig, alstate_orig, alparser);
800  if (alstate_orig == f->alstate) {
801  // we just freed it
802  f->alstate = NULL;
803  }
804  }
805  if (rd != 0) {
806  SCLogDebug("proto detect failure");
807  goto failure;
808  }
809  SCLogDebug("protocol change, old %s, new %s",
811 
813  f->alproto != f->alproto_expect) {
816 
817  if (f->alproto_expect == ALPROTO_TLS && f->alproto != ALPROTO_TLS) {
820 
821  }
822  }
823  } else {
824  SCLogDebug("stream data (len %" PRIu32 " alproto "
825  "%"PRIu16" (flow %p)", data_len, f->alproto, f);
826 #ifdef PRINT
827  if (data_len > 0) {
828  printf("=> Stream Data (app layer) -- start %s%s\n",
829  flags & STREAM_TOCLIENT ? "toclient" : "",
830  flags & STREAM_TOSERVER ? "toserver" : "");
831  PrintRawDataFp(stdout, data, data_len);
832  printf("=> Stream Data -- end\n");
833  }
834 #endif
835  /* if we don't have a data object here we are not getting it
836  * a start msg should have gotten us one */
837  if (f->alproto != ALPROTO_UNKNOWN) {
838  PACKET_PROFILING_APP_START(app_tctx, f->alproto);
839  r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto,
840  flags, data, data_len);
841  PACKET_PROFILING_APP_END(app_tctx, f->alproto);
842  p->app_update_direction = (uint8_t)dir;
843  if (r != 1) {
844  StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
845  if (r < 0) {
848  AppLayerIncrErrorExcPolicyCounter(tv, f, g_applayerparser_error_policy);
849  SCReturnInt(-1);
850  }
851  }
852  }
853  }
854 
855  goto end;
856  failure:
857  r = -1;
858  end:
859  SCReturnInt(r);
860 }
861 
862 /**
863  * \brief Handle a app layer UDP message
864  *
865  * If the protocol is yet unknown, the proto detection code is run first.
866  *
867  * \param dp_ctx Thread app layer detect context
868  * \param f *locked* flow
869  * \param p UDP packet
870  *
871  * \retval 0 ok
872  * \retval -1 error
873  */
875 {
876  SCEnter();
877  AppProto *alproto;
878  AppProto *alproto_otherdir;
879 
880  if (f->alproto_ts == ALPROTO_FAILED && f->alproto_tc == ALPROTO_FAILED) {
881  SCReturnInt(0);
882  }
883 
884  int r = 0;
885  uint8_t flags = 0;
886  if (p->flowflags & FLOW_PKT_TOSERVER) {
887  flags |= STREAM_TOSERVER;
888  alproto = &f->alproto_ts;
889  alproto_otherdir = &f->alproto_tc;
890  } else {
891  flags |= STREAM_TOCLIENT;
892  alproto = &f->alproto_tc;
893  alproto_otherdir = &f->alproto_ts;
894  }
895 
896  AppLayerProfilingReset(tctx);
897 
898  /* if the protocol is still unknown, run detection */
899  if (*alproto == ALPROTO_UNKNOWN) {
900  SCLogDebug("Detecting AL proto on udp mesg (len %" PRIu32 ")",
901  p->payload_len);
902 
903  bool reverse_flow = false;
905  *alproto = AppLayerProtoDetectGetProto(
906  tctx->alpd_tctx, f, p->payload, p->payload_len, IPPROTO_UDP, flags, &reverse_flow);
908 
909  switch (*alproto) {
910  case ALPROTO_UNKNOWN:
911  if (*alproto_otherdir != ALPROTO_UNKNOWN) {
912  // Use recognized side
913  f->alproto = *alproto_otherdir;
914  // do not keep ALPROTO_UNKNOWN for this side so as not to loop
915  *alproto = *alproto_otherdir;
916  if (*alproto_otherdir == ALPROTO_FAILED) {
917  SCLogDebug("ALPROTO_UNKNOWN flow %p", f);
918  }
919  } else {
920  // First side of protocol is unknown
921  *alproto = ALPROTO_FAILED;
922  }
923  break;
924  case ALPROTO_FAILED:
925  if (*alproto_otherdir != ALPROTO_UNKNOWN) {
926  // Use recognized side
927  f->alproto = *alproto_otherdir;
928  if (*alproto_otherdir == ALPROTO_FAILED) {
929  SCLogDebug("ALPROTO_UNKNOWN flow %p", f);
930  }
931  }
932  // else wait for second side of protocol
933  break;
934  default:
935  if (*alproto_otherdir != ALPROTO_UNKNOWN && *alproto_otherdir != ALPROTO_FAILED) {
936  if (*alproto_otherdir != *alproto) {
939  // data already sent to parser, we cannot change the protocol to use the one
940  // of the server
941  }
942  } else {
943  f->alproto = *alproto;
944  }
945  }
946  if (*alproto_otherdir == ALPROTO_UNKNOWN) {
947  if (f->alproto == ALPROTO_UNKNOWN) {
948  // so as to increase stat about .app_layer.flow.failed_udp
949  f->alproto = ALPROTO_FAILED;
950  }
951  // If the other side is unknown, this is the first packet of the flow
952  AppLayerIncFlowCounter(tv, f);
953  }
954 
955  // parse the data if we recognized one protocol
956  if (f->alproto != ALPROTO_UNKNOWN && f->alproto != ALPROTO_FAILED) {
957  if (reverse_flow) {
958  SCLogDebug("reversing flow after proto detect told us so");
959  PacketSwap(p);
960  FlowSwap(f);
961  SWAP_FLAGS(flags, STREAM_TOSERVER, STREAM_TOCLIENT);
962  }
963 
965  r = AppLayerParserParse(tv, tctx->alp_tctx, f, f->alproto,
966  flags, p->payload, p->payload_len);
969  }
971  /* we do only inspection in one direction, so flag both
972  * sides as done here */
973  FlagPacketFlow(p, f, STREAM_TOSERVER);
974  FlagPacketFlow(p, f, STREAM_TOCLIENT);
975  } else {
976  SCLogDebug("data (len %" PRIu32 " ), alproto "
977  "%"PRIu16" (flow %p)", p->payload_len, f->alproto, f);
978 
979  /* run the parser */
981  r = AppLayerParserParse(tv, tctx->alp_tctx, f, f->alproto,
982  flags, p->payload, p->payload_len);
986  }
987  if (r < 0) {
989  AppLayerIncrErrorExcPolicyCounter(tv, f, g_applayerparser_error_policy);
990  SCReturnInt(-1);
991  }
992 
993  SCReturnInt(r);
994 }
995 
996 /***** Utility *****/
997 
998 AppProto AppLayerGetProtoByName(char *alproto_name)
999 {
1000  SCEnter();
1001  AppProto r = AppLayerProtoDetectGetProtoByName(alproto_name);
1002  SCReturnCT(r, "AppProto");
1003 }
1004 
1005 const char *AppLayerGetProtoName(AppProto alproto)
1006 {
1007  SCEnter();
1008  const char * r = AppLayerProtoDetectGetProtoName(alproto);
1009  SCReturnCT(r, "char *");
1010 }
1011 
1013 {
1014  SCEnter();
1015 
1016  AppProto alproto;
1017  AppProto alprotos[ALPROTO_MAX];
1018 
1020 
1021  printf("=========Supported App Layer Protocols=========\n");
1022  for (alproto = 0; alproto < ALPROTO_MAX; alproto++) {
1023  if (alprotos[alproto] == 1)
1024  printf("%s\n", AppLayerGetProtoName(alproto));
1025  }
1026 
1027  SCReturn;
1028 }
1029 
1030 /***** Setup/General Registration *****/
1031 
1032 int AppLayerSetup(void)
1033 {
1034  SCEnter();
1035 
1038 
1041 
1043 
1044  SCReturnInt(0);
1045 }
1046 
1048 {
1049  SCEnter();
1050 
1053 
1055 
1056  SCReturnInt(0);
1057 }
1058 
1060 {
1061  SCEnter();
1062 
1063  AppLayerThreadCtx *app_tctx = SCCalloc(1, sizeof(*app_tctx));
1064  if (app_tctx == NULL)
1065  goto error;
1066 
1067  if ((app_tctx->alpd_tctx = AppLayerProtoDetectGetCtxThread()) == NULL)
1068  goto error;
1069  if ((app_tctx->alp_tctx = AppLayerParserThreadCtxAlloc()) == NULL)
1070  goto error;
1071 
1072  goto done;
1073  error:
1074  AppLayerDestroyCtxThread(app_tctx);
1075  app_tctx = NULL;
1076  done:
1077  SCReturnPtr(app_tctx, "void *");
1078 }
1079 
1081 {
1082  SCEnter();
1083 
1084  if (app_tctx == NULL)
1085  SCReturn;
1086 
1087  if (app_tctx->alpd_tctx != NULL)
1089  if (app_tctx->alp_tctx != NULL)
1091  SCFree(app_tctx);
1092 
1093  SCReturn;
1094 }
1095 
1096 #ifdef PROFILING
1098 {
1099  PACKET_PROFILING_APP_RESET(app_tctx);
1100 }
1101 
1103 {
1104  PACKET_PROFILING_APP_STORE(app_tctx, p);
1105 }
1106 #endif
1107 
1108 /** \brief HACK to work around our broken unix manager (re)init loop
1109  */
1111 {
1116  StatsRegisterGlobalCounter("app_layer.expectations", ExpectationGetCounter);
1117 }
1118 
1119 static bool IsAppLayerErrorExceptionPolicyStatsValid(enum ExceptionPolicy policy)
1120 {
1121  if (EngineModeIsIPS()) {
1123  }
1125 }
1126 
1127 static void AppLayerSetupExceptionPolicyPerProtoCounters(
1128  uint8_t ipproto_map, AppProto alproto, const char *alproto_str, const char *ipproto_suffix)
1129 {
1132  for (enum ExceptionPolicy i = EXCEPTION_POLICY_NOT_SET + 1; i < EXCEPTION_POLICY_MAX; i++) {
1133  if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1134  snprintf(applayer_counter_names[ipproto_map][alproto].eps_name[i],
1135  sizeof(applayer_counter_names[ipproto_map][alproto].eps_name[i]),
1136  "app_layer.error.%s%s.exception_policy.%s", alproto_str, ipproto_suffix,
1137  ExceptionPolicyEnumToString(i, true));
1138  }
1139  }
1140  }
1141 }
1142 
1143 #define IPPROTOS_MAX 2
1145 {
1146  const uint8_t ipprotos[] = { IPPROTO_TCP, IPPROTO_UDP };
1147  AppProto alprotos[ALPROTO_MAX];
1148  const char *str = "app_layer.flow.";
1149  const char *estr = "app_layer.error.";
1150 
1151  /* We don't log stats counters if exception policy is `ignore`/`not set` */
1153  /* Register global counters for app layer error exception policy summary */
1154  const char *eps_default_str = "app_layer.error.exception_policy.";
1155  for (enum ExceptionPolicy i = EXCEPTION_POLICY_NOT_SET + 1; i < EXCEPTION_POLICY_MAX; i++) {
1156  if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1157  snprintf(app_layer_error_eps_stats.eps_name[i],
1158  sizeof(app_layer_error_eps_stats.eps_name[i]), "%s%s", eps_default_str,
1159  ExceptionPolicyEnumToString(i, true));
1160  }
1161  }
1162  }
1163 
1165 
1166  for (uint8_t p = 0; p < IPPROTOS_MAX; p++) {
1167  const uint8_t ipproto = ipprotos[p];
1168  const uint8_t ipproto_map = FlowGetProtoMapping(ipproto);
1169  const char *ipproto_suffix = (ipproto == IPPROTO_TCP) ? "_tcp" : "_udp";
1170  uint8_t ipprotos_all[256 / 8];
1171 
1172  for (AppProto alproto = 0; alproto < ALPROTO_MAX; alproto++) {
1173  if (alprotos[alproto] == 1) {
1174  const char *tx_str = "app_layer.tx.";
1175  const char *alproto_str = AppLayerGetProtoName(alproto);
1176 
1177  memset(ipprotos_all, 0, sizeof(ipprotos_all));
1178  AppLayerProtoDetectSupportedIpprotos(alproto, ipprotos_all);
1179  if ((ipprotos_all[IPPROTO_TCP / 8] & (1 << (IPPROTO_TCP % 8))) &&
1180  (ipprotos_all[IPPROTO_UDP / 8] & (1 << (IPPROTO_UDP % 8)))) {
1181  snprintf(applayer_counter_names[ipproto_map][alproto].name,
1182  sizeof(applayer_counter_names[ipproto_map][alproto].name),
1183  "%s%s%s", str, alproto_str, ipproto_suffix);
1184  snprintf(applayer_counter_names[ipproto_map][alproto].tx_name,
1185  sizeof(applayer_counter_names[ipproto_map][alproto].tx_name),
1186  "%s%s%s", tx_str, alproto_str, ipproto_suffix);
1187 
1188  if (ipproto == IPPROTO_TCP) {
1189  snprintf(applayer_counter_names[ipproto_map][alproto].gap_error,
1190  sizeof(applayer_counter_names[ipproto_map][alproto].gap_error),
1191  "%s%s%s.gap", estr, alproto_str, ipproto_suffix);
1192  }
1193  snprintf(applayer_counter_names[ipproto_map][alproto].alloc_error,
1194  sizeof(applayer_counter_names[ipproto_map][alproto].alloc_error),
1195  "%s%s%s.alloc", estr, alproto_str, ipproto_suffix);
1196  snprintf(applayer_counter_names[ipproto_map][alproto].parser_error,
1197  sizeof(applayer_counter_names[ipproto_map][alproto].parser_error),
1198  "%s%s%s.parser", estr, alproto_str, ipproto_suffix);
1199  snprintf(applayer_counter_names[ipproto_map][alproto].internal_error,
1200  sizeof(applayer_counter_names[ipproto_map][alproto].internal_error),
1201  "%s%s%s.internal", estr, alproto_str, ipproto_suffix);
1202 
1203  AppLayerSetupExceptionPolicyPerProtoCounters(
1204  ipproto_map, alproto, alproto_str, ipproto_suffix);
1205  } else {
1206  snprintf(applayer_counter_names[ipproto_map][alproto].name,
1207  sizeof(applayer_counter_names[ipproto_map][alproto].name),
1208  "%s%s", str, alproto_str);
1209  snprintf(applayer_counter_names[ipproto_map][alproto].tx_name,
1210  sizeof(applayer_counter_names[ipproto_map][alproto].tx_name),
1211  "%s%s", tx_str, alproto_str);
1212 
1213  if (ipproto == IPPROTO_TCP) {
1214  snprintf(applayer_counter_names[ipproto_map][alproto].gap_error,
1215  sizeof(applayer_counter_names[ipproto_map][alproto].gap_error),
1216  "%s%s.gap", estr, alproto_str);
1217  }
1218  snprintf(applayer_counter_names[ipproto_map][alproto].alloc_error,
1219  sizeof(applayer_counter_names[ipproto_map][alproto].alloc_error),
1220  "%s%s.alloc", estr, alproto_str);
1221  snprintf(applayer_counter_names[ipproto_map][alproto].parser_error,
1222  sizeof(applayer_counter_names[ipproto_map][alproto].parser_error),
1223  "%s%s.parser", estr, alproto_str);
1224  snprintf(applayer_counter_names[ipproto_map][alproto].internal_error,
1225  sizeof(applayer_counter_names[ipproto_map][alproto].internal_error),
1226  "%s%s.internal", estr, alproto_str);
1227  AppLayerSetupExceptionPolicyPerProtoCounters(
1228  ipproto_map, alproto, alproto_str, "");
1229  }
1230  } else if (alproto == ALPROTO_FAILED) {
1231  snprintf(applayer_counter_names[ipproto_map][alproto].name,
1232  sizeof(applayer_counter_names[ipproto_map][alproto].name),
1233  "%s%s%s", str, "failed", ipproto_suffix);
1234  if (ipproto == IPPROTO_TCP) {
1235  snprintf(applayer_counter_names[ipproto_map][alproto].gap_error,
1236  sizeof(applayer_counter_names[ipproto_map][alproto].gap_error),
1237  "%sfailed%s.gap", estr, ipproto_suffix);
1238  }
1239  }
1240  }
1241  }
1242 }
1243 
1245 {
1246  const uint8_t ipprotos[] = { IPPROTO_TCP, IPPROTO_UDP };
1247  AppProto alprotos[ALPROTO_MAX];
1249 
1250  /* We don't log stats counters if exception policy is `ignore`/`not set` */
1252  /* Register global counters for app layer error exception policy summary */
1253  for (enum ExceptionPolicy i = EXCEPTION_POLICY_NOT_SET + 1; i < EXCEPTION_POLICY_MAX; i++) {
1254  if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1257  }
1258  }
1259  }
1260 
1261  for (uint8_t p = 0; p < IPPROTOS_MAX; p++) {
1262  const uint8_t ipproto = ipprotos[p];
1263  const uint8_t ipproto_map = FlowGetProtoMapping(ipproto);
1264 
1265  for (AppProto alproto = 0; alproto < ALPROTO_MAX; alproto++) {
1266  if (alprotos[alproto] == 1) {
1267  applayer_counters[ipproto_map][alproto].counter_id =
1268  StatsRegisterCounter(applayer_counter_names[ipproto_map][alproto].name, tv);
1269 
1270  applayer_counters[ipproto_map][alproto].counter_tx_id =
1271  StatsRegisterCounter(applayer_counter_names[ipproto_map][alproto].tx_name, tv);
1272 
1273  if (ipproto == IPPROTO_TCP) {
1274  applayer_counters[ipproto_map][alproto].gap_error_id = StatsRegisterCounter(
1275  applayer_counter_names[ipproto_map][alproto].gap_error, tv);
1276  }
1277  applayer_counters[ipproto_map][alproto].alloc_error_id = StatsRegisterCounter(
1278  applayer_counter_names[ipproto_map][alproto].alloc_error, tv);
1279  applayer_counters[ipproto_map][alproto].parser_error_id = StatsRegisterCounter(
1280  applayer_counter_names[ipproto_map][alproto].parser_error, tv);
1282  applayer_counter_names[ipproto_map][alproto].internal_error, tv);
1283  /* We don't log stats counters if exception policy is `ignore`/`not set` */
1286  for (enum ExceptionPolicy i = EXCEPTION_POLICY_NOT_SET + 1;
1287  i < EXCEPTION_POLICY_MAX; i++) {
1288  if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1289  applayer_counters[ipproto_map][alproto]
1291  applayer_counter_names[ipproto_map][alproto].eps_name[i], tv);
1292  }
1293  }
1294  }
1295  } else if (alproto == ALPROTO_FAILED) {
1296  applayer_counters[ipproto_map][alproto].counter_id =
1297  StatsRegisterCounter(applayer_counter_names[ipproto_map][alproto].name, tv);
1298 
1299  if (ipproto == IPPROTO_TCP) {
1300  applayer_counters[ipproto_map][alproto].gap_error_id = StatsRegisterCounter(
1301  applayer_counter_names[ipproto_map][alproto].gap_error, tv);
1302  }
1303  }
1304  }
1305  }
1306 }
1307 
1309 {
1310  memset(applayer_counter_names, 0, sizeof(applayer_counter_names));
1311  memset(applayer_counters, 0, sizeof(applayer_counters));
1312 }
1313 
1314 /***** Unittests *****/
1315 
1316 #ifdef UNITTESTS
1317 #include "pkt-var.h"
1318 #include "stream-tcp-util.h"
1319 #include "stream.h"
1320 #include "util-unittest.h"
1321 
1322 #define TEST_START \
1323  Packet *p = PacketGetFromAlloc(); \
1324  FAIL_IF_NULL(p); \
1325  Flow f; \
1326  ThreadVars tv; \
1327  StreamTcpThread *stt = NULL; \
1328  TCPHdr tcph; \
1329  PacketQueueNoLock pq; \
1330  memset(&pq, 0, sizeof(PacketQueueNoLock)); \
1331  memset(&f, 0, sizeof(Flow)); \
1332  memset(&tv, 0, sizeof(ThreadVars)); \
1333  memset(&tcph, 0, sizeof(TCPHdr)); \
1334  \
1335  FLOW_INITIALIZE(&f); \
1336  f.flags = FLOW_IPV4; \
1337  f.proto = IPPROTO_TCP; \
1338  p->flow = &f; \
1339  PacketSetTCP(p, (uint8_t *)&tcph); \
1340  \
1341  StreamTcpInitConfig(true); \
1342  IPPairInitConfig(true); \
1343  StreamTcpThreadInit(&tv, NULL, (void **)&stt); \
1344  \
1345  /* handshake */ \
1346  tcph.th_win = htons(5480); \
1347  tcph.th_flags = TH_SYN; \
1348  p->flowflags = FLOW_PKT_TOSERVER; \
1349  p->payload_len = 0; \
1350  p->payload = NULL; \
1351  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1); \
1352  TcpSession *ssn = (TcpSession *)f.protoctx; \
1353  \
1354  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); \
1355  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); \
1356  FAIL_IF(f.alproto != ALPROTO_UNKNOWN); \
1357  FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN); \
1358  FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN); \
1359  FAIL_IF(ssn->flags &STREAMTCP_FLAG_APP_LAYER_DISABLED); \
1360  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER)); \
1361  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER)); \
1362  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT)); \
1363  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); \
1364  FAIL_IF(ssn->data_first_seen_dir != 0); \
1365  \
1366  /* handshake */ \
1367  tcph.th_ack = htonl(1); \
1368  tcph.th_flags = TH_SYN | TH_ACK; \
1369  p->flowflags = FLOW_PKT_TOCLIENT; \
1370  p->payload_len = 0; \
1371  p->payload = NULL; \
1372  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1); \
1373  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); \
1374  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); \
1375  FAIL_IF(f.alproto != ALPROTO_UNKNOWN); \
1376  FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN); \
1377  FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN); \
1378  FAIL_IF(ssn->flags &STREAMTCP_FLAG_APP_LAYER_DISABLED); \
1379  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER)); \
1380  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER)); \
1381  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT)); \
1382  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); \
1383  FAIL_IF(ssn->data_first_seen_dir != 0); \
1384  \
1385  /* handshake */ \
1386  tcph.th_ack = htonl(1); \
1387  tcph.th_seq = htonl(1); \
1388  tcph.th_flags = TH_ACK; \
1389  p->flowflags = FLOW_PKT_TOSERVER; \
1390  p->payload_len = 0; \
1391  p->payload = NULL; \
1392  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1); \
1393  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); \
1394  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); \
1395  FAIL_IF(f.alproto != ALPROTO_UNKNOWN); \
1396  FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN); \
1397  FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN); \
1398  FAIL_IF(ssn->flags &STREAMTCP_FLAG_APP_LAYER_DISABLED); \
1399  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER)); \
1400  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER)); \
1401  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT)); \
1402  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); \
1403  FAIL_IF(ssn->data_first_seen_dir != 0);
1404 #define TEST_END \
1405  StreamTcpSessionClear(p->flow->protoctx); \
1406  StreamTcpThreadDeinit(&tv, (void *)stt); \
1407  StreamTcpFreeConfig(true); \
1408  PacketFree(p); \
1409  FLOW_DESTROY(&f); \
1410  StatsThreadCleanup(&tv);
1411 
1412 /**
1413  * \test GET -> HTTP/1.1
1414  */
1415 static int AppLayerTest01(void)
1416 {
1417  TEST_START;
1418 
1419  /* full request */
1420  uint8_t request[] = {
1421  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1422  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1423  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1424  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1425  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1426  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1427  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1428  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1429  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1430  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1431  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1432  tcph.th_ack = htonl(1);
1433  tcph.th_seq = htonl(1);
1434  tcph.th_flags = TH_PUSH | TH_ACK;
1436  p->payload_len = sizeof(request);
1437  p->payload = request;
1438  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1445  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1446  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1447  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1448  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1449  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1450 
1451  /* full response - request ack */
1452  uint8_t response[] = {
1453  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
1454  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1455  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1456  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1457  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1458  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1459  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1460  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1461  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1462  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1463  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1464  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1465  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1466  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1467  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1468  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1469  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1470  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1471  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1472  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1473  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1474  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1475  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1476  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1477  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1478  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1479  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1480  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1481  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1482  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1483  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1484  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1485  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1486  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1487  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1488  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1489  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1490  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1491  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1492  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1493  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1494  tcph.th_ack = htonl(88);
1495  tcph.th_seq = htonl(1);
1496  tcph.th_flags = TH_PUSH | TH_ACK;
1498  p->payload_len = sizeof(response);
1499  p->payload = response;
1500  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1507  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1508  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1509  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1510  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1512 
1513  /* response ack */
1514  tcph.th_ack = htonl(328);
1515  tcph.th_seq = htonl(88);
1516  tcph.th_flags = TH_ACK;
1518  p->payload_len = 0;
1519  p->payload = NULL;
1520  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1527  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1528  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1529  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1530  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1532 
1533  TEST_END;
1534  PASS;
1535 }
1536 
1537 /**
1538  * \test GE -> T -> HTTP/1.1
1539  */
1540 static int AppLayerTest02(void)
1541 {
1542  TEST_START;
1543 
1544  /* partial request */
1545  uint8_t request1[] = { 0x47, 0x45, };
1546  tcph.th_ack = htonl(1);
1547  tcph.th_seq = htonl(1);
1548  tcph.th_flags = TH_PUSH | TH_ACK;
1550  p->payload_len = sizeof(request1);
1551  p->payload = request1;
1552  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1559  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1560  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1561  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1562  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1563  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1564 
1565  /* response ack against partial request */
1566  tcph.th_ack = htonl(3);
1567  tcph.th_seq = htonl(1);
1568  tcph.th_flags = TH_ACK;
1570  p->payload_len = 0;
1571  p->payload = NULL;
1572  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1579  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1580  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1581  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1582  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1583  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1584 
1585  /* complete partial request */
1586  uint8_t request2[] = {
1587  0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1588  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1589  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1590  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1591  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1592  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1593  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1594  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1595  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1596  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1597  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1598  tcph.th_ack = htonl(1);
1599  tcph.th_seq = htonl(3);
1600  tcph.th_flags = TH_PUSH | TH_ACK;
1602  p->payload_len = sizeof(request2);
1603  p->payload = request2;
1604  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1611  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1612  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1613  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1614  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1615  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1616 
1617  /* response - request ack */
1618  uint8_t response[] = {
1619  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
1620  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1621  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1622  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1623  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1624  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1625  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1626  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1627  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1628  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1629  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1630  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1631  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1632  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1633  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1634  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1635  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1636  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1637  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1638  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1639  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1640  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1641  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1642  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1643  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1644  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1645  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1646  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1647  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1648  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1649  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1650  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1651  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1652  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1653  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1654  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1655  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1656  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1657  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1658  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1659  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1660  tcph.th_ack = htonl(88);
1661  tcph.th_seq = htonl(1);
1662  tcph.th_flags = TH_PUSH | TH_ACK;
1664  p->payload_len = sizeof(response);
1665  p->payload = response;
1666  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1673  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1674  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1675  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1676  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1678 
1679  /* response ack */
1680  tcph.th_ack = htonl(328);
1681  tcph.th_seq = htonl(88);
1682  tcph.th_flags = TH_ACK;
1684  p->payload_len = 0;
1685  p->payload = NULL;
1686  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1693  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1694  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1695  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1696  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1698 
1699  TEST_END;
1700  PASS;
1701 }
1702 
1703 /**
1704  * \test GET -> RUBBISH(PM AND PP DONE IN ONE GO)
1705  */
1706 static int AppLayerTest03(void)
1707 {
1708  TEST_START;
1709 
1710  /* request */
1711  uint8_t request[] = {
1712  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1713  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1714  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1715  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1716  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1717  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1718  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1719  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1720  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1721  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1722  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1723  tcph.th_ack = htonl(1);
1724  tcph.th_seq = htonl(1);
1725  tcph.th_flags = TH_PUSH | TH_ACK;
1727  p->payload_len = sizeof(request);
1728  p->payload = request;
1729  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1736  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1737  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1738  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1739  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1740  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1741 
1742  /* rubbish response */
1743  uint8_t response[] = {
1744  0x58, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
1745  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1746  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1747  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1748  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1749  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1750  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1751  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1752  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1753  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1754  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1755  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1756  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1757  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1758  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1759  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1760  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1761  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1762  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1763  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1764  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1765  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1766  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1767  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1768  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1769  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1770  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1771  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1772  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1773  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1774  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1775  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1776  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1777  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1778  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1779  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1780  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1781  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1782  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1783  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1784  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1785  tcph.th_ack = htonl(88);
1786  tcph.th_seq = htonl(1);
1787  tcph.th_flags = TH_PUSH | TH_ACK;
1789  p->payload_len = sizeof(response);
1790  p->payload = response;
1791  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1798  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1799  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1800  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1801  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1803 
1804  /* response ack */
1805  tcph.th_ack = htonl(328);
1806  tcph.th_seq = htonl(88);
1807  tcph.th_flags = TH_ACK;
1809  p->payload_len = 0;
1810  p->payload = NULL;
1811  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1818  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1819  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1820  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1821  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1823 
1824  TEST_END;
1825  PASS;
1826 }
1827 
1828 /**
1829  * \test GE -> RUBBISH(TC - PM AND PP NOT DONE) -> RUBBISH(TC - PM AND PP DONE).
1830  */
1831 static int AppLayerTest04(void)
1832 {
1833  TEST_START;
1834 
1835  /* request */
1836  uint8_t request[] = {
1837  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1838  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1839  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1840  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1841  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1842  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1843  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1844  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1845  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1846  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1847  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1848  PrintRawDataFp(stdout, request, sizeof(request));
1849  tcph.th_ack = htonl(1);
1850  tcph.th_seq = htonl(1);
1851  tcph.th_flags = TH_PUSH | TH_ACK;
1853  p->payload_len = sizeof(request);
1854  p->payload = request;
1855  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1862  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1863  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1864  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1865  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1866  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER); // TOSERVER data now seen
1867 
1868  /* partial response */
1869  uint8_t response1[] = { 0x58, 0x54, 0x54, 0x50, };
1870  PrintRawDataFp(stdout, response1, sizeof(response1));
1871  tcph.th_ack = htonl(88);
1872  tcph.th_seq = htonl(1);
1873  tcph.th_flags = TH_PUSH | TH_ACK;
1875  p->payload_len = sizeof(response1);
1876  p->payload = response1;
1877  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1880  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
1881  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
1884  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1885  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1886  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1887  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1888  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
1889 
1890  /* partial response ack */
1891  tcph.th_ack = htonl(5);
1892  tcph.th_seq = htonl(88);
1893  tcph.th_flags = TH_ACK;
1895  p->payload_len = 0;
1896  p->payload = NULL;
1897  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1900  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
1901  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
1904  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1905  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1906  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1907  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
1908  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
1909 
1910  /* remaining response */
1911  uint8_t response2[] = {
1912  0x2f, 0x31, 0x2e, 0x31,
1913  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1914  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1915  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1916  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1917  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1918  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1919  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1920  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1921  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1922  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1923  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1924  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1925  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1926  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1927  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1928  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1929  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1930  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1931  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1932  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1933  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1934  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1935  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1936  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1937  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1938  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1939  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1940  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1941  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1942  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1943  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1944  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1945  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1946  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1947  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1948  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1949  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1950  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1951  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1952  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1953  PrintRawDataFp(stdout, response2, sizeof(response2));
1954  tcph.th_ack = htonl(88);
1955  tcph.th_seq = htonl(5);
1956  tcph.th_flags = TH_PUSH | TH_ACK;
1958  p->payload_len = sizeof(response2);
1959  p->payload = response2;
1960  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1963  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
1964  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
1967  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1968  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1969  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1970  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
1971  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
1972 
1973  /* response ack */
1974  tcph.th_ack = htonl(328);
1975  tcph.th_seq = htonl(88);
1976  tcph.th_flags = TH_ACK;
1978  p->payload_len = 0;
1979  p->payload = NULL;
1980  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1981  FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); // toclient complete (failed)
1983  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
1984  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
1985  FAIL_IF(f.alproto_tc != ALPROTO_FAILED); // tc failed
1987  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1988  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1989  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1990  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
1991  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
1992 
1993  TEST_END;
1994  PASS;
1995 }
1996 
1997 /**
1998  * \test RUBBISH -> HTTP/1.1
1999  */
2000 static int AppLayerTest05(void)
2001 {
2002  TEST_START;
2003 
2004  /* full request */
2005  uint8_t request[] = {
2006  0x48, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2007  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
2008  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
2009  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
2010  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
2011  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
2012  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
2013  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
2014  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2015  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
2016  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2017  PrintRawDataFp(stdout, request, sizeof(request));
2018  tcph.th_ack = htonl(1);
2019  tcph.th_seq = htonl(1);
2020  tcph.th_flags = TH_PUSH | TH_ACK;
2022  p->payload_len = sizeof(request);
2023  p->payload = request;
2024  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2031  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2032  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2033  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2034  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2035  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2036 
2037  /* full response - request ack */
2038  uint8_t response[] = {
2039  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2040  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2041  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2042  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2043  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2044  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2045  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2046  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2047  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2048  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2049  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2050  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2051  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2052  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2053  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2054  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2055  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2056  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2057  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2058  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2059  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2060  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2061  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2062  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2063  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2064  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2065  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2066  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2067  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2068  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2069  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2070  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2071  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2072  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2073  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2074  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2075  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2076  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2077  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2078  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2079  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2080  PrintRawDataFp(stdout, response, sizeof(response));
2081  tcph.th_ack = htonl(88);
2082  tcph.th_seq = htonl(1);
2083  tcph.th_flags = TH_PUSH | TH_ACK;
2085  p->payload_len = sizeof(response);
2086  p->payload = response;
2087  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2094  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2095  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2096  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2097  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2098  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2099 
2100  /* response ack */
2101  tcph.th_ack = htonl(328);
2102  tcph.th_seq = htonl(88);
2103  tcph.th_flags = TH_ACK;
2105  p->payload_len = 0;
2106  p->payload = NULL;
2107  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2114  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2115  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2116  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2117  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2119 
2120  TEST_END;
2121  PASS;
2122 }
2123 
2124 /**
2125  * \test HTTP/1.1 -> GET
2126  */
2127 static int AppLayerTest06(void)
2128 {
2129  TEST_START;
2130 
2131  /* full response - request ack */
2132  uint8_t response[] = {
2133  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2134  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2135  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2136  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2137  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2138  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2139  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2140  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2141  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2142  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2143  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2144  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2145  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2146  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2147  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2148  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2149  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2150  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2151  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2152  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2153  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2154  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2155  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2156  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2157  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2158  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2159  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2160  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2161  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2162  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2163  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2164  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2165  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2166  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2167  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2168  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2169  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2170  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2171  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2172  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2173  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2174  tcph.th_ack = htonl(1);
2175  tcph.th_seq = htonl(1);
2176  tcph.th_flags = TH_PUSH | TH_ACK;
2178  p->payload_len = sizeof(response);
2179  p->payload = response;
2180  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2187  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2188  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2189  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2190  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2191  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOCLIENT);
2192 
2193  /* full request - response ack*/
2194  uint8_t request[] = {
2195  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2196  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
2197  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
2198  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
2199  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
2200  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
2201  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
2202  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
2203  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2204  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
2205  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2206  tcph.th_ack = htonl(328);
2207  tcph.th_seq = htonl(1);
2208  tcph.th_flags = TH_PUSH | TH_ACK;
2210  p->payload_len = sizeof(request);
2211  p->payload = request;
2212  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2219  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2220  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2221  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2222  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2224 
2225  tcph.th_ack = htonl(1 + sizeof(request));
2226  tcph.th_seq = htonl(328);
2227  tcph.th_flags = TH_PUSH | TH_ACK;
2229  p->payload_len = 0;
2230  p->payload = NULL;
2231  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2238  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2239  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2240  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2241  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2243 
2244  TEST_END;
2245  PASS;
2246 }
2247 
2248 /**
2249  * \test GET -> DCERPC
2250  */
2251 static int AppLayerTest07(void)
2252 {
2253  TEST_START;
2254 
2255  /* full request */
2256  uint8_t request[] = {
2257  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2258  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
2259  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
2260  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
2261  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
2262  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
2263  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
2264  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
2265  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2266  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
2267  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2268  tcph.th_ack = htonl(1);
2269  tcph.th_seq = htonl(1);
2270  tcph.th_flags = TH_PUSH | TH_ACK;
2272  p->payload_len = sizeof(request);
2273  p->payload = request;
2274  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2281  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2282  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2283  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2284  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2285  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2286 
2287  /* full response - request ack */
2288  uint8_t response[] = { 0x05, 0x00, 0x4d, 0x42, 0x00, 0x01, 0x2e, 0x31, 0x20, 0x32, 0x30, 0x30,
2289  0x20, 0x4f, 0x4b, 0x0d, 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, 0x72, 0x69, 0x2c,
2290  0x20, 0x32, 0x33, 0x20, 0x53, 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20, 0x30, 0x36,
2291  0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, 0x72,
2292  0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2293  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69, 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f,
2294  0x32, 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65,
2295  0x64, 0x3a, 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34, 0x20, 0x4e, 0x6f, 0x76, 0x20,
2296  0x32, 0x30, 0x31, 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a, 0x34, 0x36, 0x20, 0x47,
2297  0x4d, 0x54, 0x0d, 0x0a, 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61, 0x62, 0x38, 0x39,
2298  0x36, 0x35, 0x2d, 0x32, 0x63, 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61, 0x37, 0x66,
2299  0x37, 0x66, 0x38, 0x30, 0x22, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x52,
2300  0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2301  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20,
2302  0x34, 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a,
2303  0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
2304  0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d,
2305  0x6c, 0x0d, 0x0a, 0x58, 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64,
2306  0x20, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d, 0x0a, 0x0d,
2307  0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x68,
2308  0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2309  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2310  tcph.th_ack = htonl(88);
2311  tcph.th_seq = htonl(1);
2312  tcph.th_flags = TH_PUSH | TH_ACK;
2314  p->payload_len = sizeof(response);
2315  p->payload = response;
2316  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2323  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2324  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2325  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2326  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2328 
2329  /* response ack */
2330  tcph.th_ack = htonl(328);
2331  tcph.th_seq = htonl(88);
2332  tcph.th_flags = TH_ACK;
2334  p->payload_len = 0;
2335  p->payload = NULL;
2336  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2343  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2344  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2345  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2346  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2348 
2349  TEST_END;
2350  PASS;
2351 }
2352 
2353 /**
2354  * \test SMB -> HTTP/1.1
2355  */
2356 static int AppLayerTest08(void)
2357 {
2358  TEST_START;
2359 
2360  /* full request */
2361  uint8_t request[] = { 0x05, 0x00, 0x54, 0x20, 0x00, 0x01, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68,
2362  0x74, 0x6d, 0x6c, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x0d, 0x0a, 0x48,
2363  0x6f, 0x73, 0x74, 0x3a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x0d,
2364  0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41, 0x70,
2365  0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2366  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2367  tcph.th_ack = htonl(1);
2368  tcph.th_seq = htonl(1);
2369  tcph.th_flags = TH_PUSH | TH_ACK;
2371  p->payload_len = sizeof(request);
2372  p->payload = request;
2373  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2380  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2381  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2382  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2383  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2384  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2385 
2386  /* full response - request ack */
2387  uint8_t response[] = {
2388  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2389  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2390  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2391  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2392  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2393  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2394  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2395  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2396  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2397  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2398  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2399  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2400  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2401  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2402  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2403  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2404  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2405  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2406  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2407  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2408  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2409  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2410  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2411  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2412  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2413  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2414  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2415  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2416  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2417  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2418  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2419  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2420  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2421  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2422  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2423  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2424  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2425  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2426  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2427  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2428  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2429  tcph.th_ack = htonl(88);
2430  tcph.th_seq = htonl(1);
2431  tcph.th_flags = TH_PUSH | TH_ACK;
2433  p->payload_len = sizeof(response);
2434  p->payload = response;
2435  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2442  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2443  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2444  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2445  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2447 
2448  /* response ack */
2449  tcph.th_ack = htonl(328);
2450  tcph.th_seq = htonl(88);
2451  tcph.th_flags = TH_ACK;
2453  p->payload_len = 0;
2454  p->payload = NULL;
2455  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2462  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2463  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2464  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2465  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2467 
2468  TEST_END;
2469  PASS;
2470 }
2471 
2472 /**
2473  * \test RUBBISH(TC - PM and PP NOT DONE) ->
2474  * RUBBISH(TC - PM and PP DONE) ->
2475  * RUBBISH(TS - PM and PP DONE)
2476  */
2477 static int AppLayerTest09(void)
2478 {
2479  TEST_START;
2480 
2481  /* full request */
2482  uint8_t request1[] = {
2483  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64 };
2484  tcph.th_ack = htonl(1);
2485  tcph.th_seq = htonl(1);
2486  tcph.th_flags = TH_PUSH | TH_ACK;
2488  p->payload_len = sizeof(request1);
2489  p->payload = request1;
2490  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2497  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2498  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2499  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2500  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2501  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2502 
2503  /* response - request ack */
2504  tcph.th_ack = htonl(9);
2505  tcph.th_seq = htonl(1);
2506  tcph.th_flags = TH_PUSH | TH_ACK;
2508  p->payload_len = 0;
2509  p->payload = NULL;
2510  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2517  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2518  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2519  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2520  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2521  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2522 
2523  /* full request */
2524  uint8_t request2[] = {
2525  0x44, 0x44, 0x45, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff };
2526  tcph.th_ack = htonl(1);
2527  tcph.th_seq = htonl(9);
2528  tcph.th_flags = TH_PUSH | TH_ACK;
2530  p->payload_len = sizeof(request2);
2531  p->payload = request2;
2532  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2539  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2540  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2541  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2542  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2543  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2544 
2545  /* full response - request ack */
2546  uint8_t response[] = {
2547  0x55, 0x74, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2548  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2549  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2550  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2551  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2552  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2553  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2554  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2555  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2556  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2557  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2558  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2559  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2560  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2561  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2562  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2563  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2564  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2565  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2566  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2567  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2568  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2569  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2570  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2571  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2572  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2573  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2574  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2575  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2576  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2577  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2578  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2579  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2580  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2581  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2582  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2583  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2584  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2585  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2586  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2587  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2588  tcph.th_ack = htonl(18);
2589  tcph.th_seq = htonl(1);
2590  tcph.th_flags = TH_PUSH | TH_ACK;
2592  p->payload_len = sizeof(response);
2593  p->payload = response;
2594  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2601  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2602  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2603  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2604  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2605  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2606 
2607  /* response ack */
2608  tcph.th_ack = htonl(328);
2609  tcph.th_seq = htonl(18);
2610  tcph.th_flags = TH_ACK;
2612  p->payload_len = 0;
2613  p->payload = NULL;
2614  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2621  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2622  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2623  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2624  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2626 
2627  TEST_END;
2628  PASS;
2629 }
2630 
2631 /**
2632  * \test RUBBISH(TC - PM and PP DONE) ->
2633  * RUBBISH(TS - PM and PP DONE)
2634  */
2635 static int AppLayerTest10(void)
2636 {
2637  TEST_START;
2638 
2639  /* full request */
2640  uint8_t request1[] = {
2641  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2642  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff };
2643  tcph.th_ack = htonl(1);
2644  tcph.th_seq = htonl(1);
2645  tcph.th_flags = TH_PUSH | TH_ACK;
2647  p->payload_len = sizeof(request1);
2648  p->payload = request1;
2649  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2656  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2657  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2658  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2659  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2660  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2661 
2662  /* response - request ack */
2663  tcph.th_ack = htonl(18);
2664  tcph.th_seq = htonl(1);
2665  tcph.th_flags = TH_PUSH | TH_ACK;
2667  p->payload_len = 0;
2668  p->payload = NULL;
2669  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2676  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2677  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2678  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2679  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2680  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2681 
2682  /* full response - request ack */
2683  uint8_t response[] = {
2684  0x55, 0x74, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2685  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2686  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2687  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2688  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2689  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2690  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2691  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2692  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2693  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2694  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2695  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2696  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2697  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2698  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2699  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2700  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2701  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2702  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2703  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2704  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2705  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2706  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2707  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2708  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2709  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2710  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2711  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2712  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2713  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2714  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2715  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2716  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2717  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2718  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2719  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2720  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2721  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2722  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2723  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2724  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2725  tcph.th_ack = htonl(18);
2726  tcph.th_seq = htonl(1);
2727  tcph.th_flags = TH_PUSH | TH_ACK;
2729  p->payload_len = sizeof(response);
2730  p->payload = response;
2731  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2738  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2739  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2740  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2741  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2742  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2743 
2744  /* response ack */
2745  tcph.th_ack = htonl(328);
2746  tcph.th_seq = htonl(18);
2747  tcph.th_flags = TH_ACK;
2749  p->payload_len = 0;
2750  p->payload = NULL;
2751  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2758  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2759  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2760  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2761  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2763 
2764  TEST_END;
2765  PASS;
2766 }
2767 
2768 /**
2769  * \test RUBBISH(TC - PM and PP DONE) ->
2770  * RUBBISH(TS - PM and PP NOT DONE) ->
2771  * RUBBISH(TS - PM and PP DONE)
2772  */
2773 static int AppLayerTest11(void)
2774 {
2775  TEST_START;
2776 
2777  /* full request */
2778  uint8_t request1[] = {
2779  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2780  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff };
2781  tcph.th_ack = htonl(1);
2782  tcph.th_seq = htonl(1);
2783  tcph.th_flags = TH_PUSH | TH_ACK;
2785  p->payload_len = sizeof(request1);
2786  p->payload = request1;
2787  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2794  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2795  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2796  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2797  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2798  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2799 
2800  /* response - request ack */
2801  tcph.th_ack = htonl(18);
2802  tcph.th_seq = htonl(1);
2803  tcph.th_flags = TH_PUSH | TH_ACK;
2805  p->payload_len = 0;
2806  p->payload = NULL;
2807  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2814  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2815  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2816  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2817  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2818  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2819 
2820  /* full response - request ack */
2821  uint8_t response1[] = {
2822  0x55, 0x74, 0x54, 0x50, };
2823  tcph.th_ack = htonl(18);
2824  tcph.th_seq = htonl(1);
2825  tcph.th_flags = TH_PUSH | TH_ACK;
2827  p->payload_len = sizeof(response1);
2828  p->payload = response1;
2829  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2836  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2837  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2838  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2839  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2840  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2841 
2842  /* response ack from request */
2843  tcph.th_ack = htonl(5);
2844  tcph.th_seq = htonl(18);
2845  tcph.th_flags = TH_ACK;
2847  p->payload_len = 0;
2848  p->payload = NULL;
2849  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2856  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2857  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2858  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2859  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2860  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2861 
2862  uint8_t response2[] = {
2863  0x2f, 0x31, 0x2e, 0x31,
2864  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2865  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2866  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2867  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2868  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2869  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2870  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2871  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2872  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2873  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2874  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2875  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2876  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2877  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2878  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2879  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2880  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2881  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2882  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2883  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2884  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2885  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2886  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2887  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2888  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2889  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2890  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2891  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2892  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2893  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2894  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2895  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2896  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2897  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2898  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2899  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2900  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2901  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2902  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2903  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2904  tcph.th_ack = htonl(18);
2905  tcph.th_seq = htonl(5);
2906  tcph.th_flags = TH_PUSH | TH_ACK;
2908  p->payload_len = sizeof(response2);
2909  p->payload = response2;
2910  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2917  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2918  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2919  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2920  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2921  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2922 
2923  /* response ack from request */
2924  tcph.th_ack = htonl(328);
2925  tcph.th_seq = htonl(18);
2926  tcph.th_flags = TH_ACK;
2928  p->payload_len = 0;
2929  p->payload = NULL;
2930  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2937  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2938  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2939  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2940  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2942 
2943  TEST_END;
2944  PASS;
2945 }
2946 
2948 {
2949  SCEnter();
2950 
2951  UtRegisterTest("AppLayerTest01", AppLayerTest01);
2952  UtRegisterTest("AppLayerTest02", AppLayerTest02);
2953  UtRegisterTest("AppLayerTest03", AppLayerTest03);
2954  UtRegisterTest("AppLayerTest04", AppLayerTest04);
2955  UtRegisterTest("AppLayerTest05", AppLayerTest05);
2956  UtRegisterTest("AppLayerTest06", AppLayerTest06);
2957  UtRegisterTest("AppLayerTest07", AppLayerTest07);
2958  UtRegisterTest("AppLayerTest08", AppLayerTest08);
2959  UtRegisterTest("AppLayerTest09", AppLayerTest09);
2960  UtRegisterTest("AppLayerTest10", AppLayerTest10);
2961  UtRegisterTest("AppLayerTest11", AppLayerTest11);
2962 
2963  SCReturn;
2964 }
2965 
2966 #endif /* UNITTESTS */
AppLayerCounters_::alloc_error_id
uint16_t alloc_error_id
Definition: app-layer.c:93
APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER
#define APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER
Definition: app-layer.h:40
AppLayerCounters_::counter_id
uint16_t counter_id
Definition: app-layer.c:88
FLOW_RESET_PP_DONE
#define FLOW_RESET_PP_DONE(f, dir)
Definition: flow.h:287
UPDATE_DIR_PACKET
@ UPDATE_DIR_PACKET
Definition: stream-tcp-reassemble.h:56
FlowUnsetChangeProtoFlag
void FlowUnsetChangeProtoFlag(Flow *f)
Unset flag to indicate to change proto for the flow.
Definition: flow.c:196
Packet_::proto
uint8_t proto
Definition: decode.h:504
AppLayerParserDeSetup
int AppLayerParserDeSetup(void)
Definition: app-layer-parser.c:275
TcpStream_
Definition: stream-tcp-private.h:106
APPLAYER_MISMATCH_PROTOCOL_BOTH_DIRECTIONS
@ APPLAYER_MISMATCH_PROTOCOL_BOTH_DIRECTIONS
Definition: app-layer-events.h:48
ExceptionPolicyApply
void ExceptionPolicyApply(Packet *p, enum ExceptionPolicy policy, enum PacketDropReason drop_reason)
Definition: util-exception-policy.c:69
AppLayerCounters_::gap_error_id
uint16_t gap_error_id
Definition: app-layer.c:90
AppLayerCounters_
Definition: app-layer.c:87
ippair.h
FlowCleanupAppLayer
void FlowCleanupAppLayer(Flow *f)
Definition: flow.c:136
AppLayerProtoDetectSetup
int AppLayerProtoDetectSetup(void)
The first function to be called. This initializes a global protocol detection context.
Definition: app-layer-detect-proto.c:1699
ExpectationGetCounter
uint64_t ExpectationGetCounter(void)
Definition: app-layer-expectation.c:140
AppLayerCounterNames_::eps_name
char eps_name[EXCEPTION_POLICY_MAX][MAX_COUNTER_SIZE]
Definition: app-layer.c:84
StatsIncr
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:167
AppLayerCounters_::counter_tx_id
uint16_t counter_tx_id
Definition: app-layer.c:89
AppLayerCounters
struct AppLayerCounters_ AppLayerCounters
stream-tcp-inline.h
ALPROTO_DCERPC
@ ALPROTO_DCERPC
Definition: app-layer-protos.h:38
flow-util.h
applayer_counters
AppLayerCounters applayer_counters[FLOW_PROTO_APPLAYER_MAX][ALPROTO_MAX]
Definition: app-layer.c:100
stream-tcp.h
StreamTcpInlineMode
bool StreamTcpInlineMode(void)
See if stream engine is operating in inline mode.
Definition: stream-tcp.c:7061
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
ALPROTO_TLS
@ ALPROTO_TLS
Definition: app-layer-protos.h:33
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
Packet_::pcap_cnt
uint64_t pcap_cnt
Definition: decode.h:609
AppLayerCounterNames_::parser_error
char parser_error[MAX_COUNTER_SIZE]
Definition: app-layer.c:81
StatsRegisterGlobalCounter
uint16_t StatsRegisterGlobalCounter(const char *name, uint64_t(*Func)(void))
Registers a counter, which represents a global value.
Definition: counters.c:1029
AppLayerProfilingStoreInternal
void AppLayerProfilingStoreInternal(AppLayerThreadCtx *app_tctx, Packet *p)
Definition: app-layer.c:1102
Flow_::proto
uint8_t proto
Definition: flow.h:378
AppProto
uint16_t AppProto
Definition: app-layer-protos.h:82
Packet_::payload
uint8_t * payload
Definition: decode.h:588
TcpReassemblyThreadCtx_::app_tctx
void * app_tctx
Definition: stream-tcp-reassemble.h:62
Packet_::flags
uint32_t flags
Definition: decode.h:519
AppLayerThreadCtx_::proto_detect_ticks_spent
uint64_t proto_detect_ticks_spent
Definition: app-layer.c:70
APPLAYER_WRONG_DIRECTION_FIRST_DATA
@ APPLAYER_WRONG_DIRECTION_FIRST_DATA
Definition: app-layer-events.h:49
PACKET_PROFILING_APP_PD_END
#define PACKET_PROFILING_APP_PD_END(dp)
Definition: util-profiling.h:187
TcpStreamCnf_::reassembly_depth
uint32_t reassembly_depth
Definition: stream-tcp.h:65
AppLayerThreadCtx_::alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: app-layer.c:61
flow-private.h
Flow_
Flow data structure.
Definition: flow.h:356
AppLayerIncGapErrorCounter
void AppLayerIncGapErrorCounter(ThreadVars *tv, Flow *f)
Definition: app-layer.c:161
AppLayerCounters_::internal_error_id
uint16_t internal_error_id
Definition: app-layer.c:92
Flow_::protomap
uint8_t protomap
Definition: flow.h:450
AppProtoToString
const char * AppProtoToString(AppProto alproto)
Maps the ALPROTO_*, to its string equivalent.
Definition: app-layer-protos.c:76
AppLayerThreadCtx_::ticks_spent
uint64_t ticks_spent
Definition: app-layer.c:66
ExceptionPolicyStatsSetts_
Definition: util-exception-policy-types.h:48
AppLayerParserGetFirstDataDir
uint8_t AppLayerParserGetFirstDataDir(uint8_t ipproto, AppProto alproto)
Definition: app-layer-parser.c:1144
g_stats_eps_per_app_proto_errors
bool g_stats_eps_per_app_proto_errors
Definition: suricata.c:216
StreamTcpResetStreamFlagAppProtoDetectionCompleted
#define StreamTcpResetStreamFlagAppProtoDetectionCompleted(stream)
Definition: stream-tcp-private.h:303
AppLayerRegisterThreadCounters
void AppLayerRegisterThreadCounters(ThreadVars *tv)
Registers per flow counters for all protocols.
Definition: app-layer.c:1244
Flow_::alproto_orig
AppProto alproto_orig
Definition: flow.h:461
AppLayerProtoDetectSupportedIpprotos
void AppLayerProtoDetectSupportedIpprotos(AppProto alproto, uint8_t *ipprotos)
Definition: app-layer-detect-proto.c:2020
FTPMemuseGlobalCounter
uint64_t FTPMemuseGlobalCounter(void)
Definition: app-layer-ftp.c:167
AppLayerProfilingResetInternal
void AppLayerProfilingResetInternal(AppLayerThreadCtx *app_tctx)
Definition: app-layer.c:1097
AppLayerCounterNames_
Definition: app-layer.c:77
AppLayerParserStateProtoCleanup
void AppLayerParserStateProtoCleanup(uint8_t protomap, AppProto alproto, void *alstate, AppLayerParserState *pstate)
Definition: app-layer-parser.c:1617
AppLayerParserThreadCtxFree
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
Definition: app-layer-parser.c:306
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:228
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:6632
app_layer_error_eps_stats
ExceptionPolicyStatsSetts app_layer_error_eps_stats
Definition: app-layer.c:106
stream-tcp-reassemble.h
AppLayerThreadCtx_::proto_detect_ticks_end
uint64_t proto_detect_ticks_end
Definition: app-layer.c:69
TcpStream_::flags
uint16_t flags
Definition: stream-tcp-private.h:107
AppLayerUnittestsRegister
void AppLayerUnittestsRegister(void)
Definition: app-layer.c:2947
HTPMemuseGlobalCounter
uint64_t HTPMemuseGlobalCounter(void)
Definition: app-layer-htp-mem.c:83
AppLayerListSupportedProtocols
void AppLayerListSupportedProtocols(void)
Definition: app-layer.c:1012
AppLayerSetupCounters
void AppLayerSetupCounters(void)
Definition: app-layer.c:1144
app-layer-ftp.h
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:513
AppLayerThreadCtx_::alproto
AppProto alproto
Definition: app-layer.c:67
stream_config
TcpStreamCnf stream_config
Definition: stream-tcp.c:219
MAX
#define MAX(x, y)
Definition: suricata-common.h:395
ALPROTO_MAX
@ ALPROTO_MAX
Definition: app-layer-protos.h:77
Flow_::protoctx
void * protoctx
Definition: flow.h:446
AppLayerCounterNames_::tx_name
char tx_name[MAX_COUNTER_SIZE]
Definition: app-layer.c:79
AppLayerIncAllocErrorCounter
void AppLayerIncAllocErrorCounter(ThreadVars *tv, Flow *f)
Definition: app-layer.c:169
EXCEPTION_POLICY_NOT_SET
@ EXCEPTION_POLICY_NOT_SET
Definition: util-exception-policy-types.h:26
Packet_::payload_len
uint16_t payload_len
Definition: decode.h:589
Packet_::app_layer_events
AppLayerDecoderEvents * app_layer_events
Definition: decode.h:615
util-unittest.h
AppLayerGetProtoByName
AppProto AppLayerGetProtoByName(char *alproto_name)
Given a protocol string, returns the corresponding internal protocol id.
Definition: app-layer.c:998
PACKET_PROFILING_APP_PD_START
#define PACKET_PROFILING_APP_PD_START(dp)
Definition: util-profiling.h:182
AppLayerCounters_::parser_error_id
uint16_t parser_error_id
Definition: app-layer.c:91
AppLayerDeSetup
int AppLayerDeSetup(void)
De initializes the app layer.
Definition: app-layer.c:1047
PKT_PROTO_DETECT_TS_DONE
#define PKT_PROTO_DETECT_TS_DONE
Definition: decode.h:1310
MAX_COUNTER_SIZE
#define MAX_COUNTER_SIZE
Definition: app-layer.c:76
STREAMTCP_FLAG_MIDSTREAM
#define STREAMTCP_FLAG_MIDSTREAM
Definition: stream-tcp-private.h:170
TcpSession_::flags
uint32_t flags
Definition: stream-tcp-private.h:292
FLOW_IS_PM_DONE
#define FLOW_IS_PM_DONE(f, dir)
Definition: flow.h:278
Flow_::alparser
AppLayerParserState * alparser
Definition: flow.h:480
EXCEPTION_POLICY_MAX
#define EXCEPTION_POLICY_MAX
Definition: util-exception-policy-types.h:36
AppLayerParserRegisterProtocolParsers
void AppLayerParserRegisterProtocolParsers(void)
Definition: app-layer-parser.c:1719
AppLayerThreadCtx_::proto_detect_ticks_start
uint64_t proto_detect_ticks_start
Definition: app-layer.c:68
AppLayerSetup
int AppLayerSetup(void)
Setup the app layer.
Definition: app-layer.c:1032
app-layer-expectation.h
app-layer-detect-proto.h
StreamTcpReassembleAppLayer
int StreamTcpReassembleAppLayer(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpSession *ssn, TcpStream *stream, Packet *p, enum StreamUpdateDir dir)
Update the stream reassembly upon receiving a packet.
Definition: stream-tcp-reassemble.c:1351
APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION
@ APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION
Definition: app-layer-events.h:50
AppLayerProtoDetectThreadCtx_
The app layer protocol detection thread context.
Definition: app-layer-detect-proto.c:174
util-debug.h
AppLayerParserState_
Definition: app-layer-parser.c:132
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
ExceptionPolicyCounters_
Definition: util-exception-policy-types.h:43
FLOW_IS_PP_DONE
#define FLOW_IS_PP_DONE(f, dir)
Definition: flow.h:279
AppLayerRegisterGlobalCounters
void AppLayerRegisterGlobalCounters(void)
HACK to work around our broken unix manager (re)init loop.
Definition: app-layer.c:1110
PKT_DROP_REASON_APPLAYER_ERROR
@ PKT_DROP_REASON_APPLAYER_ERROR
Definition: decode.h:373
AppLayerThreadCtx_::ticks_end
uint64_t ticks_end
Definition: app-layer.c:65
PacketSwap
void PacketSwap(Packet *p)
switch direction of a packet
Definition: decode.c:551
util-exception-policy.h
AppLayerThreadCtx_
This is for the app layer in general and it contains per thread context relevant to both the alpd and...
Definition: app-layer.c:57
ExceptionPolicyCounters_::eps_id
uint16_t eps_id[EXCEPTION_POLICY_MAX]
Definition: util-exception-policy-types.h:45
util-print.h
APPLAYER_PROTO_DETECTION_SKIPPED
@ APPLAYER_PROTO_DETECTION_SKIPPED
Definition: app-layer-events.h:51
AppLayerGetCtxThread
AppLayerThreadCtx * AppLayerGetCtxThread(ThreadVars *tv)
Creates a new app layer thread context.
Definition: app-layer.c:1059
SCEnter
#define SCEnter(...)
Definition: util-debug.h:271
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
pkt-var.h
StreamTcpPacket
int StreamTcpPacket(ThreadVars *tv, Packet *p, StreamTcpThread *stt, PacketQueueNoLock *pq)
Definition: stream-tcp.c:5496
IPPROTOS_MAX
#define IPPROTOS_MAX
Definition: app-layer.c:1143
AppLayerProtoDetectReset
void AppLayerProtoDetectReset(Flow *f)
Reset proto detect for flow.
Definition: app-layer-detect-proto.c:1847
TcpSession_::state
uint8_t state
Definition: stream-tcp-private.h:285
TEST_START
#define TEST_START
Definition: app-layer.c:1322
ExceptionPolicyStatsSetts_::valid_settings_ids
bool valid_settings_ids[EXCEPTION_POLICY_MAX]
Definition: util-exception-policy-types.h:50
APPLAYER_NO_TLS_AFTER_STARTTLS
@ APPLAYER_NO_TLS_AFTER_STARTTLS
Definition: app-layer-events.h:52
TH_ACK
#define TH_ACK
Definition: decode-tcp.h:38
PACKET_PROFILING_APP_STORE
#define PACKET_PROFILING_APP_STORE(dp, p)
Definition: util-profiling.h:207
PrintRawDataFp
void PrintRawDataFp(FILE *fp, const uint8_t *buf, uint32_t buflen)
Definition: util-print.c:114
app-layer-parser.h
FLOW_PROTO_DETECT_TC_DONE
#define FLOW_PROTO_DETECT_TC_DONE
Definition: flow.h:103
AppLayerCounterNames
struct AppLayerCounterNames_ AppLayerCounterNames
util-profiling.h
AppLayerParserSetup
int AppLayerParserSetup(void)
Definition: app-layer-parser.c:254
SCReturn
#define SCReturn
Definition: util-debug.h:273
FLOW_RESET_PM_DONE
#define FLOW_RESET_PM_DONE(f, dir)
Definition: flow.h:286
stream.h
FlowGetProtoMapping
uint8_t FlowGetProtoMapping(uint8_t proto)
Function to map the protocol to the defined FLOW_PROTO_* enumeration.
Definition: flow-util.c:97
StreamTcpIsSetStreamFlagAppProtoDetectionCompleted
#define StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(stream)
Definition: stream-tcp-private.h:301
Packet_
Definition: decode.h:482
stream-tcp-private.h
FLOW_PROTO_APPLAYER_MAX
#define FLOW_PROTO_APPLAYER_MAX
Definition: flow-private.h:77
AppLayerHandleUdp
int AppLayerHandleUdp(ThreadVars *tv, AppLayerThreadCtx *tctx, Packet *p, Flow *f)
Handle a app layer UDP message.
Definition: app-layer.c:874
DEBUG_ASSERT_FLOW_LOCKED
#define DEBUG_ASSERT_FLOW_LOCKED(f)
Definition: util-validate.h:99
StreamTcpSetStreamFlagAppProtoDetectionCompleted
#define StreamTcpSetStreamFlagAppProtoDetectionCompleted(stream)
Definition: stream-tcp-private.h:299
TcpStream_::window
uint32_t window
Definition: stream-tcp-private.h:117
SCReturnPtr
#define SCReturnPtr(x, type)
Definition: util-debug.h:287
AppLayerThreadCtx_::alpd_tctx
AppLayerProtoDetectThreadCtx * alpd_tctx
Definition: app-layer.c:59
StreamDataAvailableForProtoDetect
uint32_t StreamDataAvailableForProtoDetect(TcpStream *stream)
Definition: stream-tcp-reassemble.c:712
AppLayerThreadCtx_::ticks_start
uint64_t ticks_start
Definition: app-layer.c:64
AppLayerIncParserErrorCounter
void AppLayerIncParserErrorCounter(ThreadVars *tv, Flow *f)
Definition: app-layer.c:177
FTPMemcapGlobalCounter
uint64_t FTPMemcapGlobalCounter(void)
Definition: app-layer-ftp.c:173
FLOW_PKT_TOCLIENT
#define FLOW_PKT_TOCLIENT
Definition: flow.h:229
Flow_::alproto_expect
AppProto alproto_expect
Definition: flow.h:464
decode-events.h
UPDATE_DIR_OPPOSING
@ UPDATE_DIR_OPPOSING
Definition: stream-tcp-reassemble.h:57
AppLayerParserThreadCtxAlloc
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
Definition: app-layer-parser.c: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:1286
StreamTcpDisableAppLayer
void StreamTcpDisableAppLayer(Flow *f)
Definition: stream-tcp-reassemble.c:446
suricata-common.h
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 dir)
handle TCP data for the app-layer.
Definition: app-layer.c:708
FLOW_RESET_PE_DONE
#define FLOW_RESET_PE_DONE(f, dir)
Definition: flow.h:288
AppLayerProtoDetectDeSetup
int AppLayerProtoDetectDeSetup(void)
Cleans up the app layer protocol detection phase.
Definition: app-layer-detect-proto.c:1729
ALPROTO_HTTP1
@ ALPROTO_HTTP1
Definition: app-layer-protos.h:30
AppLayerDecoderEventsSetEventRaw
void AppLayerDecoderEventsSetEventRaw(AppLayerDecoderEvents **sevents, uint8_t event)
Set an app layer decoder event.
Definition: app-layer-events.c:91
Packet_::app_update_direction
uint8_t app_update_direction
Definition: decode.h:516
FLOW_PROTO_DETECT_TS_DONE
#define FLOW_PROTO_DETECT_TS_DONE
Definition: flow.h:102
AppLayerIncInternalErrorCounter
void AppLayerIncInternalErrorCounter(ThreadVars *tv, Flow *f)
Definition: app-layer.c:185
eps_error_summary
ExceptionPolicyCounters eps_error_summary
Definition: app-layer.c:102
STREAMTCP_FLAG_MIDSTREAM_SYNACK
#define STREAMTCP_FLAG_MIDSTREAM_SYNACK
Definition: stream-tcp-private.h:174
TcpSession_::client
TcpStream client
Definition: stream-tcp-private.h:295
PKT_PROTO_DETECT_TC_DONE
#define PKT_PROTO_DETECT_TC_DONE
Definition: decode.h:1311
AppLayerParserGetStreamDepth
uint32_t AppLayerParserGetStreamDepth(const Flow *f)
Definition: app-layer-parser.c:1578
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
util-validate.h
FlowSwap
void FlowSwap(Flow *f)
swap the flow's direction
Definition: flow.c:257
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:2079
AppLayerProtoDetectGetProto
AppProto AppLayerProtoDetectGetProto(AppLayerProtoDetectThreadCtx *tctx, Flow *f, const uint8_t *buf, uint32_t buflen, uint8_t ipproto, uint8_t flags, bool *reverse_flow)
Returns the app layer protocol given a buffer.
Definition: app-layer-detect-proto.c:1396
AppLayerProtoDetectGetCtxThread
AppLayerProtoDetectThreadCtx * AppLayerProtoDetectGetCtxThread(void)
Inits and returns an app layer protocol detection thread context.
Definition: app-layer-detect-proto.c:1941
TcpSession_::server
TcpStream server
Definition: stream-tcp-private.h:294
AppLayerProtoDetectGetProtoByName
AppProto AppLayerProtoDetectGetProtoByName(const char *alproto_name)
Definition: app-layer-detect-proto.c:2037
str
#define str(s)
Definition: suricata-common.h:291
SWAP_FLAGS
#define SWAP_FLAGS(flags, a, b)
Definition: suricata-common.h:417
ExceptionPolicyEnumToString
const char * ExceptionPolicyEnumToString(enum ExceptionPolicy policy, bool is_json)
Definition: util-exception-policy.c:35
SCFree
#define SCFree(p)
Definition: util-mem.h:61
AppLayerCounterNames_::gap_error
char gap_error[MAX_COUNTER_SIZE]
Definition: app-layer.c:80
Flow_::alproto_ts
AppProto alproto_ts
Definition: flow.h:456
ExceptionPolicyStatsSetts_::valid_settings_ips
bool valid_settings_ips[EXCEPTION_POLICY_MAX]
Definition: util-exception-policy-types.h:51
TcpSessionSetReassemblyDepth
void TcpSessionSetReassemblyDepth(TcpSession *ssn, uint32_t size)
Definition: stream-tcp.c:7067
Flow_::alstate
void * alstate
Definition: flow.h:481
AppLayerDestroyCtxThread
void AppLayerDestroyCtxThread(AppLayerThreadCtx *app_tctx)
Destroys the context created by AppLayerGetCtxThread().
Definition: app-layer.c:1080
PACKET_PROFILING_APP_START
#define PACKET_PROFILING_APP_START(dp, id)
Definition: util-profiling.h:167
Flow_::flags
uint32_t flags
Definition: flow.h:426
HTPMemcapGlobalCounter
uint64_t HTPMemcapGlobalCounter(void)
Definition: app-layer-htp-mem.c:89
AppLayerGetProtoName
const char * AppLayerGetProtoName(AppProto alproto)
Given the internal protocol id, returns a string representation of the protocol.
Definition: app-layer.c:1005
g_applayerparser_error_policy
enum ExceptionPolicy g_applayerparser_error_policy
Definition: app-layer-parser.c:152
AppLayerCounters_::eps_error
ExceptionPolicyCounters eps_error
Definition: app-layer.c:94
AppLayerIncTxCounter
void AppLayerIncTxCounter(ThreadVars *tv, Flow *f, uint64_t step)
Definition: app-layer.c:153
stream-tcp-util.h
ALPROTO_UNKNOWN
@ ALPROTO_UNKNOWN
Definition: app-layer-protos.h:29
ALPROTO_FAILED
@ ALPROTO_FAILED
Definition: app-layer-protos.h:72
AppLayerCounterNames_::internal_error
char internal_error[MAX_COUNTER_SIZE]
Definition: app-layer.c:82
TcpReassemblyThreadCtx_
Definition: stream-tcp-reassemble.h:61
SCReturnCT
#define SCReturnCT(x, type)
Definition: util-debug.h:285
app-layer-protos.h
app-layer-htp-mem.h
EngineModeIsIPS
int EngineModeIsIPS(void)
Definition: suricata.c:231
STREAMTCP_FLAG_APP_LAYER_DISABLED
#define STREAMTCP_FLAG_APP_LAYER_DISABLED
Definition: stream-tcp-private.h:201
STREAMTCP_STREAM_FLAG_NOREASSEMBLY
#define STREAMTCP_STREAM_FLAG_NOREASSEMBLY
Definition: stream-tcp-private.h:219
suricata.h
TEST_END
#define TEST_END
Definition: app-layer.c:1404
StreamUpdateDir
StreamUpdateDir
Definition: stream-tcp-reassemble.h:54
PACKET_PROFILING_APP_END
#define PACKET_PROFILING_APP_END(dp, id)
Definition: util-profiling.h:173
AppLayerProtoDetectDestroyCtxThread
void AppLayerProtoDetectDestroyCtxThread(AppLayerProtoDetectThreadCtx *alpd_tctx)
Destroys the app layer protocol detection thread context.
Definition: app-layer-detect-proto.c:1994
likely
#define likely(expr)
Definition: util-optimize.h:32
applayer_counter_names
AppLayerCounterNames applayer_counter_names[FLOW_PROTO_APPLAYER_MAX][ALPROTO_MAX]
Definition: app-layer.c:98
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:59
AppLayerCounterNames_::name
char name[MAX_COUNTER_SIZE]
Definition: app-layer.c:78
FlowChangeProto
int FlowChangeProto(Flow *f)
Check if change proto flag is set for flow.
Definition: flow.c:206
TcpSession_
Definition: stream-tcp-private.h:283
TcpSession_::data_first_seen_dir
int8_t data_first_seen_dir
Definition: stream-tcp-private.h:288
flow.h
Flow_::alproto_tc
AppProto alproto_tc
Definition: flow.h:457
FLOW_PROTO_CHANGE_MAX_DEPTH
#define FLOW_PROTO_CHANGE_MAX_DEPTH
Definition: app-layer.c:74
AppLayerProtoDetectPrepareState
int AppLayerProtoDetectPrepareState(void)
Prepares the internal state for protocol detection. This needs to be called once all the patterns and...
Definition: app-layer-detect-proto.c:1499
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:455
ExceptionPolicy
ExceptionPolicy
Definition: util-exception-policy-types.h:25
StatsRegisterCounter
uint16_t StatsRegisterCounter(const char *name, struct ThreadVars_ *tv)
Registers a normal, unqualified counter.
Definition: counters.c:971
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
APPLAYER_UNEXPECTED_PROTOCOL
@ APPLAYER_UNEXPECTED_PROTOCOL
Definition: app-layer-events.h:53
AppLayerCounterNames_::alloc_error
char alloc_error[MAX_COUNTER_SIZE]
Definition: app-layer.c:83
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:275
PACKET_PROFILING_APP_RESET
#define PACKET_PROFILING_APP_RESET(dp)
Definition: util-profiling.h:196
AppLayerDeSetupCounters
void AppLayerDeSetupCounters(void)
Definition: app-layer.c:1308
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:102
ExceptionPolicyStatsSetts_::eps_name
char eps_name[EXCEPTION_POLICY_MAX][EXCEPTION_POLICY_COUNTER_MAX_LEN]
Definition: util-exception-policy-types.h:49
STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED
#define STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED
Definition: stream-tcp-private.h:232
AppLayerProtoDetectGetProtoName
const char * AppLayerProtoDetectGetProtoName(AppProto alproto)
Definition: app-layer-detect-proto.c:2062
app-layer.h