suricata
app-layer.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2024 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Victor Julien <victor@inliniac.net>
22  * \author Anoop Saldanha <anoopsaldanha@gmail.com>
23  *
24  * Generic App-layer functions
25  */
26 
27 #include "suricata-common.h"
28 #include "suricata.h"
29 #include "app-layer.h"
30 #include "app-layer-parser.h"
31 #include "app-layer-protos.h"
32 #include "app-layer-expectation.h"
33 #include "app-layer-ftp.h"
34 #include "app-layer-htp-range.h"
35 #include "app-layer-detect-proto.h"
36 #include "app-layer-frames.h"
37 #include "app-layer-events.h"
38 #include "stream-tcp-reassemble.h"
39 #include "stream-tcp-private.h"
40 #include "stream-tcp-inline.h"
41 #include "stream-tcp.h"
42 #include "flow.h"
43 #include "flow-util.h"
44 #include "flow-private.h"
45 #include "ippair.h"
46 #include "util-debug.h"
47 #include "util-print.h"
48 #include "util-profiling.h"
49 #include "util-validate.h"
50 #include "decode-events.h"
51 #include "app-layer-htp-mem.h"
52 #include "util-exception-policy.h"
53 
55 /**
56  * \brief This is for the app layer in general and it contains per thread
57  * context relevant to both the alpd and alp.
58  */
60  /* App layer protocol detection thread context, from AppLayerProtoDetectGetCtxThread(). */
62  /* App layer parser thread context, from AppLayerParserThreadCtxAlloc(). */
64 
65 #ifdef PROFILING
66  uint64_t ticks_start;
67  uint64_t ticks_end;
68  uint64_t ticks_spent;
73 #endif
74 };
75 
76 #define FLOW_PROTO_CHANGE_MAX_DEPTH 4096
77 
78 #define MAX_COUNTER_SIZE 64
79 typedef struct AppLayerCounterNames_ {
88 
89 typedef struct AppLayerCounters_ {
98 
99 /* counter names. Only used at init. */
101 /* counter id's. Used that runtime. */
103 /* Exception policy global counters ids */
105 
106 /* Settings order as in the enum */
107 // clang-format off
109  .valid_settings_ids = {
110  /* EXCEPTION_POLICY_NOT_SET */ false,
111  /* EXCEPTION_POLICY_AUTO */ false,
112  /* EXCEPTION_POLICY_PASS_PACKET */ true,
113  /* EXCEPTION_POLICY_PASS_FLOW */ true,
114  /* EXCEPTION_POLICY_BYPASS_FLOW */ true,
115  /* EXCEPTION_POLICY_DROP_PACKET */ false,
116  /* EXCEPTION_POLICY_DROP_FLOW */ false,
117  /* EXCEPTION_POLICY_REJECT */ true,
118  /* EXCEPTION_POLICY_REJECT_BOTH */ true,
119  },
120  .valid_settings_ips = {
121  /* EXCEPTION_POLICY_NOT_SET */ false,
122  /* EXCEPTION_POLICY_AUTO */ false,
123  /* EXCEPTION_POLICY_PASS_PACKET */ true,
124  /* EXCEPTION_POLICY_PASS_FLOW */ true,
125  /* EXCEPTION_POLICY_BYPASS_FLOW */ true,
126  /* EXCEPTION_POLICY_DROP_PACKET */ true,
127  /* EXCEPTION_POLICY_DROP_FLOW */ true,
128  /* EXCEPTION_POLICY_REJECT */ true,
129  /* EXCEPTION_POLICY_REJECT_BOTH */ true,
130  },
131 };
132 // clang-format on
133 
134 void AppLayerSetupCounters(void);
135 void AppLayerDeSetupCounters(void);
136 
137 /***** L7 layer dispatchers *****/
138 
139 static inline int ProtoDetectDone(const Flow *f, const TcpSession *ssn, uint8_t direction) {
140  const TcpStream *stream = (direction & STREAM_TOSERVER) ? &ssn->client : &ssn->server;
142  (FLOW_IS_PM_DONE(f, direction) && FLOW_IS_PP_DONE(f, direction)));
143 }
144 
145 /**
146  * \note id can be 0 if protocol parser is disabled but detection
147  * is enabled.
148  */
149 static void AppLayerIncFlowCounter(ThreadVars *tv, Flow *f)
150 {
152  if (likely(tv && id.id > 0)) {
153  StatsCounterIncr(&tv->stats, id);
154  }
155 }
156 
157 void AppLayerIncTxCounter(ThreadVars *tv, Flow *f, int64_t step)
158 {
160  if (likely(tv && id.id > 0)) {
161  StatsCounterAddI64(&tv->stats, id, step);
162  }
163 }
164 
166 {
168  if (likely(tv && id.id > 0)) {
169  StatsCounterIncr(&tv->stats, id);
170  }
171 }
172 
174 {
176  if (likely(tv && id.id > 0)) {
177  StatsCounterIncr(&tv->stats, id);
178  }
179 }
180 
182 {
184  if (likely(tv && id.id > 0)) {
185  StatsCounterIncr(&tv->stats, id);
186  }
187 }
188 
190 {
192  if (likely(tv && id.id > 0)) {
193  StatsCounterIncr(&tv->stats, id);
194  }
195 }
196 
197 static void AppLayerIncrErrorExcPolicyCounter(ThreadVars *tv, Flow *f, enum ExceptionPolicy policy)
198 {
199 #ifdef UNITTESTS
200  if (tv == NULL) {
201  return;
202  }
203 #endif
205  /* for the summary values */
206  StatsCounterId g_id = eps_error_summary.eps_id[policy];
207 
208  if (likely(id.id > 0)) {
209  StatsCounterIncr(&tv->stats, id);
210  }
211  if (likely(g_id.id > 0)) {
212  StatsCounterIncr(&tv->stats, g_id);
213  }
214 }
215 
216 /* in IDS mode protocol detection is done in reverse order:
217  * when TCP data is ack'd. We want to flag the correct packet,
218  * so in this case we set a flag in the flow so that the first
219  * packet in the correct direction can be tagged.
220  *
221  * For IPS we update packet and flow. */
222 static inline void FlagPacketFlow(Packet *p, Flow *f, uint8_t flags)
223 {
224  if (p->proto != IPPROTO_TCP || EngineModeIsIPS()) {
225  if (flags & STREAM_TOSERVER) {
226  if (p->flowflags & FLOW_PKT_TOSERVER) {
229  } else {
231  }
232  } else {
233  if (p->flowflags & FLOW_PKT_TOCLIENT) {
236  } else {
238  }
239  }
240  } else {
241  if (flags & STREAM_TOSERVER) {
243  } else {
245  }
246  }
247 }
248 
249 static void DisableAppLayer(ThreadVars *tv, Flow *f, Packet *p)
250 {
251  SCLogDebug("disable app layer for flow %p alproto %u ts %u tc %u",
252  f, f->alproto, f->alproto_ts, f->alproto_tc);
255  TcpSession *ssn = f->protoctx;
257  f->alproto = ALPROTO_FAILED;
258  AppLayerIncFlowCounter(tv, f);
259 
260  if (f->alproto_tc != ALPROTO_FAILED) {
261  if (f->alproto_tc == ALPROTO_UNKNOWN) {
263  }
264  FlagPacketFlow(p, f, STREAM_TOCLIENT);
265  }
266  if (f->alproto_ts != ALPROTO_FAILED) {
267  if (f->alproto_ts == ALPROTO_UNKNOWN) {
269  }
270  FlagPacketFlow(p, f, STREAM_TOSERVER);
271  }
272  SCLogDebug("disabled app layer for flow %p alproto %u ts %u tc %u",
273  f, f->alproto, f->alproto_ts, f->alproto_tc);
274 }
275 
276 /* See if we're going to have to give up:
277  *
278  * If we're getting a lot of data in one direction and the
279  * proto for this direction is unknown, proto detect will
280  * hold up segments in the segment list in the stream.
281  * They are held so that if we detect the protocol on the
282  * opposing stream, we can still parse this side of the stream
283  * as well. However, some sessions are very unbalanced. FTP
284  * data channels, large PUT/POST request and many others, can
285  * lead to cases where we would have to store many megabytes
286  * worth of segments before we see the opposing stream. This
287  * leads to risks of resource starvation.
288  *
289  * Here a cutoff point is enforced. If we've stored 100k in
290  * one direction and we've seen no data in the other direction,
291  * we give up.
292  *
293  * Giving up means we disable applayer an set an applayer event
294  */
295 static void TCPProtoDetectCheckBailConditions(ThreadVars *tv,
296  Flow *f, TcpSession *ssn, Packet *p)
297 {
298  if (ssn->state < TCP_ESTABLISHED) {
299  SCLogDebug("skip as long as TCP is not ESTABLISHED (TCP fast open)");
300  return;
301  }
302 
303  const uint32_t size_ts = StreamDataAvailableForProtoDetect(&ssn->client);
304  const uint32_t size_tc = StreamDataAvailableForProtoDetect(&ssn->server);
305  SCLogDebug("size_ts %" PRIu32 ", size_tc %" PRIu32, size_ts, size_tc);
306 
307  /* at least 100000 whatever the conditions
308  * and can be more if window is bigger and if configuration allows it */
309  const uint32_t size_tc_limit =
311  const uint32_t size_ts_limit =
313 
314  if (ProtoDetectDone(f, ssn, STREAM_TOSERVER) &&
315  ProtoDetectDone(f, ssn, STREAM_TOCLIENT))
316  {
317  goto failure;
318 
319  /* we bail out whatever the pp and pm states if
320  * we received too much data */
321  } else if (size_tc > 2 * size_tc_limit || size_ts > 2 * size_ts_limit) {
323  goto failure;
324 
325  } else if (FLOW_IS_PM_DONE(f, STREAM_TOSERVER) && FLOW_IS_PP_DONE(f, STREAM_TOSERVER) &&
326  size_ts > size_ts_limit && size_tc == 0) {
328  goto failure;
329 
330  } else if (FLOW_IS_PM_DONE(f, STREAM_TOCLIENT) && FLOW_IS_PP_DONE(f, STREAM_TOCLIENT) &&
331  size_tc > size_tc_limit && size_ts == 0) {
333  goto failure;
334 
335  /* little data in ts direction, pp done, pm not done (max
336  * depth not reached), ts direction done, lots of data in
337  * tc direction. */
338  } else if (size_tc > size_tc_limit && FLOW_IS_PP_DONE(f, STREAM_TOSERVER) &&
339  !(FLOW_IS_PM_DONE(f, STREAM_TOSERVER)) && FLOW_IS_PM_DONE(f, STREAM_TOCLIENT) &&
340  FLOW_IS_PP_DONE(f, STREAM_TOCLIENT)) {
342  goto failure;
343 
344  /* little data in tc direction, pp done, pm not done (max
345  * depth not reached), tc direction done, lots of data in
346  * ts direction. */
347  } else if (size_ts > size_ts_limit && FLOW_IS_PP_DONE(f, STREAM_TOCLIENT) &&
348  !(FLOW_IS_PM_DONE(f, STREAM_TOCLIENT)) && FLOW_IS_PM_DONE(f, STREAM_TOSERVER) &&
349  FLOW_IS_PP_DONE(f, STREAM_TOSERVER)) {
351  goto failure;
352  }
353  return;
354 
355 failure:
356  DisableAppLayer(tv, f, p);
357 }
358 
359 static int TCPProtoDetectTriggerOpposingSide(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
360  Packet *p, TcpSession *ssn, const TcpStream *stream)
361 {
362  TcpStream *opposing_stream = NULL;
363  if (stream == &ssn->client) {
364  opposing_stream = &ssn->server;
365  } else {
366  opposing_stream = &ssn->client;
367  }
368 
369  /* if the opposing side is not going to work, then
370  * we just have to give up. */
371  if (opposing_stream->flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY) {
372  SCLogDebug("opposing dir has STREAMTCP_STREAM_FLAG_NOREASSEMBLY set");
373  return -1;
374  }
375 
376  enum StreamUpdateDir dir = StreamTcpInlineMode() ?
379  int ret = StreamTcpReassembleAppLayer(tv, ra_ctx, ssn,
380  opposing_stream, p, dir);
381  return ret;
382 }
383 
385 
386 /** \todo data const
387  * \retval int -1 error
388  * \retval int 0 ok
389  */
390 static int TCPProtoDetect(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
391  AppLayerThreadCtx *app_tctx, Packet *p, Flow *f, TcpSession *ssn, TcpStream **stream,
392  uint8_t *data, uint32_t data_len, uint8_t flags, enum StreamUpdateDir app_update_dir)
393 {
394  AppProto *alproto;
395  AppProto *alproto_otherdir;
396  uint8_t direction = (flags & STREAM_TOSERVER) ? 0 : 1;
397 
398  if (flags & STREAM_TOSERVER) {
399  alproto = &f->alproto_ts;
400  alproto_otherdir = &f->alproto_tc;
401  } else {
402  alproto = &f->alproto_tc;
403  alproto_otherdir = &f->alproto_ts;
404  }
405 
406  SCLogDebug("Stream initializer (len %" PRIu32 ")", data_len);
407 #ifdef PRINT
408  if (data_len > 0) {
409  printf("=> Init Stream Data (app layer) -- start %s%s\n",
410  flags & STREAM_TOCLIENT ? "toclient" : "",
411  flags & STREAM_TOSERVER ? "toserver" : "");
412  PrintRawDataFp(stdout, data, data_len);
413  printf("=> Init Stream Data -- end\n");
414  }
415 #endif
416 
417  bool reverse_flow = false;
418  DEBUG_VALIDATE_BUG_ON(data == NULL && data_len > 0);
420  *alproto = AppLayerProtoDetectGetProto(app_tctx->alpd_tctx,
421  f, data, data_len,
422  IPPROTO_TCP, flags, &reverse_flow);
423  PACKET_PROFILING_APP_PD_END(app_tctx);
424  SCLogDebug("alproto %u rev %s", *alproto, reverse_flow ? "true" : "false");
425 
426  if (*alproto != ALPROTO_UNKNOWN) {
427  if (*alproto_otherdir != ALPROTO_UNKNOWN && *alproto_otherdir != *alproto) {
430 
432  /* if we already invoked the parser, we go with that proto */
433  f->alproto = *alproto_otherdir;
434  } else {
435  /* no data sent to parser yet, we can still choose
436  * we're trusting the server more. */
437  if (flags & STREAM_TOCLIENT)
438  f->alproto = *alproto;
439  else
440  f->alproto = *alproto_otherdir;
441  }
442  } else {
443  f->alproto = *alproto;
444  }
445 
449  FlagPacketFlow(p, f, flags);
450 
451  /* if protocol detection indicated that we need to reverse
452  * the direction of the flow, do it now. We flip the flow,
453  * packet and the direction flags */
454  if (reverse_flow &&
457  /* but only if we didn't already detect it on the other side. */
458  if (*alproto_otherdir == ALPROTO_UNKNOWN) {
459  SCLogDebug("reversing flow after proto detect told us so");
460  PacketSwap(p);
461  FlowSwap(f);
462  // Will reset signature groups in DetectRunSetup
463  f->de_ctx_version = UINT32_MAX;
464  SWAP_FLAGS(flags, STREAM_TOSERVER, STREAM_TOCLIENT);
465  if (*stream == &ssn->client) {
466  *stream = &ssn->server;
467  } else {
468  *stream = &ssn->client;
469  }
470  direction = 1 - direction;
471  } else {
472  // TODO event, error?
473  }
474  }
475 
476  /* account flow if we have both sides */
477  if (*alproto_otherdir != ALPROTO_UNKNOWN) {
478  AppLayerIncFlowCounter(tv, f);
479  }
480 
481  /* if we have seen data from the other direction first, send
482  * data for that direction first to the parser. This shouldn't
483  * be an issue, since each stream processing happens
484  * independently of the other stream direction. At this point of
485  * call, you need to know that this function's already being
486  * called by the very same StreamReassembly() function that we
487  * will now call shortly for the opposing direction. */
488  if ((ssn->data_first_seen_dir & (STREAM_TOSERVER | STREAM_TOCLIENT)) &&
489  !(flags & ssn->data_first_seen_dir))
490  {
491  SCLogDebug("protocol %s needs first data in other direction",
492  AppProtoToString(*alproto));
493 
494  if (TCPProtoDetectTriggerOpposingSide(tv, ra_ctx,
495  p, ssn, *stream) != 0)
496  {
497  goto detect_error;
498  }
499  if (FlowChangeProto(f)) {
500  /* We have the first data which requested a protocol change from P1 to P2
501  * even if it was not recognized at first as being P1
502  * As the second data was recognized as P1, the protocol did not change !
503  */
507  }
508  }
509 
510  /* if the parser operates such that it needs to see data from
511  * a particular direction first, we check if we have seen
512  * data from that direction first for the flow. IF it is not
513  * the same, we set an event and exit.
514  *
515  * \todo We need to figure out a more robust solution for this,
516  * as this can lead to easy evasion tactics, where the
517  * attacker can first send some dummy data in the wrong
518  * direction first to mislead our proto detection process.
519  * While doing this we need to update the parsers as well,
520  * since the parsers must be robust to see such wrong
521  * direction data.
522  * Either ways the moment we see the
523  * APPLAYER_WRONG_DIRECTION_FIRST_DATA event set for the
524  * flow, it shows something's fishy.
525  */
527  uint8_t first_data_dir;
528  first_data_dir = AppLayerParserGetFirstDataDir(f->proto, f->alproto);
529 
530  if (first_data_dir && !(first_data_dir & ssn->data_first_seen_dir)) {
533  goto detect_error;
534  }
535  /* This can happen if the current direction is not the
536  * right direction, and the data from the other(also
537  * the right direction) direction is available to be sent
538  * to the app layer, but it is not ack'ed yet and hence
539  * the forced call to STreamTcpAppLayerReassemble still
540  * hasn't managed to send data from the other direction
541  * to the app layer. */
542  if (first_data_dir && !(first_data_dir & flags)) {
548  SCReturnInt(-1);
549  }
550  }
551 
552  /* Set a value that is neither STREAM_TOSERVER, nor STREAM_TOCLIENT */
554 
555  /* finally, invoke the parser */
556  PACKET_PROFILING_APP_START(app_tctx, f->alproto);
557  int r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto,
558  flags, data, data_len);
559  PACKET_PROFILING_APP_END(app_tctx);
560  p->app_update_direction = (uint8_t)app_update_dir;
561  if (r != 1) {
562  StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
563  }
564  if (r == 0) {
565  if (*alproto_otherdir == ALPROTO_UNKNOWN) {
566  TcpStream *opposing_stream;
567  if (*stream == &ssn->client) {
568  opposing_stream = &ssn->server;
569  } else {
570  opposing_stream = &ssn->client;
571  }
573  // can happen in detection-only
574  AppLayerIncFlowCounter(tv, f);
575  }
576  }
577  }
578  if (r < 0) {
579  goto parser_error;
580  }
581  } else {
582  /* if the ssn is midstream, we may end up with a case where the
583  * start of an HTTP request is missing. We won't detect HTTP based
584  * on the request. However, the reply is fine, so we detect
585  * HTTP anyway. This leads to passing the incomplete request to
586  * the htp parser.
587  *
588  * This has been observed, where the http parser then saw many
589  * bogus requests in the incomplete data.
590  *
591  * To counter this case, a midstream session MUST find it's
592  * protocol in the toserver direction. If not, we assume the
593  * start of the request/toserver is incomplete and no reliable
594  * detection and parsing is possible. So we give up.
595  */
596  if ((ssn->flags & STREAMTCP_FLAG_MIDSTREAM) &&
598  {
599  if (FLOW_IS_PM_DONE(f, STREAM_TOSERVER) && FLOW_IS_PP_DONE(f, STREAM_TOSERVER)) {
600  SCLogDebug("midstream end pd %p", ssn);
601  /* midstream and toserver detection failed: give up */
602  DisableAppLayer(tv, f, p);
603  SCReturnInt(0);
604  }
605  }
606 
607  if (*alproto_otherdir != ALPROTO_UNKNOWN) {
608  uint8_t first_data_dir;
609  first_data_dir = AppLayerParserGetFirstDataDir(f->proto, *alproto_otherdir);
610 
611  /* this would handle this test case -
612  * http parser which says it wants to see toserver data first only.
613  * tcp handshake
614  * toclient data first received. - RUBBISH DATA which
615  * we don't detect as http
616  * toserver data next sent - we detect this as http.
617  * at this stage we see that toclient is the first data seen
618  * for this session and we try and redetect the app protocol,
619  * but we are unable to detect the app protocol like before.
620  * But since we have managed to detect the protocol for the
621  * other direction as http, we try to use that. At this
622  * stage we check if the direction of this stream matches
623  * to that acceptable by the app parser. If it is not the
624  * acceptable direction we error out.
625  */
627  (first_data_dir) && !(first_data_dir & flags))
628  {
629  goto detect_error;
630  }
631 
632  /* if protocol detection is marked done for our direction we
633  * pass our data on. We're only succeeded in finding one
634  * direction: the opposing stream
635  *
636  * If PD was not yet complete, we don't do anything.
637  */
638  if (FLOW_IS_PM_DONE(f, flags) && FLOW_IS_PP_DONE(f, flags)) {
639  if (data_len > 0)
641 
642  if (*alproto_otherdir != ALPROTO_FAILED) {
643  PACKET_PROFILING_APP_START(app_tctx, f->alproto);
644  int r = AppLayerParserParse(tv, app_tctx->alp_tctx, f,
645  f->alproto, flags,
646  data, data_len);
647  PACKET_PROFILING_APP_END(app_tctx);
648  p->app_update_direction = (uint8_t)app_update_dir;
649  if (r != 1) {
650  StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
651  }
652 
657  AppLayerIncFlowCounter(tv, f);
658 
659  *alproto = *alproto_otherdir;
660  SCLogDebug("packet %" PRIu64 ": pd done(us %u them %u), parser called (r==%d), "
661  "APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION set",
662  PcapPacketCntGet(p), *alproto, *alproto_otherdir, r);
663  if (r < 0) {
664  goto parser_error;
665  }
666  }
667  *alproto = ALPROTO_FAILED;
669  FlagPacketFlow(p, f, flags);
670 
671  } else if (flags & STREAM_EOF) {
672  *alproto = f->alproto;
674  AppLayerIncFlowCounter(tv, f);
675  }
676  } else {
677  /* both sides unknown, let's see if we need to give up */
678  if (FlowChangeProto(f)) {
679  /* TCPProtoDetectCheckBailConditions does not work well because
680  * size_tc from STREAM_RIGHT_EDGE is not reset to zero
681  * so, we set a lower limit to the data we inspect
682  * We could instead have set ssn->server.sb.stream_offset = 0;
683  */
684  if (data_len >= FLOW_PROTO_CHANGE_MAX_DEPTH || (flags & STREAM_EOF)) {
685  DisableAppLayer(tv, f, p);
686  }
687  } else {
688  TCPProtoDetectCheckBailConditions(tv, f, ssn, p);
689  }
690  }
691  }
692  SCReturnInt(0);
693 parser_error:
695  AppLayerIncrErrorExcPolicyCounter(tv, f, g_applayerparser_error_policy);
696  SCReturnInt(-1);
697 detect_error:
698  DisableAppLayer(tv, f, p);
699  SCReturnInt(-2);
700 }
701 
702 /** \brief handle TCP data for the app-layer.
703  *
704  * First run protocol detection and then when the protocol is known invoke
705  * the app layer parser.
706  *
707  * \param stream ptr-to-ptr to stream object. Might change if flow dir is
708  * reversed.
709  */
711  TcpSession *ssn, TcpStream **stream, uint8_t *data, uint32_t data_len, uint8_t flags,
712  enum StreamUpdateDir app_update_dir)
713 {
714  SCEnter();
715 
717  DEBUG_VALIDATE_BUG_ON(data_len > (uint32_t)INT_MAX);
718 
719  AppLayerThreadCtx *app_tctx = ra_ctx->app_tctx;
720  AppProto alproto;
721  int r = 0;
722 
723  SCLogDebug("data_len %u flags %02X", data_len, flags);
725  SCLogDebug("STREAMTCP_FLAG_APP_LAYER_DISABLED is set");
726  goto end;
727  }
728 
729  const uint8_t direction = (flags & STREAM_TOSERVER) ? 0 : 1;
730 
731  if (flags & STREAM_TOSERVER) {
732  alproto = f->alproto_ts;
733  } else {
734  alproto = f->alproto_tc;
735  }
736 
737  /* If a gap notification, relay the notification on to the
738  * app-layer if known. */
739  if (flags & STREAM_GAP) {
740  SCLogDebug("GAP of size %u", data_len);
741  if (alproto == ALPROTO_UNKNOWN) {
743  SCLogDebug("ALPROTO_UNKNOWN flow %p, due to GAP in stream start", f);
744  /* if the other side didn't already find the proto, we're done */
745  if (f->alproto == ALPROTO_UNKNOWN) {
746  goto failure;
747  }
748  AppLayerIncFlowCounter(tv, f);
749  }
750  if (FlowChangeProto(f)) {
752  SCLogDebug("Cannot handle gap while changing protocol");
753  goto failure;
754  }
755  PACKET_PROFILING_APP_START(app_tctx, f->alproto);
756  r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto,
757  flags, data, data_len);
758  PACKET_PROFILING_APP_END(app_tctx);
759  p->app_update_direction = (uint8_t)app_update_dir;
760  /* ignore parser result for gap */
761  StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
762  if (r < 0) {
764  AppLayerIncrErrorExcPolicyCounter(tv, f, g_applayerparser_error_policy);
765  SCReturnInt(-1);
766  }
767  goto end;
768  }
769 
770  /* if we don't know the proto yet and we have received a stream
771  * initializer message, we run proto detection.
772  * We receive 2 stream init msgs (one for each direction), we
773  * only run the proto detection for both and emit an event
774  * in the case protocols mismatch. */
775  if (alproto == ALPROTO_UNKNOWN && (flags & STREAM_START)) {
777  /* run protocol detection */
778  if (TCPProtoDetect(tv, ra_ctx, app_tctx, p, f, ssn, stream, data, data_len, flags,
779  app_update_dir) != 0) {
780  goto failure;
781  }
782  } else if (alproto != ALPROTO_UNKNOWN && FlowChangeProto(f)) {
783  SCLogDebug("protocol change, old %s", AppProtoToString(f->alproto_orig));
784  void *alstate_orig = f->alstate;
785  AppLayerParserState *alparser = f->alparser;
786  // we delay AppLayerParserStateCleanup because we may need previous parser state
790  /* rerun protocol detection */
791  int rd = TCPProtoDetect(
792  tv, ra_ctx, app_tctx, p, f, ssn, stream, data, data_len, flags, app_update_dir);
793  if (f->alproto == ALPROTO_UNKNOWN) {
794  DEBUG_VALIDATE_BUG_ON(alstate_orig != f->alstate);
795  // not enough data, revert AppLayerProtoDetectReset to rerun detection
796  f->alparser = alparser;
797  f->alproto = f->alproto_orig;
798  f->alproto_tc = f->alproto_orig;
799  f->alproto_ts = f->alproto_orig;
800  } else {
802  AppLayerParserStateProtoCleanup(f->protomap, f->alproto_orig, alstate_orig, alparser);
803  if (alstate_orig == f->alstate) {
804  // we just freed it
805  f->alstate = NULL;
806  }
807  }
808  if (rd != 0) {
809  SCLogDebug("proto detect failure");
810  goto failure;
811  }
812  SCLogDebug("protocol change, old %s, new %s",
814 
816  f->alproto != f->alproto_expect) {
818 
819  if (f->alproto_expect == ALPROTO_TLS && f->alproto != ALPROTO_TLS) {
822  }
823  }
824  } else {
825  SCLogDebug("stream data (len %" PRIu32 " alproto "
826  "%"PRIu16" (flow %p)", data_len, f->alproto, f);
827 #ifdef PRINT
828  if (data_len > 0) {
829  printf("=> Stream Data (app layer) -- start %s%s\n",
830  flags & STREAM_TOCLIENT ? "toclient" : "",
831  flags & STREAM_TOSERVER ? "toserver" : "");
832  PrintRawDataFp(stdout, data, data_len);
833  printf("=> Stream Data -- end\n");
834  }
835 #endif
836  /* if we don't have a data object here we are not getting it
837  * a start msg should have gotten us one */
838  if (f->alproto != ALPROTO_UNKNOWN) {
839  PACKET_PROFILING_APP_START(app_tctx, f->alproto);
840  r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto,
841  flags, data, data_len);
842  PACKET_PROFILING_APP_END(app_tctx);
843  p->app_update_direction = (uint8_t)app_update_dir;
844  if (r != 1) {
845  StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
846  if (r < 0) {
849  AppLayerIncrErrorExcPolicyCounter(tv, f, g_applayerparser_error_policy);
850  SCReturnInt(-1);
851  }
852  }
853  }
854  }
855 
856  goto end;
857  failure:
858  r = -1;
859  end:
860  SCReturnInt(r);
861 }
862 
863 /**
864  * \brief Handle a app layer UDP message
865  *
866  * If the protocol is yet unknown, the proto detection code is run first.
867  *
868  * \param dp_ctx Thread app layer detect context
869  * \param f *locked* flow
870  * \param p UDP packet
871  *
872  * \retval 0 ok
873  * \retval -1 error
874  */
876 {
877  SCEnter();
878  AppProto *alproto;
879  AppProto *alproto_otherdir;
880 
881  if (f->alproto_ts == ALPROTO_FAILED && f->alproto_tc == ALPROTO_FAILED) {
882  SCReturnInt(0);
883  }
884 
885  int r = 0;
886  uint8_t flags = 0;
887  if (p->flowflags & FLOW_PKT_TOSERVER) {
888  flags |= STREAM_TOSERVER;
889  alproto = &f->alproto_ts;
890  alproto_otherdir = &f->alproto_tc;
891  } else {
892  flags |= STREAM_TOCLIENT;
893  alproto = &f->alproto_tc;
894  alproto_otherdir = &f->alproto_ts;
895  }
896 
898 
899  /* if the protocol is still unknown, run detection */
900  if (*alproto == ALPROTO_UNKNOWN) {
901  SCLogDebug("Detecting AL proto on udp mesg (len %" PRIu32 ")",
902  p->payload_len);
903 
904  bool reverse_flow = false;
906  *alproto = AppLayerProtoDetectGetProto(
907  tctx->alpd_tctx, f, p->payload, p->payload_len, IPPROTO_UDP, flags, &reverse_flow);
909 
910  switch (*alproto) {
911  case ALPROTO_UNKNOWN:
912  if (*alproto_otherdir != ALPROTO_UNKNOWN) {
913  // Use recognized side
914  f->alproto = *alproto_otherdir;
915  // do not keep ALPROTO_UNKNOWN for this side so as not to loop
916  *alproto = *alproto_otherdir;
917  if (*alproto_otherdir == ALPROTO_FAILED) {
918  SCLogDebug("ALPROTO_UNKNOWN flow %p", f);
919  }
920  } else {
921  // First side of protocol is unknown
922  *alproto = ALPROTO_FAILED;
923  }
924  break;
925  case ALPROTO_FAILED:
926  if (*alproto_otherdir != ALPROTO_UNKNOWN) {
927  // Use recognized side
928  f->alproto = *alproto_otherdir;
929  if (*alproto_otherdir == ALPROTO_FAILED) {
930  SCLogDebug("ALPROTO_UNKNOWN flow %p", f);
931  }
932  }
933  // else wait for second side of protocol
934  break;
935  default:
936  if (*alproto_otherdir != ALPROTO_UNKNOWN && *alproto_otherdir != ALPROTO_FAILED) {
937  if (*alproto_otherdir != *alproto) {
940  // data already sent to parser, we cannot change the protocol to use the one
941  // of the server
942  }
943  } else {
944  f->alproto = *alproto;
945  }
946  }
947  if (*alproto_otherdir == ALPROTO_UNKNOWN) {
948  if (f->alproto == ALPROTO_UNKNOWN) {
949  // so as to increase stat about .app_layer.flow.failed_udp
950  f->alproto = ALPROTO_FAILED;
951  }
952  // If the other side is unknown, this is the first packet of the flow
953  AppLayerIncFlowCounter(tv, f);
954  }
955 
956  // parse the data if we recognized one protocol
957  if (f->alproto != ALPROTO_UNKNOWN && f->alproto != ALPROTO_FAILED) {
958  if (reverse_flow) {
959  SCLogDebug("reversing flow after proto detect told us so");
960  PacketSwap(p);
961  FlowSwap(f);
962  SWAP_FLAGS(flags, STREAM_TOSERVER, STREAM_TOCLIENT);
963  }
964 
966  r = AppLayerParserParse(tv, tctx->alp_tctx, f, f->alproto,
967  flags, p->payload, p->payload_len);
969  if (f->flags & FLOW_NOPAYLOAD_INSPECTION &&
970  SCAppLayerParserStateIssetFlag(f->alparser, APP_LAYER_PARSER_BYPASS_READY)) {
972  }
974  }
976  /* we do only inspection in one direction, so flag both
977  * sides as done here */
978  FlagPacketFlow(p, f, STREAM_TOSERVER);
979  FlagPacketFlow(p, f, STREAM_TOCLIENT);
980  } else {
981  SCLogDebug("data (len %" PRIu32 " ), alproto "
982  "%"PRIu16" (flow %p)", p->payload_len, f->alproto, f);
983 
984  /* run the parser */
986  r = AppLayerParserParse(tv, tctx->alp_tctx, f, f->alproto,
987  flags, p->payload, p->payload_len);
988  if (f->flags & FLOW_NOPAYLOAD_INSPECTION &&
989  SCAppLayerParserStateIssetFlag(f->alparser, APP_LAYER_PARSER_BYPASS_READY)) {
991  }
995  }
996  if (r < 0) {
998  AppLayerIncrErrorExcPolicyCounter(tv, f, g_applayerparser_error_policy);
999  SCReturnInt(-1);
1000  }
1001 
1002  SCReturnInt(r);
1003 }
1004 
1005 /***** Utility *****/
1006 
1007 AppProto AppLayerGetProtoByName(const char *alproto_name)
1008 {
1009  SCEnter();
1010  AppProto r = AppLayerProtoDetectGetProtoByName(alproto_name);
1011  SCReturnCT(r, "AppProto");
1012 }
1013 
1014 const char *AppLayerGetProtoName(AppProto alproto)
1015 {
1016  SCEnter();
1017  const char * r = AppLayerProtoDetectGetProtoName(alproto);
1018  SCReturnCT(r, "char *");
1019 }
1020 
1022 {
1023  SCEnter();
1024 
1025  AppProto alproto;
1026  AppProto alprotos[g_alproto_max];
1027 
1029 
1030  printf("=========Supported App Layer Protocols=========\n");
1031  for (alproto = 0; alproto < g_alproto_max; alproto++) {
1032  if (alprotos[alproto] == 1)
1033  printf("%s\n", AppLayerGetProtoName(alproto));
1034  }
1035 
1036  SCReturn;
1037 }
1038 
1039 /***** Setup/General Registration *****/
1040 static void AppLayerNamesSetup(void)
1041 {
1082 }
1083 
1084 int AppLayerSetup(void)
1085 {
1086  SCEnter();
1087 
1088  AppLayerNamesSetup();
1091 
1094 
1096  FrameConfigInit();
1097 
1098  SCReturnInt(0);
1099 }
1100 
1102 {
1103  SCEnter();
1104 
1107 
1110 
1111  SCReturnInt(0);
1112 }
1113 
1115 {
1116  SCEnter();
1117 
1118  AppLayerThreadCtx *app_tctx = SCCalloc(1, sizeof(*app_tctx));
1119  if (app_tctx == NULL)
1120  goto error;
1121 
1122  if ((app_tctx->alpd_tctx = AppLayerProtoDetectGetCtxThread()) == NULL)
1123  goto error;
1124  if ((app_tctx->alp_tctx = AppLayerParserThreadCtxAlloc()) == NULL)
1125  goto error;
1126 
1127  goto done;
1128  error:
1129  AppLayerDestroyCtxThread(app_tctx);
1130  app_tctx = NULL;
1131  done:
1132  SCReturnPtr(app_tctx, "void *");
1133 }
1134 
1136 {
1137  SCEnter();
1138 
1139  if (app_tctx == NULL)
1140  SCReturn;
1141 
1142  if (app_tctx->alpd_tctx != NULL)
1144  if (app_tctx->alp_tctx != NULL)
1146  SCFree(app_tctx);
1147 
1148  SCReturn;
1149 }
1150 
1151 #ifdef PROFILING
1153 {
1154  PACKET_PROFILING_APP_RESET(app_tctx);
1155 }
1156 
1158 {
1159  PACKET_PROFILING_APP_STORE(app_tctx, p);
1160 }
1161 #endif
1162 
1163 /** \brief HACK to work around our broken unix manager (re)init loop
1164  */
1166 {
1171  StatsRegisterGlobalCounter("app_layer.expectations", ExpectationGetCounter);
1174  StatsRegisterGlobalCounter("ippair.memuse", IPPairGetMemuse);
1175  StatsRegisterGlobalCounter("ippair.memcap", IPPairGetMemcap);
1176  StatsRegisterGlobalCounter("host.memuse", HostGetMemuse);
1177  StatsRegisterGlobalCounter("host.memcap", HostGetMemcap);
1178 }
1179 
1180 static bool IsAppLayerErrorExceptionPolicyStatsValid(enum ExceptionPolicy policy)
1181 {
1182  if (EngineModeIsIPS()) {
1184  }
1186 }
1187 
1188 static void AppLayerSetupExceptionPolicyPerProtoCounters(
1189  uint8_t ipproto_map, AppProto alproto, const char *alproto_str, const char *ipproto_suffix)
1190 {
1193  for (enum ExceptionPolicy i = EXCEPTION_POLICY_NOT_SET + 1; i < EXCEPTION_POLICY_MAX; i++) {
1194  if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1195  snprintf(applayer_counter_names[alproto][ipproto_map].eps_name[i],
1196  sizeof(applayer_counter_names[alproto][ipproto_map].eps_name[i]),
1197  "app_layer.error.%s%s.exception_policy.%s", alproto_str, ipproto_suffix,
1198  ExceptionPolicyEnumToString(i, true));
1199  }
1200  }
1201  }
1202 }
1203 
1205 {
1206  const uint8_t ipprotos[] = { IPPROTO_TCP, IPPROTO_UDP };
1207  AppProto alprotos[g_alproto_max];
1208  const char *str = "app_layer.flow.";
1209  const char *estr = "app_layer.error.";
1210 
1213  if (unlikely(applayer_counter_names == NULL)) {
1214  FatalError("Unable to alloc applayer_counter_names.");
1215  }
1217  if (unlikely(applayer_counters == NULL)) {
1218  FatalError("Unable to alloc applayer_counters.");
1219  }
1220  /* We don't log stats counters if exception policy is `ignore`/`not set` */
1222  /* Register global counters for app layer error exception policy summary */
1223  const char *eps_default_str = "exception_policy.app_layer.error.";
1224  for (enum ExceptionPolicy i = EXCEPTION_POLICY_NOT_SET + 1; i < EXCEPTION_POLICY_MAX; i++) {
1225  if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1226  snprintf(app_layer_error_eps_stats.eps_name[i],
1227  sizeof(app_layer_error_eps_stats.eps_name[i]), "%s%s", eps_default_str,
1228  ExceptionPolicyEnumToString(i, true));
1229  }
1230  }
1231  }
1232 
1234 
1235  for (uint8_t p = 0; p < FLOW_PROTO_APPLAYER_MAX; p++) {
1236  const uint8_t ipproto = ipprotos[p];
1237  const uint8_t ipproto_map = FlowGetProtoMapping(ipproto);
1238  const char *ipproto_suffix = (ipproto == IPPROTO_TCP) ? "_tcp" : "_udp";
1239  uint8_t ipprotos_all[256 / 8];
1240 
1241  for (AppProto alproto = 0; alproto < g_alproto_max; alproto++) {
1242  if (alprotos[alproto] == 1) {
1243  const char *tx_str = "app_layer.tx.";
1244  const char *alproto_raw = AppLayerGetProtoName(alproto);
1245  char alproto_str[32];
1246  for (size_t i = 0; i < 32; i++) {
1247  alproto_str[i] = alproto_raw[i];
1248  if (alproto_str[i] == 0) {
1249  break;
1250  } else if (alproto_str[i] == '-') {
1251  alproto_str[i] = '_';
1252  }
1253  }
1254 
1255  memset(ipprotos_all, 0, sizeof(ipprotos_all));
1256  AppLayerProtoDetectSupportedIpprotos(alproto, ipprotos_all);
1257  if ((ipprotos_all[IPPROTO_TCP / 8] & (1 << (IPPROTO_TCP % 8))) &&
1258  (ipprotos_all[IPPROTO_UDP / 8] & (1 << (IPPROTO_UDP % 8)))) {
1259  snprintf(applayer_counter_names[alproto][ipproto_map].name,
1260  sizeof(applayer_counter_names[alproto][ipproto_map].name), "%s%s%s",
1261  str, alproto_str, ipproto_suffix);
1262  snprintf(applayer_counter_names[alproto][ipproto_map].tx_name,
1263  sizeof(applayer_counter_names[alproto][ipproto_map].tx_name), "%s%s%s",
1264  tx_str, alproto_str, ipproto_suffix);
1265 
1266  if (ipproto == IPPROTO_TCP) {
1267  snprintf(applayer_counter_names[alproto][ipproto_map].gap_error,
1268  sizeof(applayer_counter_names[alproto][ipproto_map].gap_error),
1269  "%s%s%s.gap", estr, alproto_str, ipproto_suffix);
1270  }
1271  snprintf(applayer_counter_names[alproto][ipproto_map].alloc_error,
1272  sizeof(applayer_counter_names[alproto][ipproto_map].alloc_error),
1273  "%s%s%s.alloc", estr, alproto_str, ipproto_suffix);
1274  snprintf(applayer_counter_names[alproto][ipproto_map].parser_error,
1275  sizeof(applayer_counter_names[alproto][ipproto_map].parser_error),
1276  "%s%s%s.parser", estr, alproto_str, ipproto_suffix);
1277  snprintf(applayer_counter_names[alproto][ipproto_map].internal_error,
1278  sizeof(applayer_counter_names[alproto][ipproto_map].internal_error),
1279  "%s%s%s.internal", estr, alproto_str, ipproto_suffix);
1280 
1281  AppLayerSetupExceptionPolicyPerProtoCounters(
1282  ipproto_map, alproto, alproto_str, ipproto_suffix);
1283  } else {
1284  snprintf(applayer_counter_names[alproto][ipproto_map].name,
1285  sizeof(applayer_counter_names[alproto][ipproto_map].name), "%s%s", str,
1286  alproto_str);
1287  snprintf(applayer_counter_names[alproto][ipproto_map].tx_name,
1288  sizeof(applayer_counter_names[alproto][ipproto_map].tx_name), "%s%s",
1289  tx_str, alproto_str);
1290 
1291  if (ipproto == IPPROTO_TCP) {
1292  snprintf(applayer_counter_names[alproto][ipproto_map].gap_error,
1293  sizeof(applayer_counter_names[alproto][ipproto_map].gap_error),
1294  "%s%s.gap", estr, alproto_str);
1295  }
1296  snprintf(applayer_counter_names[alproto][ipproto_map].alloc_error,
1297  sizeof(applayer_counter_names[alproto][ipproto_map].alloc_error),
1298  "%s%s.alloc", estr, alproto_str);
1299  snprintf(applayer_counter_names[alproto][ipproto_map].parser_error,
1300  sizeof(applayer_counter_names[alproto][ipproto_map].parser_error),
1301  "%s%s.parser", estr, alproto_str);
1302  snprintf(applayer_counter_names[alproto][ipproto_map].internal_error,
1303  sizeof(applayer_counter_names[alproto][ipproto_map].internal_error),
1304  "%s%s.internal", estr, alproto_str);
1305  AppLayerSetupExceptionPolicyPerProtoCounters(
1306  ipproto_map, alproto, alproto_str, "");
1307  }
1308  } else if (alproto == ALPROTO_FAILED) {
1309  snprintf(applayer_counter_names[alproto][ipproto_map].name,
1310  sizeof(applayer_counter_names[alproto][ipproto_map].name), "%s%s%s", str,
1311  "failed", ipproto_suffix);
1312  if (ipproto == IPPROTO_TCP) {
1313  snprintf(applayer_counter_names[alproto][ipproto_map].gap_error,
1314  sizeof(applayer_counter_names[alproto][ipproto_map].gap_error),
1315  "%sfailed%s.gap", estr, ipproto_suffix);
1316  }
1317  }
1318  }
1319  }
1320 }
1321 
1323 {
1324  const uint8_t ipprotos[] = { IPPROTO_TCP, IPPROTO_UDP };
1325  AppProto alprotos[g_alproto_max];
1327 
1328  /* We don't log stats counters if exception policy is `ignore`/`not set` */
1330  /* Register global counters for app layer error exception policy summary */
1331  for (enum ExceptionPolicy i = EXCEPTION_POLICY_NOT_SET + 1; i < EXCEPTION_POLICY_MAX; i++) {
1332  if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1335  }
1336  }
1337  }
1338 
1339  for (uint8_t p = 0; p < FLOW_PROTO_APPLAYER_MAX; p++) {
1340  const uint8_t ipproto = ipprotos[p];
1341  const uint8_t ipproto_map = FlowGetProtoMapping(ipproto);
1342 
1343  for (AppProto alproto = 0; alproto < g_alproto_max; alproto++) {
1344  if (alprotos[alproto] == 1) {
1345  applayer_counters[alproto][ipproto_map].counter_id = StatsRegisterCounter(
1346  applayer_counter_names[alproto][ipproto_map].name, &tv->stats);
1347 
1348  if (AppLayerParserProtoIsRegistered(ipproto, alproto) != 1)
1349  continue;
1350 
1351  applayer_counters[alproto][ipproto_map].counter_tx_id = StatsRegisterCounter(
1352  applayer_counter_names[alproto][ipproto_map].tx_name, &tv->stats);
1353 
1354  if (ipproto == IPPROTO_TCP) {
1355  applayer_counters[alproto][ipproto_map].gap_error_id = StatsRegisterCounter(
1356  applayer_counter_names[alproto][ipproto_map].gap_error, &tv->stats);
1357  }
1358  applayer_counters[alproto][ipproto_map].alloc_error_id = StatsRegisterCounter(
1359  applayer_counter_names[alproto][ipproto_map].alloc_error, &tv->stats);
1360  applayer_counters[alproto][ipproto_map].parser_error_id = StatsRegisterCounter(
1361  applayer_counter_names[alproto][ipproto_map].parser_error, &tv->stats);
1363  applayer_counter_names[alproto][ipproto_map].internal_error, &tv->stats);
1364  /* We don't log stats counters if exception policy is `ignore`/`not set` */
1367  for (enum ExceptionPolicy i = EXCEPTION_POLICY_NOT_SET + 1;
1368  i < EXCEPTION_POLICY_MAX; i++) {
1369  if (IsAppLayerErrorExceptionPolicyStatsValid(i)) {
1370  applayer_counters[alproto][ipproto_map]
1372  applayer_counter_names[alproto][ipproto_map].eps_name[i],
1373  &tv->stats);
1374  }
1375  }
1376  }
1377  } else if (alproto == ALPROTO_FAILED) {
1378  applayer_counters[alproto][ipproto_map].counter_id = StatsRegisterCounter(
1379  applayer_counter_names[alproto][ipproto_map].name, &tv->stats);
1380 
1381  if (ipproto == IPPROTO_TCP) {
1382  applayer_counters[alproto][ipproto_map].gap_error_id = StatsRegisterCounter(
1383  applayer_counter_names[alproto][ipproto_map].gap_error, &tv->stats);
1384  }
1385  }
1386  }
1387  }
1388 }
1389 
1391 {
1394 }
1395 
1396 /***** Unittests *****/
1397 
1398 #ifdef UNITTESTS
1399 #include "pkt-var.h"
1400 #include "stream-tcp-util.h"
1401 #include "stream.h"
1402 #include "util-unittest.h"
1403 
1404 #define TEST_START \
1405  Packet *p = PacketGetFromAlloc(); \
1406  FAIL_IF_NULL(p); \
1407  Flow f; \
1408  ThreadVars tv; \
1409  StreamTcpThread *stt = NULL; \
1410  TCPHdr tcph; \
1411  PacketQueueNoLock pq; \
1412  memset(&pq, 0, sizeof(PacketQueueNoLock)); \
1413  memset(&f, 0, sizeof(Flow)); \
1414  memset(&tv, 0, sizeof(ThreadVars)); \
1415  StatsThreadInit(&tv.stats); \
1416  memset(&tcph, 0, sizeof(TCPHdr)); \
1417  \
1418  FLOW_INITIALIZE(&f); \
1419  f.flags = FLOW_IPV4; \
1420  f.proto = IPPROTO_TCP; \
1421  p->flow = &f; \
1422  PacketSetTCP(p, (uint8_t *)&tcph); \
1423  \
1424  StreamTcpInitConfig(true); \
1425  IPPairInitConfig(true); \
1426  StreamTcpThreadInit(&tv, NULL, (void **)&stt); \
1427  \
1428  /* handshake */ \
1429  tcph.th_win = htons(5480); \
1430  tcph.th_flags = TH_SYN; \
1431  p->flowflags = FLOW_PKT_TOSERVER; \
1432  p->payload_len = 0; \
1433  p->payload = NULL; \
1434  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1); \
1435  TcpSession *ssn = (TcpSession *)f.protoctx; \
1436  \
1437  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); \
1438  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); \
1439  FAIL_IF(f.alproto != ALPROTO_UNKNOWN); \
1440  FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN); \
1441  FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN); \
1442  FAIL_IF(ssn->flags &STREAMTCP_FLAG_APP_LAYER_DISABLED); \
1443  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER)); \
1444  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER)); \
1445  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT)); \
1446  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); \
1447  FAIL_IF(ssn->data_first_seen_dir != 0); \
1448  \
1449  /* handshake */ \
1450  tcph.th_ack = htonl(1); \
1451  tcph.th_flags = TH_SYN | TH_ACK; \
1452  p->flowflags = FLOW_PKT_TOCLIENT; \
1453  p->payload_len = 0; \
1454  p->payload = NULL; \
1455  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1); \
1456  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); \
1457  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); \
1458  FAIL_IF(f.alproto != ALPROTO_UNKNOWN); \
1459  FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN); \
1460  FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN); \
1461  FAIL_IF(ssn->flags &STREAMTCP_FLAG_APP_LAYER_DISABLED); \
1462  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER)); \
1463  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER)); \
1464  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT)); \
1465  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); \
1466  FAIL_IF(ssn->data_first_seen_dir != 0); \
1467  \
1468  /* handshake */ \
1469  tcph.th_ack = htonl(1); \
1470  tcph.th_seq = htonl(1); \
1471  tcph.th_flags = TH_ACK; \
1472  p->flowflags = FLOW_PKT_TOSERVER; \
1473  p->payload_len = 0; \
1474  p->payload = NULL; \
1475  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1); \
1476  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); \
1477  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); \
1478  FAIL_IF(f.alproto != ALPROTO_UNKNOWN); \
1479  FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN); \
1480  FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN); \
1481  FAIL_IF(ssn->flags &STREAMTCP_FLAG_APP_LAYER_DISABLED); \
1482  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER)); \
1483  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER)); \
1484  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT)); \
1485  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); \
1486  FAIL_IF(ssn->data_first_seen_dir != 0);
1487 #define TEST_END \
1488  StreamTcpSessionClear(p->flow->protoctx); \
1489  StreamTcpThreadDeinit(&tv, (void *)stt); \
1490  StreamTcpFreeConfig(true); \
1491  PacketFree(p); \
1492  FLOW_DESTROY(&f); \
1493  IPPairShutdown(); \
1494  StatsThreadCleanup(&tv.stats);
1495 
1496 /**
1497  * \test GET -> HTTP/1.1
1498  */
1499 static int AppLayerTest01(void)
1500 {
1501  TEST_START;
1502 
1503  /* full request */
1504  uint8_t request[] = {
1505  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1506  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1507  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1508  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1509  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1510  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1511  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1512  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1513  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1514  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1515  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1516  tcph.th_ack = htonl(1);
1517  tcph.th_seq = htonl(1);
1518  tcph.th_flags = TH_PUSH | TH_ACK;
1520  p->payload_len = sizeof(request);
1521  p->payload = request;
1522  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1529  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1530  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1531  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1532  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1533  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1534 
1535  /* full response - request ack */
1536  uint8_t response[] = {
1537  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
1538  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1539  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1540  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1541  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1542  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1543  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1544  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1545  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1546  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1547  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1548  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1549  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1550  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1551  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1552  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1553  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1554  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1555  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1556  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1557  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1558  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1559  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1560  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1561  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1562  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1563  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1564  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1565  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1566  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1567  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1568  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1569  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1570  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1571  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1572  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1573  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1574  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1575  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1576  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1577  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1578  tcph.th_ack = htonl(88);
1579  tcph.th_seq = htonl(1);
1580  tcph.th_flags = TH_PUSH | TH_ACK;
1582  p->payload_len = sizeof(response);
1583  p->payload = response;
1584  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1591  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1592  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1593  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1594  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1596 
1597  /* response ack */
1598  tcph.th_ack = htonl(328);
1599  tcph.th_seq = htonl(88);
1600  tcph.th_flags = TH_ACK;
1602  p->payload_len = 0;
1603  p->payload = NULL;
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));
1616 
1617  TEST_END;
1618  PASS;
1619 }
1620 
1621 /**
1622  * \test GE -> T -> HTTP/1.1
1623  */
1624 static int AppLayerTest02(void)
1625 {
1626  TEST_START;
1627 
1628  /* partial request */
1629  uint8_t request1[] = { 0x47, 0x45, };
1630  tcph.th_ack = htonl(1);
1631  tcph.th_seq = htonl(1);
1632  tcph.th_flags = TH_PUSH | TH_ACK;
1634  p->payload_len = sizeof(request1);
1635  p->payload = request1;
1636  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1643  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1644  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1645  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1646  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1647  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1648 
1649  /* response ack against partial request */
1650  tcph.th_ack = htonl(3);
1651  tcph.th_seq = htonl(1);
1652  tcph.th_flags = TH_ACK;
1654  p->payload_len = 0;
1655  p->payload = NULL;
1656  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1663  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1664  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1665  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1666  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1667  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1668 
1669  /* complete partial request */
1670  uint8_t request2[] = {
1671  0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1672  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1673  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1674  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1675  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1676  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1677  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1678  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1679  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1680  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1681  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1682  tcph.th_ack = htonl(1);
1683  tcph.th_seq = htonl(3);
1684  tcph.th_flags = TH_PUSH | TH_ACK;
1686  p->payload_len = sizeof(request2);
1687  p->payload = request2;
1688  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1695  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1696  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1697  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1698  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1699  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1700 
1701  /* response - request ack */
1702  uint8_t response[] = {
1703  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
1704  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1705  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1706  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1707  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1708  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1709  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1710  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1711  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1712  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1713  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1714  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1715  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1716  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1717  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1718  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1719  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1720  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1721  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1722  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1723  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1724  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1725  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1726  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1727  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1728  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1729  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1730  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1731  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1732  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1733  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1734  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1735  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1736  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1737  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1738  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1739  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1740  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1741  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1742  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1743  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1744  tcph.th_ack = htonl(88);
1745  tcph.th_seq = htonl(1);
1746  tcph.th_flags = TH_PUSH | TH_ACK;
1748  p->payload_len = sizeof(response);
1749  p->payload = response;
1750  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1757  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1758  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1759  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1760  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1762 
1763  /* response ack */
1764  tcph.th_ack = htonl(328);
1765  tcph.th_seq = htonl(88);
1766  tcph.th_flags = TH_ACK;
1768  p->payload_len = 0;
1769  p->payload = NULL;
1770  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1777  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1778  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1779  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1780  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1782 
1783  TEST_END;
1784  PASS;
1785 }
1786 
1787 /**
1788  * \test GET -> RUBBISH(PM AND PP DONE IN ONE GO)
1789  */
1790 static int AppLayerTest03(void)
1791 {
1792  TEST_START;
1793 
1794  /* request */
1795  uint8_t request[] = {
1796  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1797  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1798  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1799  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1800  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1801  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1802  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1803  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1804  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1805  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1806  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1807  tcph.th_ack = htonl(1);
1808  tcph.th_seq = htonl(1);
1809  tcph.th_flags = TH_PUSH | TH_ACK;
1811  p->payload_len = sizeof(request);
1812  p->payload = request;
1813  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1820  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1821  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1822  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1823  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1824  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
1825 
1826  /* rubbish response */
1827  uint8_t response[] = {
1828  0x58, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
1829  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1830  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1831  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1832  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1833  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1834  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1835  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1836  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1837  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1838  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1839  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1840  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1841  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1842  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1843  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1844  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1845  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1846  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1847  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1848  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1849  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1850  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1851  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1852  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1853  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1854  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1855  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1856  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1857  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1858  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1859  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1860  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1861  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1862  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1863  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1864  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1865  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1866  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1867  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1868  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1869  tcph.th_ack = htonl(88);
1870  tcph.th_seq = htonl(1);
1871  tcph.th_flags = TH_PUSH | TH_ACK;
1873  p->payload_len = sizeof(response);
1874  p->payload = response;
1875  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1882  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1883  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1884  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1885  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1887 
1888  /* response ack */
1889  tcph.th_ack = htonl(328);
1890  tcph.th_seq = htonl(88);
1891  tcph.th_flags = TH_ACK;
1893  p->payload_len = 0;
1894  p->payload = NULL;
1895  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1902  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1903  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1904  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1905  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1907 
1908  TEST_END;
1909  PASS;
1910 }
1911 
1912 /**
1913  * \test GE -> RUBBISH(TC - PM AND PP NOT DONE) -> RUBBISH(TC - PM AND PP DONE).
1914  */
1915 static int AppLayerTest04(void)
1916 {
1917  TEST_START;
1918 
1919  /* request */
1920  uint8_t request[] = {
1921  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1922  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1923  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1924  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1925  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1926  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1927  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1928  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1929  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1930  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1931  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1932  PrintRawDataFp(stdout, request, sizeof(request));
1933  tcph.th_ack = htonl(1);
1934  tcph.th_seq = htonl(1);
1935  tcph.th_flags = TH_PUSH | TH_ACK;
1937  p->payload_len = sizeof(request);
1938  p->payload = request;
1939  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1946  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1947  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1948  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1949  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1950  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER); // TOSERVER data now seen
1951 
1952  /* partial response */
1953  uint8_t response1[] = { 0x58, 0x54, 0x54, 0x50, };
1954  PrintRawDataFp(stdout, response1, sizeof(response1));
1955  tcph.th_ack = htonl(88);
1956  tcph.th_seq = htonl(1);
1957  tcph.th_flags = TH_PUSH | TH_ACK;
1959  p->payload_len = sizeof(response1);
1960  p->payload = response1;
1961  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1964  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
1965  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
1968  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1969  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1970  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1971  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
1972  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
1973 
1974  /* partial response ack */
1975  tcph.th_ack = htonl(5);
1976  tcph.th_seq = htonl(88);
1977  tcph.th_flags = TH_ACK;
1979  p->payload_len = 0;
1980  p->payload = NULL;
1981  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1984  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
1985  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
1988  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
1989  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
1990  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
1991  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
1992  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
1993 
1994  /* remaining response */
1995  uint8_t response2[] = {
1996  0x2f, 0x31, 0x2e, 0x31,
1997  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1998  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1999  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2000  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2001  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2002  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2003  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2004  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2005  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2006  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2007  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2008  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2009  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2010  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2011  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2012  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2013  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2014  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2015  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2016  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2017  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2018  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2019  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2020  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2021  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2022  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2023  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2024  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2025  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2026  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2027  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2028  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2029  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2030  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2031  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2032  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2033  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2034  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2035  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2036  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2037  PrintRawDataFp(stdout, response2, sizeof(response2));
2038  tcph.th_ack = htonl(88);
2039  tcph.th_seq = htonl(5);
2040  tcph.th_flags = TH_PUSH | TH_ACK;
2042  p->payload_len = sizeof(response2);
2043  p->payload = response2;
2044  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2047  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
2048  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
2051  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2052  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2053  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2054  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
2055  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
2056 
2057  /* response ack */
2058  tcph.th_ack = htonl(328);
2059  tcph.th_seq = htonl(88);
2060  tcph.th_flags = TH_ACK;
2062  p->payload_len = 0;
2063  p->payload = NULL;
2064  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2065  FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); // toclient complete (failed)
2067  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
2068  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
2069  FAIL_IF(f.alproto_tc != ALPROTO_FAILED); // tc failed
2071  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2072  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2073  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2074  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
2075  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
2076 
2077  TEST_END;
2078  PASS;
2079 }
2080 
2081 /**
2082  * \test RUBBISH -> HTTP/1.1
2083  */
2084 static int AppLayerTest05(void)
2085 {
2086  TEST_START;
2087 
2088  /* full request */
2089  uint8_t request[] = {
2090  0x48, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2091  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
2092  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
2093  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
2094  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
2095  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
2096  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
2097  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
2098  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2099  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
2100  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2101  PrintRawDataFp(stdout, request, sizeof(request));
2102  tcph.th_ack = htonl(1);
2103  tcph.th_seq = htonl(1);
2104  tcph.th_flags = TH_PUSH | TH_ACK;
2106  p->payload_len = sizeof(request);
2107  p->payload = request;
2108  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2115  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2116  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2117  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2118  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2119  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2120 
2121  /* full response - request ack */
2122  uint8_t response[] = {
2123  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2124  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2125  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2126  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2127  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2128  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2129  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2130  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2131  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2132  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2133  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2134  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2135  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2136  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2137  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2138  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2139  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2140  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2141  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2142  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2143  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2144  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2145  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2146  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2147  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2148  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2149  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2150  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2151  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2152  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2153  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2154  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2155  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2156  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2157  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2158  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2159  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2160  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2161  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2162  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2163  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2164  PrintRawDataFp(stdout, response, sizeof(response));
2165  tcph.th_ack = htonl(88);
2166  tcph.th_seq = htonl(1);
2167  tcph.th_flags = TH_PUSH | TH_ACK;
2169  p->payload_len = sizeof(response);
2170  p->payload = response;
2171  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2178  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2179  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2180  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2181  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2182  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2183 
2184  /* response ack */
2185  tcph.th_ack = htonl(328);
2186  tcph.th_seq = htonl(88);
2187  tcph.th_flags = TH_ACK;
2189  p->payload_len = 0;
2190  p->payload = NULL;
2191  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2198  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2199  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2200  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2201  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2203 
2204  TEST_END;
2205  PASS;
2206 }
2207 
2208 /**
2209  * \test HTTP/1.1 -> GET
2210  */
2211 static int AppLayerTest06(void)
2212 {
2213  TEST_START;
2214 
2215  /* full response - request ack */
2216  uint8_t response[] = {
2217  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2218  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2219  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2220  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2221  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2222  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2223  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2224  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2225  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2226  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2227  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2228  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2229  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2230  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2231  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2232  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2233  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2234  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2235  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2236  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2237  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2238  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2239  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2240  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2241  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2242  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2243  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2244  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2245  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2246  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2247  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2248  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2249  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2250  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2251  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2252  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2253  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2254  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2255  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2256  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2257  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2258  tcph.th_ack = htonl(1);
2259  tcph.th_seq = htonl(1);
2260  tcph.th_flags = TH_PUSH | TH_ACK;
2262  p->payload_len = sizeof(response);
2263  p->payload = response;
2264  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2271  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2272  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2273  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2274  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2275  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOCLIENT);
2276 
2277  /* full request - response ack*/
2278  uint8_t request[] = {
2279  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2280  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
2281  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
2282  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
2283  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
2284  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
2285  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
2286  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
2287  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2288  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
2289  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2290  tcph.th_ack = htonl(328);
2291  tcph.th_seq = htonl(1);
2292  tcph.th_flags = TH_PUSH | TH_ACK;
2294  p->payload_len = sizeof(request);
2295  p->payload = request;
2296  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2303  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2304  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2305  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2306  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2308 
2309  tcph.th_ack = htonl(1 + sizeof(request));
2310  tcph.th_seq = htonl(328);
2311  tcph.th_flags = TH_PUSH | TH_ACK;
2313  p->payload_len = 0;
2314  p->payload = NULL;
2315  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2322  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2323  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2324  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2325  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2327 
2328  TEST_END;
2329  PASS;
2330 }
2331 
2332 /**
2333  * \test GET -> DCERPC
2334  */
2335 static int AppLayerTest07(void)
2336 {
2337  TEST_START;
2338 
2339  /* full request */
2340  uint8_t request[] = {
2341  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2342  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
2343  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
2344  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
2345  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
2346  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
2347  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
2348  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
2349  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2350  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
2351  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2352  tcph.th_ack = htonl(1);
2353  tcph.th_seq = htonl(1);
2354  tcph.th_flags = TH_PUSH | TH_ACK;
2356  p->payload_len = sizeof(request);
2357  p->payload = request;
2358  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2365  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2366  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2367  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2368  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2369  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2370 
2371  /* full response - request ack */
2372  uint8_t response[] = { 0x05, 0x00, 0x4d, 0x42, 0x00, 0x01, 0x2e, 0x31, 0x20, 0x32, 0x30, 0x30,
2373  0x20, 0x4f, 0x4b, 0x0d, 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, 0x72, 0x69, 0x2c,
2374  0x20, 0x32, 0x33, 0x20, 0x53, 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20, 0x30, 0x36,
2375  0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, 0x72,
2376  0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2377  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69, 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f,
2378  0x32, 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65,
2379  0x64, 0x3a, 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34, 0x20, 0x4e, 0x6f, 0x76, 0x20,
2380  0x32, 0x30, 0x31, 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a, 0x34, 0x36, 0x20, 0x47,
2381  0x4d, 0x54, 0x0d, 0x0a, 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61, 0x62, 0x38, 0x39,
2382  0x36, 0x35, 0x2d, 0x32, 0x63, 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61, 0x37, 0x66,
2383  0x37, 0x66, 0x38, 0x30, 0x22, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x52,
2384  0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2385  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20,
2386  0x34, 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a,
2387  0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
2388  0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d,
2389  0x6c, 0x0d, 0x0a, 0x58, 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64,
2390  0x20, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d, 0x0a, 0x0d,
2391  0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x68,
2392  0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2393  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2394  tcph.th_ack = htonl(88);
2395  tcph.th_seq = htonl(1);
2396  tcph.th_flags = TH_PUSH | TH_ACK;
2398  p->payload_len = sizeof(response);
2399  p->payload = response;
2400  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2407  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2408  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2409  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2410  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2412 
2413  /* response ack */
2414  tcph.th_ack = htonl(328);
2415  tcph.th_seq = htonl(88);
2416  tcph.th_flags = TH_ACK;
2418  p->payload_len = 0;
2419  p->payload = NULL;
2420  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2427  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2428  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2429  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2430  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2432 
2433  TEST_END;
2434  PASS;
2435 }
2436 
2437 /**
2438  * \test RUBBISH(TC - PM and PP NOT DONE) ->
2439  * RUBBISH(TC - PM and PP DONE) ->
2440  * RUBBISH(TS - PM and PP DONE)
2441  */
2442 static int AppLayerTest09(void)
2443 {
2444  TEST_START;
2445 
2446  /* full request */
2447  uint8_t request1[] = {
2448  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64 };
2449  tcph.th_ack = htonl(1);
2450  tcph.th_seq = htonl(1);
2451  tcph.th_flags = TH_PUSH | TH_ACK;
2453  p->payload_len = sizeof(request1);
2454  p->payload = request1;
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));
2466  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2467 
2468  /* response - request ack */
2469  tcph.th_ack = htonl(9);
2470  tcph.th_seq = htonl(1);
2471  tcph.th_flags = TH_PUSH | TH_ACK;
2473  p->payload_len = 0;
2474  p->payload = NULL;
2475  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2482  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2483  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2484  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2485  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2486  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2487 
2488  /* full request */
2489  uint8_t request2[] = {
2490  0x44, 0x44, 0x45, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff };
2491  tcph.th_ack = htonl(1);
2492  tcph.th_seq = htonl(9);
2493  tcph.th_flags = TH_PUSH | TH_ACK;
2495  p->payload_len = sizeof(request2);
2496  p->payload = request2;
2497  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2504  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2505  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2506  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2507  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2508  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2509 
2510  /* full response - request ack */
2511  uint8_t response[] = {
2512  0x55, 0x74, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2513  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2514  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2515  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2516  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2517  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2518  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2519  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2520  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2521  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2522  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2523  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2524  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2525  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2526  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2527  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2528  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2529  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2530  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2531  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2532  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2533  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2534  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2535  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2536  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2537  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2538  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2539  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2540  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2541  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2542  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2543  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2544  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2545  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2546  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2547  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2548  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2549  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2550  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2551  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2552  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2553  tcph.th_ack = htonl(18);
2554  tcph.th_seq = htonl(1);
2555  tcph.th_flags = TH_PUSH | TH_ACK;
2557  p->payload_len = sizeof(response);
2558  p->payload = response;
2559  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2566  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2567  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2568  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2569  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2570  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2571 
2572  /* response ack */
2573  tcph.th_ack = htonl(328);
2574  tcph.th_seq = htonl(18);
2575  tcph.th_flags = TH_ACK;
2577  p->payload_len = 0;
2578  p->payload = NULL;
2579  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2586  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2587  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2588  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2589  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2591 
2592  TEST_END;
2593  PASS;
2594 }
2595 
2596 /**
2597  * \test RUBBISH(TC - PM and PP DONE) ->
2598  * RUBBISH(TS - PM and PP DONE)
2599  */
2600 static int AppLayerTest10(void)
2601 {
2602  TEST_START;
2603 
2604  /* full request */
2605  uint8_t request1[] = {
2606  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2607  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff };
2608  tcph.th_ack = htonl(1);
2609  tcph.th_seq = htonl(1);
2610  tcph.th_flags = TH_PUSH | TH_ACK;
2612  p->payload_len = sizeof(request1);
2613  p->payload = request1;
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));
2625  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2626 
2627  /* response - request ack */
2628  tcph.th_ack = htonl(18);
2629  tcph.th_seq = htonl(1);
2630  tcph.th_flags = TH_PUSH | TH_ACK;
2632  p->payload_len = 0;
2633  p->payload = NULL;
2634  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2641  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2642  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2643  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2644  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2645  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2646 
2647  /* full response - request ack */
2648  uint8_t response[] = {
2649  0x55, 0x74, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2650  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2651  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2652  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2653  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2654  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2655  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2656  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2657  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2658  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2659  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2660  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2661  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2662  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2663  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2664  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2665  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2666  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2667  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2668  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2669  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2670  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2671  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2672  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2673  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2674  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2675  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2676  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2677  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2678  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2679  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2680  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2681  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2682  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2683  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2684  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2685  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2686  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2687  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2688  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2689  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2690  tcph.th_ack = htonl(18);
2691  tcph.th_seq = htonl(1);
2692  tcph.th_flags = TH_PUSH | TH_ACK;
2694  p->payload_len = sizeof(response);
2695  p->payload = response;
2696  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2703  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2704  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2705  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2706  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2707  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2708 
2709  /* response ack */
2710  tcph.th_ack = htonl(328);
2711  tcph.th_seq = htonl(18);
2712  tcph.th_flags = TH_ACK;
2714  p->payload_len = 0;
2715  p->payload = NULL;
2716  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2723  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2724  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2725  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2726  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2728 
2729  TEST_END;
2730  PASS;
2731 }
2732 
2733 /**
2734  * \test RUBBISH(TC - PM and PP DONE) ->
2735  * RUBBISH(TS - PM and PP NOT DONE) ->
2736  * RUBBISH(TS - PM and PP DONE)
2737  */
2738 static int AppLayerTest11(void)
2739 {
2740  TEST_START;
2741 
2742  /* full request */
2743  uint8_t request1[] = {
2744  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2745  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff };
2746  tcph.th_ack = htonl(1);
2747  tcph.th_seq = htonl(1);
2748  tcph.th_flags = TH_PUSH | TH_ACK;
2750  p->payload_len = sizeof(request1);
2751  p->payload = request1;
2752  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2759  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2760  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2761  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2762  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2763  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2764 
2765  /* response - request ack */
2766  tcph.th_ack = htonl(18);
2767  tcph.th_seq = htonl(1);
2768  tcph.th_flags = TH_PUSH | TH_ACK;
2770  p->payload_len = 0;
2771  p->payload = NULL;
2772  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2779  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2780  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2781  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2782  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2783  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2784 
2785  /* full response - request ack */
2786  uint8_t response1[] = {
2787  0x55, 0x74, 0x54, 0x50, };
2788  tcph.th_ack = htonl(18);
2789  tcph.th_seq = htonl(1);
2790  tcph.th_flags = TH_PUSH | TH_ACK;
2792  p->payload_len = sizeof(response1);
2793  p->payload = response1;
2794  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2801  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2802  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2803  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2804  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2805  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2806 
2807  /* response ack from request */
2808  tcph.th_ack = htonl(5);
2809  tcph.th_seq = htonl(18);
2810  tcph.th_flags = TH_ACK;
2812  p->payload_len = 0;
2813  p->payload = NULL;
2814  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2821  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2822  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2823  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2824  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2825  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2826 
2827  uint8_t response2[] = {
2828  0x2f, 0x31, 0x2e, 0x31,
2829  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2830  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2831  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2832  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2833  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2834  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2835  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2836  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2837  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2838  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2839  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2840  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2841  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2842  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2843  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2844  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2845  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2846  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2847  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2848  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2849  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2850  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2851  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2852  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2853  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2854  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2855  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2856  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2857  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2858  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2859  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2860  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2861  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2862  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2863  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2864  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2865  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2866  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2867  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2868  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2869  tcph.th_ack = htonl(18);
2870  tcph.th_seq = htonl(5);
2871  tcph.th_flags = TH_PUSH | TH_ACK;
2873  p->payload_len = sizeof(response2);
2874  p->payload = response2;
2875  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2882  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2883  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2884  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2885  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2886  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
2887 
2888  /* response ack from request */
2889  tcph.th_ack = htonl(328);
2890  tcph.th_seq = htonl(18);
2891  tcph.th_flags = TH_ACK;
2893  p->payload_len = 0;
2894  p->payload = NULL;
2895  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2902  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
2903  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
2904  FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
2905  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
2907 
2908  TEST_END;
2909  PASS;
2910 }
2911 
2913 {
2914  SCEnter();
2915 
2916  UtRegisterTest("AppLayerTest01", AppLayerTest01);
2917  UtRegisterTest("AppLayerTest02", AppLayerTest02);
2918  UtRegisterTest("AppLayerTest03", AppLayerTest03);
2919  UtRegisterTest("AppLayerTest04", AppLayerTest04);
2920  UtRegisterTest("AppLayerTest05", AppLayerTest05);
2921  UtRegisterTest("AppLayerTest06", AppLayerTest06);
2922  UtRegisterTest("AppLayerTest07", AppLayerTest07);
2923  UtRegisterTest("AppLayerTest09", AppLayerTest09);
2924  UtRegisterTest("AppLayerTest10", AppLayerTest10);
2925  UtRegisterTest("AppLayerTest11", AppLayerTest11);
2926 
2927  SCReturn;
2928 }
2929 
2930 #endif /* UNITTESTS */
AppLayerCounters_::counter_tx_id
StatsCounterId counter_tx_id
Definition: app-layer.c:91
APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER
#define APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER
Definition: app-layer.h:40
FLOW_RESET_PP_DONE
#define FLOW_RESET_PP_DONE(f, dir)
Definition: flow.h:285
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:187
StatsRegisterGlobalCounter
StatsCounterGlobalId StatsRegisterGlobalCounter(const char *name, uint64_t(*Func)(void))
Registers a counter, which represents a global value.
Definition: counters.c:1094
Packet_::proto
uint8_t proto
Definition: decode.h:536
AppLayerParserDeSetup
int AppLayerParserDeSetup(void)
Definition: app-layer-parser.c:285
TcpStream_
Definition: stream-tcp-private.h:106
APPLAYER_UNEXPECTED_PROTOCOL
@ APPLAYER_UNEXPECTED_PROTOCOL
Definition: app-layer-events.h:51
ExceptionPolicyApply
void ExceptionPolicyApply(Packet *p, enum ExceptionPolicy policy, enum PacketDropReason drop_reason)
Definition: util-exception-policy.c:138
AppLayerCounters_
Definition: app-layer.c:89
ippair.h
SCAppLayerParserStateIssetFlag
uint16_t SCAppLayerParserStateIssetFlag(AppLayerParserState *pstate, uint16_t flag)
Definition: app-layer-parser.c:1874
app-layer-htp-range.h
FlowCleanupAppLayer
void FlowCleanupAppLayer(Flow *f)
Definition: flow.c:140
AppLayerProtoDetectSetup
int AppLayerProtoDetectSetup(void)
The first function to be called. This initializes a global protocol detection context.
Definition: app-layer-detect-proto.c:1686
ALPROTO_IKE
@ ALPROTO_IKE
Definition: app-layer-protos.h:55
ExpectationGetCounter
uint64_t ExpectationGetCounter(void)
Definition: app-layer-expectation.c:140
AppLayerCounterNames_::eps_name
char eps_name[EXCEPTION_POLICY_MAX][MAX_COUNTER_SIZE]
Definition: app-layer.c:86
Flow_::flags
uint64_t flags
Definition: flow.h:403
AppLayerCounters
struct AppLayerCounters_ AppLayerCounters
stream-tcp-inline.h
ALPROTO_DCERPC
@ ALPROTO_DCERPC
Definition: app-layer-protos.h:44
flow-util.h
ALPROTO_DNS
@ ALPROTO_DNS
Definition: app-layer-protos.h:47
AppLayerCounters_::gap_error_id
StatsCounterId gap_error_id
Definition: app-layer.c:92
AppLayerCounters_::internal_error_id
StatsCounterId internal_error_id
Definition: app-layer.c:94
PacketBypassCallback
void PacketBypassCallback(Packet *p)
Definition: decode.c:536
stream-tcp.h
ALPROTO_ENIP
@ ALPROTO_ENIP
Definition: app-layer-protos.h:49
StreamTcpInlineMode
bool StreamTcpInlineMode(void)
See if stream engine is operating in inline mode.
Definition: stream-tcp.c:7272
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
AppLayerGetProtoByName
AppProto AppLayerGetProtoByName(const char *alproto_name)
Given a protocol string, returns the corresponding internal protocol id.
Definition: app-layer.c:1007
ALPROTO_TLS
@ ALPROTO_TLS
Definition: app-layer-protos.h:39
PcapPacketCntGet
uint64_t PcapPacketCntGet(const Packet *p)
Definition: decode.c:1175
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:282
StatsRegisterCounter
StatsCounterId StatsRegisterCounter(const char *name, StatsThreadContext *stats)
Registers a normal, unqualified counter.
Definition: counters.c:1039
AppLayerCounterNames_::parser_error
char parser_error[MAX_COUNTER_SIZE]
Definition: app-layer.c:83
name
const char * name
Definition: detect-engine-proto.c:48
ALPROTO_MODBUS
@ ALPROTO_MODBUS
Definition: app-layer-protos.h:48
AppLayerProfilingStoreInternal
void AppLayerProfilingStoreInternal(AppLayerThreadCtx *app_tctx, Packet *p)
Definition: app-layer.c:1157
Flow_::proto
uint8_t proto
Definition: flow.h:376
AppProto
uint16_t AppProto
Definition: app-layer-protos.h:87
ALPROTO_QUIC
@ ALPROTO_QUIC
Definition: app-layer-protos.h:57
Packet_::payload
uint8_t * payload
Definition: decode.h:618
ALPROTO_POP3
@ ALPROTO_POP3
Definition: app-layer-protos.h:71
TcpReassemblyThreadCtx_::app_tctx
void * app_tctx
Definition: stream-tcp-reassemble.h:62
Packet_::flags
uint32_t flags
Definition: decode.h:560
AppLayerThreadCtx_::proto_detect_ticks_spent
uint64_t proto_detect_ticks_spent
Definition: app-layer.c:72
PACKET_PROFILING_APP_PD_END
#define PACKET_PROFILING_APP_PD_END(dp)
Definition: util-profiling.h:186
ALPROTO_JABBER
@ ALPROTO_JABBER
Definition: app-layer-protos.h:42
TcpStreamCnf_::reassembly_depth
uint32_t reassembly_depth
Definition: stream-tcp.h:75
AppLayerThreadCtx_::alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: app-layer.c:63
flow-private.h
Flow_
Flow data structure.
Definition: flow.h:354
AppLayerIncGapErrorCounter
void AppLayerIncGapErrorCounter(ThreadVars *tv, Flow *f)
Definition: app-layer.c:165
Flow_::protomap
uint8_t protomap
Definition: flow.h:445
AppProtoToString
const char * AppProtoToString(AppProto alproto)
Maps the ALPROTO_*, to its string equivalent.
Definition: app-layer-protos.c:41
AppLayerThreadCtx_::ticks_spent
uint64_t ticks_spent
Definition: app-layer.c:68
ALPROTO_IRC
@ ALPROTO_IRC
Definition: app-layer-protos.h:45
ExceptionPolicyStatsSetts_
Definition: util-exception-policy-types.h:59
AppLayerParserGetFirstDataDir
uint8_t AppLayerParserGetFirstDataDir(uint8_t ipproto, AppProto alproto)
Definition: app-layer-parser.c:1174
g_stats_eps_per_app_proto_errors
bool g_stats_eps_per_app_proto_errors
Definition: suricata.c:224
AppLayerParserProtoIsRegistered
int AppLayerParserProtoIsRegistered(uint8_t ipproto, AppProto alproto)
Definition: app-layer-parser.c:228
StreamTcpReassembleAppLayer
int StreamTcpReassembleAppLayer(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpSession *ssn, TcpStream *stream, Packet *p, enum StreamUpdateDir app_update_dir)
Update the stream reassembly upon receiving a packet.
Definition: stream-tcp-reassemble.c:1386
FLOW_NOPAYLOAD_INSPECTION
#define FLOW_NOPAYLOAD_INSPECTION
Definition: flow.h:66
StreamTcpResetStreamFlagAppProtoDetectionCompleted
#define StreamTcpResetStreamFlagAppProtoDetectionCompleted(stream)
Definition: stream-tcp-private.h:305
AppLayerRegisterThreadCounters
void AppLayerRegisterThreadCounters(ThreadVars *tv)
Registers per flow counters for all protocols.
Definition: app-layer.c:1322
Flow_::alproto_orig
AppProto alproto_orig
Definition: flow.h:456
AppLayerProtoDetectSupportedIpprotos
void AppLayerProtoDetectSupportedIpprotos(AppProto alproto, uint8_t *ipprotos)
Definition: app-layer-detect-proto.c:2079
FTPMemuseGlobalCounter
uint64_t FTPMemuseGlobalCounter(void)
Definition: app-layer-ftp.c:79
ALPROTO_SIP
@ ALPROTO_SIP
Definition: app-layer-protos.h:59
AppLayerProfilingResetInternal
void AppLayerProfilingResetInternal(AppLayerThreadCtx *app_tctx)
Definition: app-layer.c:1152
AppLayerCounterNames_
Definition: app-layer.c:79
AppLayerParserStateProtoCleanup
void AppLayerParserStateProtoCleanup(uint8_t protomap, AppProto alproto, void *alstate, AppLayerParserState *pstate)
Definition: app-layer-parser.c:1672
AppLayerParserThreadCtxFree
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
Definition: app-layer-parser.c:324
AppLayerHandleTCPData
int AppLayerHandleTCPData(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, Packet *p, Flow *f, TcpSession *ssn, TcpStream **stream, uint8_t *data, uint32_t data_len, uint8_t flags, enum StreamUpdateDir app_update_dir)
handle TCP data for the app-layer.
Definition: app-layer.c:710
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:231
ALPROTO_LDAP
@ ALPROTO_LDAP
Definition: app-layer-protos.h:65
TCP_ESTABLISHED
@ TCP_ESTABLISHED
Definition: stream-tcp-private.h:155
MIN
#define MIN(x, y)
Definition: suricata-common.h:416
StreamTcpUpdateAppLayerProgress
void StreamTcpUpdateAppLayerProgress(TcpSession *ssn, char direction, const uint32_t progress)
update reassembly progress
Definition: stream-tcp.c:6847
ALPROTO_FTP
@ ALPROTO_FTP
Definition: app-layer-protos.h:37
app_layer_error_eps_stats
ExceptionPolicyStatsSetts app_layer_error_eps_stats
Definition: app-layer.c:108
stream-tcp-reassemble.h
AppLayerThreadCtx_::proto_detect_ticks_end
uint64_t proto_detect_ticks_end
Definition: app-layer.c:71
TcpStream_::flags
uint16_t flags
Definition: stream-tcp-private.h:107
AppLayerUnittestsRegister
void AppLayerUnittestsRegister(void)
Definition: app-layer.c:2912
StatsCounterId
Definition: counters.h:30
APPLAYER_PROTO_DETECTION_SKIPPED
@ APPLAYER_PROTO_DETECTION_SKIPPED
Definition: app-layer-events.h:49
HTPMemuseGlobalCounter
uint64_t HTPMemuseGlobalCounter(void)
Definition: app-layer-htp-mem.c:80
AppLayerCounters_::counter_id
StatsCounterId counter_id
Definition: app-layer.c:90
AppLayerListSupportedProtocols
void AppLayerListSupportedProtocols(void)
Definition: app-layer.c:1021
p
Packet * p
Definition: fuzz_iprep.c:21
AppLayerSetupCounters
void AppLayerSetupCounters(void)
Definition: app-layer.c:1204
ALPROTO_SSH
@ ALPROTO_SSH
Definition: app-layer-protos.h:40
app-layer-ftp.h
ALPROTO_DHCP
@ ALPROTO_DHCP
Definition: app-layer-protos.h:58
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:545
AppLayerThreadCtx_::alproto
AppProto alproto
Definition: app-layer.c:69
stream_config
TcpStreamCnf stream_config
Definition: stream-tcp.c:229
MAX
#define MAX(x, y)
Definition: suricata-common.h:420
Flow_::protoctx
void * protoctx
Definition: flow.h:433
AppLayerCounterNames_::tx_name
char tx_name[MAX_COUNTER_SIZE]
Definition: app-layer.c:81
AppLayerIncAllocErrorCounter
void AppLayerIncAllocErrorCounter(ThreadVars *tv, Flow *f)
Definition: app-layer.c:173
EXCEPTION_POLICY_NOT_SET
@ EXCEPTION_POLICY_NOT_SET
Definition: util-exception-policy-types.h:27
Packet_::payload_len
uint16_t payload_len
Definition: decode.h:619
Packet_::app_layer_events
AppLayerDecoderEvents * app_layer_events
Definition: decode.h:643
util-unittest.h
PACKET_PROFILING_APP_PD_START
#define PACKET_PROFILING_APP_PD_START(dp)
Definition: util-profiling.h:181
AppLayerDeSetup
int AppLayerDeSetup(void)
De initializes the app layer.
Definition: app-layer.c:1101
HostGetMemcap
uint64_t HostGetMemcap(void)
Return memcap value.
Definition: host.c:83
SCAppLayerDecoderEventsSetEventRaw
void SCAppLayerDecoderEventsSetEventRaw(AppLayerDecoderEvents **sevents, uint8_t event)
Set an app layer decoder event.
Definition: app-layer-events.c:96
PKT_PROTO_DETECT_TS_DONE
#define PKT_PROTO_DETECT_TS_DONE
Definition: decode.h:1337
MAX_COUNTER_SIZE
#define MAX_COUNTER_SIZE
Definition: app-layer.c:78
ALPROTO_KRB5
@ ALPROTO_KRB5
Definition: app-layer-protos.h:56
STREAMTCP_FLAG_MIDSTREAM
#define STREAMTCP_FLAG_MIDSTREAM
Definition: stream-tcp-private.h:170
TcpSession_::flags
uint32_t flags
Definition: stream-tcp-private.h:294
FLOW_IS_PM_DONE
#define FLOW_IS_PM_DONE(f, dir)
Definition: flow.h:276
APPLAYER_NO_TLS_AFTER_STARTTLS
@ APPLAYER_NO_TLS_AFTER_STARTTLS
Definition: app-layer-events.h:50
Flow_::alparser
AppLayerParserState * alparser
Definition: flow.h:478
EXCEPTION_POLICY_MAX
#define EXCEPTION_POLICY_MAX
Definition: util-exception-policy-types.h:39
AppLayerParserRegisterProtocolParsers
void AppLayerParserRegisterProtocolParsers(void)
Definition: app-layer-parser.c:1812
AppLayerThreadCtx_::proto_detect_ticks_start
uint64_t proto_detect_ticks_start
Definition: app-layer.c:70
AppLayerSetup
int AppLayerSetup(void)
Setup the app layer.
Definition: app-layer.c:1084
app-layer-expectation.h
app-layer-detect-proto.h
AppLayerProtoDetectThreadCtx_
The app layer protocol detection thread context.
Definition: app-layer-detect-proto.c:179
util-debug.h
AppLayerParserState_
Definition: app-layer-parser.c:135
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
ExceptionPolicyCounters_
Definition: util-exception-policy-types.h:54
APPLAYER_MISMATCH_PROTOCOL_BOTH_DIRECTIONS
@ APPLAYER_MISMATCH_PROTOCOL_BOTH_DIRECTIONS
Definition: app-layer-events.h:46
g_alproto_max
AppProto g_alproto_max
Definition: app-layer-protos.c:30
FLOW_IS_PP_DONE
#define FLOW_IS_PP_DONE(f, dir)
Definition: flow.h:277
AppLayerRegisterGlobalCounters
void AppLayerRegisterGlobalCounters(void)
HACK to work around our broken unix manager (re)init loop.
Definition: app-layer.c:1165
ALPROTO_DNP3
@ ALPROTO_DNP3
Definition: app-layer-protos.h:50
PKT_DROP_REASON_APPLAYER_ERROR
@ PKT_DROP_REASON_APPLAYER_ERROR
Definition: decode.h:390
AppLayerThreadCtx_::ticks_end
uint64_t ticks_end
Definition: app-layer.c:67
AppLayerIncTxCounter
void AppLayerIncTxCounter(ThreadVars *tv, Flow *f, int64_t step)
Definition: app-layer.c:157
PacketSwap
void PacketSwap(Packet *p)
switch direction of a packet
Definition: decode.c:583
util-exception-policy.h
ALPROTO_SMTP
@ ALPROTO_SMTP
Definition: app-layer-protos.h:38
AppProtoRegisterProtoString
void AppProtoRegisterProtoString(AppProto alproto, const char *proto_name)
Definition: app-layer-protos.c:81
HTPByteRangeMemuseGlobalCounter
uint64_t HTPByteRangeMemuseGlobalCounter(void)
Definition: app-layer-htp-range.c:62
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:59
util-print.h
IPPairGetMemcap
uint64_t IPPairGetMemcap(void)
Return memcap value.
Definition: ippair.c:81
SCEnter
#define SCEnter(...)
Definition: util-debug.h:284
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
pkt-var.h
StreamTcpPacket
int StreamTcpPacket(ThreadVars *tv, Packet *p, StreamTcpThread *stt, PacketQueueNoLock *pq)
Definition: stream-tcp.c:5676
AppLayerProtoDetectReset
void AppLayerProtoDetectReset(Flow *f)
Reset proto detect for flow.
Definition: app-layer-detect-proto.c:1894
StatsCounterIncr
void StatsCounterIncr(StatsThreadContext *stats, StatsCounterId id)
Increments the local counter.
Definition: counters.c:164
TcpSession_::state
uint8_t state
Definition: stream-tcp-private.h:285
TEST_START
#define TEST_START
Definition: app-layer.c:1404
ExceptionPolicyStatsSetts_::valid_settings_ids
bool valid_settings_ids[EXCEPTION_POLICY_MAX]
Definition: util-exception-policy-types.h:61
TH_ACK
#define TH_ACK
Definition: decode-tcp.h:38
HostGetMemuse
uint64_t HostGetMemuse(void)
Return memuse value.
Definition: host.c:94
PACKET_PROFILING_APP_STORE
#define PACKET_PROFILING_APP_STORE(dp, p)
Definition: util-profiling.h:206
PrintRawDataFp
void PrintRawDataFp(FILE *fp, const uint8_t *buf, uint32_t buflen)
Definition: util-print.c:112
app-layer-parser.h
FLOW_PROTO_DETECT_TC_DONE
#define FLOW_PROTO_DETECT_TC_DONE
Definition: flow.h:104
AppLayerCounterNames
struct AppLayerCounterNames_ AppLayerCounterNames
util-profiling.h
AppLayerParserSetup
int AppLayerParserSetup(void)
Definition: app-layer-parser.c:259
SCReturn
#define SCReturn
Definition: util-debug.h:286
FLOW_RESET_PM_DONE
#define FLOW_RESET_PM_DONE(f, dir)
Definition: flow.h:284
stream.h
FlowGetProtoMapping
uint8_t FlowGetProtoMapping(uint8_t proto)
Function to map the protocol to the defined FLOW_PROTO_* enumeration.
Definition: flow-util.c:100
StreamTcpIsSetStreamFlagAppProtoDetectionCompleted
#define StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(stream)
Definition: stream-tcp-private.h:303
Packet_
Definition: decode.h:514
ALPROTO_IMAP
@ ALPROTO_IMAP
Definition: app-layer-protos.h:41
stream-tcp-private.h
ALPROTO_RDP
@ ALPROTO_RDP
Definition: app-layer-protos.h:68
FLOW_PROTO_APPLAYER_MAX
#define FLOW_PROTO_APPLAYER_MAX
Definition: flow-private.h:75
applayer_counters
AppLayerCounters(* applayer_counters)[FLOW_PROTO_APPLAYER_MAX]
Definition: app-layer.c:102
AppLayerHandleUdp
int AppLayerHandleUdp(ThreadVars *tv, AppLayerThreadCtx *tctx, Packet *p, Flow *f)
Handle a app layer UDP message.
Definition: app-layer.c:875
DEBUG_ASSERT_FLOW_LOCKED
#define DEBUG_ASSERT_FLOW_LOCKED(f)
Definition: util-validate.h:106
StreamTcpSetStreamFlagAppProtoDetectionCompleted
#define StreamTcpSetStreamFlagAppProtoDetectionCompleted(stream)
Definition: stream-tcp-private.h:301
PACKET_PROFILING_APP_END
#define PACKET_PROFILING_APP_END(dp)
Definition: util-profiling.h:173
TcpStream_::window
uint32_t window
Definition: stream-tcp-private.h:117
ALPROTO_TELNET
@ ALPROTO_TELNET
Definition: app-layer-protos.h:63
ALPROTO_DOH2
@ ALPROTO_DOH2
Definition: app-layer-protos.h:66
SCReturnPtr
#define SCReturnPtr(x, type)
Definition: util-debug.h:300
AppLayerThreadCtx_::alpd_tctx
AppLayerProtoDetectThreadCtx * alpd_tctx
Definition: app-layer.c:61
StreamDataAvailableForProtoDetect
uint32_t StreamDataAvailableForProtoDetect(TcpStream *stream)
Definition: stream-tcp-reassemble.c:717
AppLayerGetCtxThread
AppLayerThreadCtx * AppLayerGetCtxThread(void)
Creates a new app layer thread context.
Definition: app-layer.c:1114
ALPROTO_TFTP
@ ALPROTO_TFTP
Definition: app-layer-protos.h:54
AppLayerThreadCtx_::ticks_start
uint64_t ticks_start
Definition: app-layer.c:66
AppLayerIncParserErrorCounter
void AppLayerIncParserErrorCounter(ThreadVars *tv, Flow *f)
Definition: app-layer.c:181
ALPROTO_HTTP2
@ ALPROTO_HTTP2
Definition: app-layer-protos.h:69
FTPMemcapGlobalCounter
uint64_t FTPMemcapGlobalCounter(void)
Definition: app-layer-ftp.c:85
FLOW_PKT_TOCLIENT
#define FLOW_PKT_TOCLIENT
Definition: flow.h:232
Flow_::alproto_expect
AppProto alproto_expect
Definition: flow.h:459
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:297
TH_PUSH
#define TH_PUSH
Definition: decode-tcp.h:37
app-layer-frames.h
ALPROTO_LLMNR
@ ALPROTO_LLMNR
Definition: app-layer-protos.h:73
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:1316
StreamTcpDisableAppLayer
void StreamTcpDisableAppLayer(Flow *f)
Definition: stream-tcp-reassemble.c:445
suricata-common.h
FLOW_RESET_PE_DONE
#define FLOW_RESET_PE_DONE(f, dir)
Definition: flow.h:286
AppLayerProtoDetectDeSetup
int AppLayerProtoDetectDeSetup(void)
Cleans up the app layer protocol detection phase.
Definition: app-layer-detect-proto.c:1743
ALPROTO_HTTP1
@ ALPROTO_HTTP1
Definition: app-layer-protos.h:36
ALPROTO_PGSQL
@ ALPROTO_PGSQL
Definition: app-layer-protos.h:62
IPPairGetMemuse
uint64_t IPPairGetMemuse(void)
Return memuse value.
Definition: ippair.c:92
Packet_::app_update_direction
uint8_t app_update_direction
Definition: decode.h:548
FLOW_PROTO_DETECT_TS_DONE
#define FLOW_PROTO_DETECT_TS_DONE
Definition: flow.h:103
ALPROTO_FTPDATA
@ ALPROTO_FTPDATA
Definition: app-layer-protos.h:53
AppLayerIncInternalErrorCounter
void AppLayerIncInternalErrorCounter(ThreadVars *tv, Flow *f)
Definition: app-layer.c:189
eps_error_summary
ExceptionPolicyCounters eps_error_summary
Definition: app-layer.c:104
FatalError
#define FatalError(...)
Definition: util-debug.h:517
APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION
@ APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION
Definition: app-layer-events.h:48
STREAMTCP_FLAG_MIDSTREAM_SYNACK
#define STREAMTCP_FLAG_MIDSTREAM_SYNACK
Definition: stream-tcp-private.h:174
applayer_counter_names
AppLayerCounterNames(* applayer_counter_names)[FLOW_PROTO_APPLAYER_MAX]
Definition: app-layer.c:100
ALPROTO_WEBSOCKET
@ ALPROTO_WEBSOCKET
Definition: app-layer-protos.h:64
TcpSession_::client
TcpStream client
Definition: stream-tcp-private.h:297
PKT_PROTO_DETECT_TC_DONE
#define PKT_PROTO_DETECT_TC_DONE
Definition: decode.h:1338
FrameConfigInit
void FrameConfigInit(void)
Definition: app-layer-frames.c:40
AppLayerParserGetStreamDepth
uint32_t AppLayerParserGetStreamDepth(const Flow *f)
Definition: app-layer-parser.c:1604
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:33
app-layer-events.h
util-validate.h
FlowSwap
void FlowSwap(Flow *f)
swap the flow's direction
Definition: flow.c:246
AppLayerProtoDetectSupportedAppProtocols
void AppLayerProtoDetectSupportedAppProtocols(AppProto *alprotos)
Definition: app-layer-detect-proto.c:2141
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:1409
AppLayerProtoDetectGetCtxThread
AppLayerProtoDetectThreadCtx * AppLayerProtoDetectGetCtxThread(void)
Inits and returns an app layer protocol detection thread context.
Definition: app-layer-detect-proto.c:2000
TcpSession_::server
TcpStream server
Definition: stream-tcp-private.h:296
AppLayerProtoDetectGetProtoByName
AppProto AppLayerProtoDetectGetProtoByName(const char *alproto_name)
Definition: app-layer-detect-proto.c:2099
str
#define str(s)
Definition: suricata-common.h:316
SWAP_FLAGS
#define SWAP_FLAGS(flags, a, b)
Definition: suricata-common.h:442
ExceptionPolicyEnumToString
const char * ExceptionPolicyEnumToString(enum ExceptionPolicy policy, bool is_json)
Definition: util-exception-policy.c:39
SCFree
#define SCFree(p)
Definition: util-mem.h:61
AppLayerCounterNames_::gap_error
char gap_error[MAX_COUNTER_SIZE]
Definition: app-layer.c:82
Flow_::alproto_ts
AppProto alproto_ts
Definition: flow.h:451
AppLayerCounters_::alloc_error_id
StatsCounterId alloc_error_id
Definition: app-layer.c:95
ExceptionPolicyStatsSetts_::valid_settings_ips
bool valid_settings_ips[EXCEPTION_POLICY_MAX]
Definition: util-exception-policy-types.h:62
TcpSessionSetReassemblyDepth
void TcpSessionSetReassemblyDepth(TcpSession *ssn, uint32_t size)
Definition: stream-tcp.c:7278
Flow_::alstate
void * alstate
Definition: flow.h:479
AppLayerDestroyCtxThread
void AppLayerDestroyCtxThread(AppLayerThreadCtx *app_tctx)
Destroys the context created by AppLayerGetCtxThread().
Definition: app-layer.c:1135
PACKET_PROFILING_APP_START
#define PACKET_PROFILING_APP_START(dp, id)
Definition: util-profiling.h:167
HTPByteRangeMemcapGlobalCounter
uint64_t HTPByteRangeMemcapGlobalCounter(void)
Definition: app-layer-htp-range.c:56
ALPROTO_MDNS
@ ALPROTO_MDNS
Definition: app-layer-protos.h:72
StatsCounterId::id
uint16_t id
Definition: counters.h:31
HTPMemcapGlobalCounter
uint64_t HTPMemcapGlobalCounter(void)
Definition: app-layer-htp-mem.c:86
ALPROTO_MQTT
@ ALPROTO_MQTT
Definition: app-layer-protos.h:61
AppLayerGetProtoName
const char * AppLayerGetProtoName(AppProto alproto)
Given the internal protocol id, returns a string representation of the protocol.
Definition: app-layer.c:1014
g_applayerparser_error_policy
enum ExceptionPolicy g_applayerparser_error_policy
Definition: app-layer-parser.c:155
ALPROTO_HTTP
@ ALPROTO_HTTP
Definition: app-layer-protos.h:77
AppLayerCounters_::eps_error
ExceptionPolicyCounters eps_error
Definition: app-layer.c:96
stream-tcp-util.h
ALPROTO_UNKNOWN
@ ALPROTO_UNKNOWN
Definition: app-layer-protos.h:29
ALPROTO_FAILED
@ ALPROTO_FAILED
Definition: app-layer-protos.h:33
ALPROTO_TEMPLATE
@ ALPROTO_TEMPLATE
Definition: app-layer-protos.h:67
AppLayerCounterNames_::internal_error
char internal_error[MAX_COUNTER_SIZE]
Definition: app-layer.c:84
TcpReassemblyThreadCtx_
Definition: stream-tcp-reassemble.h:61
SCReturnCT
#define SCReturnCT(x, type)
Definition: util-debug.h:298
app-layer-protos.h
AppLayerProfilingReset
#define AppLayerProfilingReset(app_tctx)
Definition: app-layer.h:127
app-layer-htp-mem.h
EngineModeIsIPS
int EngineModeIsIPS(void)
Definition: suricata.c:246
STREAMTCP_FLAG_APP_LAYER_DISABLED
#define STREAMTCP_FLAG_APP_LAYER_DISABLED
Definition: stream-tcp-private.h:201
STREAMTCP_STREAM_FLAG_NOREASSEMBLY
#define STREAMTCP_STREAM_FLAG_NOREASSEMBLY
Definition: stream-tcp-private.h:219
suricata.h
ALPROTO_RFB
@ ALPROTO_RFB
Definition: app-layer-protos.h:60
TEST_END
#define TEST_END
Definition: app-layer.c:1487
StreamUpdateDir
StreamUpdateDir
Definition: stream-tcp-reassemble.h:54
AppLayerProtoDetectDestroyCtxThread
void AppLayerProtoDetectDestroyCtxThread(AppLayerProtoDetectThreadCtx *alpd_tctx)
Destroys the app layer protocol detection thread context.
Definition: app-layer-detect-proto.c:2053
ALPROTO_BITTORRENT_DHT
@ ALPROTO_BITTORRENT_DHT
Definition: app-layer-protos.h:70
ALPROTO_NTP
@ ALPROTO_NTP
Definition: app-layer-protos.h:52
ALPROTO_SMB
@ ALPROTO_SMB
Definition: app-layer-protos.h:43
AppLayerCounters_::parser_error_id
StatsCounterId parser_error_id
Definition: app-layer.c:93
likely
#define likely(expr)
Definition: util-optimize.h:32
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:60
AppLayerCounterNames_::name
char name[MAX_COUNTER_SIZE]
Definition: app-layer.c:80
FlowChangeProto
int FlowChangeProto(Flow *f)
Check if change proto flag is set for flow.
Definition: flow.c:197
TcpSession_
Definition: stream-tcp-private.h:283
FrameConfigDeInit
void FrameConfigDeInit(void)
Definition: app-layer-frames.c:51
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:452
FLOW_PROTO_CHANGE_MAX_DEPTH
#define FLOW_PROTO_CHANGE_MAX_DEPTH
Definition: app-layer.c:76
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:1497
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:450
ExceptionPolicy
ExceptionPolicy
Definition: util-exception-policy-types.h:26
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
AppLayerCounterNames_::alloc_error
char alloc_error[MAX_COUNTER_SIZE]
Definition: app-layer.c:85
ThreadVars_::stats
StatsThreadContext stats
Definition: threadvars.h:121
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:288
PACKET_PROFILING_APP_RESET
#define PACKET_PROFILING_APP_RESET(dp)
Definition: util-profiling.h:195
StatsCounterAddI64
void StatsCounterAddI64(StatsThreadContext *stats, StatsCounterId id, int64_t x)
Adds a value of type uint64_t to the local counter.
Definition: counters.c:145
APPLAYER_WRONG_DIRECTION_FIRST_DATA
@ APPLAYER_WRONG_DIRECTION_FIRST_DATA
Definition: app-layer-events.h:47
AppLayerDeSetupCounters
void AppLayerDeSetupCounters(void)
Definition: app-layer.c:1390
ExceptionPolicyCounters_::eps_id
StatsCounterId eps_id[EXCEPTION_POLICY_MAX]
Definition: util-exception-policy-types.h:56
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:109
ALPROTO_NFS
@ ALPROTO_NFS
Definition: app-layer-protos.h:51
ExceptionPolicyStatsSetts_::eps_name
char eps_name[EXCEPTION_POLICY_MAX][EXCEPTION_POLICY_COUNTER_MAX_LEN]
Definition: util-exception-policy-types.h:60
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:2124
app-layer.h
Flow_::de_ctx_version
uint32_t de_ctx_version
Definition: flow.h:464