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