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