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