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