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