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