suricata
app-layer.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2021 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 
29 #include "app-layer.h"
30 #include "app-layer-parser.h"
31 #include "app-layer-protos.h"
32 #include "app-layer-expectation.h"
33 #include "app-layer-ftp.h"
34 #include "app-layer-detect-proto.h"
35 #include "stream-tcp-reassemble.h"
36 #include "stream-tcp-private.h"
37 #include "stream-tcp-inline.h"
38 #include "stream-tcp.h"
39 #include "flow.h"
40 #include "flow-util.h"
41 #include "flow-private.h"
42 #include "ippair.h"
43 
44 #include "util-debug.h"
45 #include "util-print.h"
46 #include "util-profiling.h"
47 #include "util-validate.h"
48 #include "decode-events.h"
49 
50 #include "app-layer-htp-mem.h"
51 
52 /**
53  * \brief This is for the app layer in general and it contains per thread
54  * context relevant to both the alpd and alp.
55  */
57  /* App layer protocol detection thread context, from AppLayerProtoDetectGetCtxThread(). */
59  /* App layer parser thread context, from AppLayerParserThreadCtxAlloc(). */
61 
62 #ifdef PROFILING
63  uint64_t ticks_start;
64  uint64_t ticks_end;
65  uint64_t ticks_spent;
70 #endif
71 };
72 
73 #define FLOW_PROTO_CHANGE_MAX_DEPTH 4096
74 
75 #define MAX_COUNTER_SIZE 64
76 typedef struct AppLayerCounterNames_ {
80 
81 typedef struct AppLayerCounters_ {
82  uint16_t counter_id;
83  uint16_t counter_tx_id;
85 
86 /* counter names. Only used at init. */
88 /* counter id's. Used that runtime. */
90 
91 void AppLayerSetupCounters(void);
92 void AppLayerDeSetupCounters(void);
93 
94 /***** L7 layer dispatchers *****/
95 
96 static inline int ProtoDetectDone(const Flow *f, const TcpSession *ssn, uint8_t direction) {
97  const TcpStream *stream = (direction & STREAM_TOSERVER) ? &ssn->client : &ssn->server;
99  (FLOW_IS_PM_DONE(f, direction) && FLOW_IS_PP_DONE(f, direction)));
100 }
101 
102 /**
103  * \note id can be 0 if protocol parser is disabled but detection
104  * is enabled.
105  */
106 static void AppLayerIncFlowCounter(ThreadVars *tv, Flow *f)
107 {
108  const uint16_t id = applayer_counters[f->protomap][f->alproto].counter_id;
109  if (likely(tv && id > 0)) {
110  StatsIncr(tv, id);
111  }
112 }
113 
114 void AppLayerIncTxCounter(ThreadVars *tv, Flow *f, uint64_t step)
115 {
116  const uint16_t id = applayer_counters[f->protomap][f->alproto].counter_tx_id;
117  if (likely(tv && id > 0)) {
118  StatsAddUI64(tv, id, step);
119  }
120 }
121 
122 /* in IDS mode protocol detection is done in reverse order:
123  * when TCP data is ack'd. We want to flag the correct packet,
124  * so in this case we set a flag in the flow so that the first
125  * packet in the correct direction can be tagged.
126  *
127  * For IPS things are much simpler, and we don't use the flow
128  * flag. We just tag the packet directly. */
129 static inline void FlagPacketFlow(Packet *p, Flow *f, uint8_t flags)
130 {
131  if (EngineModeIsIPS()) {
132  if (flags & STREAM_TOSERVER) {
133  if (p->flowflags & FLOW_PKT_TOSERVER) {
135  } else {
137  }
138  } else {
139  if (p->flowflags & FLOW_PKT_TOCLIENT) {
141  } else {
143  }
144  }
145  } else {
146  if (flags & STREAM_TOSERVER) {
148  } else {
150  }
151  }
152 }
153 
154 static void DisableAppLayer(ThreadVars *tv, Flow *f, Packet *p)
155 {
156  SCLogDebug("disable app layer for flow %p alproto %u ts %u tc %u",
157  f, f->alproto, f->alproto_ts, f->alproto_tc);
160  TcpSession *ssn = f->protoctx;
162  f->alproto = ALPROTO_FAILED;
163  AppLayerIncFlowCounter(tv, f);
164 
165  if (f->alproto_tc != ALPROTO_FAILED) {
166  if (f->alproto_tc == ALPROTO_UNKNOWN) {
168  }
169  FlagPacketFlow(p, f, STREAM_TOCLIENT);
170  }
171  if (f->alproto_ts != ALPROTO_FAILED) {
172  if (f->alproto_ts == ALPROTO_UNKNOWN) {
174  }
175  FlagPacketFlow(p, f, STREAM_TOSERVER);
176  }
177  SCLogDebug("disabled app layer for flow %p alproto %u ts %u tc %u",
178  f, f->alproto, f->alproto_ts, f->alproto_tc);
179 }
180 
181 /* See if we're going to have to give up:
182  *
183  * If we're getting a lot of data in one direction and the
184  * proto for this direction is unknown, proto detect will
185  * hold up segments in the segment list in the stream.
186  * They are held so that if we detect the protocol on the
187  * opposing stream, we can still parse this side of the stream
188  * as well. However, some sessions are very unbalanced. FTP
189  * data channels, large PUT/POST request and many others, can
190  * lead to cases where we would have to store many megabytes
191  * worth of segments before we see the opposing stream. This
192  * leads to risks of resource starvation.
193  *
194  * Here a cutoff point is enforced. If we've stored 100k in
195  * one direction and we've seen no data in the other direction,
196  * we give up.
197  *
198  * Giving up means we disable applayer an set an applayer event
199  */
200 static void TCPProtoDetectCheckBailConditions(ThreadVars *tv,
201  Flow *f, TcpSession *ssn, Packet *p)
202 {
203  if (ssn->state < TCP_ESTABLISHED) {
204  SCLogDebug("skip as long as TCP is not ESTABLISHED (TCP fast open)");
205  return;
206  }
207 
208  const uint32_t size_ts = StreamDataAvailableForProtoDetect(&ssn->client);
209  const uint32_t size_tc = StreamDataAvailableForProtoDetect(&ssn->server);
210  SCLogDebug("size_ts %" PRIu32 ", size_tc %" PRIu32, size_ts, size_tc);
211 
212  /* at least 100000 whatever the conditions
213  * and can be more if window is bigger and if configuration allows it */
214  const uint32_t size_tc_limit =
216  const uint32_t size_ts_limit =
218 
219  if (ProtoDetectDone(f, ssn, STREAM_TOSERVER) &&
220  ProtoDetectDone(f, ssn, STREAM_TOCLIENT))
221  {
222  goto failure;
223 
224  /* we bail out whatever the pp and pm states if
225  * we received too much data */
226  } else if (size_tc > 2 * size_tc_limit || size_ts > 2 * size_ts_limit) {
228  goto failure;
229 
231  size_ts > size_ts_limit && size_tc == 0) {
234  goto failure;
235 
237  size_tc > size_tc_limit && size_ts == 0) {
240  goto failure;
241 
242  /* little data in ts direction, pp done, pm not done (max
243  * depth not reached), ts direction done, lots of data in
244  * tc direction. */
245  } else if (size_tc > size_tc_limit && FLOW_IS_PP_DONE(f, STREAM_TOSERVER) &&
250  goto failure;
251 
252  /* little data in tc direction, pp done, pm not done (max
253  * depth not reached), tc direction done, lots of data in
254  * ts direction. */
255  } else if (size_ts > size_ts_limit && FLOW_IS_PP_DONE(f, STREAM_TOCLIENT) &&
260  goto failure;
261  }
262  return;
263 
264 failure:
265  DisableAppLayer(tv, f, p);
266  return;
267 }
268 
269 static int TCPProtoDetectTriggerOpposingSide(ThreadVars *tv,
270  TcpReassemblyThreadCtx *ra_ctx,
271  Packet *p, TcpSession *ssn, TcpStream *stream)
272 {
273  TcpStream *opposing_stream = NULL;
274  if (stream == &ssn->client) {
275  opposing_stream = &ssn->server;
276  } else {
277  opposing_stream = &ssn->client;
278  }
279 
280  /* if the opposing side is not going to work, then
281  * we just have to give up. */
282  if (opposing_stream->flags & STREAMTCP_STREAM_FLAG_NOREASSEMBLY) {
283  SCLogDebug("opposing dir has STREAMTCP_STREAM_FLAG_NOREASSEMBLY set");
284  return -1;
285  }
286 
287  enum StreamUpdateDir dir = StreamTcpInlineMode() ?
290  int ret = StreamTcpReassembleAppLayer(tv, ra_ctx, ssn,
291  opposing_stream, p, dir);
292  return ret;
293 }
294 
295 /** \todo data const
296  * \retval int -1 error
297  * \retval int 0 ok
298  */
299 static int TCPProtoDetect(ThreadVars *tv,
300  TcpReassemblyThreadCtx *ra_ctx, AppLayerThreadCtx *app_tctx,
301  Packet *p, Flow *f, TcpSession *ssn, TcpStream **stream,
302  uint8_t *data, uint32_t data_len, uint8_t flags)
303 {
304  AppProto *alproto;
305  AppProto *alproto_otherdir;
306  int direction = (flags & STREAM_TOSERVER) ? 0 : 1;
307 
308  if (flags & STREAM_TOSERVER) {
309  alproto = &f->alproto_ts;
310  alproto_otherdir = &f->alproto_tc;
311  } else {
312  alproto = &f->alproto_tc;
313  alproto_otherdir = &f->alproto_ts;
314  }
315 
316  SCLogDebug("Stream initializer (len %" PRIu32 ")", data_len);
317 #ifdef PRINT
318  if (data_len > 0) {
319  printf("=> Init Stream Data (app layer) -- start %s%s\n",
320  flags & STREAM_TOCLIENT ? "toclient" : "",
321  flags & STREAM_TOSERVER ? "toserver" : "");
322  PrintRawDataFp(stdout, data, data_len);
323  printf("=> Init Stream Data -- end\n");
324  }
325 #endif
326 
327  bool reverse_flow = false;
328  DEBUG_VALIDATE_BUG_ON(data == NULL && data_len > 0);
330  *alproto = AppLayerProtoDetectGetProto(app_tctx->alpd_tctx,
331  f, data, data_len,
332  IPPROTO_TCP, flags, &reverse_flow);
333  PACKET_PROFILING_APP_PD_END(app_tctx);
334  SCLogDebug("alproto %u rev %s", *alproto, reverse_flow ? "true" : "false");
335 
336  if (*alproto != ALPROTO_UNKNOWN) {
337  if (*alproto_otherdir != ALPROTO_UNKNOWN && *alproto_otherdir != *alproto) {
340 
342  /* if we already invoked the parser, we go with that proto */
343  f->alproto = *alproto_otherdir;
344  } else {
345  /* no data sent to parser yet, we can still choose
346  * we're trusting the server more. */
347  if (flags & STREAM_TOCLIENT)
348  f->alproto = *alproto;
349  else
350  f->alproto = *alproto_otherdir;
351  }
352  } else {
353  f->alproto = *alproto;
354  }
355 
359  FlagPacketFlow(p, f, flags);
360  /* if protocol detection indicated that we need to reverse
361  * the direction of the flow, do it now. We flip the flow,
362  * packet and the direction flags */
363  if (reverse_flow && (ssn->flags & STREAMTCP_FLAG_MIDSTREAM)) {
364  SCLogDebug("reversing flow after proto detect told us so");
365  PacketSwap(p);
366  FlowSwap(f);
368  if (*stream == &ssn->client) {
369  *stream = &ssn->server;
370  } else {
371  *stream = &ssn->client;
372  }
373  direction = 1 - direction;
374  }
375 
376  /* account flow if we have both sides */
377  if (*alproto_otherdir != ALPROTO_UNKNOWN) {
378  AppLayerIncFlowCounter(tv, f);
379  }
380 
381  /* if we have seen data from the other direction first, send
382  * data for that direction first to the parser. This shouldn't
383  * be an issue, since each stream processing happens
384  * independently of the other stream direction. At this point of
385  * call, you need to know that this function's already being
386  * called by the very same StreamReassembly() function that we
387  * will now call shortly for the opposing direction. */
389  !(flags & ssn->data_first_seen_dir))
390  {
391  SCLogDebug("protocol %s needs first data in other direction",
392  AppProtoToString(*alproto));
393 
394  if (TCPProtoDetectTriggerOpposingSide(tv, ra_ctx,
395  p, ssn, *stream) != 0)
396  {
397  DisableAppLayer(tv, f, p);
398  SCReturnInt(-1);
399  }
400  }
401 
402  /* if the parser operates such that it needs to see data from
403  * a particular direction first, we check if we have seen
404  * data from that direction first for the flow. IF it is not
405  * the same, we set an event and exit.
406  *
407  * \todo We need to figure out a more robust solution for this,
408  * as this can lead to easy evasion tactics, where the
409  * attackeer can first send some dummy data in the wrong
410  * direction first to mislead our proto detection process.
411  * While doing this we need to update the parsers as well,
412  * since the parsers must be robust to see such wrong
413  * direction data.
414  * Either ways the moment we see the
415  * APPLAYER_WRONG_DIRECTION_FIRST_DATA event set for the
416  * flow, it shows something's fishy.
417  */
419  uint8_t first_data_dir;
420  first_data_dir = AppLayerParserGetFirstDataDir(f->proto, f->alproto);
421 
422  if (first_data_dir && !(first_data_dir & ssn->data_first_seen_dir)) {
425  DisableAppLayer(tv, f, p);
426  SCReturnInt(-1);
427  }
428  /* This can happen if the current direction is not the
429  * right direction, and the data from the other(also
430  * the right direction) direction is available to be sent
431  * to the app layer, but it is not ack'ed yet and hence
432  * the forced call to STreamTcpAppLayerReassemble still
433  * hasn't managed to send data from the other direction
434  * to the app layer. */
435  if (first_data_dir && !(first_data_dir & flags)) {
441  SCReturnInt(-1);
442  }
443  }
444 
445  /* Set a value that is neither STREAM_TOSERVER, nor STREAM_TOCLIENT */
447 
448  /* finally, invoke the parser */
449  PACKET_PROFILING_APP_START(app_tctx, f->alproto);
450  int r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto,
451  flags, data, data_len);
452  PACKET_PROFILING_APP_END(app_tctx, f->alproto);
453  if (r < 0) {
454  SCReturnInt(-1);
455  } else if (r == 0) {
456  StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
457  }
458  } else {
459  /* if the ssn is midstream, we may end up with a case where the
460  * start of an HTTP request is missing. We won't detect HTTP based
461  * on the request. However, the reply is fine, so we detect
462  * HTTP anyway. This leads to passing the incomplete request to
463  * the htp parser.
464  *
465  * This has been observed, where the http parser then saw many
466  * bogus requests in the incomplete data.
467  *
468  * To counter this case, a midstream session MUST find it's
469  * protocol in the toserver direction. If not, we assume the
470  * start of the request/toserver is incomplete and no reliable
471  * detection and parsing is possible. So we give up.
472  */
473  if ((ssn->flags & STREAMTCP_FLAG_MIDSTREAM) &&
475  {
477  SCLogDebug("midstream end pd %p", ssn);
478  /* midstream and toserver detection failed: give up */
479  DisableAppLayer(tv, f, p);
480  SCReturnInt(0);
481  }
482  }
483 
484  if (*alproto_otherdir != ALPROTO_UNKNOWN) {
485  uint8_t first_data_dir;
486  first_data_dir = AppLayerParserGetFirstDataDir(f->proto, *alproto_otherdir);
487 
488  /* this would handle this test case -
489  * http parser which says it wants to see toserver data first only.
490  * tcp handshake
491  * toclient data first received. - RUBBISH DATA which
492  * we don't detect as http
493  * toserver data next sent - we detect this as http.
494  * at this stage we see that toclient is the first data seen
495  * for this session and we try and redetect the app protocol,
496  * but we are unable to detect the app protocol like before.
497  * But since we have managed to detect the protocol for the
498  * other direction as http, we try to use that. At this
499  * stage we check if the direction of this stream matches
500  * to that acceptable by the app parser. If it is not the
501  * acceptable direction we error out.
502  */
504  (first_data_dir) && !(first_data_dir & flags))
505  {
506  DisableAppLayer(tv, f, p);
507  SCReturnInt(-1);
508  }
509 
510  /* if protocol detection is marked done for our direction we
511  * pass our data on. We're only succeeded in finding one
512  * direction: the opposing stream
513  *
514  * If PD was not yet complete, we don't do anything.
515  */
516  if (FLOW_IS_PM_DONE(f, flags) && FLOW_IS_PP_DONE(f, flags)) {
517  if (data_len > 0)
519 
520  if (*alproto_otherdir != ALPROTO_FAILED) {
521  PACKET_PROFILING_APP_START(app_tctx, f->alproto);
522  int r = AppLayerParserParse(tv, app_tctx->alp_tctx, f,
523  f->alproto, flags,
524  data, data_len);
525  PACKET_PROFILING_APP_END(app_tctx, f->alproto);
526  if (r == 0) {
527  StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
528  }
529 
534 
535  *alproto = *alproto_otherdir;
536  SCLogDebug("packet %"PRIu64": pd done(us %u them %u), parser called (r==%d), APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION set",
537  p->pcap_cnt, *alproto, *alproto_otherdir, r);
538  if (r < 0) {
539  SCReturnInt(-1);
540  }
541  }
542  *alproto = ALPROTO_FAILED;
544  AppLayerIncFlowCounter(tv, f);
545  FlagPacketFlow(p, f, flags);
546 
547  }
548  } else {
549  /* both sides unknown, let's see if we need to give up */
550  if (FlowChangeProto(f)) {
551  /* TCPProtoDetectCheckBailConditions does not work well because
552  * size_tc from STREAM_RIGHT_EDGE is not reset to zero
553  * so, we set a lower limit to the data we inspect
554  * We could instead have set ssn->server.sb.stream_offset = 0;
555  */
556  if (data_len >= FLOW_PROTO_CHANGE_MAX_DEPTH || (flags & STREAM_EOF)) {
557  DisableAppLayer(tv, f, p);
558  }
559  } else {
560  TCPProtoDetectCheckBailConditions(tv, f, ssn, p);
561  }
562  }
563  }
564  SCReturnInt(0);
565 }
566 
567 /** \brief handle TCP data for the app-layer.
568  *
569  * First run protocol detection and then when the protocol is known invoke
570  * the app layer parser.
571  *
572  * \param stream ptr-to-ptr to stream object. Might change if flow dir is
573  * reversed.
574  */
576  Packet *p, Flow *f,
577  TcpSession *ssn, TcpStream **stream,
578  uint8_t *data, uint32_t data_len,
579  uint8_t flags)
580 {
581  SCEnter();
582 
584  DEBUG_VALIDATE_BUG_ON(data_len > (uint32_t)INT_MAX);
585 
586  AppLayerThreadCtx *app_tctx = ra_ctx->app_tctx;
587  AppProto alproto;
588  int r = 0;
589 
590  SCLogDebug("data_len %u flags %02X", data_len, flags);
592  SCLogDebug("STREAMTCP_FLAG_APP_LAYER_DISABLED is set");
593  goto end;
594  }
595 
596  const int direction = (flags & STREAM_TOSERVER) ? 0 : 1;
597 
598  if (flags & STREAM_TOSERVER) {
599  alproto = f->alproto_ts;
600  } else {
601  alproto = f->alproto_tc;
602  }
603 
604  /* If a gap notification, relay the notification on to the
605  * app-layer if known. */
606  if (flags & STREAM_GAP) {
607  if (alproto == ALPROTO_UNKNOWN) {
609  SCLogDebug("ALPROTO_UNKNOWN flow %p, due to GAP in stream start", f);
610  /* if the other side didn't already find the proto, we're done */
611  if (f->alproto == ALPROTO_UNKNOWN) {
612  goto failure;
613  }
614  }
615  if (FlowChangeProto(f)) {
617  SCLogDebug("Cannot handle gap while changing protocol");
618  goto failure;
619  }
620  PACKET_PROFILING_APP_START(app_tctx, f->alproto);
621  r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto,
622  flags, data, data_len);
623  PACKET_PROFILING_APP_END(app_tctx, f->alproto);
624  /* ignore parser result for gap */
625  StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
626  goto end;
627  }
628 
629  /* if we don't know the proto yet and we have received a stream
630  * initializer message, we run proto detection.
631  * We receive 2 stream init msgs (one for each direction) but we
632  * only run the proto detection once. */
633  if (alproto == ALPROTO_UNKNOWN && (flags & STREAM_START)) {
635  /* run protocol detection */
636  if (TCPProtoDetect(tv, ra_ctx, app_tctx, p, f, ssn, stream,
637  data, data_len, flags) != 0) {
638  goto failure;
639  }
640  } else if (alproto != ALPROTO_UNKNOWN && FlowChangeProto(f)) {
641  SCLogDebug("protocol change, old %s", AppProtoToString(f->alproto_orig));
642  void *alstate_orig = f->alstate;
643  AppLayerParserState *alparser = f->alparser;
644  // we delay AppLayerParserStateCleanup because we may need previous parser state
648  /* rerun protocol detection */
649  int rd = TCPProtoDetect(tv, ra_ctx, app_tctx, p, f, ssn, stream, data, data_len, flags);
650  if (f->alproto == ALPROTO_UNKNOWN) {
651  DEBUG_VALIDATE_BUG_ON(alstate_orig != f->alstate);
652  // not enough data, revert AppLayerProtoDetectReset to rerun detection
653  f->alparser = alparser;
654  f->alproto = f->alproto_orig;
655  f->alproto_tc = f->alproto_orig;
656  f->alproto_ts = f->alproto_orig;
657  } else {
659  AppLayerParserStateProtoCleanup(f->protomap, f->alproto_orig, alstate_orig, alparser);
660  if (alstate_orig == f->alstate) {
661  // we just freed it
662  f->alstate = NULL;
663  }
664  }
665  if (rd != 0) {
666  SCLogDebug("proto detect failure");
667  goto failure;
668  }
669  SCLogDebug("protocol change, old %s, new %s",
671 
672  if (f->alproto_expect != ALPROTO_UNKNOWN &&
673  f->alproto != f->alproto_expect)
674  {
677 
678  if (f->alproto_expect == ALPROTO_TLS && f->alproto != ALPROTO_TLS) {
681 
682  }
683  }
684  } else {
685  SCLogDebug("stream data (len %" PRIu32 " alproto "
686  "%"PRIu16" (flow %p)", data_len, f->alproto, f);
687 #ifdef PRINT
688  if (data_len > 0) {
689  printf("=> Stream Data (app layer) -- start %s%s\n",
690  flags & STREAM_TOCLIENT ? "toclient" : "",
691  flags & STREAM_TOSERVER ? "toserver" : "");
692  PrintRawDataFp(stdout, data, data_len);
693  printf("=> Stream Data -- end\n");
694  }
695 #endif
696  /* if we don't have a data object here we are not getting it
697  * a start msg should have gotten us one */
698  if (f->alproto != ALPROTO_UNKNOWN) {
699  PACKET_PROFILING_APP_START(app_tctx, f->alproto);
700  r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, f->alproto,
701  flags, data, data_len);
702  PACKET_PROFILING_APP_END(app_tctx, f->alproto);
703  if (r == 0) {
704  StreamTcpUpdateAppLayerProgress(ssn, direction, data_len);
705  }
706  }
707  }
708 
709  goto end;
710  failure:
711  r = -1;
712  end:
713  SCReturnInt(r);
714 }
715 
716 /**
717  * \brief Handle a app layer UDP message
718  *
719  * If the protocol is yet unknown, the proto detection code is run first.
720  *
721  * \param dp_ctx Thread app layer detect context
722  * \param f *locked* flow
723  * \param p UDP packet
724  *
725  * \retval 0 ok
726  * \retval -1 error
727  */
729 {
730  SCEnter();
731 
732  if (f->alproto == ALPROTO_FAILED) {
733  SCReturnInt(0);
734  }
735 
736  int r = 0;
737  uint8_t flags = 0;
738  if (p->flowflags & FLOW_PKT_TOSERVER) {
740  } else {
742  }
743 
744  AppLayerProfilingReset(tctx);
745 
746  /* if the protocol is still unknown, run detection */
747  if (f->alproto == ALPROTO_UNKNOWN) {
748  SCLogDebug("Detecting AL proto on udp mesg (len %" PRIu32 ")",
749  p->payload_len);
750 
751  bool reverse_flow = false;
754  f, p->payload, p->payload_len,
755  IPPROTO_UDP, flags, &reverse_flow);
757 
758  if (f->alproto != ALPROTO_UNKNOWN) {
759  AppLayerIncFlowCounter(tv, f);
760 
761  if (reverse_flow) {
762  SCLogDebug("reversing flow after proto detect told us so");
763  PacketSwap(p);
764  FlowSwap(f);
766  }
767 
769  r = AppLayerParserParse(tv, tctx->alp_tctx, f, f->alproto,
770  flags, p->payload, p->payload_len);
772  } else {
773  f->alproto = ALPROTO_FAILED;
774  AppLayerIncFlowCounter(tv, f);
775  SCLogDebug("ALPROTO_UNKNOWN flow %p", f);
776  }
778  /* we do only inspection in one direction, so flag both
779  * sides as done here */
780  FlagPacketFlow(p, f, STREAM_TOSERVER);
781  FlagPacketFlow(p, f, STREAM_TOCLIENT);
782  } else {
783  SCLogDebug("data (len %" PRIu32 " ), alproto "
784  "%"PRIu16" (flow %p)", p->payload_len, f->alproto, f);
785 
786  /* run the parser */
788  r = AppLayerParserParse(tv, tctx->alp_tctx, f, f->alproto,
789  flags, p->payload, p->payload_len);
792  }
793 
794  SCReturnInt(r);
795 }
796 
797 /***** Utility *****/
798 
799 AppProto AppLayerGetProtoByName(char *alproto_name)
800 {
801  SCEnter();
803  SCReturnCT(r, "AppProto");
804 }
805 
806 const char *AppLayerGetProtoName(AppProto alproto)
807 {
808  SCEnter();
809  const char * r = AppLayerProtoDetectGetProtoName(alproto);
810  SCReturnCT(r, "char *");
811 }
812 
814 {
815  SCEnter();
816 
817  AppProto alproto;
818  AppProto alprotos[ALPROTO_MAX];
819 
821 
822  printf("=========Supported App Layer Protocols=========\n");
823  for (alproto = 0; alproto < ALPROTO_MAX; alproto++) {
824  if (alprotos[alproto] == 1)
825  printf("%s\n", AppLayerGetProtoName(alproto));
826  }
827 
828  SCReturn;
829 }
830 
831 /***** Setup/General Registration *****/
832 
833 int AppLayerSetup(void)
834 {
835  SCEnter();
836 
839 
842 
844 
845  SCReturnInt(0);
846 }
847 
849 {
850  SCEnter();
851 
854 
856 
857  SCReturnInt(0);
858 }
859 
861 {
862  SCEnter();
863 
864  AppLayerThreadCtx *app_tctx = SCMalloc(sizeof(*app_tctx));
865  if (app_tctx == NULL)
866  goto error;
867  memset(app_tctx, 0, sizeof(*app_tctx));
868 
869  if ((app_tctx->alpd_tctx = AppLayerProtoDetectGetCtxThread()) == NULL)
870  goto error;
871  if ((app_tctx->alp_tctx = AppLayerParserThreadCtxAlloc()) == NULL)
872  goto error;
873 
874  goto done;
875  error:
876  AppLayerDestroyCtxThread(app_tctx);
877  app_tctx = NULL;
878  done:
879  SCReturnPtr(app_tctx, "void *");
880 }
881 
883 {
884  SCEnter();
885 
886  if (app_tctx == NULL)
887  SCReturn;
888 
889  if (app_tctx->alpd_tctx != NULL)
891  if (app_tctx->alp_tctx != NULL)
893  SCFree(app_tctx);
894 
895  SCReturn;
896 }
897 
899 {
900  PACKET_PROFILING_APP_RESET(app_tctx);
901 }
902 
904 {
905  PACKET_PROFILING_APP_STORE(app_tctx, p);
906 }
907 
908 /** \brief HACK to work around our broken unix manager (re)init loop
909  */
911 {
916  StatsRegisterGlobalCounter("app_layer.expectations", ExpectationGetCounter);
917 }
918 
919 #define IPPROTOS_MAX 2
921 {
922  uint8_t ipprotos[] = { IPPROTO_TCP, IPPROTO_UDP };
923  uint8_t ipproto;
924  AppProto alproto;
925  AppProto alprotos[ALPROTO_MAX];
926  const char *str = "app_layer.flow.";
927 
929 
930  for (ipproto = 0; ipproto < IPPROTOS_MAX; ipproto++) {
931  uint8_t ipproto_map = FlowGetProtoMapping(ipprotos[ipproto]);
932  uint8_t other_ipproto = (ipprotos[ipproto] == IPPROTO_TCP) ? IPPROTO_UDP : IPPROTO_TCP;
933  const char *ipproto_suffix = (ipprotos[ipproto] == IPPROTO_TCP) ? "_tcp" : "_udp";
934 
935  for (alproto = 0; alproto < ALPROTO_MAX; alproto++) {
936  if (alprotos[alproto] == 1) {
937  const char *tx_str = "app_layer.tx.";
938  const char *alproto_str = AppLayerGetProtoName(alproto);
939 
940  if (AppLayerParserProtoIsRegistered(ipprotos[ipproto], alproto) &&
941  AppLayerParserProtoIsRegistered(other_ipproto, alproto))
942  {
943  snprintf(applayer_counter_names[ipproto_map][alproto].name,
944  sizeof(applayer_counter_names[ipproto_map][alproto].name),
945  "%s%s%s", str, alproto_str, ipproto_suffix);
946  snprintf(applayer_counter_names[ipproto_map][alproto].tx_name,
947  sizeof(applayer_counter_names[ipproto_map][alproto].tx_name),
948  "%s%s%s", tx_str, alproto_str, ipproto_suffix);
949  } else {
950  snprintf(applayer_counter_names[ipproto_map][alproto].name,
951  sizeof(applayer_counter_names[ipproto_map][alproto].name),
952  "%s%s", str, alproto_str);
953  snprintf(applayer_counter_names[ipproto_map][alproto].tx_name,
954  sizeof(applayer_counter_names[ipproto_map][alproto].tx_name),
955  "%s%s", tx_str, alproto_str);
956  }
957  } else if (alproto == ALPROTO_FAILED) {
958  snprintf(applayer_counter_names[ipproto_map][alproto].name,
959  sizeof(applayer_counter_names[ipproto_map][alproto].name),
960  "%s%s%s", str, "failed", ipproto_suffix);
961  }
962  }
963  }
964 }
965 
967 {
968  uint8_t ipprotos[] = { IPPROTO_TCP, IPPROTO_UDP };
969  uint8_t ipproto;
970  AppProto alproto;
971  AppProto alprotos[ALPROTO_MAX];
972 
974 
975  for (ipproto = 0; ipproto < IPPROTOS_MAX; ipproto++) {
976  uint8_t ipproto_map = FlowGetProtoMapping(ipprotos[ipproto]);
977 
978  for (alproto = 0; alproto < ALPROTO_MAX; alproto++) {
979  if (alprotos[alproto] == 1) {
980  applayer_counters[ipproto_map][alproto].counter_id =
981  StatsRegisterCounter(applayer_counter_names[ipproto_map][alproto].name, tv);
982 
983  applayer_counters[ipproto_map][alproto].counter_tx_id =
984  StatsRegisterCounter(applayer_counter_names[ipproto_map][alproto].tx_name, tv);
985  } else if (alproto == ALPROTO_FAILED) {
986  applayer_counters[ipproto_map][alproto].counter_id =
987  StatsRegisterCounter(applayer_counter_names[ipproto_map][alproto].name, tv);
988  }
989  }
990  }
991 }
992 
994 {
996  memset(applayer_counters, 0, sizeof(applayer_counters));
997 }
998 
999 /***** Unittests *****/
1000 
1001 #ifdef UNITTESTS
1002 #include "pkt-var.h"
1003 #include "stream-tcp.h"
1004 #include "stream-tcp-util.h"
1005 #include "stream.h"
1006 #include "util-unittest.h"
1007 
1008 #define TEST_START \
1009  Packet *p = SCMalloc(SIZE_OF_PACKET); \
1010  FAIL_IF_NULL(p); \
1011  Flow f; \
1012  ThreadVars tv; \
1013  StreamTcpThread *stt = NULL; \
1014  TCPHdr tcph; \
1015  PacketQueueNoLock pq; \
1016  memset(&pq, 0, sizeof(PacketQueueNoLock)); \
1017  memset(p, 0, SIZE_OF_PACKET); \
1018  memset(&f, 0, sizeof(Flow)); \
1019  memset(&tv, 0, sizeof(ThreadVars)); \
1020  memset(&tcph, 0, sizeof(TCPHdr)); \
1021  \
1022  FLOW_INITIALIZE(&f); \
1023  f.flags = FLOW_IPV4; \
1024  f.proto = IPPROTO_TCP; \
1025  p->flow = &f; \
1026  p->tcph = &tcph; \
1027  \
1028  StreamTcpInitConfig(true); \
1029  IPPairInitConfig(true); \
1030  StreamTcpThreadInit(&tv, NULL, (void **)&stt); \
1031  \
1032  /* handshake */ \
1033  tcph.th_win = htons(5480); \
1034  tcph.th_flags = TH_SYN; \
1035  p->flowflags = FLOW_PKT_TOSERVER; \
1036  p->payload_len = 0; \
1037  p->payload = NULL; \
1038  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1); \
1039  TcpSession *ssn = (TcpSession *)f.protoctx; \
1040  \
1041  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); \
1042  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); \
1043  FAIL_IF(f.alproto != ALPROTO_UNKNOWN); \
1044  FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN); \
1045  FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN); \
1046  FAIL_IF(ssn->flags &STREAMTCP_FLAG_APP_LAYER_DISABLED); \
1047  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER)); \
1048  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER)); \
1049  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT)); \
1050  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); \
1051  FAIL_IF(ssn->data_first_seen_dir != 0); \
1052  \
1053  /* handshake */ \
1054  p->tcph->th_ack = htonl(1); \
1055  p->tcph->th_flags = TH_SYN | TH_ACK; \
1056  p->flowflags = FLOW_PKT_TOCLIENT; \
1057  p->payload_len = 0; \
1058  p->payload = NULL; \
1059  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1); \
1060  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); \
1061  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); \
1062  FAIL_IF(f.alproto != ALPROTO_UNKNOWN); \
1063  FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN); \
1064  FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN); \
1065  FAIL_IF(ssn->flags &STREAMTCP_FLAG_APP_LAYER_DISABLED); \
1066  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER)); \
1067  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER)); \
1068  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT)); \
1069  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); \
1070  FAIL_IF(ssn->data_first_seen_dir != 0); \
1071  \
1072  /* handshake */ \
1073  p->tcph->th_ack = htonl(1); \
1074  p->tcph->th_seq = htonl(1); \
1075  p->tcph->th_flags = TH_ACK; \
1076  p->flowflags = FLOW_PKT_TOSERVER; \
1077  p->payload_len = 0; \
1078  p->payload = NULL; \
1079  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1); \
1080  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); \
1081  FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); \
1082  FAIL_IF(f.alproto != ALPROTO_UNKNOWN); \
1083  FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN); \
1084  FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN); \
1085  FAIL_IF(ssn->flags &STREAMTCP_FLAG_APP_LAYER_DISABLED); \
1086  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER)); \
1087  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER)); \
1088  FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT)); \
1089  FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); \
1090  FAIL_IF(ssn->data_first_seen_dir != 0);
1091 #define TEST_END \
1092  StreamTcpSessionClear(p->flow->protoctx); \
1093  StreamTcpThreadDeinit(&tv, (void *)stt); \
1094  StreamTcpFreeConfig(true); \
1095  PACKET_DESTRUCTOR(p); \
1096  SCFree(p); \
1097  FLOW_DESTROY(&f); \
1098  StatsThreadCleanup(&tv);
1099 
1100 /**
1101  * \test GET -> HTTP/1.1
1102  */
1103 static int AppLayerTest01(void)
1104 {
1105  TEST_START;
1106 
1107  /* full request */
1108  uint8_t request[] = {
1109  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1110  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1111  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1112  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1113  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1114  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1115  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1116  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1117  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1118  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1119  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1120  p->tcph->th_ack = htonl(1);
1121  p->tcph->th_seq = htonl(1);
1122  p->tcph->th_flags = TH_PUSH | TH_ACK;
1124  p->payload_len = sizeof(request);
1125  p->payload = request;
1126  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1138 
1139  /* full response - request ack */
1140  uint8_t response[] = {
1141  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
1142  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1143  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1144  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1145  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1146  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1147  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1148  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1149  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1150  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1151  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1152  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1153  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1154  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1155  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1156  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1157  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1158  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1159  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1160  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1161  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1162  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1163  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1164  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1165  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1166  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1167  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1168  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1169  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1170  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1171  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1172  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1173  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1174  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1175  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1176  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1177  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1178  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1179  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1180  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1181  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1182  p->tcph->th_ack = htonl(88);
1183  p->tcph->th_seq = htonl(1);
1184  p->tcph->th_flags = TH_PUSH | TH_ACK;
1186  p->payload_len = sizeof(response);
1187  p->payload = response;
1188  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1200 
1201  /* response ack */
1202  p->tcph->th_ack = htonl(328);
1203  p->tcph->th_seq = htonl(88);
1204  p->tcph->th_flags = TH_ACK;
1206  p->payload_len = 0;
1207  p->payload = NULL;
1208  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1220 
1221  TEST_END;
1222  PASS;
1223 }
1224 
1225 /**
1226  * \test GE -> T -> HTTP/1.1
1227  */
1228 static int AppLayerTest02(void)
1229 {
1230  TEST_START;
1231 
1232  /* partial request */
1233  uint8_t request1[] = { 0x47, 0x45, };
1234  p->tcph->th_ack = htonl(1);
1235  p->tcph->th_seq = htonl(1);
1236  p->tcph->th_flags = TH_PUSH | TH_ACK;
1238  p->payload_len = sizeof(request1);
1239  p->payload = request1;
1240  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1252 
1253  /* response ack against partial request */
1254  p->tcph->th_ack = htonl(3);
1255  p->tcph->th_seq = htonl(1);
1256  p->tcph->th_flags = TH_ACK;
1258  p->payload_len = 0;
1259  p->payload = NULL;
1260  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1272 
1273  /* complete partial request */
1274  uint8_t request2[] = {
1275  0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1276  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1277  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1278  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1279  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1280  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1281  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1282  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1283  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1284  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1285  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1286  p->tcph->th_ack = htonl(1);
1287  p->tcph->th_seq = htonl(3);
1288  p->tcph->th_flags = TH_PUSH | TH_ACK;
1290  p->payload_len = sizeof(request2);
1291  p->payload = request2;
1292  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1304 
1305  /* response - request ack */
1306  uint8_t response[] = {
1307  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
1308  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1309  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1310  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1311  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1312  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1313  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1314  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1315  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1316  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1317  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1318  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1319  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1320  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1321  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1322  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1323  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1324  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1325  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1326  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1327  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1328  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1329  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1330  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1331  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1332  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1333  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1334  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1335  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1336  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1337  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1338  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1339  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1340  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1341  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1342  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1343  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1344  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1345  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1346  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1347  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1348  p->tcph->th_ack = htonl(88);
1349  p->tcph->th_seq = htonl(1);
1350  p->tcph->th_flags = TH_PUSH | TH_ACK;
1352  p->payload_len = sizeof(response);
1353  p->payload = response;
1354  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1366 
1367  /* response ack */
1368  p->tcph->th_ack = htonl(328);
1369  p->tcph->th_seq = htonl(88);
1370  p->tcph->th_flags = TH_ACK;
1372  p->payload_len = 0;
1373  p->payload = NULL;
1374  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1386 
1387  TEST_END;
1388  PASS;
1389 }
1390 
1391 /**
1392  * \test GET -> RUBBISH(PM AND PP DONE IN ONE GO)
1393  */
1394 static int AppLayerTest03(void)
1395 {
1396  TEST_START;
1397 
1398  /* request */
1399  uint8_t request[] = {
1400  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1401  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1402  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1403  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1404  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1405  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1406  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1407  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1408  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1409  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1410  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1411  p->tcph->th_ack = htonl(1);
1412  p->tcph->th_seq = htonl(1);
1413  p->tcph->th_flags = TH_PUSH | TH_ACK;
1415  p->payload_len = sizeof(request);
1416  p->payload = request;
1417  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1429 
1430  /* rubbish response */
1431  uint8_t response[] = {
1432  0x58, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
1433  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1434  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1435  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1436  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1437  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1438  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1439  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1440  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1441  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1442  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1443  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1444  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1445  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1446  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1447  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1448  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1449  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1450  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1451  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1452  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1453  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1454  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1455  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1456  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1457  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1458  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1459  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1460  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1461  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1462  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1463  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1464  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1465  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1466  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1467  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1468  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1469  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1470  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1471  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1472  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1473  p->tcph->th_ack = htonl(88);
1474  p->tcph->th_seq = htonl(1);
1475  p->tcph->th_flags = TH_PUSH | TH_ACK;
1477  p->payload_len = sizeof(response);
1478  p->payload = response;
1479  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1491 
1492  /* response ack */
1493  p->tcph->th_ack = htonl(328);
1494  p->tcph->th_seq = htonl(88);
1495  p->tcph->th_flags = TH_ACK;
1497  p->payload_len = 0;
1498  p->payload = NULL;
1499  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1511 
1512  TEST_END;
1513  PASS;
1514 }
1515 
1516 /**
1517  * \test GE -> RUBBISH(TC - PM AND PP NOT DONE) -> RUBBISH(TC - PM AND PP DONE).
1518  */
1519 static int AppLayerTest04(void)
1520 {
1521  TEST_START;
1522 
1523  /* request */
1524  uint8_t request[] = {
1525  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1526  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1527  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1528  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1529  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1530  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1531  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1532  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1533  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1534  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1535  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1536  PrintRawDataFp(stdout, request, sizeof(request));
1537  p->tcph->th_ack = htonl(1);
1538  p->tcph->th_seq = htonl(1);
1539  p->tcph->th_flags = TH_PUSH | TH_ACK;
1541  p->payload_len = sizeof(request);
1542  p->payload = request;
1543  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1554  FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER); // TOSERVER data now seen
1555 
1556  /* partial response */
1557  uint8_t response1[] = { 0x58, 0x54, 0x54, 0x50, };
1558  PrintRawDataFp(stdout, response1, sizeof(response1));
1559  p->tcph->th_ack = htonl(88);
1560  p->tcph->th_seq = htonl(1);
1561  p->tcph->th_flags = TH_PUSH | TH_ACK;
1563  p->payload_len = sizeof(response1);
1564  p->payload = response1;
1565  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1568  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
1569  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
1576  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
1577 
1578  /* partial response ack */
1579  p->tcph->th_ack = htonl(5);
1580  p->tcph->th_seq = htonl(88);
1581  p->tcph->th_flags = TH_ACK;
1583  p->payload_len = 0;
1584  p->payload = NULL;
1585  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1588  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
1589  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
1595  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
1596  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
1597 
1598  /* remaining response */
1599  uint8_t response2[] = {
1600  0x2f, 0x31, 0x2e, 0x31,
1601  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1602  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1603  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1604  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1605  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1606  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1607  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1608  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1609  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1610  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1611  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1612  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1613  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1614  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1615  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1616  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1617  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1618  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1619  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1620  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1621  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1622  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1623  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1624  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1625  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1626  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1627  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1628  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1629  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1630  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1631  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1632  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1633  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1634  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1635  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1636  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1637  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1638  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1639  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1640  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1641  PrintRawDataFp(stdout, response2, sizeof(response2));
1642  p->tcph->th_ack = htonl(88);
1643  p->tcph->th_seq = htonl(5);
1644  p->tcph->th_flags = TH_PUSH | TH_ACK;
1646  p->payload_len = sizeof(response2);
1647  p->payload = response2;
1648  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1651  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
1652  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
1658  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
1659  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
1660 
1661  /* response ack */
1662  p->tcph->th_ack = htonl(328);
1663  p->tcph->th_seq = htonl(88);
1664  p->tcph->th_flags = TH_ACK;
1666  p->payload_len = 0;
1667  p->payload = NULL;
1668  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1669  FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); // toclient complete (failed)
1671  FAIL_IF(f.alproto != ALPROTO_HTTP1); // http based on ts
1672  FAIL_IF(f.alproto_ts != ALPROTO_HTTP1); // ts complete
1673  FAIL_IF(f.alproto_tc != ALPROTO_FAILED); // tc failed
1678  FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
1679  FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
1680 
1681  TEST_END;
1682  PASS;
1683 }
1684 
1685 /**
1686  * \test RUBBISH -> HTTP/1.1
1687  */
1688 static int AppLayerTest05(void)
1689 {
1690  TEST_START;
1691 
1692  /* full request */
1693  uint8_t request[] = {
1694  0x48, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1695  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1696  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1697  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1698  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1699  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1700  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1701  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1702  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1703  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1704  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1705  PrintRawDataFp(stdout, request, sizeof(request));
1706  p->tcph->th_ack = htonl(1);
1707  p->tcph->th_seq = htonl(1);
1708  p->tcph->th_flags = TH_PUSH | TH_ACK;
1710  p->payload_len = sizeof(request);
1711  p->payload = request;
1712  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1724 
1725  /* full response - request ack */
1726  uint8_t response[] = {
1727  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
1728  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1729  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1730  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1731  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1732  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1733  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1734  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1735  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1736  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1737  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1738  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1739  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1740  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1741  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1742  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1743  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1744  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1745  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1746  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1747  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1748  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1749  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1750  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1751  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1752  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1753  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1754  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1755  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1756  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1757  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1758  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1759  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1760  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1761  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1762  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1763  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1764  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1765  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1766  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1767  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1768  PrintRawDataFp(stdout, response, sizeof(response));
1769  p->tcph->th_ack = htonl(88);
1770  p->tcph->th_seq = htonl(1);
1771  p->tcph->th_flags = TH_PUSH | TH_ACK;
1773  p->payload_len = sizeof(response);
1774  p->payload = response;
1775  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1787 
1788  /* response ack */
1789  p->tcph->th_ack = htonl(328);
1790  p->tcph->th_seq = htonl(88);
1791  p->tcph->th_flags = TH_ACK;
1793  p->payload_len = 0;
1794  p->payload = NULL;
1795  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1807 
1808  TEST_END;
1809  PASS;
1810 }
1811 
1812 /**
1813  * \test HTTP/1.1 -> GET
1814  */
1815 static int AppLayerTest06(void)
1816 {
1817  TEST_START;
1818 
1819  /* full response - request ack */
1820  uint8_t response[] = {
1821  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
1822  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
1823  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
1824  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
1825  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
1826  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
1827  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
1828  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
1829  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1830  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
1831  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
1832  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
1833  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
1834  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
1835  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
1836  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
1837  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
1838  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
1839  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
1840  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
1841  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
1842  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
1843  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
1844  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1845  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
1846  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
1847  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
1848  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
1849  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
1850  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
1851  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
1852  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
1853  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
1854  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
1855  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
1856  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
1857  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
1858  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
1859  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1860  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
1861  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1862  p->tcph->th_ack = htonl(1);
1863  p->tcph->th_seq = htonl(1);
1864  p->tcph->th_flags = TH_PUSH | TH_ACK;
1866  p->payload_len = sizeof(response);
1867  p->payload = response;
1868  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1880 
1881  /* full request - response ack*/
1882  uint8_t request[] = {
1883  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1884  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1885  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1886  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1887  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1888  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1889  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1890  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1891  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1892  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1893  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1894  p->tcph->th_ack = htonl(328);
1895  p->tcph->th_seq = htonl(1);
1896  p->tcph->th_flags = TH_PUSH | TH_ACK;
1898  p->payload_len = sizeof(request);
1899  p->payload = request;
1900  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1912 
1913  p->tcph->th_ack = htonl(1 + sizeof(request));
1914  p->tcph->th_seq = htonl(328);
1915  p->tcph->th_flags = TH_PUSH | TH_ACK;
1917  p->payload_len = 0;
1918  p->payload = NULL;
1919  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1931 
1932  TEST_END;
1933  PASS;
1934 }
1935 
1936 /**
1937  * \test GET -> DCERPC
1938  */
1939 static int AppLayerTest07(void)
1940 {
1941  TEST_START;
1942 
1943  /* full request */
1944  uint8_t request[] = {
1945  0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
1946  0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
1947  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
1948  0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
1949  0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
1950  0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
1951  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
1952  0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
1953  0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
1954  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
1955  0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
1956  p->tcph->th_ack = htonl(1);
1957  p->tcph->th_seq = htonl(1);
1958  p->tcph->th_flags = TH_PUSH | TH_ACK;
1960  p->payload_len = sizeof(request);
1961  p->payload = request;
1962  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
1974 
1975  /* full response - request ack */
1976  uint8_t response[] = { 0x05, 0x00, 0x4d, 0x42, 0x00, 0x01, 0x2e, 0x31, 0x20, 0x32, 0x30, 0x30,
1977  0x20, 0x4f, 0x4b, 0x0d, 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, 0x72, 0x69, 0x2c,
1978  0x20, 0x32, 0x33, 0x20, 0x53, 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20, 0x30, 0x36,
1979  0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, 0x72,
1980  0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
1981  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69, 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f,
1982  0x32, 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65,
1983  0x64, 0x3a, 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34, 0x20, 0x4e, 0x6f, 0x76, 0x20,
1984  0x32, 0x30, 0x31, 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a, 0x34, 0x36, 0x20, 0x47,
1985  0x4d, 0x54, 0x0d, 0x0a, 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61, 0x62, 0x38, 0x39,
1986  0x36, 0x35, 0x2d, 0x32, 0x63, 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61, 0x37, 0x66,
1987  0x37, 0x66, 0x38, 0x30, 0x22, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x52,
1988  0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
1989  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20,
1990  0x34, 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a,
1991  0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
1992  0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d,
1993  0x6c, 0x0d, 0x0a, 0x58, 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64,
1994  0x20, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d, 0x0a, 0x0d,
1995  0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x68,
1996  0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
1997  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
1998  p->tcph->th_ack = htonl(88);
1999  p->tcph->th_seq = htonl(1);
2000  p->tcph->th_flags = TH_PUSH | TH_ACK;
2002  p->payload_len = sizeof(response);
2003  p->payload = response;
2004  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2016 
2017  /* response ack */
2018  p->tcph->th_ack = htonl(328);
2019  p->tcph->th_seq = htonl(88);
2020  p->tcph->th_flags = TH_ACK;
2022  p->payload_len = 0;
2023  p->payload = NULL;
2024  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2036 
2037  TEST_END;
2038  PASS;
2039 }
2040 
2041 /**
2042  * \test SMB -> HTTP/1.1
2043  */
2044 static int AppLayerTest08(void)
2045 {
2046  TEST_START;
2047 
2048  /* full request */
2049  uint8_t request[] = { 0x05, 0x00, 0x54, 0x20, 0x00, 0x01, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68,
2050  0x74, 0x6d, 0x6c, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x0d, 0x0a, 0x48,
2051  0x6f, 0x73, 0x74, 0x3a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x0d,
2052  0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41, 0x70,
2053  0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e, 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2054  0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2055  p->tcph->th_ack = htonl(1);
2056  p->tcph->th_seq = htonl(1);
2057  p->tcph->th_flags = TH_PUSH | TH_ACK;
2059  p->payload_len = sizeof(request);
2060  p->payload = request;
2061  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2073 
2074  /* full response - request ack */
2075  uint8_t response[] = {
2076  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2077  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2078  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2079  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2080  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2081  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2082  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2083  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2084  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2085  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2086  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2087  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2088  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2089  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2090  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2091  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2092  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2093  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2094  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2095  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2096  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2097  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2098  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2099  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2100  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2101  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2102  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2103  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2104  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2105  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2106  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2107  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2108  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2109  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2110  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2111  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2112  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2113  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2114  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2115  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2116  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2117  p->tcph->th_ack = htonl(88);
2118  p->tcph->th_seq = htonl(1);
2119  p->tcph->th_flags = TH_PUSH | TH_ACK;
2121  p->payload_len = sizeof(response);
2122  p->payload = response;
2123  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2135 
2136  /* response ack */
2137  p->tcph->th_ack = htonl(328);
2138  p->tcph->th_seq = htonl(88);
2139  p->tcph->th_flags = TH_ACK;
2141  p->payload_len = 0;
2142  p->payload = NULL;
2143  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2155 
2156  TEST_END;
2157  PASS;
2158 }
2159 
2160 /**
2161  * \test RUBBISH(TC - PM and PP NOT DONE) ->
2162  * RUBBISH(TC - PM and PP DONE) ->
2163  * RUBBISH(TS - PM and PP DONE)
2164  */
2165 static int AppLayerTest09(void)
2166 {
2167  TEST_START;
2168 
2169  /* full request */
2170  uint8_t request1[] = {
2171  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64 };
2172  p->tcph->th_ack = htonl(1);
2173  p->tcph->th_seq = htonl(1);
2174  p->tcph->th_flags = TH_PUSH | TH_ACK;
2176  p->payload_len = sizeof(request1);
2177  p->payload = request1;
2178  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2190 
2191  /* response - request ack */
2192  p->tcph->th_ack = htonl(9);
2193  p->tcph->th_seq = htonl(1);
2194  p->tcph->th_flags = TH_PUSH | TH_ACK;
2196  p->payload_len = 0;
2197  p->payload = NULL;
2198  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2210 
2211  /* full request */
2212  uint8_t request2[] = {
2213  0x44, 0x44, 0x45, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff };
2214  p->tcph->th_ack = htonl(1);
2215  p->tcph->th_seq = htonl(9);
2216  p->tcph->th_flags = TH_PUSH | TH_ACK;
2218  p->payload_len = sizeof(request2);
2219  p->payload = request2;
2220  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2232 
2233  /* full response - request ack */
2234  uint8_t response[] = {
2235  0x55, 0x74, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2236  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2237  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2238  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2239  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2240  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2241  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2242  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2243  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2244  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2245  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2246  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2247  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2248  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2249  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2250  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2251  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2252  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2253  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2254  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2255  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2256  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2257  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2258  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2259  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2260  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2261  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2262  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2263  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2264  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2265  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2266  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2267  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2268  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2269  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2270  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2271  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2272  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2273  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2274  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2275  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2276  p->tcph->th_ack = htonl(18);
2277  p->tcph->th_seq = htonl(1);
2278  p->tcph->th_flags = TH_PUSH | TH_ACK;
2280  p->payload_len = sizeof(response);
2281  p->payload = response;
2282  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2294 
2295  /* response ack */
2296  p->tcph->th_ack = htonl(328);
2297  p->tcph->th_seq = htonl(18);
2298  p->tcph->th_flags = TH_ACK;
2300  p->payload_len = 0;
2301  p->payload = NULL;
2302  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2314 
2315  TEST_END;
2316  PASS;
2317 }
2318 
2319 /**
2320  * \test RUBBISH(TC - PM and PP DONE) ->
2321  * RUBBISH(TS - PM and PP DONE)
2322  */
2323 static int AppLayerTest10(void)
2324 {
2325  TEST_START;
2326 
2327  /* full request */
2328  uint8_t request1[] = {
2329  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2330  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff };
2331  p->tcph->th_ack = htonl(1);
2332  p->tcph->th_seq = htonl(1);
2333  p->tcph->th_flags = TH_PUSH | TH_ACK;
2335  p->payload_len = sizeof(request1);
2336  p->payload = request1;
2337  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2349 
2350  /* response - request ack */
2351  p->tcph->th_ack = htonl(18);
2352  p->tcph->th_seq = htonl(1);
2353  p->tcph->th_flags = TH_PUSH | TH_ACK;
2355  p->payload_len = 0;
2356  p->payload = NULL;
2357  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2369 
2370  /* full response - request ack */
2371  uint8_t response[] = {
2372  0x55, 0x74, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2373  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2374  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2375  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2376  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2377  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2378  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2379  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2380  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2381  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2382  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2383  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2384  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2385  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2386  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2387  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2388  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2389  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2390  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2391  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2392  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2393  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2394  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2395  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2396  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2397  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2398  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2399  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2400  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2401  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2402  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2403  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2404  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2405  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2406  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2407  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2408  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2409  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2410  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2411  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2412  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2413  p->tcph->th_ack = htonl(18);
2414  p->tcph->th_seq = htonl(1);
2415  p->tcph->th_flags = TH_PUSH | TH_ACK;
2417  p->payload_len = sizeof(response);
2418  p->payload = response;
2419  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2431 
2432  /* response ack */
2433  p->tcph->th_ack = htonl(328);
2434  p->tcph->th_seq = htonl(18);
2435  p->tcph->th_flags = TH_ACK;
2437  p->payload_len = 0;
2438  p->payload = NULL;
2439  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2451 
2452  TEST_END;
2453  PASS;
2454 }
2455 
2456 /**
2457  * \test RUBBISH(TC - PM and PP DONE) ->
2458  * RUBBISH(TS - PM and PP NOT DONE) ->
2459  * RUBBISH(TS - PM and PP DONE)
2460  */
2461 static int AppLayerTest11(void)
2462 {
2463  TEST_START;
2464 
2465  /* full request */
2466  uint8_t request1[] = {
2467  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2468  0x47, 0x47, 0x49, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0xff };
2469  p->tcph->th_ack = htonl(1);
2470  p->tcph->th_seq = htonl(1);
2471  p->tcph->th_flags = TH_PUSH | TH_ACK;
2473  p->payload_len = sizeof(request1);
2474  p->payload = request1;
2475  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2487 
2488  /* response - request ack */
2489  p->tcph->th_ack = htonl(18);
2490  p->tcph->th_seq = htonl(1);
2491  p->tcph->th_flags = TH_PUSH | TH_ACK;
2493  p->payload_len = 0;
2494  p->payload = NULL;
2495  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2507 
2508  /* full response - request ack */
2509  uint8_t response1[] = {
2510  0x55, 0x74, 0x54, 0x50, };
2511  p->tcph->th_ack = htonl(18);
2512  p->tcph->th_seq = htonl(1);
2513  p->tcph->th_flags = TH_PUSH | TH_ACK;
2515  p->payload_len = sizeof(response1);
2516  p->payload = response1;
2517  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2529 
2530  /* response ack from request */
2531  p->tcph->th_ack = htonl(5);
2532  p->tcph->th_seq = htonl(18);
2533  p->tcph->th_flags = TH_ACK;
2535  p->payload_len = 0;
2536  p->payload = NULL;
2537  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2549 
2550  uint8_t response2[] = {
2551  0x2f, 0x31, 0x2e, 0x31,
2552  0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2553  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2554  0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2555  0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2556  0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2557  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2558  0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2559  0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2560  0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2561  0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2562  0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2563  0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2564  0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2565  0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2566  0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2567  0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2568  0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2569  0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2570  0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2571  0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2572  0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2573  0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2574  0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2575  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2576  0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2577  0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2578  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2579  0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2580  0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2581  0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2582  0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2583  0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2584  0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2585  0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2586  0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2587  0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2588  0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2589  0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2590  0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2591  0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2592  p->tcph->th_ack = htonl(18);
2593  p->tcph->th_seq = htonl(5);
2594  p->tcph->th_flags = TH_PUSH | TH_ACK;
2596  p->payload_len = sizeof(response2);
2597  p->payload = response2;
2598  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2610 
2611  /* response ack from request */
2612  p->tcph->th_ack = htonl(328);
2613  p->tcph->th_seq = htonl(18);
2614  p->tcph->th_flags = TH_ACK;
2616  p->payload_len = 0;
2617  p->payload = NULL;
2618  FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
2630 
2631  TEST_END;
2632  PASS;
2633 }
2634 
2636 {
2637  SCEnter();
2638 
2639  UtRegisterTest("AppLayerTest01", AppLayerTest01);
2640  UtRegisterTest("AppLayerTest02", AppLayerTest02);
2641  UtRegisterTest("AppLayerTest03", AppLayerTest03);
2642  UtRegisterTest("AppLayerTest04", AppLayerTest04);
2643  UtRegisterTest("AppLayerTest05", AppLayerTest05);
2644  UtRegisterTest("AppLayerTest06", AppLayerTest06);
2645  UtRegisterTest("AppLayerTest07", AppLayerTest07);
2646  UtRegisterTest("AppLayerTest08", AppLayerTest08);
2647  UtRegisterTest("AppLayerTest09", AppLayerTest09);
2648  UtRegisterTest("AppLayerTest10", AppLayerTest10);
2649  UtRegisterTest("AppLayerTest11", AppLayerTest11);
2650 
2651  SCReturn;
2652 }
2653 
2654 #endif /* UNITTESTS */
APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER
#define APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER
Definition: app-layer.h:36
AppLayerCounters_::counter_id
uint16_t counter_id
Definition: app-layer.c:82
FLOW_RESET_PP_DONE
#define FLOW_RESET_PP_DONE(f, dir)
Definition: flow.h:284
UPDATE_DIR_PACKET
@ UPDATE_DIR_PACKET
Definition: stream-tcp-reassemble.h:55
FlowUnsetChangeProtoFlag
void FlowUnsetChangeProtoFlag(Flow *f)
Unset flag to indicate to change proto for the flow.
Definition: flow.c:202
AppLayerParserDeSetup
int AppLayerParserDeSetup(void)
Definition: app-layer-parser.c:241
TcpStream_
Definition: stream-tcp-private.h:94
APPLAYER_MISMATCH_PROTOCOL_BOTH_DIRECTIONS
@ APPLAYER_MISMATCH_PROTOCOL_BOTH_DIRECTIONS
Definition: app-layer-events.h:47
AppLayerCounters_
Definition: app-layer.c:81
ippair.h
FlowCleanupAppLayer
void FlowCleanupAppLayer(Flow *f)
Definition: flow.c:142
AppLayerProtoDetectSetup
int AppLayerProtoDetectSetup(void)
The first function to be called. This initializes a global protocol detection context.
Definition: app-layer-detect-proto.c:1827
ExpectationGetCounter
uint64_t ExpectationGetCounter(void)
Definition: app-layer-expectation.c:141
StatsIncr
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:169
AppLayerCounters_::counter_tx_id
uint16_t counter_tx_id
Definition: app-layer.c:83
AppLayerCounters
struct AppLayerCounters_ AppLayerCounters
stream-tcp-inline.h
ALPROTO_DCERPC
@ ALPROTO_DCERPC
Definition: app-layer-protos.h:38
flow-util.h
applayer_counters
AppLayerCounters applayer_counters[FLOW_PROTO_APPLAYER_MAX][ALPROTO_MAX]
Definition: app-layer.c:89
stream-tcp.h
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
ALPROTO_TLS
@ ALPROTO_TLS
Definition: app-layer-protos.h:33
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
Packet_::pcap_cnt
uint64_t pcap_cnt
Definition: decode.h:572
StatsRegisterGlobalCounter
uint16_t StatsRegisterGlobalCounter(const char *name, uint64_t(*Func)(void))
Registers a counter, which represents a global value.
Definition: counters.c:1000
AppLayerProfilingStoreInternal
void AppLayerProfilingStoreInternal(AppLayerThreadCtx *app_tctx, Packet *p)
Definition: app-layer.c:903
Flow_::proto
uint8_t proto
Definition: flow.h:375
AppProto
uint16_t AppProto
Definition: app-layer-protos.h:77
Packet_::payload
uint8_t * payload
Definition: decode.h:551
StreamTcpInlineMode
int StreamTcpInlineMode(void)
See if stream engine is operating in inline mode.
Definition: stream-tcp.c:6359
TcpReassemblyThreadCtx_::app_tctx
void * app_tctx
Definition: stream-tcp-reassemble.h:61
Packet_::flags
uint32_t flags
Definition: decode.h:449
AppLayerThreadCtx_::proto_detect_ticks_spent
uint64_t proto_detect_ticks_spent
Definition: app-layer.c:69
APPLAYER_WRONG_DIRECTION_FIRST_DATA
@ APPLAYER_WRONG_DIRECTION_FIRST_DATA
Definition: app-layer-events.h:48
PACKET_PROFILING_APP_PD_END
#define PACKET_PROFILING_APP_PD_END(dp)
Definition: util-profiling.h:206
TcpStreamCnf_::reassembly_depth
uint32_t reassembly_depth
Definition: stream-tcp.h:60
AppLayerThreadCtx_::alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: app-layer.c:60
flow-private.h
Flow_
Flow data structure.
Definition: flow.h:353
Flow_::protomap
uint8_t protomap
Definition: flow.h:455
AppProtoToString
const char * AppProtoToString(AppProto alproto)
Maps the ALPROTO_*, to its string equivalent.
Definition: app-layer-protos.c:30
AppLayerThreadCtx_::ticks_spent
uint64_t ticks_spent
Definition: app-layer.c:65
AppLayerParserGetFirstDataDir
uint8_t AppLayerParserGetFirstDataDir(uint8_t ipproto, AppProto alproto)
Definition: app-layer-parser.c:1126
AppLayerParserProtoIsRegistered
int AppLayerParserProtoIsRegistered(uint8_t ipproto, AppProto alproto)
Definition: app-layer-parser.c:186
StreamTcpResetStreamFlagAppProtoDetectionCompleted
#define StreamTcpResetStreamFlagAppProtoDetectionCompleted(stream)
Definition: stream-tcp-private.h:280
AppLayerRegisterThreadCounters
void AppLayerRegisterThreadCounters(ThreadVars *tv)
Registers per flow counters for all protocols.
Definition: app-layer.c:966
Flow_::alproto_orig
AppProto alproto_orig
Definition: flow.h:466
FTPMemuseGlobalCounter
uint64_t FTPMemuseGlobalCounter(void)
Definition: app-layer-ftp.c:169
AppLayerProfilingResetInternal
void AppLayerProfilingResetInternal(AppLayerThreadCtx *app_tctx)
Definition: app-layer.c:898
AppLayerCounterNames_
Definition: app-layer.c:76
AppLayerParserStateProtoCleanup
void AppLayerParserStateProtoCleanup(uint8_t protomap, AppProto alproto, void *alstate, AppLayerParserState *pstate)
Definition: app-layer-parser.c:1489
AppLayerParserThreadCtxFree
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
Definition: app-layer-parser.c:277
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:225
TCP_ESTABLISHED
@ TCP_ESTABLISHED
Definition: stream-tcp-private.h:143
MIN
#define MIN(x, y)
Definition: suricata-common.h:368
StreamTcpUpdateAppLayerProgress
void StreamTcpUpdateAppLayerProgress(TcpSession *ssn, char direction, const uint32_t progress)
update reassembly progress
Definition: stream-tcp.c:5954
stream-tcp-reassemble.h
AppLayerThreadCtx_::proto_detect_ticks_end
uint64_t proto_detect_ticks_end
Definition: app-layer.c:68
TcpStream_::flags
uint16_t flags
Definition: stream-tcp-private.h:95
AppLayerUnittestsRegister
void AppLayerUnittestsRegister(void)
Definition: app-layer.c:2635
HTPMemuseGlobalCounter
uint64_t HTPMemuseGlobalCounter(void)
Definition: app-layer-htp-mem.c:85
AppLayerListSupportedProtocols
void AppLayerListSupportedProtocols(void)
Definition: app-layer.c:813
AppLayerSetupCounters
void AppLayerSetupCounters(void)
Definition: app-layer.c:920
app-layer-ftp.h
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:445
AppLayerThreadCtx_::alproto
AppProto alproto
Definition: app-layer.c:66
stream_config
TcpStreamCnf stream_config
Definition: stream-tcp.c:119
MAX
#define MAX(x, y)
Definition: suricata-common.h:372
ALPROTO_MAX
@ ALPROTO_MAX
Definition: app-layer-protos.h:72
Flow_::protoctx
void * protoctx
Definition: flow.h:451
AppLayerCounterNames_::tx_name
char tx_name[MAX_COUNTER_SIZE]
Definition: app-layer.c:78
Packet_::payload_len
uint16_t payload_len
Definition: decode.h:552
Packet_::app_layer_events
AppLayerDecoderEvents * app_layer_events
Definition: decode.h:578
util-unittest.h
AppLayerGetProtoByName
AppProto AppLayerGetProtoByName(char *alproto_name)
Given a protocol string, returns the corresponding internal protocol id.
Definition: app-layer.c:799
PACKET_PROFILING_APP_PD_START
#define PACKET_PROFILING_APP_PD_START(dp)
Definition: util-profiling.h:201
TcpSession_::flags
uint16_t flags
Definition: stream-tcp-private.h:269
STREAM_START
#define STREAM_START
Definition: stream.h:29
AppLayerDeSetup
int AppLayerDeSetup(void)
De initializes the app layer.
Definition: app-layer.c:848
PKT_PROTO_DETECT_TS_DONE
#define PKT_PROTO_DETECT_TS_DONE
Definition: decode.h:1185
MAX_COUNTER_SIZE
#define MAX_COUNTER_SIZE
Definition: app-layer.c:75
STREAMTCP_FLAG_MIDSTREAM
#define STREAMTCP_FLAG_MIDSTREAM
Definition: stream-tcp-private.h:158
FLOW_IS_PM_DONE
#define FLOW_IS_PM_DONE(f, dir)
Definition: flow.h:275
Flow_::alparser
AppLayerParserState * alparser
Definition: flow.h:485
AppLayerParserRegisterProtocolParsers
void AppLayerParserRegisterProtocolParsers(void)
Definition: app-layer-parser.c:1592
AppLayerThreadCtx_::proto_detect_ticks_start
uint64_t proto_detect_ticks_start
Definition: app-layer.c:67
AppLayerSetup
int AppLayerSetup(void)
Setup the app layer.
Definition: app-layer.c:833
app-layer-expectation.h
app-layer-detect-proto.h
StreamTcpReassembleAppLayer
int StreamTcpReassembleAppLayer(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpSession *ssn, TcpStream *stream, Packet *p, enum StreamUpdateDir dir)
Update the stream reassembly upon receiving a packet.
Definition: stream-tcp-reassemble.c:1216
APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION
@ APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION
Definition: app-layer-events.h:49
AppLayerProtoDetectThreadCtx_
The app layer protocol detection thread context.
Definition: app-layer-detect-proto.c:175
util-debug.h
AppLayerHandleTCPData
int AppLayerHandleTCPData(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, Packet *p, Flow *f, TcpSession *ssn, TcpStream **stream, uint8_t *data, uint32_t data_len, uint8_t flags)
handle TCP data for the app-layer.
Definition: app-layer.c:575
AppLayerParserState_
Definition: app-layer-parser.c:153
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
FLOW_IS_PP_DONE
#define FLOW_IS_PP_DONE(f, dir)
Definition: flow.h:276
AppLayerRegisterGlobalCounters
void AppLayerRegisterGlobalCounters(void)
HACK to work around our broken unix manager (re)init loop.
Definition: app-layer.c:910
AppLayerThreadCtx_::ticks_end
uint64_t ticks_end
Definition: app-layer.c:64
PacketSwap
void PacketSwap(Packet *p)
switch direction of a packet
Definition: decode.c:456
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:56
STREAM_TOSERVER
#define STREAM_TOSERVER
Definition: stream.h:31
util-print.h
APPLAYER_PROTO_DETECTION_SKIPPED
@ APPLAYER_PROTO_DETECTION_SKIPPED
Definition: app-layer-events.h:50
AppLayerGetCtxThread
AppLayerThreadCtx * AppLayerGetCtxThread(ThreadVars *tv)
Creates a new app layer thread context.
Definition: app-layer.c:860
SCEnter
#define SCEnter(...)
Definition: util-debug.h:300
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:4853
IPPROTOS_MAX
#define IPPROTOS_MAX
Definition: app-layer.c:919
AppLayerProtoDetectReset
void AppLayerProtoDetectReset(Flow *f)
Reset proto detect for flow.
Definition: app-layer-detect-proto.c:1968
TcpSession_::state
uint8_t state
Definition: stream-tcp-private.h:262
TEST_START
#define TEST_START
Definition: app-layer.c:1008
APPLAYER_NO_TLS_AFTER_STARTTLS
@ APPLAYER_NO_TLS_AFTER_STARTTLS
Definition: app-layer-events.h:51
TH_ACK
#define TH_ACK
Definition: decode-tcp.h:38
PACKET_PROFILING_APP_STORE
#define PACKET_PROFILING_APP_STORE(dp, p)
Definition: util-profiling.h:226
PrintRawDataFp
void PrintRawDataFp(FILE *fp, const uint8_t *buf, uint32_t buflen)
Definition: util-print.c:141
app-layer-parser.h
FLOW_PROTO_DETECT_TC_DONE
#define FLOW_PROTO_DETECT_TC_DONE
Definition: flow.h:103
AppLayerCounterNames
struct AppLayerCounterNames_ AppLayerCounterNames
util-profiling.h
AppLayerParserSetup
int AppLayerParserSetup(void)
Definition: app-layer-parser.c:217
SCReturn
#define SCReturn
Definition: util-debug.h:302
FLOW_RESET_PM_DONE
#define FLOW_RESET_PM_DONE(f, dir)
Definition: flow.h:283
stream.h
FlowGetProtoMapping
uint8_t FlowGetProtoMapping(uint8_t proto)
Function to map the protocol to the defined FLOW_PROTO_* enumeration.
Definition: flow-util.c:95
StreamTcpIsSetStreamFlagAppProtoDetectionCompleted
#define StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(stream)
Definition: stream-tcp-private.h:278
Packet_
Definition: decode.h:414
stream-tcp-private.h
FLOW_PROTO_APPLAYER_MAX
#define FLOW_PROTO_APPLAYER_MAX
Definition: flow-private.h:79
AppLayerHandleUdp
int AppLayerHandleUdp(ThreadVars *tv, AppLayerThreadCtx *tctx, Packet *p, Flow *f)
Handle a app layer UDP message.
Definition: app-layer.c:728
DEBUG_ASSERT_FLOW_LOCKED
#define DEBUG_ASSERT_FLOW_LOCKED(f)
Definition: util-validate.h:108
StreamTcpSetStreamFlagAppProtoDetectionCompleted
#define StreamTcpSetStreamFlagAppProtoDetectionCompleted(stream)
Definition: stream-tcp-private.h:276
TcpStream_::window
uint32_t window
Definition: stream-tcp-private.h:105
SCReturnPtr
#define SCReturnPtr(x, type)
Definition: util-debug.h:316
AppLayerThreadCtx_::alpd_tctx
AppLayerProtoDetectThreadCtx * alpd_tctx
Definition: app-layer.c:58
StreamDataAvailableForProtoDetect
uint32_t StreamDataAvailableForProtoDetect(TcpStream *stream)
Definition: stream-tcp-reassemble.c:590
STREAM_GAP
#define STREAM_GAP
Definition: stream.h:33
AppLayerThreadCtx_::ticks_start
uint64_t ticks_start
Definition: app-layer.c:63
FTPMemcapGlobalCounter
uint64_t FTPMemcapGlobalCounter(void)
Definition: app-layer-ftp.c:175
FLOW_PKT_TOCLIENT
#define FLOW_PKT_TOCLIENT
Definition: flow.h:226
Flow_::alproto_expect
AppProto alproto_expect
Definition: flow.h:469
decode-events.h
UPDATE_DIR_OPPOSING
@ UPDATE_DIR_OPPOSING
Definition: stream-tcp-reassemble.h:56
AppLayerParserThreadCtxAlloc
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
Definition: app-layer-parser.c:251
TH_PUSH
#define TH_PUSH
Definition: decode-tcp.h:37
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
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:1211
StreamTcpDisableAppLayer
void StreamTcpDisableAppLayer(Flow *f)
Definition: stream-tcp-reassemble.c:337
suricata-common.h
FLOW_RESET_PE_DONE
#define FLOW_RESET_PE_DONE(f, dir)
Definition: flow.h:285
Packet_::tcph
TCPHdr * tcph
Definition: decode.h:531
AppLayerProtoDetectDeSetup
int AppLayerProtoDetectDeSetup(void)
Cleans up the app layer protocol detection phase.
Definition: app-layer-detect-proto.c:1857
ALPROTO_HTTP1
@ ALPROTO_HTTP1
Definition: app-layer-protos.h:30
AppLayerDecoderEventsSetEventRaw
void AppLayerDecoderEventsSetEventRaw(AppLayerDecoderEvents **sevents, uint8_t event)
Set an app layer decoder event.
Definition: app-layer-events.c:89
STREAM_TOCLIENT
#define STREAM_TOCLIENT
Definition: stream.h:32
FLOW_PROTO_DETECT_TS_DONE
#define FLOW_PROTO_DETECT_TS_DONE
Definition: flow.h:102
STREAMTCP_FLAG_MIDSTREAM_SYNACK
#define STREAMTCP_FLAG_MIDSTREAM_SYNACK
Definition: stream-tcp-private.h:162
TcpSession_::client
TcpStream client
Definition: stream-tcp-private.h:272
PKT_PROTO_DETECT_TC_DONE
#define PKT_PROTO_DETECT_TC_DONE
Definition: decode.h:1186
AppLayerParserGetStreamDepth
uint32_t AppLayerParserGetStreamDepth(const Flow *f)
Definition: app-layer-parser.c:1468
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:29
util-validate.h
FlowSwap
void FlowSwap(Flow *f)
swap the flow's direction
Definition: flow.c:261
StatsAddUI64
void StatsAddUI64(ThreadVars *tv, uint16_t id, uint64_t x)
Adds a value of type uint64_t to the local counter.
Definition: counters.c:148
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
AppLayerProtoDetectSupportedAppProtocols
void AppLayerProtoDetectSupportedAppProtocols(AppProto *alprotos)
Definition: app-layer-detect-proto.c:2184
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:1530
AppLayerProtoDetectGetCtxThread
AppLayerProtoDetectThreadCtx * AppLayerProtoDetectGetCtxThread(void)
Inits and returns an app layer protocol detection thread context.
Definition: app-layer-detect-proto.c:2057
TcpSession_::server
TcpStream server
Definition: stream-tcp-private.h:271
AppLayerProtoDetectGetProtoByName
AppProto AppLayerProtoDetectGetProtoByName(const char *alproto_name)
Definition: app-layer-detect-proto.c:2154
str
#define str(s)
Definition: suricata-common.h:268
SWAP_FLAGS
#define SWAP_FLAGS(flags, a, b)
Definition: suricata-common.h:394
SCFree
#define SCFree(p)
Definition: util-mem.h:61
Flow_::alproto_ts
AppProto alproto_ts
Definition: flow.h:461
TcpSessionSetReassemblyDepth
void TcpSessionSetReassemblyDepth(TcpSession *ssn, uint32_t size)
Definition: stream-tcp.c:6365
Flow_::alstate
void * alstate
Definition: flow.h:486
AppLayerDestroyCtxThread
void AppLayerDestroyCtxThread(AppLayerThreadCtx *app_tctx)
Destroys the context created by AppLayeGetCtxThread().
Definition: app-layer.c:882
PACKET_PROFILING_APP_START
#define PACKET_PROFILING_APP_START(dp, id)
Definition: util-profiling.h:186
Flow_::flags
uint32_t flags
Definition: flow.h:431
HTPMemcapGlobalCounter
uint64_t HTPMemcapGlobalCounter(void)
Definition: app-layer-htp-mem.c:91
AppLayerGetProtoName
const char * AppLayerGetProtoName(AppProto alproto)
Given the internal protocol id, returns a string representation of the protocol.
Definition: app-layer.c:806
AppLayerIncTxCounter
void AppLayerIncTxCounter(ThreadVars *tv, Flow *f, uint64_t step)
Definition: app-layer.c:114
stream-tcp-util.h
ALPROTO_UNKNOWN
@ ALPROTO_UNKNOWN
Definition: app-layer-protos.h:29
ALPROTO_FAILED
@ ALPROTO_FAILED
Definition: app-layer-protos.h:67
STREAM_EOF
#define STREAM_EOF
Definition: stream.h:30
TcpReassemblyThreadCtx_
Definition: stream-tcp-reassemble.h:60
SCReturnCT
#define SCReturnCT(x, type)
Definition: util-debug.h:314
app-layer-protos.h
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:188
STREAMTCP_STREAM_FLAG_NOREASSEMBLY
#define STREAMTCP_STREAM_FLAG_NOREASSEMBLY
Definition: stream-tcp-private.h:200
TEST_END
#define TEST_END
Definition: app-layer.c:1091
StreamUpdateDir
StreamUpdateDir
Definition: stream-tcp-reassemble.h:54
PACKET_PROFILING_APP_END
#define PACKET_PROFILING_APP_END(dp, id)
Definition: util-profiling.h:192
AppLayerProtoDetectDestroyCtxThread
void AppLayerProtoDetectDestroyCtxThread(AppLayerProtoDetectThreadCtx *alpd_tctx)
Destroys the app layer protocol detection thread context.
Definition: app-layer-detect-proto.c:2111
likely
#define likely(expr)
Definition: util-optimize.h:32
applayer_counter_names
AppLayerCounterNames applayer_counter_names[FLOW_PROTO_APPLAYER_MAX][ALPROTO_MAX]
Definition: app-layer.c:87
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:85
AppLayerCounterNames_::name
char name[MAX_COUNTER_SIZE]
Definition: app-layer.c:77
FlowChangeProto
int FlowChangeProto(Flow *f)
Check if change proto flag is set for flow.
Definition: flow.c:212
TcpSession_
Definition: stream-tcp-private.h:260
TcpSession_::data_first_seen_dir
int8_t data_first_seen_dir
Definition: stream-tcp-private.h:265
flow.h
Flow_::alproto_tc
AppProto alproto_tc
Definition: flow.h:462
FLOW_PROTO_CHANGE_MAX_DEPTH
#define FLOW_PROTO_CHANGE_MAX_DEPTH
Definition: app-layer.c:73
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:1633
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:460
StatsRegisterCounter
uint16_t StatsRegisterCounter(const char *name, struct ThreadVars_ *tv)
Registers a normal, unqualified counter.
Definition: counters.c:942
APPLAYER_UNEXPECTED_PROTOCOL
@ APPLAYER_UNEXPECTED_PROTOCOL
Definition: app-layer-events.h:52
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:304
PACKET_PROFILING_APP_RESET
#define PACKET_PROFILING_APP_RESET(dp)
Definition: util-profiling.h:215
AppLayerDeSetupCounters
void AppLayerDeSetupCounters(void)
Definition: app-layer.c:993
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:111
STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED
#define STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED
Definition: stream-tcp-private.h:213
AppLayerProtoDetectGetProtoName
const char * AppLayerProtoDetectGetProtoName(AppProto alproto)
Definition: app-layer-detect-proto.c:2179
app-layer.h