suricata
app-layer-parser.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  *
23  * Generic App-layer parsing functions.
24  */
25 
26 #include "suricata-common.h"
27 #include "app-layer-parser.h"
28 
29 #include "flow.h"
30 #include "flow-private.h"
31 #include "flow-util.h"
32 
33 #include "app-layer-frames.h"
34 
35 #include "stream-tcp.h"
36 
37 #include "util-validate.h"
38 
39 #include "app-layer.h"
40 #include "app-layer-detect-proto.h"
41 
42 #include "app-layer-ftp.h"
43 #include "app-layer-smtp.h"
44 
45 #include "app-layer-smb.h"
46 #include "app-layer-htp.h"
47 #include "app-layer-ssl.h"
48 #include "app-layer-ssh.h"
49 #include "app-layer-modbus.h"
50 #include "app-layer-enip.h"
51 #include "app-layer-dnp3.h"
52 #include "app-layer-nfs-tcp.h"
53 #include "app-layer-nfs-udp.h"
54 #include "app-layer-ntp.h"
55 #include "app-layer-tftp.h"
56 #include "app-layer-ike.h"
57 #include "app-layer-krb5.h"
58 #include "app-layer-sip.h"
59 #include "app-layer-rfb.h"
60 #include "app-layer-mqtt.h"
61 #include "app-layer-snmp.h"
62 #include "app-layer-quic.h"
63 #include "app-layer-rdp.h"
64 #include "app-layer-http2.h"
65 
68 };
69 
70 
71 /**
72  * \brief App layer protocol parser context.
73  */
75 {
76  /* 0 - to_server, 1 - to_client. */
78 
79  bool logger;
80 
81  /* Indicates the direction the parser is ready to see the data
82  * the first time for a flow. Values accepted -
83  * STREAM_TOSERVER, STREAM_TOCLIENT */
84  uint8_t first_data_dir;
85 
86  uint32_t logger_bits; /**< registered loggers for this proto */
87 
88  void *(*StateAlloc)(void *, AppProto);
89  void (*StateFree)(void *);
90  void (*StateTransactionFree)(void *, uint64_t);
91  void *(*LocalStorageAlloc)(void);
92  void (*LocalStorageFree)(void *);
93 
94  void (*Truncate)(void *, uint8_t);
95 
96  /** get FileContainer reference from the TX. MUST return a non-NULL reference if the TX
97  * has or may have files in the requested direction at some point. */
98  AppLayerGetFileState (*GetTxFiles)(void *, void *, uint8_t);
99 
100  int (*StateGetProgress)(void *alstate, uint8_t direction);
101  uint64_t (*StateGetTxCnt)(void *alstate);
102  void *(*StateGetTx)(void *alstate, uint64_t tx_id);
106  int (*StateGetEventInfoById)(int event_id, const char **event_name,
107  AppLayerEventType *event_type);
108  int (*StateGetEventInfo)(const char *event_name,
109  int *event_id, AppLayerEventType *event_type);
110 
111  AppLayerStateData *(*GetStateData)(void *state);
112  AppLayerTxData *(*GetTxData)(void *tx);
113  bool (*ApplyTxConfig)(void *state, void *tx, int mode, AppLayerTxConfig);
114 
115  void (*SetStreamDepthFlag)(void *tx, uint8_t flags);
116 
119 
120  /* each app-layer has its own value */
121  uint32_t stream_depth;
122 
123  /* Option flags such as supporting gaps or not. */
124  uint32_t option_flags;
125  /* coccinelle: AppLayerParserProtoCtx:option_flags:APP_LAYER_PARSER_OPT_ */
126 
127  uint32_t internal_flags;
128  /* coccinelle: AppLayerParserProtoCtx:internal_flags:APP_LAYER_PARSER_INT_ */
129 
130 #ifdef UNITTESTS
131  void (*RegisterUnittests)(void);
132 #endif
134 
135 typedef struct AppLayerParserCtx_ {
138 
140  /* coccinelle: AppLayerParserState:flags:APP_LAYER_PARSER_ */
141  uint16_t flags;
142 
143  /* Indicates the current transaction that is being inspected.
144  * We have a var per direction. */
145  uint64_t inspect_id[2];
146  /* Indicates the current transaction being logged. Unlike inspect_id,
147  * we don't need a var per direction since we don't log a transaction
148  * unless we have the entire transaction. */
149  uint64_t log_id;
150 
151  uint64_t min_id;
152 
153  /* Used to store decoder events. */
155 
157 };
158 
160 
161 static void AppLayerConfg(void)
162 {
163  g_applayerparser_error_policy = ExceptionPolicyParse("app-layer.error-policy", true);
164 }
165 
166 static void AppLayerParserFramesFreeContainer(FramesContainer *frames)
167 {
168  if (frames != NULL) {
169  FramesFree(&frames->toserver);
170  FramesFree(&frames->toclient);
171  SCFree(frames);
172  }
173 }
174 
176 {
177  if (f == NULL || f->alparser == NULL || f->alparser->frames == NULL)
178  return;
179  AppLayerParserFramesFreeContainer(f->alparser->frames);
180  f->alparser->frames = NULL;
181 }
182 
184 {
185  if (f == NULL || f->alparser == NULL)
186  return NULL;
187  return f->alparser->frames;
188 }
189 
191 {
192 #ifdef UNITTESTS
193  if (f == NULL || f->alparser == NULL || (f->proto == IPPROTO_TCP && f->protoctx == NULL))
194  return NULL;
195 #endif
196  DEBUG_VALIDATE_BUG_ON(f == NULL || f->alparser == NULL);
197  if (f->alparser->frames == NULL) {
198  f->alparser->frames = SCCalloc(1, sizeof(FramesContainer));
199  if (f->alparser->frames == NULL) {
200  return NULL;
201  }
202 #ifdef DEBUG
203  f->alparser->frames->toserver.ipproto = f->proto;
204  f->alparser->frames->toserver.alproto = f->alproto;
205  f->alparser->frames->toclient.ipproto = f->proto;
206  f->alparser->frames->toclient.alproto = f->alproto;
207 #endif
208  }
209  return f->alparser->frames;
210 }
211 
212 static inline void AppLayerParserStreamTruncated(AppLayerParserState *pstate, const uint8_t ipproto,
213  const AppProto alproto, void *alstate, const uint8_t direction);
214 
215 #ifdef UNITTESTS
216 void UTHAppLayerParserStateGetIds(void *ptr, uint64_t *i1, uint64_t *i2, uint64_t *log, uint64_t *min)
217 {
218  struct AppLayerParserState_ *s = ptr;
219  *i1 = s->inspect_id[0];
220  *i2 = s->inspect_id[1];
221  *log = s->log_id;
222  *min = s->min_id;
223 }
224 #endif
225 
226 /* Static global version of the parser context.
227  * Post 2.0 let's look at changing this to move it out to app-layer.c. */
228 static AppLayerParserCtx alp_ctx;
229 
230 int AppLayerParserProtoIsRegistered(uint8_t ipproto, AppProto alproto)
231 {
232  uint8_t ipproto_map = FlowGetProtoMapping(ipproto);
233 
234  return (alp_ctx.ctxs[ipproto_map][alproto].StateAlloc != NULL) ? 1 : 0;
235 }
236 
238 {
239  SCEnter();
240 
241  AppLayerParserState *pstate = (AppLayerParserState *)SCMalloc(sizeof(*pstate));
242  if (pstate == NULL)
243  goto end;
244  memset(pstate, 0, sizeof(*pstate));
245 
246  end:
247  SCReturnPtr(pstate, "AppLayerParserState");
248 }
249 
251 {
252  SCEnter();
253 
254  if (pstate->decoder_events != NULL)
256  AppLayerParserFramesFreeContainer(pstate->frames);
257  SCFree(pstate);
258 
259  SCReturn;
260 }
261 
263 {
264  SCEnter();
265  memset(&alp_ctx, 0, sizeof(alp_ctx));
266  SCReturnInt(0);
267 }
268 
270 {
271  /* lets set a default value for stream_depth */
272  for (int flow_proto = 0; flow_proto < FLOW_PROTO_DEFAULT; flow_proto++) {
273  for (AppProto alproto = 0; alproto < ALPROTO_MAX; alproto++) {
274  if (!(alp_ctx.ctxs[flow_proto][alproto].internal_flags &
276  alp_ctx.ctxs[flow_proto][alproto].stream_depth =
278  }
279  }
280  }
281 }
282 
284 {
285  SCEnter();
286 
289 
290  SCReturnInt(0);
291 }
292 
294 {
295  SCEnter();
296 
297  AppLayerParserThreadCtx *tctx = SCCalloc(1, sizeof(*tctx));
298  if (tctx == NULL)
299  goto end;
300 
301  for (uint8_t flow_proto = 0; flow_proto < FLOW_PROTO_DEFAULT; flow_proto++) {
302  for (AppProto alproto = 0; alproto < ALPROTO_MAX; alproto++) {
303  uint8_t ipproto = FlowGetReverseProtoMapping(flow_proto);
304 
305  tctx->alproto_local_storage[flow_proto][alproto] =
307  }
308  }
309 
310  end:
311  SCReturnPtr(tctx, "void *");
312 }
313 
315 {
316  SCEnter();
317 
318  for (uint8_t flow_proto = 0; flow_proto < FLOW_PROTO_DEFAULT; flow_proto++) {
319  for (AppProto alproto = 0; alproto < ALPROTO_MAX; alproto++) {
320  uint8_t ipproto = FlowGetReverseProtoMapping(flow_proto);
321 
323  tctx->alproto_local_storage[flow_proto][alproto]);
324  }
325  }
326 
327  SCFree(tctx);
328  SCReturn;
329 }
330 
331 /** \brief check if a parser is enabled in the config
332  * Returns enabled always if: were running unittests
333  */
334 int AppLayerParserConfParserEnabled(const char *ipproto,
335  const char *alproto_name)
336 {
337  SCEnter();
338 
339  int enabled = 1;
340  char param[100];
341  ConfNode *node;
342  int r;
343 
344  if (RunmodeIsUnittests())
345  goto enabled;
346 
347  r = snprintf(param, sizeof(param), "%s%s%s", "app-layer.protocols.",
348  alproto_name, ".enabled");
349  if (r < 0) {
350  FatalError("snprintf failure.");
351  } else if (r > (int)sizeof(param)) {
352  FatalError("buffer not big enough to write param.");
353  }
354 
355  node = ConfGetNode(param);
356  if (node == NULL) {
357  SCLogDebug("Entry for %s not found.", param);
358  r = snprintf(param, sizeof(param), "%s%s%s%s%s", "app-layer.protocols.",
359  alproto_name, ".", ipproto, ".enabled");
360  if (r < 0) {
361  FatalError("snprintf failure.");
362  } else if (r > (int)sizeof(param)) {
363  FatalError("buffer not big enough to write param.");
364  }
365 
366  node = ConfGetNode(param);
367  if (node == NULL) {
368  SCLogDebug("Entry for %s not found.", param);
369  goto enabled;
370  }
371  }
372 
373  if (ConfValIsTrue(node->val)) {
374  goto enabled;
375  } else if (ConfValIsFalse(node->val)) {
376  goto disabled;
377  } else if (strcasecmp(node->val, "detection-only") == 0) {
378  goto disabled;
379  } else {
380  SCLogError("Invalid value found for %s.", param);
381  exit(EXIT_FAILURE);
382  }
383 
384  disabled:
385  enabled = 0;
386  enabled:
387  SCReturnInt(enabled);
388 }
389 
390 /***** Parser related registration *****/
391 
392 int AppLayerParserRegisterParser(uint8_t ipproto, AppProto alproto,
393  uint8_t direction,
394  AppLayerParserFPtr Parser)
395 {
396  SCEnter();
397 
398  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
399  Parser[(direction & STREAM_TOSERVER) ? 0 : 1] = Parser;
400 
401  SCReturnInt(0);
402 }
403 
405  uint8_t direction)
406 {
407  SCEnter();
408 
409  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].first_data_dir |=
410  (direction & (STREAM_TOSERVER | STREAM_TOCLIENT));
411 
412  SCReturn;
413 }
414 
415 void AppLayerParserRegisterOptionFlags(uint8_t ipproto, AppProto alproto,
416  uint32_t flags)
417 {
418  SCEnter();
419 
420  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].option_flags |= flags;
421 
422  SCReturn;
423 }
424 
425 uint32_t AppLayerParserGetOptionFlags(uint8_t protomap, AppProto alproto)
426 {
427  SCEnter();
428  SCReturnUInt(alp_ctx.ctxs[protomap][alproto].option_flags);
429 }
430 
431 void AppLayerParserRegisterStateFuncs(uint8_t ipproto, AppProto alproto,
432  void *(*StateAlloc)(void *, AppProto), void (*StateFree)(void *))
433 {
434  SCEnter();
435 
436  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateAlloc =
437  StateAlloc;
438  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateFree =
439  StateFree;
440 
441  SCReturn;
442 }
443 
444 void AppLayerParserRegisterLocalStorageFunc(uint8_t ipproto, AppProto alproto,
445  void *(*LocalStorageAlloc)(void),
446  void (*LocalStorageFree)(void *))
447 {
448  SCEnter();
449 
450  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].LocalStorageAlloc =
451  LocalStorageAlloc;
452  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].LocalStorageFree =
453  LocalStorageFree;
454 
455  SCReturn;
456 }
457 
458 void AppLayerParserRegisterGetTxFilesFunc(uint8_t ipproto, AppProto alproto,
459  AppLayerGetFileState (*GetTxFiles)(void *, void *, uint8_t))
460 {
461  SCEnter();
462 
463  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetTxFiles = GetTxFiles;
464 
465  SCReturn;
466 }
467 
468 void AppLayerParserRegisterLoggerBits(uint8_t ipproto, AppProto alproto, LoggerId bits)
469 {
470  SCEnter();
471 
472  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].logger_bits = bits;
473 
474  SCReturn;
475 }
476 
477 void AppLayerParserRegisterLogger(uint8_t ipproto, AppProto alproto)
478 {
479  SCEnter();
480 
481  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].logger = true;
482 
483  SCReturn;
484 }
485 
486 void AppLayerParserRegisterTruncateFunc(uint8_t ipproto, AppProto alproto,
487  void (*Truncate)(void *, uint8_t))
488 {
489  SCEnter();
490 
491  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].Truncate = Truncate;
492 
493  SCReturn;
494 }
495 
497  int (*StateGetProgress)(void *alstate, uint8_t direction))
498 {
499  SCEnter();
500 
501  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
502  StateGetProgress = StateGetProgress;
503 
504  SCReturn;
505 }
506 
507 void AppLayerParserRegisterTxFreeFunc(uint8_t ipproto, AppProto alproto,
508  void (*StateTransactionFree)(void *, uint64_t))
509 {
510  SCEnter();
511 
512  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
513  StateTransactionFree = StateTransactionFree;
514 
515  SCReturn;
516 }
517 
518 void AppLayerParserRegisterGetTxCnt(uint8_t ipproto, AppProto alproto,
519  uint64_t (*StateGetTxCnt)(void *alstate))
520 {
521  SCEnter();
522 
523  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
524  StateGetTxCnt = StateGetTxCnt;
525 
526  SCReturn;
527 }
528 
529 void AppLayerParserRegisterGetTx(uint8_t ipproto, AppProto alproto,
530  void *(StateGetTx)(void *alstate, uint64_t tx_id))
531 {
532  SCEnter();
533 
534  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
535  StateGetTx = StateGetTx;
536 
537  SCReturn;
538 }
539 
540 void AppLayerParserRegisterGetTxIterator(uint8_t ipproto, AppProto alproto,
542 {
543  SCEnter();
544  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateGetTxIterator = Func;
545  SCReturn;
546 }
547 
549  AppProto alproto, const int ts, const int tc)
550 {
551  BUG_ON(ts == 0);
552  BUG_ON(tc == 0);
553  BUG_ON(!AppProtoIsValid(alproto));
554  BUG_ON(alp_ctx.ctxs[FLOW_PROTO_DEFAULT][alproto].complete_ts != 0 &&
555  alp_ctx.ctxs[FLOW_PROTO_DEFAULT][alproto].complete_ts != ts);
556  BUG_ON(alp_ctx.ctxs[FLOW_PROTO_DEFAULT][alproto].complete_tc != 0 &&
557  alp_ctx.ctxs[FLOW_PROTO_DEFAULT][alproto].complete_tc != tc);
558 
559  alp_ctx.ctxs[FLOW_PROTO_DEFAULT][alproto].complete_ts = ts;
560  alp_ctx.ctxs[FLOW_PROTO_DEFAULT][alproto].complete_tc = tc;
561 }
562 
563 void AppLayerParserRegisterGetEventInfoById(uint8_t ipproto, AppProto alproto,
564  int (*StateGetEventInfoById)(int event_id, const char **event_name,
565  AppLayerEventType *event_type))
566 {
567  SCEnter();
568 
569  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
570  StateGetEventInfoById = StateGetEventInfoById;
571 
572  SCReturn;
573 }
574 
575 void AppLayerParserRegisterGetFrameFuncs(uint8_t ipproto, AppProto alproto,
576  AppLayerParserGetFrameIdByNameFn GetIdByNameFunc,
577  AppLayerParserGetFrameNameByIdFn GetNameByIdFunc)
578 {
579  SCEnter();
580  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetFrameIdByName = GetIdByNameFunc;
581  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetFrameNameById = GetNameByIdFunc;
582  SCReturn;
583 }
584 
585 void AppLayerParserRegisterGetEventInfo(uint8_t ipproto, AppProto alproto,
586  int (*StateGetEventInfo)(const char *event_name, int *event_id,
587  AppLayerEventType *event_type))
588 {
589  SCEnter();
590 
591  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
592  StateGetEventInfo = StateGetEventInfo;
593 
594  SCReturn;
595 }
596 
597 void AppLayerParserRegisterTxDataFunc(uint8_t ipproto, AppProto alproto,
598  AppLayerTxData *(*GetTxData)(void *tx))
599 {
600  SCEnter();
601 
602  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetTxData = GetTxData;
603 
604  SCReturn;
605 }
606 
608  uint8_t ipproto, AppProto alproto, AppLayerStateData *(*GetStateData)(void *state))
609 {
610  SCEnter();
611 
612  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetStateData = GetStateData;
613 
614  SCReturn;
615 }
616 
617 void AppLayerParserRegisterApplyTxConfigFunc(uint8_t ipproto, AppProto alproto,
618  bool (*ApplyTxConfig)(void *state, void *tx, int mode, AppLayerTxConfig))
619 {
620  SCEnter();
621 
622  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].ApplyTxConfig = ApplyTxConfig;
623 
624  SCReturn;
625 }
626 
628  void (*SetStreamDepthFlag)(void *tx, uint8_t flags))
629 {
630  SCEnter();
631 
632  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].SetStreamDepthFlag = SetStreamDepthFlag;
633 
634  SCReturn;
635 }
636 
637 /***** Get and transaction functions *****/
638 
640 {
641  SCEnter();
642  void * r = NULL;
643 
644  if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
645  LocalStorageAlloc != NULL)
646  {
647  r = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
648  LocalStorageAlloc();
649  }
650 
651  SCReturnPtr(r, "void *");
652 }
653 
655  void *local_data)
656 {
657  SCEnter();
658 
659  if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
660  LocalStorageFree != NULL)
661  {
662  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
663  LocalStorageFree(local_data);
664  }
665 
666  SCReturn;
667 }
668 
669 /** \brief default tx iterator
670  *
671  * Used if the app layer parser doesn't register its own iterator.
672  * Simply walks the tx_id space until it finds a tx. Uses 'state' to
673  * keep track of where it left off.
674  *
675  * \retval txptr or NULL if no more txs in list
676  */
677 static AppLayerGetTxIterTuple AppLayerDefaultGetTxIterator(
678  const uint8_t ipproto, const AppProto alproto,
679  void *alstate, uint64_t min_tx_id, uint64_t max_tx_id,
680  AppLayerGetTxIterState *state)
681 {
682  uint64_t ustate = *(uint64_t *)state;
683  uint64_t tx_id = MAX(min_tx_id, ustate);
684  for ( ; tx_id < max_tx_id; tx_id++) {
685  void *tx_ptr = AppLayerParserGetTx(ipproto, alproto, alstate, tx_id);
686  if (tx_ptr != NULL) {
687  ustate = tx_id + 1;
688  *state = *(AppLayerGetTxIterState *)&ustate;
689  AppLayerGetTxIterTuple tuple = {
690  .tx_ptr = tx_ptr,
691  .tx_id = tx_id,
692  .has_next = (tx_id + 1 < max_tx_id),
693  };
694  SCLogDebug("tuple: %p/%"PRIu64"/%s", tuple.tx_ptr, tuple.tx_id,
695  tuple.has_next ? "true" : "false");
696  return tuple;
697  }
698  }
699 
700  AppLayerGetTxIterTuple no_tuple = { NULL, 0, false };
701  return no_tuple;
702 }
703 
705  const AppProto alproto)
706 {
708  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateGetTxIterator;
709  return Func ? Func : AppLayerDefaultGetTxIterator;
710 }
711 
713 {
714  SCEnter();
715 
716  SCReturnCT((pstate == NULL) ? 0 : pstate->log_id, "uint64_t");
717 }
718 
720 {
721  SCEnter();
722 
723  if (pstate != NULL)
724  pstate->log_id = tx_id;
725 
726  SCReturn;
727 }
728 
729 uint64_t AppLayerParserGetTransactionInspectId(AppLayerParserState *pstate, uint8_t direction)
730 {
731  SCEnter();
732 
733  if (pstate == NULL)
734  SCReturnCT(0ULL, "uint64_t");
735 
736  SCReturnCT(pstate->inspect_id[(direction & STREAM_TOSERVER) ? 0 : 1], "uint64_t");
737 }
738 
739 static inline uint64_t GetTxDetectFlags(AppLayerTxData *txd, const uint8_t dir)
740 {
741  uint64_t detect_flags =
742  (dir & STREAM_TOSERVER) ? txd->detect_flags_ts : txd->detect_flags_tc;
743  return detect_flags;
744 }
745 
746 static inline void SetTxDetectFlags(AppLayerTxData *txd, const uint8_t dir, const uint64_t detect_flags)
747 {
748  if (dir & STREAM_TOSERVER) {
749  txd->detect_flags_ts = detect_flags;
750  } else {
751  txd->detect_flags_tc = detect_flags;
752  }
753 }
754 
755 static inline uint32_t GetTxLogged(AppLayerTxData *txd)
756 {
757  return txd->logged.flags;
758 }
759 
761  void *alstate, const uint8_t flags,
762  bool tag_txs_as_inspected)
763 {
764  SCEnter();
765 
766  const int direction = (flags & STREAM_TOSERVER) ? 0 : 1;
767  const uint64_t total_txs = AppLayerParserGetTxCnt(f, alstate);
768  uint64_t idx = AppLayerParserGetTransactionInspectId(pstate, flags);
769  const int state_done_progress = AppLayerParserGetStateProgressCompletionStatus(f->alproto, flags);
770  const uint8_t ipproto = f->proto;
771  const AppProto alproto = f->alproto;
772 
773  AppLayerGetTxIteratorFunc IterFunc = AppLayerGetTxIterator(ipproto, alproto);
775  memset(&state, 0, sizeof(state));
776 
777  SCLogDebug("called: %s, tag_txs_as_inspected %s",direction==0?"toserver":"toclient",
778  tag_txs_as_inspected?"true":"false");
779 
780  /* mark all txs as inspected if the applayer progress is
781  * at the 'end state'. */
782  while (1) {
783  AppLayerGetTxIterTuple ires = IterFunc(ipproto, alproto, alstate, idx, total_txs, &state);
784  if (ires.tx_ptr == NULL)
785  break;
786 
787  void *tx = ires.tx_ptr;
788  idx = ires.tx_id;
789 
790  int state_progress = AppLayerParserGetStateProgress(ipproto, alproto, tx, flags);
791  if (state_progress < state_done_progress)
792  break;
793 
794  AppLayerTxData *txd = AppLayerParserGetTxData(ipproto, alproto, tx);
795  if (txd && tag_txs_as_inspected) {
796  uint64_t detect_flags = GetTxDetectFlags(txd, flags);
797  if ((detect_flags & APP_LAYER_TX_INSPECTED_FLAG) == 0) {
798  detect_flags |= APP_LAYER_TX_INSPECTED_FLAG;
799  SetTxDetectFlags(txd, flags, detect_flags);
800  SCLogDebug("%p/%"PRIu64" in-order tx is done for direction %s. Flag %016"PRIx64,
801  tx, idx, flags & STREAM_TOSERVER ? "toserver" : "toclient", detect_flags);
802  }
803  }
804  idx++;
805  if (!ires.has_next)
806  break;
807  }
808  pstate->inspect_id[direction] = idx;
809  SCLogDebug("inspect_id now %"PRIu64, pstate->inspect_id[direction]);
810 
811  /* if necessary we flag all txs that are complete as 'inspected'
812  * also move inspect_id forward. */
813  if (tag_txs_as_inspected) {
814  /* continue at idx */
815  while (1) {
816  AppLayerGetTxIterTuple ires = IterFunc(ipproto, alproto, alstate, idx, total_txs, &state);
817  if (ires.tx_ptr == NULL)
818  break;
819 
820  void *tx = ires.tx_ptr;
821  /* if we got a higher id than the minimum we requested, we
822  * skipped a bunch of 'null-txs'. Lets see if we can up the
823  * inspect tracker */
824  if (ires.tx_id > idx && pstate->inspect_id[direction] == idx) {
825  pstate->inspect_id[direction] = ires.tx_id;
826  }
827  idx = ires.tx_id;
828 
829  const int state_progress = AppLayerParserGetStateProgress(ipproto, alproto, tx, flags);
830  if (state_progress < state_done_progress)
831  break;
832 
833  /* txd can be NULL for HTTP sessions where the user data alloc failed */
834  AppLayerTxData *txd = AppLayerParserGetTxData(ipproto, alproto, tx);
835  if (likely(txd)) {
836  uint64_t detect_flags = GetTxDetectFlags(txd, flags);
837  if ((detect_flags & APP_LAYER_TX_INSPECTED_FLAG) == 0) {
838  detect_flags |= APP_LAYER_TX_INSPECTED_FLAG;
839  SetTxDetectFlags(txd, flags, detect_flags);
840  SCLogDebug("%p/%"PRIu64" out of order tx is done for direction %s. Flag %016"PRIx64,
841  tx, idx, flags & STREAM_TOSERVER ? "toserver" : "toclient", detect_flags);
842 
843  SCLogDebug("%p/%"PRIu64" out of order tx. Update inspect_id? %"PRIu64,
844  tx, idx, pstate->inspect_id[direction]);
845  if (pstate->inspect_id[direction]+1 == idx)
846  pstate->inspect_id[direction] = idx;
847  }
848  } else {
849  if (pstate->inspect_id[direction]+1 == idx)
850  pstate->inspect_id[direction] = idx;
851  }
852  if (!ires.has_next)
853  break;
854  idx++;
855  }
856  }
857 
858  SCReturn;
859 }
860 
862 {
863  SCEnter();
864 
865  SCReturnPtr(pstate->decoder_events,
866  "AppLayerDecoderEvents *");
867 }
868 
870 {
871  pstate->decoder_events = devents;
872 }
873 
875  void *tx)
876 {
877  SCEnter();
878 
879  AppLayerDecoderEvents *ptr = NULL;
880 
881  /* Access events via the tx_data. */
882  AppLayerTxData *txd = AppLayerParserGetTxData(ipproto, alproto, tx);
883  if (txd != NULL && txd->events != NULL) {
884  ptr = txd->events;
885  }
886 
887  SCReturnPtr(ptr, "AppLayerDecoderEvents *");
888 }
889 
890 AppLayerGetFileState AppLayerParserGetTxFiles(
891  const Flow *f, void *state, void *tx, const uint8_t direction)
892 {
893  SCEnter();
894 
895  if (alp_ctx.ctxs[f->protomap][f->alproto].GetTxFiles != NULL) {
896  return alp_ctx.ctxs[f->protomap][f->alproto].GetTxFiles(state, tx, direction);
897  }
898 
899  AppLayerGetFileState files = { .fc = NULL, .cfg = NULL };
900  return files;
901 }
902 
903 static void AppLayerParserFileTxHousekeeping(
904  const Flow *f, void *tx, const uint8_t pkt_dir, const bool trunc)
905 {
906  AppLayerGetFileState files = AppLayerParserGetTxFiles(f, FlowGetAppState(f), tx, pkt_dir);
907  if (files.fc) {
908  FilesPrune(files.fc, files.cfg, trunc);
909  }
910 }
911 
912 #define IS_DISRUPTED(flags) ((flags) & (STREAM_DEPTH | STREAM_GAP))
913 
914 extern int g_detect_disabled;
915 extern bool g_file_logger_enabled;
916 extern bool g_filedata_logger_enabled;
917 
918 /**
919  * \brief remove obsolete (inspected and logged) transactions
920  */
921 void AppLayerParserTransactionsCleanup(Flow *f, const uint8_t pkt_dir)
922 {
923  SCEnter();
925 
926  AppLayerParserProtoCtx *p = &alp_ctx.ctxs[f->protomap][f->alproto];
927  if (unlikely(p->StateTransactionFree == NULL))
928  SCReturn;
929 
930  const bool has_tx_detect_flags = !g_detect_disabled;
931  const uint8_t ipproto = f->proto;
932  const AppProto alproto = f->alproto;
933  void * const alstate = f->alstate;
934  AppLayerParserState * const alparser = f->alparser;
935 
936  if (alstate == NULL || alparser == NULL)
937  SCReturn;
938 
939  const uint64_t min = alparser->min_id;
940  const uint64_t total_txs = AppLayerParserGetTxCnt(f, alstate);
941  const LoggerId logger_expectation = AppLayerParserProtocolGetLoggerBits(ipproto, alproto);
942  const int tx_end_state_ts = AppLayerParserGetStateProgressCompletionStatus(alproto, STREAM_TOSERVER);
943  const int tx_end_state_tc = AppLayerParserGetStateProgressCompletionStatus(alproto, STREAM_TOCLIENT);
944  const uint8_t ts_disrupt_flags = FlowGetDisruptionFlags(f, STREAM_TOSERVER);
945  const uint8_t tc_disrupt_flags = FlowGetDisruptionFlags(f, STREAM_TOCLIENT);
946 
947  int pkt_dir_trunc = -1;
948 
949  AppLayerGetTxIteratorFunc IterFunc = AppLayerGetTxIterator(ipproto, alproto);
951  memset(&state, 0, sizeof(state));
952  uint64_t i = min;
953  uint64_t new_min = min;
954  SCLogDebug("start min %"PRIu64, min);
955  bool skipped = false;
956  const bool is_unidir =
958  // const bool support_files = AppLayerParserSupportsFiles(f->proto, f->alproto);
959 
960  while (1) {
961  AppLayerGetTxIterTuple ires = IterFunc(ipproto, alproto, alstate, i, total_txs, &state);
962  if (ires.tx_ptr == NULL)
963  break;
964 
965  bool tx_skipped = false;
966  void *tx = ires.tx_ptr;
967  i = ires.tx_id; // actual tx id for the tx the IterFunc returned
968 
969  SCLogDebug("%p/%"PRIu64" checking", tx, i);
970  AppLayerTxData *txd = AppLayerParserGetTxData(ipproto, alproto, tx);
971  if (txd != NULL && AppLayerParserHasFilesInDir(txd, pkt_dir)) {
972  if (pkt_dir_trunc == -1)
973  pkt_dir_trunc =
975  (pkt_dir == STREAM_TOSERVER) ? APP_LAYER_PARSER_TRUNC_TS
977 
978  AppLayerParserFileTxHousekeeping(f, tx, pkt_dir, (bool)pkt_dir_trunc);
979  }
980 
981  const int tx_progress_tc =
982  AppLayerParserGetStateProgress(ipproto, alproto, tx, tc_disrupt_flags);
983  if (tx_progress_tc < tx_end_state_tc) {
984  SCLogDebug("%p/%"PRIu64" skipping: tc parser not done", tx, i);
985  skipped = true;
986  goto next;
987  }
988  const int tx_progress_ts =
989  AppLayerParserGetStateProgress(ipproto, alproto, tx, ts_disrupt_flags);
990  if (tx_progress_ts < tx_end_state_ts) {
991  SCLogDebug("%p/%"PRIu64" skipping: ts parser not done", tx, i);
992  skipped = true;
993  goto next;
994  }
995 
996  bool inspected = false;
997  if (txd && has_tx_detect_flags) {
998  if (!IS_DISRUPTED(ts_disrupt_flags) && f->sgh_toserver != NULL) {
999  uint64_t detect_flags_ts = GetTxDetectFlags(txd, STREAM_TOSERVER);
1000  if (!(detect_flags_ts & APP_LAYER_TX_INSPECTED_FLAG)) {
1001  SCLogDebug("%p/%"PRIu64" skipping: TS inspect not done: ts:%"PRIx64,
1002  tx, i, detect_flags_ts);
1003  tx_skipped = true;
1004  } else {
1005  inspected = true;
1006  }
1007  }
1008  if (!IS_DISRUPTED(tc_disrupt_flags) && f->sgh_toclient != NULL) {
1009  uint64_t detect_flags_tc = GetTxDetectFlags(txd, STREAM_TOCLIENT);
1010  if (!(detect_flags_tc & APP_LAYER_TX_INSPECTED_FLAG)) {
1011  SCLogDebug("%p/%"PRIu64" skipping: TC inspect not done: tc:%"PRIx64,
1012  tx, i, detect_flags_tc);
1013  tx_skipped = true;
1014  } else {
1015  inspected = true;
1016  }
1017  }
1018  }
1019 
1020  // If not a unidirectional transaction both sides are required to have
1021  // been inspected.
1022  if (!is_unidir && tx_skipped) {
1023  SCLogDebug("%p/%" PRIu64 " !is_unidir && tx_skipped", tx, i);
1024  skipped = true;
1025  goto next;
1026  }
1027 
1028  // If this is a unidirectional transaction require only one side to be
1029  // inspected, which the inspected flag tells us. This is also guarded
1030  // with skip to limit this check to transactions that actually had the
1031  // tx inspected flag checked.
1032  if (is_unidir && tx_skipped && !inspected) {
1033  SCLogDebug("%p/%" PRIu64 " is_unidir && tx_skipped && !inspected", tx, i);
1034  skipped = true;
1035  goto next;
1036  }
1037 
1038  if (txd && logger_expectation != 0) {
1039  LoggerId tx_logged = GetTxLogged(txd);
1040  if (tx_logged != logger_expectation) {
1041  SCLogDebug("%p/%"PRIu64" skipping: logging not done: want:%"PRIx32", have:%"PRIx32,
1042  tx, i, logger_expectation, tx_logged);
1043  skipped = true;
1044  goto next;
1045  }
1046  }
1047 
1048  /* if file logging is enabled, we keep a tx active while some of the files aren't
1049  * logged yet. */
1050  if (txd) {
1051  SCLogDebug("files_opened %u files_logged %u files_stored %u", txd->files_opened,
1052  txd->files_logged, txd->files_stored);
1053 
1054  if (txd->files_opened) {
1055  if (g_file_logger_enabled && txd->files_opened != txd->files_logged) {
1056  skipped = true;
1057  goto next;
1058  }
1059  if (g_filedata_logger_enabled && txd->files_opened != txd->files_stored) {
1060  skipped = true;
1061  goto next;
1062  }
1063  }
1064  }
1065 
1066  /* if we are here, the tx can be freed. */
1067  p->StateTransactionFree(alstate, i);
1068  SCLogDebug("%p/%"PRIu64" freed", tx, i);
1069 
1070  /* if we didn't skip any tx so far, up the minimum */
1071  SCLogDebug("skipped? %s i %"PRIu64", new_min %"PRIu64, skipped ? "true" : "false", i, new_min);
1072  if (!skipped)
1073  new_min = i + 1;
1074  SCLogDebug("final i %"PRIu64", new_min %"PRIu64, i, new_min);
1075 
1076 next:
1077  if (!ires.has_next) {
1078  /* this was the last tx. See if we skipped any. If not
1079  * we removed all and can update the minimum to the max
1080  * id. */
1081  SCLogDebug("no next: cur tx i %"PRIu64", total %"PRIu64, i, total_txs);
1082  if (!skipped) {
1083  new_min = total_txs;
1084  SCLogDebug("no next: cur tx i %"PRIu64", total %"PRIu64": "
1085  "new_min updated to %"PRIu64, i, total_txs, new_min);
1086  }
1087  break;
1088  }
1089  i++;
1090  }
1091 
1092  /* see if we need to bring all trackers up to date. */
1093  SCLogDebug("update f->alparser->min_id? %"PRIu64" vs %"PRIu64, new_min, alparser->min_id);
1094  if (new_min > alparser->min_id) {
1095  const uint64_t next_id = new_min;
1096  alparser->min_id = next_id;
1097  alparser->inspect_id[0] = MAX(alparser->inspect_id[0], next_id);
1098  alparser->inspect_id[1] = MAX(alparser->inspect_id[1], next_id);
1099  alparser->log_id = MAX(alparser->log_id, next_id);
1100  SCLogDebug("updated f->alparser->min_id %"PRIu64, alparser->min_id);
1101  }
1102  SCReturn;
1103 }
1104 
1105 static inline int StateGetProgressCompletionStatus(const AppProto alproto, const uint8_t flags)
1106 {
1107  if (flags & STREAM_TOSERVER) {
1108  return alp_ctx.ctxs[FLOW_PROTO_DEFAULT][alproto].complete_ts;
1109  } else if (flags & STREAM_TOCLIENT) {
1110  return alp_ctx.ctxs[FLOW_PROTO_DEFAULT][alproto].complete_tc;
1111  } else {
1113  return 0;
1114  }
1115 }
1116 
1117 /**
1118  * \brief get the progress value for a tx/protocol
1119  *
1120  * If the stream is disrupted, we return the 'completion' value.
1121  */
1122 int AppLayerParserGetStateProgress(uint8_t ipproto, AppProto alproto,
1123  void *alstate, uint8_t flags)
1124 {
1125  SCEnter();
1126  int r;
1127  if (unlikely(IS_DISRUPTED(flags))) {
1128  r = StateGetProgressCompletionStatus(alproto, flags);
1129  } else {
1130  r = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
1131  StateGetProgress(alstate, flags);
1132  }
1133  SCReturnInt(r);
1134 }
1135 
1136 uint64_t AppLayerParserGetTxCnt(const Flow *f, void *alstate)
1137 {
1138  SCEnter();
1139  uint64_t r = alp_ctx.ctxs[f->protomap][f->alproto].StateGetTxCnt(alstate);
1140  SCReturnCT(r, "uint64_t");
1141 }
1142 
1143 void *AppLayerParserGetTx(uint8_t ipproto, AppProto alproto, void *alstate, uint64_t tx_id)
1144 {
1145  SCEnter();
1146  void *r = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateGetTx(alstate, tx_id);
1147  SCReturnPtr(r, "void *");
1148 }
1149 
1151  uint8_t direction)
1152 {
1153  SCEnter();
1154  int r = StateGetProgressCompletionStatus(alproto, direction);
1155  SCReturnInt(r);
1156 }
1157 
1158 int AppLayerParserGetEventInfo(uint8_t ipproto, AppProto alproto, const char *event_name,
1159  int *event_id, AppLayerEventType *event_type)
1160 {
1161  SCEnter();
1162  const int ipproto_map = FlowGetProtoMapping(ipproto);
1163  int r = (alp_ctx.ctxs[ipproto_map][alproto].StateGetEventInfo == NULL) ?
1164  -1 : alp_ctx.ctxs[ipproto_map][alproto].StateGetEventInfo(event_name, event_id, event_type);
1165  SCReturnInt(r);
1166 }
1167 
1168 int AppLayerParserGetEventInfoById(uint8_t ipproto, AppProto alproto, int event_id,
1169  const char **event_name, AppLayerEventType *event_type)
1170 {
1171  SCEnter();
1172  const int ipproto_map = FlowGetProtoMapping(ipproto);
1173  *event_name = (const char *)NULL;
1174  int r = (alp_ctx.ctxs[ipproto_map][alproto].StateGetEventInfoById == NULL) ?
1175  -1 : alp_ctx.ctxs[ipproto_map][alproto].StateGetEventInfoById(event_id, event_name, event_type);
1176  SCReturnInt(r);
1177 }
1178 
1179 uint8_t AppLayerParserGetFirstDataDir(uint8_t ipproto, AppProto alproto)
1180 {
1181  SCEnter();
1182  uint8_t r = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].first_data_dir;
1183  SCReturnCT(r, "uint8_t");
1184 }
1185 
1187  AppLayerParserState *pstate, uint8_t direction)
1188 {
1189  SCEnter();
1190 
1191  uint64_t active_id;
1192  uint64_t log_id = pstate->log_id;
1193  uint64_t inspect_id = pstate->inspect_id[(direction & STREAM_TOSERVER) ? 0 : 1];
1194  if (alp_ctx.ctxs[f->protomap][f->alproto].logger == true) {
1195  active_id = MIN(log_id, inspect_id);
1196  } else {
1197  active_id = inspect_id;
1198  }
1199 
1200  SCReturnCT(active_id, "uint64_t");
1201 }
1202 
1203 int AppLayerParserSupportsFiles(uint8_t ipproto, AppProto alproto)
1204 {
1205  // Custom case for only signature-only protocol so far
1206  if (alproto == ALPROTO_HTTP) {
1207  return AppLayerParserSupportsFiles(ipproto, ALPROTO_HTTP1) ||
1209  }
1210  if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetTxFiles != NULL)
1211  return TRUE;
1212  return FALSE;
1213 }
1214 
1215 AppLayerTxData *AppLayerParserGetTxData(uint8_t ipproto, AppProto alproto, void *tx)
1216 {
1217  SCEnter();
1218  AppLayerTxData *d = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetTxData(tx);
1219  SCReturnPtr(d, "AppLayerTxData");
1220 }
1221 
1222 AppLayerStateData *AppLayerParserGetStateData(uint8_t ipproto, AppProto alproto, void *state)
1223 {
1224  SCEnter();
1225  if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetStateData) {
1226  AppLayerStateData *d =
1227  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetStateData(state);
1228  SCReturnPtr(d, "AppLayerStateData");
1229  }
1230  SCReturnPtr(NULL, "AppLayerStateData");
1231 }
1232 
1233 void AppLayerParserApplyTxConfig(uint8_t ipproto, AppProto alproto,
1234  void *state, void *tx, enum ConfigAction mode, AppLayerTxConfig config)
1235 {
1236  SCEnter();
1237  const int ipproto_map = FlowGetProtoMapping(ipproto);
1238  if (alp_ctx.ctxs[ipproto_map][alproto].ApplyTxConfig) {
1239  alp_ctx.ctxs[ipproto_map][alproto].ApplyTxConfig(state, tx, mode, config);
1240  }
1241  SCReturn;
1242 }
1243 
1244 /***** General *****/
1245 
1246 static inline void SetEOFFlags(AppLayerParserState *pstate, const uint8_t flags)
1247 {
1248  if ((flags & (STREAM_EOF|STREAM_TOSERVER)) == (STREAM_EOF|STREAM_TOSERVER)) {
1249  SCLogDebug("setting APP_LAYER_PARSER_EOF_TS");
1251  } else if ((flags & (STREAM_EOF|STREAM_TOCLIENT)) == (STREAM_EOF|STREAM_TOCLIENT)) {
1252  SCLogDebug("setting APP_LAYER_PARSER_EOF_TC");
1254  }
1255 }
1256 
1257 /** \internal
1258  * \brief create/close stream frames
1259  * On first invocation of TCP parser in a direction, create a <alproto>.stream frame.
1260  * On STREAM_EOF, set the final length. */
1261 static void HandleStreamFrames(Flow *f, StreamSlice stream_slice, const uint8_t *input,
1262  const uint32_t input_len, const uint8_t flags)
1263 {
1264  const uint8_t direction = (flags & STREAM_TOSERVER) ? 0 : 1;
1265  AppLayerParserState *pstate = f->alparser;
1266 
1267  /* setup the generic stream frame */
1268  if (((direction == 0 && (pstate->flags & APP_LAYER_PARSER_SFRAME_TS) == 0) ||
1269  (direction == 1 && (pstate->flags & APP_LAYER_PARSER_SFRAME_TC) == 0)) &&
1270  input != NULL && f->proto == IPPROTO_TCP) {
1271  Frame *frame = AppLayerFrameGetById(f, direction, FRAME_STREAM_ID);
1272  if (frame == NULL) {
1273  int64_t frame_len = -1;
1274  if (flags & STREAM_EOF)
1275  frame_len = input_len;
1276 
1278  f, &stream_slice, stream_slice.offset, frame_len, direction, FRAME_STREAM_TYPE);
1279  if (frame) {
1280  SCLogDebug("opened: frame %p id %" PRIi64, frame, frame->id);
1281  frame->flags = FRAME_FLAG_ENDS_AT_EOF; // TODO logic is not yet implemented
1283  frame->id != 1); // should always be the first frame that is created
1284  }
1285  if (direction == 0) {
1286  pstate->flags |= APP_LAYER_PARSER_SFRAME_TS;
1287  } else {
1288  pstate->flags |= APP_LAYER_PARSER_SFRAME_TC;
1289  }
1290  }
1291  } else if (flags & STREAM_EOF) {
1292  Frame *frame = AppLayerFrameGetById(f, direction, FRAME_STREAM_ID);
1293  SCLogDebug("EOF closing: frame %p", frame);
1294  if (frame) {
1295  /* calculate final frame length */
1296  int64_t slice_o = (int64_t)stream_slice.offset - (int64_t)frame->offset;
1297  int64_t frame_len = slice_o + (int64_t)input_len;
1298  SCLogDebug("%s: EOF frame->offset %" PRIu64 " -> %" PRIi64 ": o %" PRIi64,
1299  AppProtoToString(f->alproto), frame->offset, frame_len, slice_o);
1300  frame->len = frame_len;
1301  }
1302  }
1303 }
1304 
1305 static void Setup(Flow *f, const uint8_t direction, const uint8_t *input, uint32_t input_len,
1306  const uint8_t flags, StreamSlice *as)
1307 {
1308  memset(as, 0, sizeof(*as));
1309  as->input = input;
1310  as->input_len = input_len;
1311  as->flags = flags;
1312 
1313  if (f->proto == IPPROTO_TCP && f->protoctx != NULL) {
1314  TcpSession *ssn = f->protoctx;
1315  TcpStream *stream = (direction & STREAM_TOSERVER) ? &ssn->client : &ssn->server;
1316  as->offset = STREAM_APP_PROGRESS(stream);
1317  }
1318 }
1319 
1320 /** \retval int -1 in case of unrecoverable error. App-layer tracking stops for this flow.
1321  * \retval int 0 ok: we did not update app_progress
1322  * \retval int 1 ok: we updated app_progress */
1324  uint8_t flags, const uint8_t *input, uint32_t input_len)
1325 {
1326  SCEnter();
1327 #ifdef DEBUG_VALIDATION
1329 #endif
1330  AppLayerParserState *pstate = f->alparser;
1331  AppLayerParserProtoCtx *p = &alp_ctx.ctxs[f->protomap][alproto];
1332  StreamSlice stream_slice;
1333  void *alstate = NULL;
1334  uint64_t p_tx_cnt = 0;
1335  uint32_t consumed = input_len;
1336  const uint8_t direction = (flags & STREAM_TOSERVER) ? 0 : 1;
1337 
1338  /* we don't have the parser registered for this protocol */
1339  if (p->StateAlloc == NULL) {
1340  if (f->proto == IPPROTO_TCP) {
1342  }
1343  goto end;
1344  }
1345 
1346  if (flags & STREAM_GAP) {
1348  SCLogDebug("app-layer parser does not accept gaps");
1349  if (f->alstate != NULL && !FlowChangeProto(f)) {
1350  AppLayerParserStreamTruncated(pstate, f->proto, alproto, f->alstate, flags);
1351  }
1353  goto error;
1354  }
1355  }
1356 
1357  /* Get the parser state (if any) */
1358  if (pstate == NULL) {
1359  f->alparser = pstate = AppLayerParserStateAlloc();
1360  if (pstate == NULL) {
1362  goto error;
1363  }
1364  }
1365 
1366  SetEOFFlags(pstate, flags);
1367 
1368  alstate = f->alstate;
1369  if (alstate == NULL || FlowChangeProto(f)) {
1370  f->alstate = alstate = p->StateAlloc(alstate, f->alproto_orig);
1371  if (alstate == NULL) {
1373  goto error;
1374  }
1375  SCLogDebug("alloced new app layer state %p (name %s)",
1376  alstate, AppLayerGetProtoName(f->alproto));
1377 
1378  /* set flow flags to state */
1379  if (f->file_flags != 0) {
1380  AppLayerStateData *sd = AppLayerParserGetStateData(f->proto, f->alproto, f->alstate);
1381  if (sd != NULL) {
1382  if ((sd->file_flags & f->file_flags) != f->file_flags) {
1383  SCLogDebug("state data: updating file_flags %04x with flow file_flags %04x",
1384  sd->file_flags, f->file_flags);
1385  sd->file_flags |= f->file_flags;
1386  }
1387  }
1388  }
1389  } else {
1390  SCLogDebug("using existing app layer state %p (name %s))",
1391  alstate, AppLayerGetProtoName(f->alproto));
1392  }
1393 
1394  p_tx_cnt = AppLayerParserGetTxCnt(f, f->alstate);
1395 
1396  /* invoke the recursive parser, but only on data. We may get empty msgs on EOF */
1397  if (input_len > 0 || (flags & STREAM_EOF)) {
1398  Setup(f, flags & (STREAM_TOSERVER | STREAM_TOCLIENT), input, input_len, flags,
1399  &stream_slice);
1400  HandleStreamFrames(f, stream_slice, input, input_len, flags);
1401 
1402 #ifdef DEBUG
1403  if (((stream_slice.flags & STREAM_TOSERVER) &&
1404  stream_slice.offset >= g_eps_applayer_error_offset_ts)) {
1405  SCLogNotice("putting parser %s into an error state from toserver offset %" PRIu64,
1406  AppProtoToString(alproto), g_eps_applayer_error_offset_ts);
1408  goto error;
1409  }
1410  if (((stream_slice.flags & STREAM_TOCLIENT) &&
1411  stream_slice.offset >= g_eps_applayer_error_offset_tc)) {
1412  SCLogNotice("putting parser %s into an error state from toclient offset %" PRIu64,
1413  AppProtoToString(alproto), g_eps_applayer_error_offset_tc);
1415  goto error;
1416  }
1417 #endif
1418  /* invoke the parser */
1419  AppLayerResult res = p->Parser[direction](f, alstate, pstate, stream_slice,
1420  alp_tctx->alproto_local_storage[f->protomap][alproto]);
1421  if (res.status < 0) {
1423  goto error;
1424  } else if (res.status > 0) {
1425  DEBUG_VALIDATE_BUG_ON(res.consumed > input_len);
1426  DEBUG_VALIDATE_BUG_ON(res.needed + res.consumed < input_len);
1427  DEBUG_VALIDATE_BUG_ON(res.needed == 0);
1428  /* incomplete is only supported for TCP */
1429  DEBUG_VALIDATE_BUG_ON(f->proto != IPPROTO_TCP);
1430 
1431  /* put protocol in error state on improper use of the
1432  * return codes. */
1433  if (res.consumed > input_len || res.needed + res.consumed < input_len) {
1435  goto error;
1436  }
1437 
1438  if (f->proto == IPPROTO_TCP && f->protoctx != NULL) {
1439  TcpSession *ssn = f->protoctx;
1440  SCLogDebug("direction %d/%s", direction,
1441  (flags & STREAM_TOSERVER) ? "toserver" : "toclient");
1442  if (direction == 0) {
1443  /* parser told us how much data it needs on top of what it
1444  * consumed. So we need tell stream engine how much we need
1445  * before the next call */
1446  ssn->client.data_required = res.needed;
1447  SCLogDebug("setting data_required %u", ssn->client.data_required);
1448  } else {
1449  /* parser told us how much data it needs on top of what it
1450  * consumed. So we need tell stream engine how much we need
1451  * before the next call */
1452  ssn->server.data_required = res.needed;
1453  SCLogDebug("setting data_required %u", ssn->server.data_required);
1454  }
1455  }
1456  consumed = res.consumed;
1457  }
1458  }
1459 
1460  /* set the packets to no inspection and reassembly if required */
1461  if (pstate->flags & APP_LAYER_PARSER_NO_INSPECTION) {
1462  AppLayerParserSetEOF(pstate);
1463  FlowSetNoPayloadInspectionFlag(f);
1464 
1465  if (f->proto == IPPROTO_TCP) {
1467 
1468  /* Set the no reassembly flag for both the stream in this TcpSession */
1469  if (pstate->flags & APP_LAYER_PARSER_NO_REASSEMBLY) {
1470  /* Used only if it's TCP */
1471  TcpSession *ssn = f->protoctx;
1472  if (ssn != NULL) {
1475  }
1476  }
1477  /* Set the bypass flag for both the stream in this TcpSession */
1478  if (pstate->flags & APP_LAYER_PARSER_BYPASS_READY) {
1479  /* Used only if it's TCP */
1480  TcpSession *ssn = f->protoctx;
1481  if (ssn != NULL) {
1483  }
1484  }
1485  }
1486  }
1487 
1488  /* In cases like HeartBleed for TLS we need to inspect AppLayer but not Payload */
1490  FlowSetNoPayloadInspectionFlag(f);
1491  /* Set the no reassembly flag for both the stream in this TcpSession */
1492  if (f->proto == IPPROTO_TCP) {
1493  /* Used only if it's TCP */
1494  TcpSession *ssn = f->protoctx;
1495  if (ssn != NULL) {
1498  }
1499  }
1500  }
1501 
1502  /* get the diff in tx cnt for stats keeping */
1503  uint64_t cur_tx_cnt = AppLayerParserGetTxCnt(f, f->alstate);
1504  if (cur_tx_cnt > p_tx_cnt && tv) {
1505  AppLayerIncTxCounter(tv, f, cur_tx_cnt - p_tx_cnt);
1506  }
1507 
1508  /* stream truncated, inform app layer */
1509  if (flags & STREAM_DEPTH)
1510  AppLayerParserStreamTruncated(pstate, f->proto, alproto, f->alstate, flags);
1511 
1512  end:
1513  /* update app progress */
1514  if (consumed != input_len && f->proto == IPPROTO_TCP && f->protoctx != NULL) {
1515  TcpSession *ssn = f->protoctx;
1516  StreamTcpUpdateAppLayerProgress(ssn, direction, consumed);
1517  SCReturnInt(1);
1518  }
1519 
1520  SCReturnInt(0);
1521  error:
1522  /* Set the no app layer inspection flag for both
1523  * the stream in this Flow */
1524  if (f->proto == IPPROTO_TCP) {
1526  }
1527  AppLayerParserSetEOF(pstate);
1528  SCReturnInt(-1);
1529 }
1530 
1532 {
1533  SCEnter();
1534 
1535  if (pstate == NULL)
1536  goto end;
1537 
1538  SCLogDebug("setting APP_LAYER_PARSER_EOF_TC and APP_LAYER_PARSER_EOF_TS");
1540 
1541  end:
1542  SCReturn;
1543 }
1544 
1545 /* return true if there are app parser decoder events. These are
1546  * only the ones that are set during protocol detection. */
1548 {
1549  SCEnter();
1550 
1551  if (pstate == NULL)
1552  return false;
1553 
1556  return true;
1557 
1558  /* if we have reached here, we don't have events */
1559  return false;
1560 }
1561 
1562 /** \brief simple way to globally test if a alproto is registered
1563  * and fully enabled in the configuration.
1564  */
1566 {
1567  for (int i = 0; i < FLOW_PROTO_APPLAYER_MAX; i++) {
1568  if (alp_ctx.ctxs[i][alproto].StateGetProgress != NULL) {
1569  return 1;
1570  }
1571  }
1572  return 0;
1573 }
1574 
1575 int AppLayerParserProtocolHasLogger(uint8_t ipproto, AppProto alproto)
1576 {
1577  SCEnter();
1578  int ipproto_map = FlowGetProtoMapping(ipproto);
1579  int r = (alp_ctx.ctxs[ipproto_map][alproto].logger == false) ? 0 : 1;
1580  SCReturnInt(r);
1581 }
1582 
1584 {
1585  SCEnter();
1586  const int ipproto_map = FlowGetProtoMapping(ipproto);
1587  LoggerId r = alp_ctx.ctxs[ipproto_map][alproto].logger_bits;
1588  SCReturnUInt(r);
1589 }
1590 
1592 {
1593  SCEnter();
1594 
1595  SCLogDebug("f %p tcp %p direction %d", f, f ? f->protoctx : NULL, direction);
1596  if (f != NULL && f->protoctx != NULL)
1598 
1599  SCReturn;
1600 }
1601 
1602 void AppLayerParserSetStreamDepth(uint8_t ipproto, AppProto alproto, uint32_t stream_depth)
1603 {
1604  SCEnter();
1605 
1606  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].stream_depth = stream_depth;
1607  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].internal_flags |=
1609 
1610  SCReturn;
1611 }
1612 
1614 {
1615  SCReturnInt(alp_ctx.ctxs[f->protomap][f->alproto].stream_depth);
1616 }
1617 
1618 void AppLayerParserSetStreamDepthFlag(uint8_t ipproto, AppProto alproto, void *state, uint64_t tx_id, uint8_t flags)
1619 {
1620  SCEnter();
1621  void *tx = NULL;
1622  if (state != NULL) {
1623  if ((tx = AppLayerParserGetTx(ipproto, alproto, state, tx_id)) != NULL) {
1624  if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].SetStreamDepthFlag != NULL) {
1625  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].SetStreamDepthFlag(tx, flags);
1626  }
1627  }
1628  }
1629  SCReturn;
1630 }
1631 
1632 int AppLayerParserGetFrameIdByName(uint8_t ipproto, AppProto alproto, const char *name)
1633 {
1634  if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetFrameIdByName != NULL) {
1635  return alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetFrameIdByName(name);
1636  } else {
1637  return -1;
1638  }
1639 }
1640 
1641 const char *AppLayerParserGetFrameNameById(uint8_t ipproto, AppProto alproto, const uint8_t id)
1642 {
1643  if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetFrameNameById != NULL) {
1644  return alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetFrameNameById(id);
1645  } else {
1646  return NULL;
1647  }
1648 }
1649 
1650 /***** Cleanup *****/
1651 
1653  uint8_t protomap, AppProto alproto, void *alstate, AppLayerParserState *pstate)
1654 {
1655  SCEnter();
1656 
1657  AppLayerParserProtoCtx *ctx = &alp_ctx.ctxs[protomap][alproto];
1658 
1659  if (ctx->StateFree != NULL && alstate != NULL)
1660  ctx->StateFree(alstate);
1661 
1662  /* free the app layer parser api state */
1663  if (pstate != NULL)
1664  AppLayerParserStateFree(pstate);
1665 
1666  SCReturn;
1667 }
1668 
1669 void AppLayerParserStateCleanup(const Flow *f, void *alstate, AppLayerParserState *pstate)
1670 {
1671  AppLayerParserStateProtoCleanup(f->protomap, f->alproto, alstate, pstate);
1672 }
1673 
1674 static void ValidateParserProtoDump(AppProto alproto, uint8_t ipproto)
1675 {
1676  uint8_t map = FlowGetProtoMapping(ipproto);
1677  const AppLayerParserProtoCtx *ctx = &alp_ctx.ctxs[map][alproto];
1678  printf("ERROR: incomplete app-layer registration\n");
1679  printf("AppLayer protocol %s ipproto %u\n", AppProtoToString(alproto), ipproto);
1680  printf("- option flags %"PRIx32"\n", ctx->option_flags);
1681  printf("- first_data_dir %"PRIx8"\n", ctx->first_data_dir);
1682  printf("Mandatory:\n");
1683  printf("- Parser[0] %p Parser[1] %p\n", ctx->Parser[0], ctx->Parser[1]);
1684  printf("- StateAlloc %p StateFree %p\n", ctx->StateAlloc, ctx->StateFree);
1685  printf("- StateGetTx %p StateGetTxCnt %p StateTransactionFree %p\n",
1686  ctx->StateGetTx, ctx->StateGetTxCnt, ctx->StateTransactionFree);
1687  printf("- GetTxData %p\n", ctx->GetTxData);
1688  printf("- GetStateData %p\n", ctx->GetStateData);
1689  printf("- StateGetProgress %p\n", ctx->StateGetProgress);
1690  printf("Optional:\n");
1691  printf("- LocalStorageAlloc %p LocalStorageFree %p\n", ctx->LocalStorageAlloc, ctx->LocalStorageFree);
1692  printf("- StateGetEventInfo %p StateGetEventInfoById %p\n", ctx->StateGetEventInfo,
1693  ctx->StateGetEventInfoById);
1694 }
1695 
1696 #define BOTH_SET(a, b) ((a) != NULL && (b) != NULL)
1697 #define BOTH_SET_OR_BOTH_UNSET(a, b) (((a) == NULL && (b) == NULL) || ((a) != NULL && (b) != NULL))
1698 #define THREE_SET_OR_THREE_UNSET(a, b, c) (((a) == NULL && (b) == NULL && (c) == NULL) || ((a) != NULL && (b) != NULL && (c) != NULL))
1699 #define THREE_SET(a, b, c) ((a) != NULL && (b) != NULL && (c) != NULL)
1701 static void ValidateParserProto(AppProto alproto, uint8_t ipproto)
1702 {
1703  uint8_t map = FlowGetProtoMapping(ipproto);
1704  const AppLayerParserProtoCtx *ctx = &alp_ctx.ctxs[map][alproto];
1705 
1706  if (ctx->Parser[0] == NULL && ctx->Parser[1] == NULL)
1707  return;
1708 
1709  if (!(BOTH_SET(ctx->Parser[0], ctx->Parser[1]))) {
1710  goto bad;
1711  }
1712  if (!(BOTH_SET(ctx->StateFree, ctx->StateAlloc))) {
1713  goto bad;
1714  }
1715  if (!(THREE_SET(ctx->StateGetTx, ctx->StateGetTxCnt, ctx->StateTransactionFree))) {
1716  goto bad;
1717  }
1718  if (ctx->StateGetProgress == NULL) {
1719  goto bad;
1720  }
1721  /* local storage is optional, but needs both set if used */
1723  goto bad;
1724  }
1725  if (ctx->GetTxData == NULL) {
1726  goto bad;
1727  }
1728  if (ctx->GetStateData == NULL) {
1729  goto bad;
1730  }
1731  return;
1732 bad:
1733  ValidateParserProtoDump(alproto, ipproto);
1734  exit(EXIT_FAILURE);
1735 }
1736 #undef BOTH_SET
1737 #undef BOTH_SET_OR_BOTH_UNSET
1738 #undef THREE_SET_OR_THREE_UNSET
1739 #undef THREE_SET
1740 
1741 static void ValidateParser(AppProto alproto)
1742 {
1743  ValidateParserProto(alproto, IPPROTO_TCP);
1744  ValidateParserProto(alproto, IPPROTO_UDP);
1745 }
1746 
1747 static void ValidateParsers(void)
1748 {
1749  AppProto p = 0;
1750  for ( ; p < ALPROTO_MAX; p++) {
1751  ValidateParser(p);
1752  }
1753 }
1754 
1756 {
1757  SCEnter();
1758 
1759  AppLayerConfg();
1760 
1763  rs_dcerpc_register_parser();
1764  rs_dcerpc_udp_register_parser();
1769  rs_dns_udp_register_parser();
1770  rs_dns_tcp_register_parser();
1771  rs_bittorrent_dht_udp_register_parser();
1782  rs_dhcp_register_parser();
1786  rs_template_register_parser();
1789  rs_pgsql_register_parser();
1792  rs_telnet_register_parser();
1793 
1794  /** IMAP */
1796  if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", "imap")) {
1798  "1|20|capability", 12, 0, STREAM_TOSERVER) < 0)
1799  {
1800  SCLogInfo("imap proto registration failure");
1801  exit(EXIT_FAILURE);
1802  }
1803  } else {
1804  SCLogInfo("Protocol detection and parser disabled for %s protocol.",
1805  "imap");
1806  }
1807 
1808  ValidateParsers();
1809  return;
1810 }
1811 
1812 
1813 /* coccinelle: AppLayerParserStateSetFlag():2,2:APP_LAYER_PARSER_ */
1815 {
1816  SCEnter();
1817  pstate->flags |= flag;
1818  SCReturn;
1819 }
1820 
1821 /* coccinelle: AppLayerParserStateIssetFlag():2,2:APP_LAYER_PARSER_ */
1822 uint16_t AppLayerParserStateIssetFlag(AppLayerParserState *pstate, uint16_t flag)
1823 {
1824  SCEnter();
1825  SCReturnUInt(pstate->flags & flag);
1826 }
1827 
1828 static inline void AppLayerParserStreamTruncated(AppLayerParserState *pstate, const uint8_t ipproto,
1829  const AppProto alproto, void *alstate, const uint8_t direction)
1830 {
1831  SCEnter();
1832 
1833  if (direction & STREAM_TOSERVER) {
1835  } else {
1837  }
1838 
1839  if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].Truncate != NULL) {
1840  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].Truncate(alstate, direction);
1841  }
1842 
1843  SCReturn;
1844 }
1845 
1846 #ifdef DEBUG
1847 void AppLayerParserStatePrintDetails(AppLayerParserState *pstate)
1848 {
1849  SCEnter();
1850 
1851  if (pstate == NULL)
1852  SCReturn;
1853 
1854  AppLayerParserState *p = pstate;
1855  SCLogDebug("AppLayerParser parser state information for parser state p(%p). "
1856  "p->inspect_id[0](%"PRIu64"), "
1857  "p->inspect_id[1](%"PRIu64"), "
1858  "p->log_id(%"PRIu64"), "
1859  "p->decoder_events(%p).",
1860  pstate, p->inspect_id[0], p->inspect_id[1], p->log_id,
1861  p->decoder_events);
1862 
1863  SCReturn;
1864 }
1865 #endif
1866 
1867 /***** Unittests *****/
1868 
1869 #ifdef UNITTESTS
1870 #include "util-unittest-helper.h"
1871 
1872 static AppLayerParserCtx alp_ctx_backup_unittest;
1873 
1874 typedef struct TestState_ {
1875  uint8_t test;
1877 
1878 /**
1879  * \brief Test parser function to test the memory deallocation of app layer
1880  * parser of occurence of an error.
1881  */
1882 static AppLayerResult TestProtocolParser(Flow *f, void *test_state, AppLayerParserState *pstate,
1883  StreamSlice stream_slice, void *local_data)
1884 {
1885  SCEnter();
1887 }
1888 
1889 /** \brief Function to allocates the Test protocol state memory
1890  */
1891 static void *TestProtocolStateAlloc(void *orig_state, AppProto proto_orig)
1892 {
1893  SCEnter();
1894  void *s = SCMalloc(sizeof(TestState));
1895  if (unlikely(s == NULL))
1896  goto end;
1897  memset(s, 0, sizeof(TestState));
1898  end:
1899  SCReturnPtr(s, "TestState");
1900 }
1901 
1902 /** \brief Function to free the Test Protocol state memory
1903  */
1904 static void TestProtocolStateFree(void *s)
1905 {
1906  SCFree(s);
1907 }
1908 
1909 static uint64_t TestGetTxCnt(void *state)
1910 {
1911  /* single tx */
1912  return 1;
1913 }
1914 
1915 static void TestStateTransactionFree(void *state, uint64_t tx_id)
1916 {
1917  /* do nothing */
1918 }
1919 
1920 static void *TestGetTx(void *state, uint64_t tx_id)
1921 {
1922  TestState *test_state = (TestState *)state;
1923  return test_state;
1924 }
1925 
1927  void (*RegisterUnittests)(void))
1928 {
1929  SCEnter();
1930  alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
1931  RegisterUnittests = RegisterUnittests;
1932  SCReturn;
1933 }
1934 
1936 {
1937  SCEnter();
1938  alp_ctx_backup_unittest = alp_ctx;
1939  memset(&alp_ctx, 0, sizeof(alp_ctx));
1940  SCReturn;
1941 }
1942 
1944 {
1945  SCEnter();
1946  alp_ctx = alp_ctx_backup_unittest;
1947  memset(&alp_ctx_backup_unittest, 0, sizeof(alp_ctx_backup_unittest));
1948  SCReturn;
1949 }
1950 
1951 /**
1952  * \test Test the deallocation of app layer parser memory on occurance of
1953  * error in the parsing process.
1954  */
1955 static int AppLayerParserTest01(void)
1956 {
1958 
1959  Flow *f = NULL;
1960  uint8_t testbuf[] = { 0x11 };
1961  uint32_t testlen = sizeof(testbuf);
1962  TcpSession ssn;
1964 
1965  memset(&ssn, 0, sizeof(ssn));
1966 
1967  /* Register the Test protocol state and parser functions */
1968  AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_TEST, STREAM_TOSERVER, TestProtocolParser);
1970  TestProtocolStateAlloc, TestProtocolStateFree);
1971  AppLayerParserRegisterTxFreeFunc(IPPROTO_TCP, ALPROTO_TEST, TestStateTransactionFree);
1972  AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_TEST, TestGetTx);
1973  AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_TEST, TestGetTxCnt);
1974 
1975  f = UTHBuildFlow(AF_INET, "1.2.3.4", "4.3.2.1", 20, 40);
1976  FAIL_IF_NULL(f);
1977  f->protoctx = &ssn;
1978  f->alproto = ALPROTO_TEST;
1979  f->proto = IPPROTO_TCP;
1980 
1981  StreamTcpInitConfig(true);
1982 
1983  int r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_TEST,
1984  STREAM_TOSERVER | STREAM_EOF, testbuf,
1985  testlen);
1986  FAIL_IF(r != -1);
1987 
1989 
1991  StreamTcpFreeConfig(true);
1992  UTHFreeFlow(f);
1993  PASS;
1994 }
1995 
1996 /**
1997  * \test Test the deallocation of app layer parser memory on occurance of
1998  * error in the parsing process for UDP.
1999  */
2000 static int AppLayerParserTest02(void)
2001 {
2003 
2004  Flow *f = NULL;
2005  uint8_t testbuf[] = { 0x11 };
2006  uint32_t testlen = sizeof(testbuf);
2008 
2009  /* Register the Test protocol state and parser functions */
2010  AppLayerParserRegisterParser(IPPROTO_UDP, ALPROTO_TEST, STREAM_TOSERVER,
2011  TestProtocolParser);
2013  TestProtocolStateAlloc, TestProtocolStateFree);
2014  AppLayerParserRegisterTxFreeFunc(IPPROTO_UDP, ALPROTO_TEST, TestStateTransactionFree);
2015  AppLayerParserRegisterGetTx(IPPROTO_UDP, ALPROTO_TEST, TestGetTx);
2016  AppLayerParserRegisterGetTxCnt(IPPROTO_UDP, ALPROTO_TEST, TestGetTxCnt);
2017 
2018  f = UTHBuildFlow(AF_INET, "1.2.3.4", "4.3.2.1", 20, 40);
2019  FAIL_IF_NULL(f);
2020  f->alproto = ALPROTO_TEST;
2021  f->proto = IPPROTO_UDP;
2023 
2024  StreamTcpInitConfig(true);
2025 
2026  int r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_TEST,
2027  STREAM_TOSERVER | STREAM_EOF, testbuf,
2028  testlen);
2029  FAIL_IF(r != -1);
2030 
2032  StreamTcpFreeConfig(true);
2033  UTHFreeFlow(f);
2034  PASS;
2035 }
2036 
2037 
2039 {
2040  SCEnter();
2041 
2042  int ip;
2043  AppProto alproto;
2045 
2046  for (ip = 0; ip < FLOW_PROTO_DEFAULT; ip++) {
2047  for (alproto = 0; alproto < ALPROTO_MAX; alproto++) {
2048  ctx = &alp_ctx.ctxs[ip][alproto];
2049  if (ctx->RegisterUnittests == NULL)
2050  continue;
2051  ctx->RegisterUnittests();
2052  }
2053  }
2054 
2055  UtRegisterTest("AppLayerParserTest01", AppLayerParserTest01);
2056  UtRegisterTest("AppLayerParserTest02", AppLayerParserTest02);
2057 
2058  SCReturn;
2059 }
2060 
2061 #endif
AppLayerParserProtoCtx_::Truncate
void(* Truncate)(void *, uint8_t)
Definition: app-layer-parser.c:94
FRAME_STREAM_ID
#define FRAME_STREAM_ID
Definition: app-layer-frames.h:32
app-layer-nfs-udp.h
ALPROTO_TEST
@ ALPROTO_TEST
Definition: app-layer-protos.h:72
AppLayerParserRegisterGetStateProgressFunc
void AppLayerParserRegisterGetStateProgressFunc(uint8_t ipproto, AppProto alproto, int(*StateGetProgress)(void *alstate, uint8_t direction))
Definition: app-layer-parser.c:496
AppLayerParserDeSetup
int AppLayerParserDeSetup(void)
Definition: app-layer-parser.c:283
TcpStream_
Definition: stream-tcp-private.h:106
AppLayerParserProtoCtx_::GetStateData
AppLayerStateData *(* GetStateData)(void *state)
Definition: app-layer-parser.c:111
ts
uint64_t ts
Definition: source-erf-file.c:55
RegisterNTPParsers
void RegisterNTPParsers(void)
Definition: app-layer-ntp.c:38
AppLayerParserProtoCtx_::StateGetTxCnt
uint64_t(* StateGetTxCnt)(void *alstate)
Definition: app-layer-parser.c:101
g_applayerparser_error_policy
enum ExceptionPolicy g_applayerparser_error_policy
Definition: app-layer-parser.c:159
AppLayerParserProtoCtx_::logger_bits
uint32_t logger_bits
Definition: app-layer-parser.c:86
AppLayerParserProtoCtx_::complete_tc
int complete_tc
Definition: app-layer-parser.c:105
AppLayerParserProtoCtx_::GetTxData
AppLayerTxData *(* GetTxData)(void *tx)
Definition: app-layer-parser.c:112
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
app-layer-tftp.h
AppLayerParserCtx_::ctxs
AppLayerParserProtoCtx ctxs[FLOW_PROTO_MAX][ALPROTO_MAX]
Definition: app-layer-parser.c:136
app-layer-quic.h
AppLayerParserState_::log_id
uint64_t log_id
Definition: app-layer-parser.c:149
RegisterSMBParsers
void RegisterSMBParsers(void)
Definition: app-layer-smb.c:39
app-layer-ssh.h
RegisterIKEParsers
void RegisterIKEParsers(void)
Definition: app-layer-ike.c:40
AppLayerParserIsEnabled
int AppLayerParserIsEnabled(AppProto alproto)
simple way to globally test if a alproto is registered and fully enabled in the configuration.
Definition: app-layer-parser.c:1565
AppLayerParserRegisterLocalStorageFunc
void AppLayerParserRegisterLocalStorageFunc(uint8_t ipproto, AppProto alproto, void *(*LocalStorageAlloc)(void), void(*LocalStorageFree)(void *))
Definition: app-layer-parser.c:444
BOTH_SET
#define BOTH_SET(a, b)
Definition: app-layer-parser.c:1696
AppLayerParserProtocolHasLogger
int AppLayerParserProtocolHasLogger(uint8_t ipproto, AppProto alproto)
Definition: app-layer-parser.c:1575
AppLayerParserRegisterOptionFlags
void AppLayerParserRegisterOptionFlags(uint8_t ipproto, AppProto alproto, uint32_t flags)
Definition: app-layer-parser.c:415
flow-util.h
FramesFree
void FramesFree(Frames *frames)
Definition: app-layer-frames.c:406
AppLayerParserSetStreamDepthFlag
void AppLayerParserSetStreamDepthFlag(uint8_t ipproto, AppProto alproto, void *state, uint64_t tx_id, uint8_t flags)
Definition: app-layer-parser.c:1618
RegisterQuicParsers
void RegisterQuicParsers(void)
Definition: app-layer-quic.c:37
AppLayerParserSetTransactionLogId
void AppLayerParserSetTransactionLogId(AppLayerParserState *pstate, uint64_t tx_id)
Definition: app-layer-parser.c:719
g_filedata_logger_enabled
bool g_filedata_logger_enabled
Definition: output-filedata.c:37
AppLayerParserSetStreamDepth
void AppLayerParserSetStreamDepth(uint8_t ipproto, AppProto alproto, uint32_t stream_depth)
Definition: app-layer-parser.c:1602
ConfNode_::val
char * val
Definition: conf.h:34
stream-tcp.h
AppLayerParserApplyTxConfig
void AppLayerParserApplyTxConfig(uint8_t ipproto, AppProto alproto, void *state, void *tx, enum ConfigAction mode, AppLayerTxConfig config)
Definition: app-layer-parser.c:1233
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
AppLayerParserTransactionsCleanup
void AppLayerParserTransactionsCleanup(Flow *f, const uint8_t pkt_dir)
remove obsolete (inspected and logged) transactions
Definition: app-layer-parser.c:921
AppLayerParserGetProtocolParserLocalStorage
void * AppLayerParserGetProtocolParserLocalStorage(uint8_t ipproto, AppProto alproto)
Definition: app-layer-parser.c:639
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
AppLayerParserProtoCtx_::LocalStorageFree
void(* LocalStorageFree)(void *)
Definition: app-layer-parser.c:92
AppLayerParserProtoCtx_
App layer protocol parser context.
Definition: app-layer-parser.c:75
RegisterSSHParsers
void RegisterSSHParsers(void)
Function to register the SSH protocol parsers and other functions.
Definition: app-layer-ssh.c:81
AppLayerParserProtoCtx_::StateGetTx
void *(* StateGetTx)(void *alstate, uint64_t tx_id)
Definition: app-layer-parser.c:102
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
AppLayerParserSetTransactionInspectId
void AppLayerParserSetTransactionInspectId(const Flow *f, AppLayerParserState *pstate, void *alstate, const uint8_t flags, bool tag_txs_as_inspected)
Definition: app-layer-parser.c:760
APP_LAYER_PARSER_BYPASS_READY
#define APP_LAYER_PARSER_BYPASS_READY
Definition: app-layer-parser.h:38
AppLayerParserGetEventsByTx
AppLayerDecoderEvents * AppLayerParserGetEventsByTx(uint8_t ipproto, AppProto alproto, void *tx)
Definition: app-layer-parser.c:874
AppLayerGetTxIterator
AppLayerGetTxIteratorFunc AppLayerGetTxIterator(const uint8_t ipproto, const AppProto alproto)
Definition: app-layer-parser.c:704
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:0
RegisterModbusParsers
void RegisterModbusParsers(void)
Function to register the Modbus protocol parser.
Definition: app-layer-modbus.c:49
Flow_::proto
uint8_t proto
Definition: flow.h:379
AppLayerParserProtoCtx_::GetTxFiles
AppLayerGetFileState(* GetTxFiles)(void *, void *, uint8_t)
Definition: app-layer-parser.c:98
AppProto
uint16_t AppProto
Definition: app-layer-protos.h:80
StreamTcpSetDisableRawReassemblyFlag
void StreamTcpSetDisableRawReassemblyFlag(TcpSession *, char)
Set the No reassembly flag for the given direction in given TCP session.
Definition: stream-tcp.c:6388
AppLayerFramesSetupContainer
FramesContainer * AppLayerFramesSetupContainer(Flow *f)
Definition: app-layer-parser.c:190
AppLayerParserConfParserEnabled
int AppLayerParserConfParserEnabled(const char *ipproto, const char *alproto_name)
check if a parser is enabled in the config Returns enabled always if: were running unittests
Definition: app-layer-parser.c:334
AppLayerParserGetStateProgress
int AppLayerParserGetStateProgress(uint8_t ipproto, AppProto alproto, void *alstate, uint8_t flags)
get the progress value for a tx/protocol
Definition: app-layer-parser.c:1122
AppLayerParserTriggerRawStreamReassembly
void AppLayerParserTriggerRawStreamReassembly(Flow *f, int direction)
Definition: app-layer-parser.c:1591
FramesContainer::toserver
Frames toserver
Definition: app-layer-frames.h:74
ConfGetNode
ConfNode * ConfGetNode(const char *name)
Get a ConfNode by name.
Definition: conf.c:181
Frame::offset
uint64_t offset
Definition: app-layer-frames.h:51
TcpStreamCnf_::reassembly_depth
uint32_t reassembly_depth
Definition: stream-tcp.h:64
Frame
Definition: app-layer-frames.h:45
flow-private.h
Flow_
Flow data structure.
Definition: flow.h:357
AppLayerIncGapErrorCounter
void AppLayerIncGapErrorCounter(ThreadVars *tv, Flow *f)
Definition: app-layer.c:130
APP_LAYER_PARSER_INT_STREAM_DEPTH_SET
#define APP_LAYER_PARSER_INT_STREAM_DEPTH_SET
Definition: app-layer-parser.h:50
AppLayerEventType
enum AppLayerEventType_ AppLayerEventType
StreamTcpReassembleTriggerRawReassembly
void StreamTcpReassembleTriggerRawReassembly(TcpSession *ssn, int direction)
Trigger RAW stream reassembly.
Definition: stream-tcp-reassemble.c:2121
LoggerId
LoggerId
Definition: suricata-common.h:449
Flow_::protomap
uint8_t protomap
Definition: flow.h:451
AppLayerParserGetTransactionLogId
uint64_t AppLayerParserGetTransactionLogId(AppLayerParserState *pstate)
Definition: app-layer-parser.c:712
AppProtoToString
const char * AppProtoToString(AppProto alproto)
Maps the ALPROTO_*, to its string equivalent.
Definition: app-layer-protos.c:30
AppLayerParserRegisterTruncateFunc
void AppLayerParserRegisterTruncateFunc(uint8_t ipproto, AppProto alproto, void(*Truncate)(void *, uint8_t))
Definition: app-layer-parser.c:486
AppLayerParserRegisterStateProgressCompletionStatus
void AppLayerParserRegisterStateProgressCompletionStatus(AppProto alproto, const int ts, const int tc)
Definition: app-layer-parser.c:548
AppLayerParserRegisterParserAcceptableDataDirection
void AppLayerParserRegisterParserAcceptableDataDirection(uint8_t ipproto, AppProto alproto, uint8_t direction)
Definition: app-layer-parser.c:404
AppLayerParserGetStateProgressCompletionStatus
int AppLayerParserGetStateProgressCompletionStatus(AppProto alproto, uint8_t direction)
Definition: app-layer-parser.c:1150
AppLayerParserGetFirstDataDir
uint8_t AppLayerParserGetFirstDataDir(uint8_t ipproto, AppProto alproto)
Definition: app-layer-parser.c:1179
AppLayerParserProtoIsRegistered
int AppLayerParserProtoIsRegistered(uint8_t ipproto, AppProto alproto)
Definition: app-layer-parser.c:230
AppLayerParserRegisterTxFreeFunc
void AppLayerParserRegisterTxFreeFunc(uint8_t ipproto, AppProto alproto, void(*StateTransactionFree)(void *, uint64_t))
Definition: app-layer-parser.c:507
FLOW_NOPAYLOAD_INSPECTION
#define FLOW_NOPAYLOAD_INSPECTION
Definition: flow.h:64
AppLayerParserSupportsFiles
int AppLayerParserSupportsFiles(uint8_t ipproto, AppProto alproto)
Definition: app-layer-parser.c:1203
Frame::id
int64_t id
Definition: app-layer-frames.h:53
Flow_::alproto_orig
AppProto alproto_orig
Definition: flow.h:462
AppLayerParserStateProtoCleanup
void AppLayerParserStateProtoCleanup(uint8_t protomap, AppProto alproto, void *alstate, AppLayerParserState *pstate)
Definition: app-layer-parser.c:1652
AppLayerParserProtoCtx_::StateGetTxIterator
AppLayerGetTxIteratorFunc StateGetTxIterator
Definition: app-layer-parser.c:103
AppLayerParserThreadCtxFree
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
Definition: app-layer-parser.c:314
MIN
#define MIN(x, y)
Definition: suricata-common.h:380
AppLayerDecoderEventsFreeEvents
void AppLayerDecoderEventsFreeEvents(AppLayerDecoderEvents **events)
Definition: app-layer-events.c:134
StreamTcpUpdateAppLayerProgress
void StreamTcpUpdateAppLayerProgress(TcpSession *ssn, char direction, const uint32_t progress)
update reassembly progress
Definition: stream-tcp.c:6352
FramesContainer
Definition: app-layer-frames.h:73
APP_LAYER_TX_INSPECTED_FLAG
#define APP_LAYER_TX_INSPECTED_FLAG
Definition: app-layer-parser.h:81
AppLayerParserGetOptionFlags
uint32_t AppLayerParserGetOptionFlags(uint8_t protomap, AppProto alproto)
Definition: app-layer-parser.c:425
AppLayerParserRegisterGetTxFilesFunc
void AppLayerParserRegisterGetTxFilesFunc(uint8_t ipproto, AppProto alproto, AppLayerGetFileState(*GetTxFiles)(void *, void *, uint8_t))
Definition: app-layer-parser.c:458
AppLayerParserGetStateData
AppLayerStateData * AppLayerParserGetStateData(uint8_t ipproto, AppProto alproto, void *state)
Definition: app-layer-parser.c:1222
TestState
struct TestState_ TestState
app-layer-http2.h
RegisterSIPParsers
void RegisterSIPParsers(void)
Definition: app-layer-sip.c:30
app-layer-ftp.h
AppLayerFrameNewByAbsoluteOffset
Frame * AppLayerFrameNewByAbsoluteOffset(Flow *f, const StreamSlice *stream_slice, const uint64_t frame_start, const int64_t len, int dir, uint8_t frame_type)
create new frame using the absolute offset from the start of the stream
Definition: app-layer-frames.c:555
stream_config
TcpStreamCnf stream_config
Definition: stream-tcp.c:115
MAX
#define MAX(x, y)
Definition: suricata-common.h:384
APP_LAYER_PARSER_EOF_TS
#define APP_LAYER_PARSER_EOF_TS
Definition: app-layer-parser.h:39
ALPROTO_MAX
@ ALPROTO_MAX
Definition: app-layer-protos.h:75
Flow_::protoctx
void * protoctx
Definition: flow.h:447
TcpStream_::data_required
uint32_t data_required
Definition: stream-tcp-private.h:132
AppLayerIncAllocErrorCounter
void AppLayerIncAllocErrorCounter(ThreadVars *tv, Flow *f)
Definition: app-layer.c:138
AppLayerParserRegisterUnittests
void AppLayerParserRegisterUnittests(void)
Definition: app-layer-parser.c:2038
AppLayerParserGetTransactionInspectId
uint64_t AppLayerParserGetTransactionInspectId(AppLayerParserState *pstate, uint8_t direction)
Definition: app-layer-parser.c:729
RegisterKRB5Parsers
void RegisterKRB5Parsers(void)
Definition: app-layer-krb5.c:38
AppLayerDecoderEvents_
Data structure to store app layer decoder events.
Definition: app-layer-events.h:34
AppLayerParserProtoCtx_::ApplyTxConfig
bool(* ApplyTxConfig)(void *state, void *tx, int mode, AppLayerTxConfig)
Definition: app-layer-parser.c:113
FlowGetReverseProtoMapping
uint8_t FlowGetReverseProtoMapping(uint8_t rproto)
Definition: flow-util.c:112
RegisterDNP3Parsers
void RegisterDNP3Parsers(void)
Register the DNP3 application protocol parser.
Definition: app-layer-dnp3.c:1560
ConfValIsTrue
int ConfValIsTrue(const char *val)
Check if a value is true.
Definition: conf.c:536
util-unittest-helper.h
FTPParserCleanup
void FTPParserCleanup(void)
Free memory allocated for global FTP parser state.
Definition: app-layer-ftp.c:1434
AppLayerParserGetEventInfoById
int AppLayerParserGetEventInfoById(uint8_t ipproto, AppProto alproto, int event_id, const char **event_name, AppLayerEventType *event_type)
Definition: app-layer-parser.c:1168
TcpSession_::flags
uint32_t flags
Definition: stream-tcp-private.h:288
AppLayerParserState_::flags
uint16_t flags
Definition: app-layer-parser.c:141
Flow_::sgh_toserver
const struct SigGroupHead_ * sgh_toserver
Definition: flow.h:489
AppLayerParserRestoreParserTable
void AppLayerParserRestoreParserTable(void)
Definition: app-layer-parser.c:1943
AppLayerParserState_::inspect_id
uint64_t inspect_id[2]
Definition: app-layer-parser.c:145
AppLayerParserFPtr
AppLayerResult(* AppLayerParserFPtr)(Flow *f, void *protocol_state, AppLayerParserState *pstate, StreamSlice stream_slice, void *local_storage)
Prototype for parsing functions.
Definition: app-layer-parser.h:141
AppLayerParserCtx
struct AppLayerParserCtx_ AppLayerParserCtx
Flow_::alparser
AppLayerParserState * alparser
Definition: flow.h:481
AppLayerParserRegisterProtocolParsers
void AppLayerParserRegisterProtocolParsers(void)
Definition: app-layer-parser.c:1755
app-layer-krb5.h
RegisterRFBParsers
void RegisterRFBParsers(void)
Definition: app-layer-rfb.c:54
app-layer-detect-proto.h
StreamTcpInitConfig
void StreamTcpInitConfig(bool)
To initialize the stream global configuration data.
Definition: stream-tcp.c:359
UTHBuildFlow
Flow * UTHBuildFlow(int family, const char *src, const char *dst, Port sp, Port dp)
Definition: util-unittest-helper.c:521
APP_LAYER_PARSER_SFRAME_TS
#define APP_LAYER_PARSER_SFRAME_TS
Definition: app-layer-parser.h:43
app-layer-htp.h
FramesContainer::toclient
Frames toclient
Definition: app-layer-frames.h:75
AppLayerParserProtoCtx_::stream_depth
uint32_t stream_depth
Definition: app-layer-parser.c:121
AppLayerParserState_
Definition: app-layer-parser.c:139
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
AppLayerParserProtoCtx_::GetFrameIdByName
AppLayerParserGetFrameIdByNameFn GetFrameIdByName
Definition: app-layer-parser.c:117
AppLayerParserGetFrameNameById
const char * AppLayerParserGetFrameNameById(uint8_t ipproto, AppProto alproto, const uint8_t id)
Definition: app-layer-parser.c:1641
AppLayerParserGetTransactionActive
uint64_t AppLayerParserGetTransactionActive(const Flow *f, AppLayerParserState *pstate, uint8_t direction)
Definition: app-layer-parser.c:1186
AppLayerParserProtoCtx_::logger
bool logger
Definition: app-layer-parser.c:79
app-layer-ike.h
AppLayerFramesFreeContainer
void AppLayerFramesFreeContainer(Flow *f)
Definition: app-layer-parser.c:175
FLOW_PROTO_DEFAULT
@ FLOW_PROTO_DEFAULT
Definition: flow-private.h:73
app-layer-dnp3.h
alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: fuzz_applayerparserparse.c:22
AppLayerParserRegisterLogger
void AppLayerParserRegisterLogger(uint8_t ipproto, AppProto alproto)
Definition: app-layer-parser.c:477
app-layer-rfb.h
AppLayerParserRegisterGetFrameFuncs
void AppLayerParserRegisterGetFrameFuncs(uint8_t ipproto, AppProto alproto, AppLayerParserGetFrameIdByNameFn GetIdByNameFunc, AppLayerParserGetFrameNameByIdFn GetNameByIdFunc)
Definition: app-layer-parser.c:575
SCEnter
#define SCEnter(...)
Definition: util-debug.h:271
AppLayerParserProtoCtx_::SetStreamDepthFlag
void(* SetStreamDepthFlag)(void *tx, uint8_t flags)
Definition: app-layer-parser.c:115
AppLayerParserState_::min_id
uint64_t min_id
Definition: app-layer-parser.c:151
RegisterENIPTCPParsers
void RegisterENIPTCPParsers(void)
Function to register the ENIP protocol parsers and other functions.
Definition: app-layer-enip.c:570
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
AppLayerParserRegisterLoggerBits
void AppLayerParserRegisterLoggerBits(uint8_t ipproto, AppProto alproto, LoggerId bits)
Definition: app-layer-parser.c:468
AppLayerParserProtoCtx_::StateGetEventInfo
int(* StateGetEventInfo)(const char *event_name, int *event_id, AppLayerEventType *event_type)
Definition: app-layer-parser.c:108
AppLayerParserRegisterStateFuncs
void AppLayerParserRegisterStateFuncs(uint8_t ipproto, AppProto alproto, void *(*StateAlloc)(void *, AppProto), void(*StateFree)(void *))
Definition: app-layer-parser.c:431
APP_LAYER_PARSER_OPT_UNIDIR_TXS
#define APP_LAYER_PARSER_OPT_UNIDIR_TXS
Definition: app-layer-parser.h:48
APP_LAYER_PARSER_NO_REASSEMBLY
#define APP_LAYER_PARSER_NO_REASSEMBLY
Definition: app-layer-parser.h:36
IS_DISRUPTED
#define IS_DISRUPTED(flags)
Definition: app-layer-parser.c:912
AppLayerParserSetEOF
void AppLayerParserSetEOF(AppLayerParserState *pstate)
Definition: app-layer-parser.c:1531
AppLayerParserProtoCtx_::RegisterUnittests
void(* RegisterUnittests)(void)
Definition: app-layer-parser.c:131
AppLayerParserStateFree
void AppLayerParserStateFree(AppLayerParserState *pstate)
Definition: app-layer-parser.c:250
app-layer-parser.h
AppLayerParserStateCleanup
void AppLayerParserStateCleanup(const Flow *f, void *alstate, AppLayerParserState *pstate)
Definition: app-layer-parser.c:1669
TRUE
#define TRUE
Definition: suricata-common.h:33
AppLayerParserBackupParserTable
void AppLayerParserBackupParserTable(void)
Definition: app-layer-parser.c:1935
AppLayerParserProtoCtx_::StateGetEventInfoById
int(* StateGetEventInfoById)(int event_id, const char **event_name, AppLayerEventType *event_type)
Definition: app-layer-parser.c:106
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:289
AppLayerDecoderEvents_::cnt
uint8_t cnt
Definition: app-layer-events.h:38
Flow_::sgh_toclient
const struct SigGroupHead_ * sgh_toclient
Definition: flow.h:486
RegisterNFSTCPParsers
void RegisterNFSTCPParsers(void)
Definition: app-layer-nfs-tcp.c:46
AppLayerParserProtoCtx_::GetFrameNameById
AppLayerParserGetFrameNameByIdFn GetFrameNameById
Definition: app-layer-parser.c:118
AppLayerParserProtoCtx
struct AppLayerParserProtoCtx_ AppLayerParserProtoCtx
App layer protocol parser context.
ExceptionPolicy
ExceptionPolicy
Definition: util-exception-policy.h:27
FALSE
#define FALSE
Definition: suricata-common.h:34
AppLayerParserSetup
int AppLayerParserSetup(void)
Definition: app-layer-parser.c:262
SCReturn
#define SCReturn
Definition: util-debug.h:273
RegisterFTPParsers
void RegisterFTPParsers(void)
Definition: app-layer-ftp.c:1290
AppLayerParserRegisterProtocolUnittests
void AppLayerParserRegisterProtocolUnittests(uint8_t ipproto, AppProto alproto, void(*RegisterUnittests)(void))
Definition: app-layer-parser.c:1926
AppLayerGetTxIterState
Definition: app-layer-parser.h:144
AppLayerParserProtoCtx_::StateAlloc
void *(* StateAlloc)(void *, AppProto)
Definition: app-layer-parser.c:88
FlowGetProtoMapping
uint8_t FlowGetProtoMapping(uint8_t proto)
Function to map the protocol to the defined FLOW_PROTO_* enumeration.
Definition: flow-util.c:98
RegisterTFTPParsers
void RegisterTFTPParsers(void)
Definition: app-layer-tftp.c:160
ALPROTO_IMAP
@ ALPROTO_IMAP
Definition: app-layer-protos.h:35
FLOW_PROTO_APPLAYER_MAX
#define FLOW_PROTO_APPLAYER_MAX
Definition: flow-private.h:79
APP_LAYER_PARSER_EOF_TC
#define APP_LAYER_PARSER_EOF_TC
Definition: app-layer-parser.h:40
SCReturnUInt
#define SCReturnUInt(x)
Definition: util-debug.h:277
DEBUG_ASSERT_FLOW_LOCKED
#define DEBUG_ASSERT_FLOW_LOCKED(f)
Definition: util-validate.h:108
BOTH_SET_OR_BOTH_UNSET
#define BOTH_SET_OR_BOTH_UNSET(a, b)
Definition: app-layer-parser.c:1697
AppLayerParserThreadCtx_::alproto_local_storage
void * alproto_local_storage[FLOW_PROTO_MAX][ALPROTO_MAX]
Definition: app-layer-parser.c:67
Frame::len
int64_t len
Definition: app-layer-frames.h:52
AppLayerParserRegisterGetEventInfo
void AppLayerParserRegisterGetEventInfo(uint8_t ipproto, AppProto alproto, int(*StateGetEventInfo)(const char *event_name, int *event_id, AppLayerEventType *event_type))
Definition: app-layer-parser.c:585
AppLayerParserSetDecoderEvents
void AppLayerParserSetDecoderEvents(AppLayerParserState *pstate, AppLayerDecoderEvents *devents)
Definition: app-layer-parser.c:869
SCReturnPtr
#define SCReturnPtr(x, type)
Definition: util-debug.h:287
AppLayerParserProtoCtx_::StateFree
void(* StateFree)(void *)
Definition: app-layer-parser.c:89
AppLayerProtoDetectRegisterProtocol
void AppLayerProtoDetectRegisterProtocol(AppProto alproto, const char *alproto_name)
Registers a protocol for protocol detection phase.
Definition: app-layer-detect-proto.c:1909
AppLayerParserRegisterSetStreamDepthFlag
void AppLayerParserRegisterSetStreamDepthFlag(uint8_t ipproto, AppProto alproto, void(*SetStreamDepthFlag)(void *tx, uint8_t flags))
Definition: app-layer-parser.c:627
app-layer-sip.h
APP_LAYER_PARSER_SFRAME_TC
#define APP_LAYER_PARSER_SFRAME_TC
Definition: app-layer-parser.h:44
AppLayerIncParserErrorCounter
void AppLayerIncParserErrorCounter(ThreadVars *tv, Flow *f)
Definition: app-layer.c:146
ALPROTO_HTTP2
@ ALPROTO_HTTP2
Definition: app-layer-protos.h:61
RunmodeIsUnittests
int RunmodeIsUnittests(void)
Definition: suricata.c:232
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:224
RegisterRdpParsers
void RegisterRdpParsers(void)
Definition: app-layer-rdp.c:35
APP_LAYER_PARSER_NO_INSPECTION
#define APP_LAYER_PARSER_NO_INSPECTION
Definition: app-layer-parser.h:35
AppLayerParserGetTx
void * AppLayerParserGetTx(uint8_t ipproto, AppProto alproto, void *alstate, uint64_t tx_id)
Definition: app-layer-parser.c:1143
g_detect_disabled
int g_detect_disabled
Definition: suricata.c:181
AppLayerParserRegisterParser
int AppLayerParserRegisterParser(uint8_t ipproto, AppProto alproto, uint8_t direction, AppLayerParserFPtr Parser)
Register app layer parser for the protocol.
Definition: app-layer-parser.c:392
UTHFreeFlow
void UTHFreeFlow(Flow *flow)
Definition: util-unittest-helper.c:526
Frame::flags
uint8_t flags
Definition: app-layer-frames.h:47
AppLayerParserThreadCtxAlloc
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
Definition: app-layer-parser.c:293
AppLayerParserRegisterGetTx
void AppLayerParserRegisterGetTx(uint8_t ipproto, AppProto alproto, void *(StateGetTx)(void *alstate, uint64_t tx_id))
Definition: app-layer-parser.c:529
ConfigAction
ConfigAction
Definition: util-config.h:27
AppLayerParserStateSetFlag
void AppLayerParserStateSetFlag(AppLayerParserState *pstate, uint16_t flag)
Definition: app-layer-parser.c:1814
AppLayerParserProtoCtx_::Parser
AppLayerParserFPtr Parser[2]
Definition: app-layer-parser.c:77
app-layer-modbus.h
AppLayerTxData
struct AppLayerTxData AppLayerTxData
Definition: detect.h:1305
AppLayerParserProtoCtx_::StateTransactionFree
void(* StateTransactionFree)(void *, uint64_t)
Definition: app-layer-parser.c:90
app-layer-enip.h
app-layer-frames.h
SCReturnStruct
#define SCReturnStruct(x)
Definition: util-debug.h:291
RegisterSSLParsers
void RegisterSSLParsers(void)
Function to register the SSL protocol parser and other functions.
Definition: app-layer-ssl.c:2956
AppLayerParserProtoCtx_::option_flags
uint32_t option_flags
Definition: app-layer-parser.c:124
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
StreamTcpSetSessionNoReassemblyFlag
void StreamTcpSetSessionNoReassemblyFlag(TcpSession *, char)
disable reassembly
Definition: stream-tcp.c:6372
StreamTcpFreeConfig
void StreamTcpFreeConfig(bool quiet)
Definition: stream-tcp.c:695
ExceptionPolicyParse
enum ExceptionPolicy ExceptionPolicyParse(const char *option, const bool support_flow)
Definition: util-exception-policy.c:120
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:1323
AppLayerParserGetFrameNameByIdFn
const char *(* AppLayerParserGetFrameNameByIdFn)(const uint8_t id)
Definition: app-layer-parser.h:160
StreamTcpDisableAppLayer
void StreamTcpDisableAppLayer(Flow *f)
Definition: stream-tcp-reassemble.c:445
suricata-common.h
AppLayerParserGetFrameIdByName
int AppLayerParserGetFrameIdByName(uint8_t ipproto, AppProto alproto, const char *name)
Definition: app-layer-parser.c:1632
ALPROTO_HTTP1
@ ALPROTO_HTTP1
Definition: app-layer-protos.h:30
AppLayerParserProtoCtx_::internal_flags
uint32_t internal_flags
Definition: app-layer-parser.c:127
AppLayerParserRegisterApplyTxConfigFunc
void AppLayerParserRegisterApplyTxConfigFunc(uint8_t ipproto, AppProto alproto, bool(*ApplyTxConfig)(void *state, void *tx, int mode, AppLayerTxConfig))
Definition: app-layer-parser.c:617
RegisterENIPUDPParsers
void RegisterENIPUDPParsers(void)
Function to register the ENIP protocol parsers and other functions.
Definition: app-layer-enip.c:485
AppLayerParserRegisterStateDataFunc
void AppLayerParserRegisterStateDataFunc(uint8_t ipproto, AppProto alproto, AppLayerStateData *(*GetStateData)(void *state))
Definition: app-layer-parser.c:607
FilesPrune
void FilesPrune(FileContainer *fc, const StreamingBufferConfig *sbcfg, const bool trunc)
Definition: util-file.c:1205
AppLayerIncInternalErrorCounter
void AppLayerIncInternalErrorCounter(ThreadVars *tv, Flow *f)
Definition: app-layer.c:154
AppLayerParserGetTxData
AppLayerTxData * AppLayerParserGetTxData(uint8_t ipproto, AppProto alproto, void *tx)
Definition: app-layer-parser.c:1215
FatalError
#define FatalError(...)
Definition: util-debug.h:502
AppLayerParserRegisterTxDataFunc
void AppLayerParserRegisterTxDataFunc(uint8_t ipproto, AppProto alproto, AppLayerTxData *(*GetTxData)(void *tx))
Definition: app-layer-parser.c:597
TcpSession_::client
TcpStream client
Definition: stream-tcp-private.h:291
AppLayerParserGetStreamDepth
uint32_t AppLayerParserGetStreamDepth(const Flow *f)
Definition: app-layer-parser.c:1613
AppLayerFrameGetById
Frame * AppLayerFrameGetById(Flow *f, const int dir, const FrameId frame_id)
Definition: app-layer-frames.c:651
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
util-validate.h
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
RegisterSNMPParsers
void RegisterSNMPParsers(void)
Definition: app-layer-snmp.c:39
FRAME_STREAM_TYPE
#define FRAME_STREAM_TYPE
Definition: app-layer-frames.h:30
APP_LAYER_PARSER_OPT_ACCEPT_GAPS
#define APP_LAYER_PARSER_OPT_ACCEPT_GAPS
Definition: app-layer-parser.h:47
TcpSession_::server
TcpStream server
Definition: stream-tcp-private.h:290
AppLayerParserRegisterGetTxIterator
void AppLayerParserRegisterGetTxIterator(uint8_t ipproto, AppProto alproto, AppLayerGetTxIteratorFunc Func)
Definition: app-layer-parser.c:540
AppLayerFramesGetContainer
FramesContainer * AppLayerFramesGetContainer(Flow *f)
Definition: app-layer-parser.c:183
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
AppLayerParserProtoCtx_::complete_ts
int complete_ts
Definition: app-layer-parser.c:104
SCFree
#define SCFree(p)
Definition: util-mem.h:61
ConfNode_
Definition: conf.h:32
Flow_::alstate
void * alstate
Definition: flow.h:482
AppLayerParserPostStreamSetup
void AppLayerParserPostStreamSetup(void)
Definition: app-layer-parser.c:269
Flow_::flags
uint32_t flags
Definition: flow.h:427
AppLayerParserGetDecoderEvents
AppLayerDecoderEvents * AppLayerParserGetDecoderEvents(AppLayerParserState *pstate)
Definition: app-layer-parser.c:861
THREE_SET
#define THREE_SET(a, b, c)
Definition: app-layer-parser.c:1699
TestState_::test
uint8_t test
Definition: app-layer-parser.c:1875
AppLayerParserRegisterGetEventInfoById
void AppLayerParserRegisterGetEventInfoById(uint8_t ipproto, AppProto alproto, int(*StateGetEventInfoById)(int event_id, const char **event_name, AppLayerEventType *event_type))
Definition: app-layer-parser.c:563
AppLayerGetProtoName
const char * AppLayerGetProtoName(AppProto alproto)
Given the internal protocol id, returns a string representation of the protocol.
Definition: app-layer.c:939
UTHAppLayerParserStateGetIds
void UTHAppLayerParserStateGetIds(void *ptr, uint64_t *i1, uint64_t *i2, uint64_t *log, uint64_t *min)
Definition: app-layer-parser.c:216
ConfValIsFalse
int ConfValIsFalse(const char *val)
Check if a value is false.
Definition: conf.c:561
RegisterHTPParsers
void RegisterHTPParsers(void)
Register the HTTP protocol and state handling functions to APP layer of the engine.
Definition: app-layer-htp.c:3184
ALPROTO_HTTP
@ ALPROTO_HTTP
Definition: app-layer-protos.h:66
AppLayerIncTxCounter
void AppLayerIncTxCounter(ThreadVars *tv, Flow *f, uint64_t step)
Definition: app-layer.c:122
FRAME_FLAG_ENDS_AT_EOF
#define FRAME_FLAG_ENDS_AT_EOF
Definition: app-layer-frames.h:40
APP_LAYER_PARSER_TRUNC_TC
#define APP_LAYER_PARSER_TRUNC_TC
Definition: app-layer-parser.h:42
app-layer-snmp.h
RegisterSMTPParsers
void RegisterSMTPParsers(void)
Register the SMTP Protocol parser.
Definition: app-layer-smtp.c:1769
AppLayerParserStateAlloc
AppLayerParserState * AppLayerParserStateAlloc(void)
Definition: app-layer-parser.c:237
SCReturnCT
#define SCReturnCT(x, type)
Definition: util-debug.h:285
STREAMTCP_FLAG_APP_LAYER_DISABLED
#define STREAMTCP_FLAG_APP_LAYER_DISABLED
Definition: stream-tcp-private.h:200
AppLayerParserState_::decoder_events
AppLayerDecoderEvents * decoder_events
Definition: app-layer-parser.c:154
AppLayerParserRegisterGetTxCnt
void AppLayerParserRegisterGetTxCnt(uint8_t ipproto, AppProto alproto, uint64_t(*StateGetTxCnt)(void *alstate))
Definition: app-layer-parser.c:518
APP_LAYER_ERROR
#define APP_LAYER_ERROR
Definition: app-layer-parser.h:92
app-layer-smb.h
FLOW_PROTO_MAX
@ FLOW_PROTO_MAX
Definition: flow-private.h:76
app-layer-mqtt.h
AppLayerParserProtoCtx_::StateGetProgress
int(* StateGetProgress)(void *alstate, uint8_t direction)
Definition: app-layer-parser.c:100
AppLayerParserProtocolGetLoggerBits
LoggerId AppLayerParserProtocolGetLoggerBits(uint8_t ipproto, AppProto alproto)
Definition: app-layer-parser.c:1583
AppLayerParserCtx_
Definition: app-layer-parser.c:135
AppLayerGetTxIteratorFunc
AppLayerGetTxIterTuple(* AppLayerGetTxIteratorFunc)(const uint8_t ipproto, const AppProto alproto, void *alstate, uint64_t min_tx_id, uint64_t max_tx_id, AppLayerGetTxIterState *state)
tx iterator prototype
Definition: app-layer-parser.h:153
g_file_logger_enabled
bool g_file_logger_enabled
Definition: output-file.c:39
likely
#define likely(expr)
Definition: util-optimize.h:32
AppLayerParserGetTxFiles
AppLayerGetFileState AppLayerParserGetTxFiles(const Flow *f, void *state, void *tx, const uint8_t direction)
Definition: app-layer-parser.c:890
RegisterHTTP2Parsers
void RegisterHTTP2Parsers(void)
Definition: app-layer-http2.c:56
STREAM_APP_PROGRESS
#define STREAM_APP_PROGRESS(stream)
Definition: stream-tcp-private.h:144
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:66
AppLayerProtoDetectPMRegisterPatternCS
int AppLayerProtoDetectPMRegisterPatternCS(uint8_t ipproto, AppProto alproto, const char *pattern, uint16_t depth, uint16_t offset, uint8_t direction)
Registers a case-sensitive pattern for protocol detection.
Definition: app-layer-detect-proto.c:1805
app-layer-smtp.h
APP_LAYER_PARSER_NO_INSPECTION_PAYLOAD
#define APP_LAYER_PARSER_NO_INSPECTION_PAYLOAD
Definition: app-layer-parser.h:37
FlowChangeProto
int FlowChangeProto(Flow *f)
Check if change proto flag is set for flow.
Definition: flow.c:230
FlowGetDisruptionFlags
uint8_t FlowGetDisruptionFlags(const Flow *f, uint8_t flags)
get 'disruption' flags: GAP/DEPTH/PASS
Definition: flow.c:1151
TcpSession_
Definition: stream-tcp-private.h:279
APP_LAYER_PARSER_TRUNC_TS
#define APP_LAYER_PARSER_TRUNC_TS
Definition: app-layer-parser.h:41
flow.h
AppLayerParserStateIssetFlag
uint16_t AppLayerParserStateIssetFlag(AppLayerParserState *pstate, uint16_t flag)
Definition: app-layer-parser.c:1822
SCLogNotice
#define SCLogNotice(...)
Macro used to log NOTICE messages.
Definition: util-debug.h:237
RegisterNFSUDPParsers
void RegisterNFSUDPParsers(void)
Definition: app-layer-nfs-udp.c:63
Flow_::file_flags
uint16_t file_flags
Definition: flow.h:429
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:456
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
AppLayerParserDestroyProtocolParserLocalStorage
void AppLayerParserDestroyProtocolParserLocalStorage(uint8_t ipproto, AppProto alproto, void *local_data)
Definition: app-layer-parser.c:654
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:275
AppLayerParserGetTxCnt
uint64_t AppLayerParserGetTxCnt(const Flow *f, void *alstate)
Definition: app-layer-parser.c:1136
AppLayerProtoDetectConfProtoDetectionEnabled
int AppLayerProtoDetectConfProtoDetectionEnabled(const char *ipproto, const char *alproto)
Given a protocol name, checks if proto detection is enabled in the conf file.
Definition: app-layer-detect-proto.c:2079
SMTPParserCleanup
void SMTPParserCleanup(void)
Free memory allocated for global SMTP parser state.
Definition: app-layer-smtp.c:1824
AppLayerParserHasDecoderEvents
bool AppLayerParserHasDecoderEvents(AppLayerParserState *pstate)
Definition: app-layer-parser.c:1547
RegisterMQTTParsers
void RegisterMQTTParsers(void)
Definition: app-layer-mqtt.c:37
AppLayerParserGetFrameIdByNameFn
int(* AppLayerParserGetFrameIdByNameFn)(const char *frame_name)
Definition: app-layer-parser.h:159
AppLayerDecoderEvents_::events
uint8_t * events
Definition: app-layer-events.h:36
AppLayerParserState_::frames
FramesContainer * frames
Definition: app-layer-parser.c:156
StreamTcpSetSessionBypassFlag
void StreamTcpSetSessionBypassFlag(TcpSession *)
enable bypass
Definition: stream-tcp.c:6399
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:111
app-layer-ssl.h
TestState_
Definition: app-layer-parser.c:1874
app-layer-ntp.h
EXCEPTION_POLICY_NOT_SET
@ EXCEPTION_POLICY_NOT_SET
Definition: util-exception-policy.h:28
AppLayerParserProtoCtx_::LocalStorageAlloc
void *(* LocalStorageAlloc)(void)
Definition: app-layer-parser.c:91
app-layer-nfs-tcp.h
app-layer-rdp.h
app-layer.h
AppLayerParserGetEventInfo
int AppLayerParserGetEventInfo(uint8_t ipproto, AppProto alproto, const char *event_name, int *event_id, AppLayerEventType *event_type)
Definition: app-layer-parser.c:1158
AppLayerParserProtoCtx_::first_data_dir
uint8_t first_data_dir
Definition: app-layer-parser.c:84