• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OISF / suricata / 23374838686

21 Mar 2026 07:29AM UTC coverage: 59.341% (-20.0%) from 79.315%
23374838686

Pull #15075

github

web-flow
Merge 90b4e834f into 6587e363a
Pull Request #15075: Stack 8001 v16.4

38 of 70 new or added lines in 10 files covered. (54.29%)

34165 existing lines in 563 files now uncovered.

119621 of 201584 relevant lines covered (59.34%)

650666.92 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.83
/src/app-layer-parser.h
1
/* Copyright (C) 2007-2025 Open Information Security Foundation
2
 *
3
 * You can copy, redistribute or modify this Program under the terms of
4
 * the GNU General Public License version 2 as published by the Free
5
 * Software Foundation.
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * version 2 along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15
 * 02110-1301, USA.
16
 */
17

18
/**
19
 * \file
20
 *
21
 * \author Victor Julien <victor@inliniac.net>
22
 * \author Anoop Saldanha <anoopsaldanha@gmail.com>
23
 */
24

25
#ifndef SURICATA_APP_LAYER_PARSER_H
26
#define SURICATA_APP_LAYER_PARSER_H
27

28
#include "app-layer-protos.h"
29
#include "app-layer-events.h"
30
#include "detect-engine-state.h"
31
// Forward declarations for bindgen
32
enum ConfigAction;
33
typedef struct Flow_ Flow;
34
typedef struct AppLayerParserState_ AppLayerParserState;
35
typedef struct AppLayerDecoderEvents_ AppLayerDecoderEvents;
36
typedef struct ThreadVars_ ThreadVars;
37
typedef struct File_ File;
38
typedef enum LoggerId LoggerId;
39
// Forward declarations from util-file.h
40
typedef struct AppLayerGetFileState AppLayerGetFileState;
41

42
/* Flags for AppLayerParserState. */
43
// flag available                               BIT_U16(0)
44
#define APP_LAYER_PARSER_NO_INSPECTION         BIT_U16(1)
2,069,274✔
45
#define APP_LAYER_PARSER_NO_REASSEMBLY         BIT_U16(2)
34✔
46
#define APP_LAYER_PARSER_NO_INSPECTION_PAYLOAD BIT_U16(3)
539,202✔
47
#define APP_LAYER_PARSER_BYPASS_READY          BIT_U16(4)
610✔
48
#define APP_LAYER_PARSER_EOF_TS                BIT_U16(5)
846,473✔
49
#define APP_LAYER_PARSER_EOF_TC                BIT_U16(6)
778,750✔
50
/* 2x vacancy */
51
#define APP_LAYER_PARSER_SFRAME_TS             BIT_U16(9)
325,084✔
52
#define APP_LAYER_PARSER_SFRAME_TC             BIT_U16(10)
253,955✔
53

54
/* Flags for AppLayerParserProtoCtx. */
55
#define APP_LAYER_PARSER_OPT_ACCEPT_GAPS BIT_U32(0)
9,194✔
56

57
#define APP_LAYER_PARSER_INT_STREAM_DEPTH_SET   BIT_U32(0)
244✔
58

59
/* for use with the detect_progress_ts|detect_progress_tc fields */
60

61
/** should inspection be skipped in that direction */
62
#define APP_LAYER_TX_SKIP_INSPECT_TS BIT_U8(0)
1,701,862✔
63
#define APP_LAYER_TX_SKIP_INSPECT_TC BIT_U8(1)
1,756,703✔
64
/** is tx fully inspected? */
65
#define APP_LAYER_TX_INSPECTED_TS BIT_U8(2)
4,330,582✔
66
#define APP_LAYER_TX_INSPECTED_TC BIT_U8(3)
2,154,985✔
67
/** accept is applied to entire tx */
UNCOV
68
#define APP_LAYER_TX_ACCEPT BIT_U8(4)
×
69

70
/** parser has successfully processed in the input, and has consumed
71
 *  all of it. */
72
#define APP_LAYER_OK (AppLayerResult) { 0, 0, 0 }
20,824✔
73

74
/** parser has hit an unrecoverable error. Returning this to the API
75
 *  leads to no further calls to the parser. */
76
#define APP_LAYER_ERROR (AppLayerResult) { -1, 0, 0 }
9,925✔
77

78
/** parser needs more data. Through 'c' it will indicate how many
79
 *  of the input bytes it has consumed. Through 'n' it will indicate
80
 *  how many more bytes it needs before getting called again.
81
 *  \note consumed (c) should never be more than the input len
82
 *        needed (n) + consumed (c) should be more than the input len
83
 */
84
#define APP_LAYER_INCOMPLETE(c,n) (AppLayerResult) { 1, (c), (n) }
85

86
int AppLayerParserProtoIsRegistered(uint8_t ipproto, AppProto alproto);
87

88
/***** transaction handling *****/
89

90
int AppLayerParserSetup(void);
91
void AppLayerParserPostStreamSetup(void);
92
int AppLayerParserDeSetup(void);
93

94
typedef struct AppLayerParserThreadCtx_ AppLayerParserThreadCtx;
95

96
/**
97
 * \brief Gets a new app layer protocol's parser thread context.
98
 *
99
 * \retval Non-NULL pointer on success.
100
 *         NULL pointer on failure.
101
 */
102
AppLayerParserThreadCtx *AppLayerParserThreadCtxAlloc(void);
103

104
/**
105
 * \brief Destroys the app layer parser thread context obtained
106
 *        using AppLayerParserThreadCtxAlloc().
107
 *
108
 * \param tctx Pointer to the thread context to be destroyed.
109
 */
110
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx);
111

112
/**
113
 * \brief Given a protocol name, checks if the parser is enabled in
114
 *        the conf file.
115
 *
116
 * \param alproto_name Name of the app layer protocol.
117
 *
118
 * \retval 1 If enabled.
119
 * \retval 0 If disabled.
120
 */
121
int SCAppLayerParserConfParserEnabled(const char *ipproto, const char *alproto_name);
122

123
enum ExceptionPolicy AppLayerErrorGetExceptionPolicy(void);
124

125
typedef struct AppLayerResult {
126
    int32_t status;
127
    uint32_t consumed;
128
    uint32_t needed;
129
} AppLayerResult;
130

131
typedef struct StreamSlice {
132
    const uint8_t *input;
133
    uint32_t input_len;
134
    /// STREAM_* flags
135
    uint8_t flags;
136
    uint64_t offset;
137
} StreamSlice;
138

139
static inline const uint8_t *StreamSliceGetData(const StreamSlice *stream_slice)
140
{
145,859✔
141
    return stream_slice->input;
145,859✔
142
}
145,859✔
143

144
static inline uint32_t StreamSliceGetDataLen(const StreamSlice *stream_slice)
145
{
145,859✔
146
    return stream_slice->input_len;
145,859✔
147
}
145,859✔
148

149
/** \brief Prototype for parsing functions */
150
typedef AppLayerResult (*AppLayerParserFPtr)(Flow *f, void *protocol_state,
151
        AppLayerParserState *pstate, StreamSlice stream_slice, void *local_storage);
152

153
typedef struct AppLayerGetTxIterState {
154
    union {
155
        void *ptr;
156
        uint64_t u64;
157
    } un;
158
} AppLayerGetTxIterState;
159

160
typedef struct AppLayerStateData {
161
    uint16_t file_flags;
162
} AppLayerStateData;
163

164
typedef struct AppLayerGetTxIterTuple {
165
    void *tx_ptr;
166
    uint64_t tx_id;
167
    bool has_next;
168
} AppLayerGetTxIterTuple;
169

170
typedef struct AppLayerTxConfig {
171
    /// config: log flags
172
    uint8_t log_flags;
173
} AppLayerTxConfig;
174

175
typedef struct GenericVar_ GenericVar;
176

177
typedef struct AppLayerTxData {
178
    /// config: log flags
179
    AppLayerTxConfig config;
180

181
    /// The tx has been updated and needs to be processed : detection, logging, cleaning
182
    /// It can then be skipped until new data arrives.
183
    /// There is a boolean for both directions : to server and to client
184
    bool updated_tc;
185
    bool updated_ts;
186

187
    uint8_t flags;
188

189
    /// logger flags for tx logging api
190
    uint32_t logged;
191

192
    /// track file open/logs so we can know how long to keep the tx
193
    uint32_t files_opened;
194
    uint32_t files_logged;
195
    uint32_t files_stored;
196

197
    uint16_t file_flags;
198

199
    /// Indicated if a file tracking tx, and if so in which direction:
200
    ///  0: not a file tx
201
    /// STREAM_TOSERVER: file tx, files only in toserver dir
202
    /// STREAM_TOCLIENT: file tx , files only in toclient dir
203
    /// STREAM_TOSERVER|STREAM_TOCLIENT: files possible in both dirs
204
    uint8_t file_tx;
205
    /// Number of times this tx data has already been logged for signatures
206
    /// not using application layer keywords
207
    uint8_t guessed_applayer_logged;
208

209
    /// detection engine progress tracking for use by detection engine
210
    /// Reflects the "progress" of prefilter engines into this TX, where
211
    /// the value is offset by 1. So if for progress state 0 the engines
212
    /// are done, the value here will be 1. So a value of 0 means, no
213
    /// progress tracked yet.
214
    ///
215
    uint8_t detect_progress_ts;
216
    uint8_t detect_progress_tc;
217

218
    DetectEngineState *de_state;
219
    AppLayerDecoderEvents *events;
220
    GenericVar *txbits;
221
} AppLayerTxData;
222

223
void SCAppLayerTxDataCleanup(AppLayerTxData *txd);
224

225
/** \brief tx iterator prototype */
226
typedef AppLayerGetTxIterTuple (*AppLayerGetTxIteratorFunc)
227
       (const uint8_t ipproto, const AppProto alproto,
228
        void *alstate, uint64_t min_tx_id, uint64_t max_tx_id,
229
        AppLayerGetTxIterState *state);
230

231
/***** Parser related registration *****/
232

233
/**
234
 *  \param name progress name to get the id for
235
 *  \param direction STREAM_TOSERVER/STREAM_TOCLIENT
236
 */
237
typedef int (*AppLayerParserGetStateIdByNameFn)(const char *name, const uint8_t direction);
238
/**
239
 *  \param id progress value id to get the name for
240
 *  \param direction STREAM_TOSERVER/STREAM_TOCLIENT
241
 */
242
typedef const char *(*AppLayerParserGetStateNameByIdFn)(const int id, const uint8_t direction);
243

244
typedef int (*AppLayerParserGetFrameIdByNameFn)(const char *frame_name);
245
typedef const char *(*AppLayerParserGetFrameNameByIdFn)(const uint8_t id);
246

247
int SCAppLayerParserReallocCtx(AppProto alproto);
248
int AppLayerParserPreRegister(void (*Register)(void));
249
/**
250
 * \brief Register app layer parser for the protocol.
251
 *
252
 * \retval 0 On success.
253
 * \retval -1 On failure.
254
 */
255
int AppLayerParserRegisterParser(uint8_t ipproto, AppProto alproto,
256
                      uint8_t direction,
257
                      AppLayerParserFPtr Parser);
258
void SCAppLayerParserRegisterParserAcceptableDataDirection(
259
        uint8_t ipproto, AppProto alproto, uint8_t direction);
260
void AppLayerParserRegisterOptionFlags(uint8_t ipproto, AppProto alproto,
261
        uint32_t flags);
262
void AppLayerParserRegisterStateFuncs(uint8_t ipproto, AppProto alproto,
263
        void *(*StateAlloc)(void *, AppProto), void (*StateFree)(void *));
264
void AppLayerParserRegisterLocalStorageFunc(uint8_t ipproto, AppProto proto,
265
        void *(*LocalStorageAlloc)(void), void (*LocalStorageFree)(void *));
266
// void AppLayerParserRegisterGetEventsFunc(uint8_t ipproto, AppProto proto,
267
//     AppLayerDecoderEvents *(*StateGetEvents)(void *) __attribute__((nonnull)));
268
void AppLayerParserRegisterGetTxFilesFunc(
269
        uint8_t ipproto, AppProto alproto, AppLayerGetFileState (*GetTxFiles)(void *, uint8_t));
270
void SCAppLayerParserRegisterLogger(uint8_t ipproto, AppProto alproto);
271
void AppLayerParserRegisterLoggerBits(uint8_t ipproto, AppProto alproto, LoggerId bits);
272
void AppLayerParserRegisterGetStateProgressFunc(uint8_t ipproto, AppProto alproto,
273
    int (*StateGetStateProgress)(void *alstate, uint8_t direction));
274
void AppLayerParserRegisterTxFreeFunc(uint8_t ipproto, AppProto alproto,
275
                           void (*StateTransactionFree)(void *, uint64_t));
276
void AppLayerParserRegisterGetTxCnt(uint8_t ipproto, AppProto alproto,
277
                         uint64_t (*StateGetTxCnt)(void *alstate));
278
void AppLayerParserRegisterGetTx(uint8_t ipproto, AppProto alproto,
279
                      void *(StateGetTx)(void *alstate, uint64_t tx_id));
280
void AppLayerParserRegisterGetTxIterator(uint8_t ipproto, AppProto alproto,
281
                      AppLayerGetTxIteratorFunc Func);
282
void AppLayerParserRegisterStateProgressCompletionStatus(
283
        AppProto alproto, const int ts, const int tc);
284
void AppLayerParserRegisterGetEventInfo(uint8_t ipproto, AppProto alproto,
285
        int (*StateGetEventInfo)(
286
                const char *event_name, uint8_t *event_id, AppLayerEventType *event_type));
287
void AppLayerParserRegisterGetEventInfoById(uint8_t ipproto, AppProto alproto,
288
        int (*StateGetEventInfoById)(
289
                uint8_t event_id, const char **event_name, AppLayerEventType *event_type));
290
void AppLayerParserRegisterGetFrameFuncs(uint8_t ipproto, AppProto alproto,
291
        AppLayerParserGetFrameIdByNameFn GetFrameIdByName,
292
        AppLayerParserGetFrameNameByIdFn GetFrameNameById);
293
void AppLayerParserRegisterSetStreamDepthFlag(uint8_t ipproto, AppProto alproto,
294
        void (*SetStreamDepthFlag)(void *tx, uint8_t flags));
295
void AppLayerParserRegisterGetStateFuncs(uint8_t ipproto, AppProto alproto,
296
        AppLayerParserGetStateIdByNameFn GetStateIdByName,
297
        AppLayerParserGetStateNameByIdFn GetStateNameById);
298

299
void AppLayerParserRegisterTxDataFunc(uint8_t ipproto, AppProto alproto,
300
        AppLayerTxData *(*GetTxData)(void *tx));
301
void AppLayerParserRegisterApplyTxConfigFunc(uint8_t ipproto, AppProto alproto,
302
        void (*ApplyTxConfig)(void *state, void *tx, int mode, AppLayerTxConfig));
303
void AppLayerParserRegisterStateDataFunc(
304
        uint8_t ipproto, AppProto alproto, AppLayerStateData *(*GetStateData)(void *state));
305

306
/***** Get and transaction functions *****/
307

308
AppLayerGetTxIteratorFunc AppLayerGetTxIterator(const uint8_t ipproto,
309
         const AppProto alproto);
310

311
void *AppLayerParserGetProtocolParserLocalStorage(uint8_t ipproto, AppProto alproto);
312
void AppLayerParserDestroyProtocolParserLocalStorage(uint8_t ipproto, AppProto alproto,
313
                                          void *local_data);
314

315

316
uint64_t AppLayerParserGetTransactionLogId(AppLayerParserState *pstate);
317
uint64_t AppLayerParserGetMinId(AppLayerParserState *pstate);
318
void AppLayerParserSetTransactionLogId(AppLayerParserState *pstate, uint64_t tx_id);
319

320
uint64_t AppLayerParserGetTransactionInspectId(AppLayerParserState *pstate, uint8_t direction);
321
void AppLayerParserSetTransactionInspectId(const Flow *f, AppLayerParserState *pstate,
322
                                void *alstate, const uint8_t flags, bool tag_txs_as_inspected);
323

324
AppLayerDecoderEvents *AppLayerParserGetDecoderEvents(AppLayerParserState *pstate);
325
AppLayerDecoderEvents *AppLayerParserGetEventsByTx(uint8_t ipproto, AppProto alproto, void *tx);
326
AppLayerGetFileState AppLayerParserGetTxFiles(const Flow *f, void *tx, const uint8_t direction);
327
int AppLayerParserGetStateProgress(uint8_t ipproto, AppProto alproto,
328
                        void *alstate, uint8_t direction);
329
uint64_t AppLayerParserGetTxCnt(const Flow *, void *alstate);
330
void *AppLayerParserGetTx(uint8_t ipproto, AppProto alproto, void *alstate, uint64_t tx_id);
331
int AppLayerParserGetStateProgressCompletionStatus(AppProto alproto, uint8_t direction);
332
int AppLayerParserGetEventInfo(uint8_t ipproto, AppProto alproto, const char *event_name,
333
        uint8_t *event_id, AppLayerEventType *event_type);
334
int AppLayerParserGetEventInfoById(uint8_t ipproto, AppProto alproto, uint8_t event_id,
335
        const char **event_name, AppLayerEventType *event_type);
336

337
uint64_t AppLayerParserGetTransactionActive(const Flow *f, AppLayerParserState *pstate, uint8_t direction);
338

339
uint8_t AppLayerParserGetFirstDataDir(uint8_t ipproto, AppProto alproto);
340

341
bool AppLayerParserSupportsFiles(uint8_t ipproto, AppProto alproto);
342

343
AppLayerTxData *AppLayerParserGetTxData(uint8_t ipproto, AppProto alproto, void *tx);
344
uint8_t AppLayerParserGetTxDetectProgress(AppLayerTxData *txd, const uint8_t dir);
345
AppLayerStateData *AppLayerParserGetStateData(uint8_t ipproto, AppProto alproto, void *state);
346
void AppLayerParserApplyTxConfig(uint8_t ipproto, AppProto alproto,
347
        void *state, void *tx, enum ConfigAction mode, AppLayerTxConfig);
348

349
/** \brief check if tx (possibly) has files in this tx for the direction */
350
#define AppLayerParserHasFilesInDir(txd, direction)                                                \
351
    ((txd)->files_opened && ((txd)->file_tx & (direction)) != 0)
4,085,426✔
352

353
/***** General *****/
354

355
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *tctx, Flow *f, AppProto alproto,
356
                   uint8_t flags, const uint8_t *input, uint32_t input_len);
357
void AppLayerParserSetEOF(AppLayerParserState *pstate);
358
bool AppLayerParserHasDecoderEvents(AppLayerParserState *pstate);
359
int AppLayerParserProtocolHasLogger(uint8_t ipproto, AppProto alproto);
360
LoggerId AppLayerParserProtocolGetLoggerBits(uint8_t ipproto, AppProto alproto);
361
void SCAppLayerParserTriggerRawStreamInspection(Flow *f, int direction);
362
void SCAppLayerParserSetStreamDepth(uint8_t ipproto, AppProto alproto, uint32_t stream_depth);
363
uint32_t AppLayerParserGetStreamDepth(const Flow *f);
364
void AppLayerParserSetStreamDepthFlag(uint8_t ipproto, AppProto alproto, void *state, uint64_t tx_id, uint8_t flags);
365
int AppLayerParserIsEnabled(AppProto alproto);
366
int AppLayerParserGetFrameIdByName(uint8_t ipproto, AppProto alproto, const char *name);
367
const char *AppLayerParserGetFrameNameById(uint8_t ipproto, AppProto alproto, const uint8_t id);
368
/**
369
 *  \param name progress name to get the id for
370
 *  \param direction STREAM_TOSERVER/STREAM_TOCLIENT
371
 */
372
int AppLayerParserGetStateIdByName(
373
        uint8_t ipproto, AppProto alproto, const char *name, uint8_t direction);
374
/**
375
 *  \param id progress value id to get the name for
376
 *  \param direction STREAM_TOSERVER/STREAM_TOCLIENT
377
 */
378
const char *AppLayerParserGetStateNameById(
379
        uint8_t ipproto, AppProto alproto, const int id, uint8_t direction);
380

381
/***** Cleanup *****/
382

383
void AppLayerParserStateProtoCleanup(
384
        uint8_t protomap, AppProto alproto, void *alstate, AppLayerParserState *pstate);
385
void AppLayerParserStateCleanup(const Flow *f, void *alstate, AppLayerParserState *pstate);
386

387
void AppLayerParserRegisterProtocolParsers(void);
388

389
void SCAppLayerParserStateSetFlag(AppLayerParserState *pstate, uint16_t flag);
390
uint16_t SCAppLayerParserStateIssetFlag(AppLayerParserState *pstate, uint16_t flag);
391

392
AppLayerParserState *AppLayerParserStateAlloc(void);
393
void AppLayerParserStateFree(AppLayerParserState *pstate);
394

395
void AppLayerParserTransactionsCleanup(Flow *f, const uint8_t pkt_dir);
396

397
/***** Unittests *****/
398

399
#ifdef UNITTESTS
400
void AppLayerParserRegisterProtocolUnittests(uint8_t ipproto, AppProto alproto,
401
                                  void (*RegisterUnittests)(void));
402
void AppLayerParserRegisterUnittests(void);
403
void UTHAppLayerParserStateGetIds(void *ptr, uint64_t *i1, uint64_t *i2, uint64_t *log, uint64_t *min);
404
#endif
405

406
void AppLayerFramesFreeContainer(Flow *f);
407
void FileApplyTxFlags(const AppLayerTxData *txd, const uint8_t direction, File *file);
408

409
#endif /* SURICATA_APP_LAYER_PARSER_H */
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc