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