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