]> git.ipfire.org Git - people/ms/suricata.git/blame - src/app-layer-parser.c
Rust gen-c-headers: keep 'const' attribute
[people/ms/suricata.git] / src / app-layer-parser.c
CommitLineData
5532af46 1/* Copyright (C) 2007-2013 Open Information Security Foundation
ce019275
WM
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 */
8e10844f 25
ecf86f9c 26#include "suricata-common.h"
8e10844f 27#include "debug.h"
c1e485cc 28#include "util-unittest.h"
8e10844f
VJ
29#include "decode.h"
30#include "threads.h"
31
32#include "util-print.h"
33#include "util-pool.h"
34
cc76aa4b 35#include "flow-util.h"
429c6388 36#include "flow-private.h"
cc76aa4b 37
0e4235cc 38#include "detect-engine-state.h"
d9686fae 39#include "detect-engine-port.h"
0e4235cc 40
6a53ab9c 41#include "stream-tcp.h"
8e10844f
VJ
42#include "stream-tcp-private.h"
43#include "stream.h"
a16e7b74 44#include "stream-tcp-reassemble.h"
8e10844f 45
e1022ee5 46#include "app-layer.h"
8e10844f
VJ
47#include "app-layer-protos.h"
48#include "app-layer-parser.h"
000ce98c 49#include "app-layer-smb.h"
9faa4b74 50#include "app-layer-smb2.h"
000ce98c
AS
51#include "app-layer-dcerpc.h"
52#include "app-layer-dcerpc-udp.h"
53#include "app-layer-htp.h"
54#include "app-layer-ftp.h"
55#include "app-layer-ssl.h"
56#include "app-layer-ssh.h"
576ec7da 57#include "app-layer-smtp.h"
8e01cba8
VJ
58#include "app-layer-dns-udp.h"
59#include "app-layer-dns-tcp.h"
5a040995 60#include "app-layer-modbus.h"
a3ffebd8 61#include "app-layer-enip.h"
bbaa79b8 62#include "app-layer-dnp3.h"
0d79181d
VJ
63#include "app-layer-nfs-tcp.h"
64#include "app-layer-nfs-udp.h"
c1b92126 65#include "app-layer-template.h"
8e10844f 66
ddde572f 67#include "conf.h"
705471e4 68#include "util-spm.h"
9f78d47c 69
91bc83e5 70#include "util-debug.h"
eea5ab4a 71#include "decode-events.h"
262a7300 72#include "util-unittest-helper.h"
5ba41c78 73#include "util-validate.h"
91bc83e5 74
429c6388 75#include "runmodes.h"
cae8e06c 76
2c857087
VJ
77static GetActiveTxIdFunc AppLayerGetActiveTxIdFuncPtr = NULL;
78
446e68ad 79struct AppLayerParserThreadCtx_ {
429c6388 80 void *alproto_local_storage[FLOW_PROTO_MAX][ALPROTO_MAX];
446e68ad 81};
cae8e06c 82
b74c7330 83
429c6388
AS
84/**
85 * \brief App layer protocol parser context.
86 */
c23742a0 87typedef struct AppLayerParserProtoCtx_
429c6388
AS
88{
89 /* 0 - to_server, 1 - to_client. */
90 int (*Parser[2])(Flow *f, void *protocol_state,
9634e60e 91 AppLayerParserState *pstate,
429c6388
AS
92 uint8_t *input, uint32_t input_len,
93 void *local_storage);
94 char logger;
95
96 void *(*StateAlloc)(void);
97 void (*StateFree)(void *);
98 void (*StateTransactionFree)(void *, uint64_t);
99 void *(*LocalStorageAlloc)(void);
100 void (*LocalStorageFree)(void *);
101
102 void (*Truncate)(void *, uint8_t);
103 FileContainer *(*StateGetFiles)(void *, uint8_t);
104 AppLayerDecoderEvents *(*StateGetEvents)(void *, uint64_t);
105 int (*StateHasEvents)(void *);
106
107 int (*StateGetProgress)(void *alstate, uint8_t direction);
108 uint64_t (*StateGetTxCnt)(void *alstate);
109 void *(*StateGetTx)(void *alstate, uint64_t tx_id);
110 int (*StateGetProgressCompletionStatus)(uint8_t direction);
111 int (*StateGetEventInfo)(const char *event_name,
112 int *event_id, AppLayerEventType *event_type);
113
f3599323
MK
114 int (*StateGetTxLogged)(void *alstate, void *tx, uint32_t logger);
115 void (*StateSetTxLogged)(void *alstate, void *tx, uint32_t logger);
116
f536099a 117 int (*StateHasTxDetectState)(void *alstate);
1cf02560 118 DetectEngineState *(*GetTxDetectState)(void *tx);
f536099a 119 int (*SetTxDetectState)(void *alstate, void *tx, DetectEngineState *);
1cf02560 120
a0fad6bb
VJ
121 uint64_t (*GetTxMpmIDs)(void *tx);
122 int (*SetTxMpmIDs)(void *tx, uint64_t);
123
b160c49e
GL
124 /* each app-layer has its own value */
125 uint32_t stream_depth;
126
429c6388
AS
127 /* Indicates the direction the parser is ready to see the data
128 * the first time for a flow. Values accepted -
129 * STREAM_TOSERVER, STREAM_TOCLIENT */
130 uint8_t first_data_dir;
e1022ee5 131
c862bbdc
JI
132 /* Option flags such as supporting gaps or not. */
133 uint64_t flags;
134
429c6388
AS
135#ifdef UNITTESTS
136 void (*RegisterUnittests)(void);
137#endif
c23742a0 138} AppLayerParserProtoCtx;
429c6388
AS
139
140typedef struct AppLayerParserCtx_ {
c23742a0 141 AppLayerParserProtoCtx ctxs[FLOW_PROTO_MAX][ALPROTO_MAX];
429c6388
AS
142} AppLayerParserCtx;
143
446e68ad 144struct AppLayerParserState_ {
26eb49d7 145 /* coccinelle: AppLayerParserState:flags:APP_LAYER_PARSER_ */
429c6388
AS
146 uint8_t flags;
147
148 /* Indicates the current transaction that is being inspected.
149 * We have a var per direction. */
150 uint64_t inspect_id[2];
151 /* Indicates the current transaction being logged. Unlike inspect_id,
152 * we don't need a var per direction since we don't log a transaction
153 * unless we have the entire transaction. */
154 uint64_t log_id;
429c6388 155
5b56d324
VJ
156 uint64_t min_id;
157
429c6388
AS
158 /* Used to store decoder events. */
159 AppLayerDecoderEvents *decoder_events;
446e68ad 160};
e1022ee5 161
429c6388
AS
162/* Static global version of the parser context.
163 * Post 2.0 let's look at changing this to move it out to app-layer.c. */
164static AppLayerParserCtx alp_ctx;
5a9a23f9 165
5908dd08
GL
166int AppLayerParserProtoIsRegistered(uint8_t ipproto, AppProto alproto)
167{
168 uint8_t ipproto_map = FlowGetProtoMapping(ipproto);
169
170 return (alp_ctx.ctxs[ipproto_map][alproto].StateAlloc != NULL) ? 1 : 0;
171}
172
9634e60e 173AppLayerParserState *AppLayerParserStateAlloc(void)
429c6388
AS
174{
175 SCEnter();
9dc04d9f 176
cd0627cd 177 AppLayerParserState *pstate = (AppLayerParserState *)SCMalloc(sizeof(*pstate));
429c6388
AS
178 if (pstate == NULL)
179 goto end;
180 memset(pstate, 0, sizeof(*pstate));
9dc04d9f 181
429c6388 182 end:
9634e60e 183 SCReturnPtr(pstate, "AppLayerParserState");
9dc04d9f
VJ
184}
185
9634e60e 186void AppLayerParserStateFree(AppLayerParserState *pstate)
429c6388
AS
187{
188 SCEnter();
189
9634e60e 190 if (pstate->decoder_events != NULL)
347c0df9 191 AppLayerDecoderEventsFreeEvents(&pstate->decoder_events);
429c6388 192 SCFree(pstate);
9dc04d9f 193
429c6388 194 SCReturn;
9dc04d9f
VJ
195}
196
429c6388 197int AppLayerParserSetup(void)
c1e485cc 198{
429c6388 199 SCEnter();
fa079c1d 200
429c6388 201 memset(&alp_ctx, 0, sizeof(alp_ctx));
5a9a23f9 202
2c857087
VJ
203 /* set the default tx handler if none was set explicitly */
204 if (AppLayerGetActiveTxIdFuncPtr == NULL) {
205 RegisterAppLayerGetActiveTxIdFunc(AppLayerTransactionGetActiveDetectLog);
206 }
207
6d562f3b
VJ
208 SCReturnInt(0);
209}
210
211void AppLayerParserPostStreamSetup(void)
212{
213 AppProto alproto = 0;
214 int flow_proto = 0;
215
b160c49e
GL
216 /* lets set a default value for stream_depth */
217 for (flow_proto = 0; flow_proto < FLOW_PROTO_DEFAULT; flow_proto++) {
218 for (alproto = 0; alproto < ALPROTO_MAX; alproto++) {
219 alp_ctx.ctxs[flow_proto][alproto].stream_depth =
220 stream_config.reassembly_depth;
221 }
222 }
5a9a23f9 223}
5a9a23f9 224
429c6388 225int AppLayerParserDeSetup(void)
d4d18e31 226{
429c6388 227 SCEnter();
d4d18e31 228
7a0dbc6f
JV
229 SMTPParserCleanup();
230
429c6388 231 SCReturnInt(0);
d4d18e31
AS
232}
233
9634e60e 234AppLayerParserThreadCtx *AppLayerParserThreadCtxAlloc(void)
d4d18e31 235{
429c6388 236 SCEnter();
d4d18e31 237
55255889
VJ
238 AppProto alproto = 0;
239 int flow_proto = 0;
72a16459 240 AppLayerParserThreadCtx *tctx;
d4d18e31 241
429c6388
AS
242 tctx = SCMalloc(sizeof(*tctx));
243 if (tctx == NULL)
244 goto end;
245 memset(tctx, 0, sizeof(*tctx));
246
55255889
VJ
247 for (flow_proto = 0; flow_proto < FLOW_PROTO_DEFAULT; flow_proto++) {
248 for (alproto = 0; alproto < ALPROTO_MAX; alproto++) {
249 uint8_t ipproto = FlowGetReverseProtoMapping(flow_proto);
250
251 tctx->alproto_local_storage[flow_proto][alproto] =
252 AppLayerParserGetProtocolParserLocalStorage(ipproto, alproto);
429c6388
AS
253 }
254 }
255
256 end:
257 SCReturnPtr(tctx, "void *");
d4d18e31
AS
258}
259
9634e60e 260void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
c1e485cc 261{
429c6388 262 SCEnter();
9f78d47c 263
55255889
VJ
264 AppProto alproto = 0;
265 int flow_proto = 0;
266
267 for (flow_proto = 0; flow_proto < FLOW_PROTO_DEFAULT; flow_proto++) {
268 for (alproto = 0; alproto < ALPROTO_MAX; alproto++) {
269 uint8_t ipproto = FlowGetReverseProtoMapping(flow_proto);
429c6388 270
55255889
VJ
271 AppLayerParserDestroyProtocolParserLocalStorage(ipproto, alproto,
272 tctx->alproto_local_storage[flow_proto][alproto]);
429c6388 273 }
9f78d47c 274 }
cae8e06c 275
0bac43a1 276 SCFree(tctx);
429c6388 277 SCReturn;
9f78d47c
VJ
278}
279
4683b0e6
VJ
280/** \brief check if a parser is enabled in the config
281 * Returns enabled always if: were running unittests and
282 * when compiled with --enable-afl
283 */
429c6388
AS
284int AppLayerParserConfParserEnabled(const char *ipproto,
285 const char *alproto_name)
c1e485cc 286{
429c6388
AS
287 SCEnter();
288
289 int enabled = 1;
290 char param[100];
291 ConfNode *node;
292 int r;
cae8e06c 293
4683b0e6
VJ
294#ifdef AFLFUZZ_APPLAYER
295 goto enabled;
296#endif
429c6388
AS
297 if (RunmodeIsUnittests())
298 goto enabled;
299
300 r = snprintf(param, sizeof(param), "%s%s%s", "app-layer.protocols.",
301 alproto_name, ".enabled");
302 if (r < 0) {
303 SCLogError(SC_ERR_FATAL, "snprintf failure.");
304 exit(EXIT_FAILURE);
305 } else if (r > (int)sizeof(param)) {
306 SCLogError(SC_ERR_FATAL, "buffer not big enough to write param.");
307 exit(EXIT_FAILURE);
4914d8d9 308 }
5a9a23f9 309
429c6388
AS
310 node = ConfGetNode(param);
311 if (node == NULL) {
312 SCLogDebug("Entry for %s not found.", param);
313 r = snprintf(param, sizeof(param), "%s%s%s%s%s", "app-layer.protocols.",
314 alproto_name, ".", ipproto, ".enabled");
315 if (r < 0) {
316 SCLogError(SC_ERR_FATAL, "snprintf failure.");
317 exit(EXIT_FAILURE);
318 } else if (r > (int)sizeof(param)) {
319 SCLogError(SC_ERR_FATAL, "buffer not big enough to write param.");
320 exit(EXIT_FAILURE);
321 }
322
323 node = ConfGetNode(param);
324 if (node == NULL) {
325 SCLogDebug("Entry for %s not found.", param);
326 goto enabled;
327 }
9f78d47c 328 }
9f78d47c 329
16e4c92b 330 if (ConfValIsTrue(node->val)) {
429c6388 331 goto enabled;
16e4c92b 332 } else if (ConfValIsFalse(node->val)) {
429c6388
AS
333 goto disabled;
334 } else if (strcasecmp(node->val, "detection-only") == 0) {
ff8dae3b 335 goto disabled;
9f78d47c 336 } else {
429c6388
AS
337 SCLogError(SC_ERR_FATAL, "Invalid value found for %s.", param);
338 exit(EXIT_FAILURE);
9f78d47c 339 }
429c6388
AS
340
341 disabled:
342 enabled = 0;
343 enabled:
344 SCReturnInt(enabled);
9f78d47c
VJ
345}
346
429c6388
AS
347/***** Parser related registration *****/
348
5cdeadb3 349int AppLayerParserRegisterParser(uint8_t ipproto, AppProto alproto,
429c6388
AS
350 uint8_t direction,
351 int (*Parser)(Flow *f, void *protocol_state,
9634e60e 352 AppLayerParserState *pstate,
429c6388
AS
353 uint8_t *buf, uint32_t buf_len,
354 void *local_storage))
c1e485cc 355{
574bcea0
VJ
356 SCEnter();
357
429c6388
AS
358 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
359 Parser[(direction & STREAM_TOSERVER) ? 0 : 1] = Parser;
9f78d47c 360
574bcea0 361 SCReturnInt(0);
9f78d47c
VJ
362}
363
5cdeadb3 364void AppLayerParserRegisterParserAcceptableDataDirection(uint8_t ipproto, AppProto alproto,
429c6388 365 uint8_t direction)
c13ad8c2 366{
429c6388
AS
367 SCEnter();
368
369 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].first_data_dir |=
370 (direction & (STREAM_TOSERVER | STREAM_TOCLIENT));
371
372 SCReturn;
c13ad8c2
AS
373}
374
c862bbdc
JI
375void AppLayerParserRegisterOptionFlags(uint8_t ipproto, AppProto alproto,
376 uint64_t flags)
377{
378 SCEnter();
379
380 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].flags |= flags;
381
382 SCReturn;
383}
384
5cdeadb3 385void AppLayerParserRegisterStateFuncs(uint8_t ipproto, AppProto alproto,
429c6388
AS
386 void *(*StateAlloc)(void),
387 void (*StateFree)(void *))
c1e485cc 388{
574bcea0
VJ
389 SCEnter();
390
429c6388
AS
391 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateAlloc =
392 StateAlloc;
393 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateFree =
394 StateFree;
086ba5f4 395
429c6388
AS
396 SCReturn;
397}
086ba5f4 398
5cdeadb3 399void AppLayerParserRegisterLocalStorageFunc(uint8_t ipproto, AppProto alproto,
429c6388
AS
400 void *(*LocalStorageAlloc)(void),
401 void (*LocalStorageFree)(void *))
402{
403 SCEnter();
574bcea0 404
429c6388
AS
405 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].LocalStorageAlloc =
406 LocalStorageAlloc;
407 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].LocalStorageFree =
408 LocalStorageFree;
086ba5f4 409
429c6388
AS
410 SCReturn;
411}
086ba5f4 412
5cdeadb3 413void AppLayerParserRegisterGetFilesFunc(uint8_t ipproto, AppProto alproto,
429c6388
AS
414 FileContainer *(*StateGetFiles)(void *, uint8_t))
415{
416 SCEnter();
086ba5f4 417
429c6388
AS
418 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateGetFiles =
419 StateGetFiles;
086ba5f4 420
429c6388
AS
421 SCReturn;
422}
086ba5f4 423
5cdeadb3 424void AppLayerParserRegisterGetEventsFunc(uint8_t ipproto, AppProto alproto,
429c6388
AS
425 AppLayerDecoderEvents *(*StateGetEvents)(void *, uint64_t))
426{
427 SCEnter();
574bcea0 428
429c6388
AS
429 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateGetEvents =
430 StateGetEvents;
086ba5f4 431
429c6388 432 SCReturn;
086ba5f4
VJ
433}
434
5cdeadb3 435void AppLayerParserRegisterHasEventsFunc(uint8_t ipproto, AppProto alproto,
429c6388 436 int (*StateHasEvents)(void *))
c1e485cc 437{
574bcea0 438 SCEnter();
574bcea0 439
429c6388
AS
440 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateHasEvents =
441 StateHasEvents;
574bcea0 442
429c6388
AS
443 SCReturn;
444}
574bcea0 445
f3599323
MK
446void AppLayerParserRegisterLoggerFuncs(uint8_t ipproto, AppProto alproto,
447 int (*StateGetTxLogged)(void *, void *, uint32_t),
448 void (*StateSetTxLogged)(void *, void *, uint32_t))
449{
450 SCEnter();
451
452 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateGetTxLogged =
453 StateGetTxLogged;
454
455 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateSetTxLogged =
456 StateSetTxLogged;
457
458 SCReturn;
459}
460
5cdeadb3 461void AppLayerParserRegisterLogger(uint8_t ipproto, AppProto alproto)
429c6388
AS
462{
463 SCEnter();
9f78d47c 464
429c6388 465 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].logger = TRUE;
9f78d47c 466
429c6388
AS
467 SCReturn;
468}
9f78d47c 469
5cdeadb3 470void AppLayerParserRegisterTruncateFunc(uint8_t ipproto, AppProto alproto,
429c6388
AS
471 void (*Truncate)(void *, uint8_t))
472{
473 SCEnter();
574bcea0 474
429c6388 475 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].Truncate = Truncate;
574bcea0 476
429c6388
AS
477 SCReturn;
478}
9f78d47c 479
5cdeadb3 480void AppLayerParserRegisterGetStateProgressFunc(uint8_t ipproto, AppProto alproto,
429c6388
AS
481 int (*StateGetProgress)(void *alstate, uint8_t direction))
482{
483 SCEnter();
9f78d47c 484
429c6388
AS
485 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
486 StateGetProgress = StateGetProgress;
9f78d47c 487
429c6388 488 SCReturn;
9f78d47c
VJ
489}
490
5cdeadb3 491void AppLayerParserRegisterTxFreeFunc(uint8_t ipproto, AppProto alproto,
429c6388 492 void (*StateTransactionFree)(void *, uint64_t))
c1e485cc 493{
574bcea0 494 SCEnter();
9f78d47c 495
429c6388
AS
496 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
497 StateTransactionFree = StateTransactionFree;
9f78d47c 498
429c6388
AS
499 SCReturn;
500}
9f78d47c 501
5cdeadb3 502void AppLayerParserRegisterGetTxCnt(uint8_t ipproto, AppProto alproto,
429c6388
AS
503 uint64_t (*StateGetTxCnt)(void *alstate))
504{
505 SCEnter();
9f78d47c 506
429c6388
AS
507 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
508 StateGetTxCnt = StateGetTxCnt;
9f78d47c 509
429c6388
AS
510 SCReturn;
511}
9f78d47c 512
5cdeadb3 513void AppLayerParserRegisterGetTx(uint8_t ipproto, AppProto alproto,
429c6388
AS
514 void *(StateGetTx)(void *alstate, uint64_t tx_id))
515{
516 SCEnter();
9f78d47c 517
429c6388
AS
518 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
519 StateGetTx = StateGetTx;
9f78d47c 520
429c6388 521 SCReturn;
9f78d47c
VJ
522}
523
c4b918b6 524void AppLayerParserRegisterGetStateProgressCompletionStatus(AppProto alproto,
429c6388 525 int (*StateGetProgressCompletionStatus)(uint8_t direction))
c1e485cc 526{
429c6388 527 SCEnter();
f1f7df07 528
c4b918b6 529 alp_ctx.ctxs[FLOW_PROTO_DEFAULT][alproto].
429c6388 530 StateGetProgressCompletionStatus = StateGetProgressCompletionStatus;
f1f7df07 531
429c6388
AS
532 SCReturn;
533}
f1f7df07 534
5cdeadb3 535void AppLayerParserRegisterGetEventInfo(uint8_t ipproto, AppProto alproto,
429c6388
AS
536 int (*StateGetEventInfo)(const char *event_name, int *event_id,
537 AppLayerEventType *event_type))
538{
539 SCEnter();
f1f7df07 540
429c6388
AS
541 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
542 StateGetEventInfo = StateGetEventInfo;
d9686fae 543
429c6388
AS
544 SCReturn;
545}
d9686fae 546
1cf02560 547void AppLayerParserRegisterDetectStateFuncs(uint8_t ipproto, AppProto alproto,
f536099a 548 int (*StateHasTxDetectState)(void *alstate),
1cf02560 549 DetectEngineState *(*GetTxDetectState)(void *tx),
f536099a 550 int (*SetTxDetectState)(void *alstate, void *tx, DetectEngineState *))
1cf02560
VJ
551{
552 SCEnter();
553
f536099a 554 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateHasTxDetectState = StateHasTxDetectState;
1cf02560
VJ
555 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetTxDetectState = GetTxDetectState;
556 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].SetTxDetectState = SetTxDetectState;
557
558 SCReturn;
559}
560
a0fad6bb
VJ
561void AppLayerParserRegisterMpmIDsFuncs(uint8_t ipproto, AppProto alproto,
562 uint64_t(*GetTxMpmIDs)(void *tx),
563 int (*SetTxMpmIDs)(void *tx, uint64_t))
564{
565 SCEnter();
566
567 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetTxMpmIDs = GetTxMpmIDs;
568 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].SetTxMpmIDs = SetTxMpmIDs;
569
570 SCReturn;
571}
572
429c6388 573/***** Get and transaction functions *****/
d9686fae 574
5cdeadb3 575void *AppLayerParserGetProtocolParserLocalStorage(uint8_t ipproto, AppProto alproto)
429c6388
AS
576{
577 SCEnter();
dc1599e0 578 void * r = NULL;
429c6388
AS
579
580 if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
581 LocalStorageAlloc != NULL)
582 {
dc1599e0 583 r = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
584 LocalStorageAlloc();
d9686fae
AS
585 }
586
dc1599e0 587 SCReturnPtr(r, "void *");
f1f7df07
VJ
588}
589
5cdeadb3 590void AppLayerParserDestroyProtocolParserLocalStorage(uint8_t ipproto, AppProto alproto,
429c6388 591 void *local_data)
68425453 592{
429c6388 593 SCEnter();
68425453 594
429c6388
AS
595 if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
596 LocalStorageFree != NULL)
597 {
598 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
599 LocalStorageFree(local_data);
68425453
EL
600 }
601
429c6388 602 SCReturn;
68425453
EL
603}
604
f3599323
MK
605void AppLayerParserSetTxLogged(uint8_t ipproto, AppProto alproto,
606 void *alstate, void *tx, uint32_t logger)
607{
608 SCEnter();
609
610 if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
611 StateSetTxLogged != NULL) {
612 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
613 StateSetTxLogged(alstate, tx, logger);
614 }
615
616 SCReturn;
617}
618
4459b887 619int AppLayerParserGetTxLogged(const Flow *f,
f3599323
MK
620 void *alstate, void *tx, uint32_t logger)
621{
622 SCEnter();
623
624 uint8_t r = 0;
4459b887
VJ
625 if (alp_ctx.ctxs[f->protomap][f->alproto].StateGetTxLogged != NULL) {
626 r = alp_ctx.ctxs[f->protomap][f->alproto].
627 StateGetTxLogged(alstate, tx, logger);
f3599323
MK
628 }
629
630 SCReturnInt(r);
631}
632
9634e60e 633uint64_t AppLayerParserGetTransactionLogId(AppLayerParserState *pstate)
c1e485cc 634{
429c6388 635 SCEnter();
8e10844f 636
0564a8da 637 SCReturnCT((pstate == NULL) ? 0 : pstate->log_id, "uint64_t");
429c6388 638}
8e10844f 639
e9fccfa6 640void AppLayerParserSetTransactionLogId(AppLayerParserState *pstate, uint64_t tx_id)
429c6388
AS
641{
642 SCEnter();
5fc30051 643
0564a8da 644 if (pstate != NULL)
e9fccfa6 645 pstate->log_id = tx_id;
5a9a23f9 646
429c6388 647 SCReturn;
8e10844f
VJ
648}
649
9634e60e 650uint64_t AppLayerParserGetTransactionInspectId(AppLayerParserState *pstate, uint8_t direction)
c1e485cc 651{
429c6388 652 SCEnter();
8e10844f 653
0564a8da
VJ
654 if (pstate == NULL)
655 SCReturnCT(0ULL, "uint64_t");
656
9634e60e 657 SCReturnCT(pstate->inspect_id[direction & STREAM_TOSERVER ? 0 : 1], "uint64_t");
429c6388 658}
5fc30051 659
5c01b409 660void AppLayerParserSetTransactionInspectId(const Flow *f, AppLayerParserState *pstate,
6946e0be 661 void *alstate, const uint8_t flags)
429c6388
AS
662{
663 SCEnter();
59780ca7 664
6946e0be 665 int direction = (flags & STREAM_TOSERVER) ? 0 : 1;
5c01b409 666 const uint64_t total_txs = AppLayerParserGetTxCnt(f, alstate);
6946e0be 667 uint64_t idx = AppLayerParserGetTransactionInspectId(pstate, flags);
5c01b409 668 const int state_done_progress = AppLayerParserGetStateProgressCompletionStatus(f->alproto, flags);
429c6388
AS
669 void *tx;
670 int state_progress;
8e10844f 671
429c6388 672 for (; idx < total_txs; idx++) {
5c01b409 673 tx = AppLayerParserGetTx(f->proto, f->alproto, alstate, idx);
429c6388
AS
674 if (tx == NULL)
675 continue;
5c01b409 676 state_progress = AppLayerParserGetStateProgress(f->proto, f->alproto, tx, flags);
429c6388
AS
677 if (state_progress >= state_done_progress)
678 continue;
679 else
680 break;
8e10844f 681 }
6946e0be 682 pstate->inspect_id[direction] = idx;
8e10844f 683
429c6388 684 SCReturn;
9faa4b74 685}
9faa4b74 686
9634e60e 687AppLayerDecoderEvents *AppLayerParserGetDecoderEvents(AppLayerParserState *pstate)
c1e485cc 688{
429c6388 689 SCEnter();
9f78d47c 690
9634e60e 691 SCReturnPtr(pstate->decoder_events,
429c6388 692 "AppLayerDecoderEvents *");
70b32f73
VJ
693}
694
9634e60e 695void AppLayerParserSetDecoderEvents(AppLayerParserState *pstate, AppLayerDecoderEvents *devents)
9a6aef45 696{
9634e60e 697 pstate->decoder_events = devents;
9a6aef45
AS
698}
699
5cdeadb3 700AppLayerDecoderEvents *AppLayerParserGetEventsByTx(uint8_t ipproto, AppProto alproto,
429c6388 701 void *alstate, uint64_t tx_id)
869109a6 702{
429c6388 703 SCEnter();
869109a6 704
429c6388 705 AppLayerDecoderEvents *ptr = NULL;
869109a6 706
429c6388
AS
707 if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
708 StateGetEvents != NULL)
709 {
710 ptr = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
711 StateGetEvents(alstate, tx_id);
01a35bb6
AS
712 }
713
429c6388 714 SCReturnPtr(ptr, "AppLayerDecoderEvents *");
6cb00142 715}
70b32f73 716
5cdeadb3 717FileContainer *AppLayerParserGetFiles(uint8_t ipproto, AppProto alproto,
429c6388 718 void *alstate, uint8_t direction)
c1e485cc 719{
91bc83e5 720 SCEnter();
8e10844f 721
429c6388 722 FileContainer *ptr = NULL;
45d86ff5 723
429c6388
AS
724 if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
725 StateGetFiles != NULL)
726 {
727 ptr = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
728 StateGetFiles(alstate, direction);
3b3dce83 729 }
5ba41c78 730
429c6388 731 SCReturnPtr(ptr, "FileContainer *");
70b32f73 732}
70b32f73 733
2c857087 734/** \brief active TX retrieval for normal ops: so with detection and logging
c06c595c 735 *
2c857087 736 * \retval tx_id lowest tx_id that still needs work */
8f1d7503
KS
737uint64_t AppLayerTransactionGetActiveDetectLog(Flow *f, uint8_t flags)
738{
c06c595c
VJ
739 AppLayerParserProtoCtx *p = &alp_ctx.ctxs[FlowGetProtoMapping(f->proto)][f->alproto];
740 uint64_t log_id = f->alparser->log_id;
741 uint64_t inspect_id = f->alparser->inspect_id[flags & STREAM_TOSERVER ? 0 : 1];
742 if (p->logger == TRUE) {
743 return (log_id < inspect_id) ? log_id : inspect_id;
744 } else {
745 return inspect_id;
746 }
747}
748
5cc880c5
VJ
749/** \brief active TX retrieval for logging only: so NO detection
750 *
3474c36b 751 * If the logger is enabled, we simply return the log_id here.
5cc880c5 752 *
3474c36b
VJ
753 * Otherwise, we go look for the tx id. There probably is no point
754 * in running this function in that case though. With no detection
755 * and no logging, why run a parser in the first place?
5cc880c5 756 **/
8f1d7503
KS
757uint64_t AppLayerTransactionGetActiveLogOnly(Flow *f, uint8_t flags)
758{
3474c36b
VJ
759 AppLayerParserProtoCtx *p = &alp_ctx.ctxs[f->protomap][f->alproto];
760
761 if (p->logger == TRUE) {
762 uint64_t log_id = f->alparser->log_id;
763 SCLogDebug("returning %"PRIu64, log_id);
764 return log_id;
765 }
766
767 /* logger is disabled, return highest 'complete' tx id */
5c01b409 768 uint64_t total_txs = AppLayerParserGetTxCnt(f, f->alstate);
5b56d324 769 uint64_t idx = f->alparser->min_id;
c4b918b6 770 int state_done_progress = AppLayerParserGetStateProgressCompletionStatus(f->alproto, flags);
3474c36b
VJ
771 void *tx;
772 int state_progress;
773
774 for (; idx < total_txs; idx++) {
775 tx = AppLayerParserGetTx(f->proto, f->alproto, f->alstate, idx);
776 if (tx == NULL)
777 continue;
00ef789f 778 state_progress = AppLayerParserGetStateProgress(f->proto, f->alproto, tx, flags);
3474c36b
VJ
779 if (state_progress >= state_done_progress)
780 continue;
781 else
782 break;
783 }
784 SCLogDebug("returning %"PRIu64, idx);
785 return idx;
5cc880c5
VJ
786}
787
8f1d7503
KS
788void RegisterAppLayerGetActiveTxIdFunc(GetActiveTxIdFunc FuncPtr)
789{
5cc880c5 790 //BUG_ON(AppLayerGetActiveTxIdFuncPtr != NULL);
2c857087 791 AppLayerGetActiveTxIdFuncPtr = FuncPtr;
5cc880c5 792 SCLogDebug("AppLayerGetActiveTxIdFuncPtr is now %p", AppLayerGetActiveTxIdFuncPtr);
2c857087
VJ
793}
794
795/**
796 * \brief Get 'active' tx id, meaning the lowest id that still need work.
797 *
798 * \retval id tx id
799 */
8f1d7503
KS
800static uint64_t AppLayerTransactionGetActive(Flow *f, uint8_t flags)
801{
2c857087
VJ
802 BUG_ON(AppLayerGetActiveTxIdFuncPtr == NULL);
803
804 return AppLayerGetActiveTxIdFuncPtr(f, flags);
805}
806
c06c595c
VJ
807#ifndef MIN
808#define MIN(a, b) (((a) < (b)) ? (a) : (b))
809#endif
810
811/**
812 * \brief remove obsolete (inspected and logged) transactions
813 */
814static void AppLayerParserTransactionsCleanup(Flow *f)
815{
816 DEBUG_ASSERT_FLOW_LOCKED(f);
817
818 AppLayerParserProtoCtx *p = &alp_ctx.ctxs[FlowGetProtoMapping(f->proto)][f->alproto];
819 if (p->StateTransactionFree == NULL)
820 return;
821
822 uint64_t tx_id_ts = AppLayerTransactionGetActive(f, STREAM_TOSERVER);
823 uint64_t tx_id_tc = AppLayerTransactionGetActive(f, STREAM_TOCLIENT);
824
825 uint64_t min = MIN(tx_id_ts, tx_id_tc);
826 if (min > 0) {
5b56d324
VJ
827 uint64_t x = f->alparser->min_id;
828 for ( ; x < min - 1; x++) {
829 void *tx = AppLayerParserGetTx(f->proto, f->alproto, f->alstate, x);
830 if (tx != 0) {
831 SCLogDebug("while freeing %"PRIu64", also free TX at %"PRIu64, min - 1, x);
832 p->StateTransactionFree(f->alstate, x);
833 }
834 }
835
c06c595c 836 SCLogDebug("freeing %"PRIu64" %p", min - 1, p->StateTransactionFree);
5b56d324
VJ
837
838 if ((AppLayerParserGetTx(f->proto, f->alproto, f->alstate, min - 1))) {
839 p->StateTransactionFree(f->alstate, min - 1);
840 }
841 f->alparser->min_id = min - 1;
842 SCLogDebug("f->alparser->min_id %"PRIu64, f->alparser->min_id);
c06c595c
VJ
843 }
844}
845
ea571add
VJ
846#define IS_DISRUPTED(flags) \
847 ((flags) & (STREAM_DEPTH|STREAM_GAP))
848
849/**
850 * \brief get the progress value for a tx/protocol
851 *
852 * If the stream is disrupted, we return the 'completion' value.
853 */
5cdeadb3 854int AppLayerParserGetStateProgress(uint8_t ipproto, AppProto alproto,
ea571add 855 void *alstate, uint8_t flags)
d4d18e31 856{
73efb4c7 857 SCEnter();
dc1599e0 858 int r = 0;
ea571add 859 if (unlikely(IS_DISRUPTED(flags))) {
c4b918b6 860 r = alp_ctx.ctxs[FLOW_PROTO_DEFAULT][alproto].
ea571add
VJ
861 StateGetProgressCompletionStatus(flags);
862 } else {
863 r = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
864 StateGetProgress(alstate, flags);
865 }
dc1599e0 866 SCReturnInt(r);
d4d18e31 867}
70b32f73 868
5c01b409 869uint64_t AppLayerParserGetTxCnt(const Flow *f, void *alstate)
d4d18e31 870{
16cfae2f 871 SCEnter();
dc1599e0 872 uint64_t r = 0;
5c01b409 873 r = alp_ctx.ctxs[f->protomap][f->alproto].
dc1599e0 874 StateGetTxCnt(alstate);
875 SCReturnCT(r, "uint64_t");
16cfae2f
VJ
876}
877
5cdeadb3 878void *AppLayerParserGetTx(uint8_t ipproto, AppProto alproto, void *alstate, uint64_t tx_id)
ddde572f 879{
429c6388 880 SCEnter();
dc1599e0 881 void * r = NULL;
882 r = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
883 StateGetTx(alstate, tx_id);
884 SCReturnPtr(r, "void *");
ddde572f
AS
885}
886
c4b918b6
MK
887int AppLayerParserGetStateProgressCompletionStatus(AppProto alproto,
888 uint8_t direction)
6cb00142 889{
429c6388 890 SCEnter();
dc1599e0 891 int r = 0;
c4b918b6 892 r = alp_ctx.ctxs[FLOW_PROTO_DEFAULT][alproto].
dc1599e0 893 StateGetProgressCompletionStatus(direction);
894 SCReturnInt(r);
6cb00142
AS
895}
896
5cdeadb3 897int AppLayerParserGetEventInfo(uint8_t ipproto, AppProto alproto, const char *event_name,
429c6388 898 int *event_id, AppLayerEventType *event_type)
6f8cfd99 899{
429c6388
AS
900 SCEnter();
901 int ipproto_map = FlowGetProtoMapping(ipproto);
1cbd1cdf
VJ
902 int r = (alp_ctx.ctxs[ipproto_map][alproto].StateGetEventInfo == NULL) ?
903 -1 : alp_ctx.ctxs[ipproto_map][alproto].StateGetEventInfo(event_name, event_id, event_type);
904 SCReturnInt(r);
6f8cfd99
AS
905}
906
f5f14880 907uint8_t AppLayerParserGetFirstDataDir(uint8_t ipproto, AppProto alproto)
432c3317 908{
429c6388 909 SCEnter();
dc1599e0 910 uint8_t r = 0;
911 r = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
912 first_data_dir;
913 SCReturnCT(r, "uint8_t");
432c3317 914}
7c31a232 915
3148ff34
VJ
916uint64_t AppLayerParserGetTransactionActive(const Flow *f,
917 AppLayerParserState *pstate, uint8_t direction)
d9686fae 918{
429c6388 919 SCEnter();
d9686fae 920
429c6388 921 uint64_t active_id;
d9686fae 922
9634e60e
VJ
923 uint64_t log_id = pstate->log_id;
924 uint64_t inspect_id = pstate->inspect_id[direction & STREAM_TOSERVER ? 0 : 1];
3148ff34 925 if (alp_ctx.ctxs[f->protomap][f->alproto].logger == TRUE) {
429c6388
AS
926 active_id = (log_id < inspect_id) ? log_id : inspect_id;
927 } else {
928 active_id = inspect_id;
d9686fae 929 }
d9686fae 930
429c6388 931 SCReturnCT(active_id, "uint64_t");
d9686fae
AS
932}
933
bcfa484b
VJ
934int AppLayerParserSupportsFiles(uint8_t ipproto, AppProto alproto)
935{
936 if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateGetFiles != NULL)
937 return TRUE;
938 return FALSE;
939}
940
1cf02560
VJ
941int AppLayerParserSupportsTxDetectState(uint8_t ipproto, AppProto alproto)
942{
943 if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetTxDetectState != NULL)
944 return TRUE;
945 return FALSE;
946}
947
f536099a
VJ
948int AppLayerParserHasTxDetectState(uint8_t ipproto, AppProto alproto, void *alstate)
949{
950 int r;
951 SCEnter();
952 if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateHasTxDetectState == NULL)
953 return -ENOSYS;
954 r = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].StateHasTxDetectState(alstate);
955 SCReturnInt(r);
956}
957
1cf02560
VJ
958DetectEngineState *AppLayerParserGetTxDetectState(uint8_t ipproto, AppProto alproto, void *tx)
959{
960 SCEnter();
961 DetectEngineState *s;
962 s = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetTxDetectState(tx);
963 SCReturnPtr(s, "DetectEngineState");
964}
965
3148ff34 966int AppLayerParserSetTxDetectState(const Flow *f,
f536099a 967 void *alstate, void *tx, DetectEngineState *s)
1cf02560
VJ
968{
969 int r;
970 SCEnter();
3148ff34 971 if ((alp_ctx.ctxs[f->protomap][f->alproto].GetTxDetectState(tx) != NULL))
1cf02560 972 SCReturnInt(-EBUSY);
3148ff34 973 r = alp_ctx.ctxs[f->protomap][f->alproto].SetTxDetectState(alstate, tx, s);
1cf02560
VJ
974 SCReturnInt(r);
975}
976
a0fad6bb
VJ
977uint64_t AppLayerParserGetTxMpmIDs(uint8_t ipproto, AppProto alproto, void *tx)
978{
979 if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetTxMpmIDs != NULL) {
980 return alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].GetTxMpmIDs(tx);
981 }
982
983 return 0ULL;
984}
985
986int AppLayerParserSetTxMpmIDs(uint8_t ipproto, AppProto alproto, void *tx, uint64_t mpm_ids)
987{
988 int r = 0;
989 if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].SetTxMpmIDs != NULL) {
990 r = alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].SetTxMpmIDs(tx, mpm_ids);
991 }
992 SCReturnInt(r);
993}
994
429c6388
AS
995/***** General *****/
996
675fa564 997int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto,
429c6388 998 uint8_t flags, uint8_t *input, uint32_t input_len)
d9686fae 999{
429c6388 1000 SCEnter();
a77b9b36
VJ
1001#ifdef DEBUG_VALIDATION
1002 BUG_ON(f->protomap != FlowGetProtoMapping(f->proto));
1003#endif
cd0627cd 1004 AppLayerParserState *pstate = NULL;
a77b9b36 1005 AppLayerParserProtoCtx *p = &alp_ctx.ctxs[f->protomap][alproto];
429c6388 1006 void *alstate = NULL;
a194dfbd 1007 uint64_t p_tx_cnt = 0;
d9686fae 1008
429c6388
AS
1009 /* we don't have the parser registered for this protocol */
1010 if (p->StateAlloc == NULL)
1011 goto end;
d9686fae 1012
429c6388 1013 if (flags & STREAM_GAP) {
c862bbdc
JI
1014 if (!(p->flags & APP_LAYER_PARSER_OPT_ACCEPT_GAPS)) {
1015 SCLogDebug("app-layer parser does not accept gaps");
1016 if (f->alstate != NULL) {
1017 AppLayerParserStreamTruncated(f->proto, alproto, f->alstate,
1018 flags);
1019 }
1020 goto error;
1021 }
d9686fae 1022 }
d9686fae 1023
429c6388
AS
1024 /* Get the parser state (if any) */
1025 pstate = f->alparser;
1026 if (pstate == NULL) {
8527b8e0 1027 f->alparser = pstate = AppLayerParserStateAlloc();
429c6388
AS
1028 if (pstate == NULL)
1029 goto error;
d9686fae
AS
1030 }
1031
429c6388 1032 if (flags & STREAM_EOF)
8527b8e0 1033 AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_EOF);
7c31a232 1034
429c6388
AS
1035 alstate = f->alstate;
1036 if (alstate == NULL) {
1037 f->alstate = alstate = p->StateAlloc();
1038 if (alstate == NULL)
1039 goto error;
1040 SCLogDebug("alloced new app layer state %p (name %s)",
1041 alstate, AppLayerGetProtoName(f->alproto));
1042 } else {
1043 SCLogDebug("using existing app layer state %p (name %s))",
1044 alstate, AppLayerGetProtoName(f->alproto));
6e0d98d9 1045 }
429c6388 1046
a194dfbd 1047 if (AppLayerParserProtocolIsTxAware(f->proto, alproto)) {
5c01b409 1048 p_tx_cnt = AppLayerParserGetTxCnt(f, f->alstate);
a194dfbd
EL
1049 }
1050
429c6388 1051 /* invoke the recursive parser, but only on data. We may get empty msgs on EOF */
cf9ff6ad 1052 if (input_len > 0 || (flags & STREAM_EOF)) {
429c6388
AS
1053 /* invoke the parser */
1054 if (p->Parser[(flags & STREAM_TOSERVER) ? 0 : 1](f, alstate, pstate,
1055 input, input_len,
a77b9b36 1056 alp_tctx->alproto_local_storage[f->protomap][alproto]) < 0)
59327e0f
VJ
1057 {
1058 goto error;
1059 }
6e0d98d9 1060 }
429c6388
AS
1061
1062 /* set the packets to no inspection and reassembly if required */
1063 if (pstate->flags & APP_LAYER_PARSER_NO_INSPECTION) {
1064 AppLayerParserSetEOF(pstate);
1065 FlowSetNoPayloadInspectionFlag(f);
429c6388 1066
c1558f5a
VJ
1067 if (f->proto == IPPROTO_TCP) {
1068 StreamTcpDisableAppLayer(f);
1069
1070 /* Set the no reassembly flag for both the stream in this TcpSession */
1071 if (pstate->flags & APP_LAYER_PARSER_NO_REASSEMBLY) {
1072 /* Used only if it's TCP */
1073 TcpSession *ssn = f->protoctx;
1074 if (ssn != NULL) {
1075 StreamTcpSetSessionNoReassemblyFlag(ssn,
1076 flags & STREAM_TOCLIENT ? 1 : 0);
1077 StreamTcpSetSessionNoReassemblyFlag(ssn,
1078 flags & STREAM_TOSERVER ? 1 : 0);
1079 }
429c6388 1080 }
26eb49d7
EL
1081 /* Set the bypass flag for both the stream in this TcpSession */
1082 if (pstate->flags & APP_LAYER_PARSER_BYPASS_READY) {
1083 /* Used only if it's TCP */
1084 TcpSession *ssn = f->protoctx;
1085 if (ssn != NULL) {
1086 StreamTcpSetSessionBypassFlag(ssn);
1087 }
1088 }
429c6388 1089 }
7f8fb0f0
AS
1090 }
1091
26169ad8 1092 /* In cases like HeartBleed for TLS we need to inspect AppLayer but not Payload */
3543150f 1093 if (!(f->flags & FLOW_NOPAYLOAD_INSPECTION) && pstate->flags & APP_LAYER_PARSER_NO_INSPECTION_PAYLOAD) {
26169ad8 1094 FlowSetNoPayloadInspectionFlag(f);
3543150f
VJ
1095 /* Set the no reassembly flag for both the stream in this TcpSession */
1096 if (f->proto == IPPROTO_TCP) {
1097 /* Used only if it's TCP */
1098 TcpSession *ssn = f->protoctx;
1099 if (ssn != NULL) {
1100 StreamTcpSetDisableRawReassemblyFlag(ssn, 0);
1101 StreamTcpSetDisableRawReassemblyFlag(ssn, 1);
3543150f
VJ
1102 }
1103 }
26169ad8
WM
1104 }
1105
a194dfbd
EL
1106 if (AppLayerParserProtocolIsTxAware(f->proto, alproto)) {
1107 if (likely(tv)) {
5c01b409 1108 uint64_t cur_tx_cnt = AppLayerParserGetTxCnt(f, f->alstate);
a194dfbd
EL
1109 if (cur_tx_cnt > p_tx_cnt) {
1110 AppLayerIncTxCounter(tv, f, cur_tx_cnt - p_tx_cnt);
1111 }
1112 }
1113 }
429c6388 1114 /* next, see if we can get rid of transactions now */
c06c595c 1115 AppLayerParserTransactionsCleanup(f);
429c6388
AS
1116
1117 /* stream truncated, inform app layer */
1118 if (flags & STREAM_DEPTH)
1119 AppLayerParserStreamTruncated(f->proto, alproto, alstate, flags);
1120
1121 end:
1122 SCReturnInt(0);
6e0d98d9 1123 error:
a77b9b36
VJ
1124 /* Set the no app layer inspection flag for both
1125 * the stream in this Flow */
c1558f5a
VJ
1126 if (f->proto == IPPROTO_TCP) {
1127 StreamTcpDisableAppLayer(f);
1128 }
a77b9b36 1129 AppLayerParserSetEOF(pstate);
429c6388 1130 SCReturnInt(-1);
7c31a232
AS
1131}
1132
9634e60e 1133void AppLayerParserSetEOF(AppLayerParserState *pstate)
7c31a232 1134{
429c6388 1135 SCEnter();
7c31a232 1136
429c6388
AS
1137 if (pstate == NULL)
1138 goto end;
1139
8527b8e0 1140 AppLayerParserStateSetFlag(pstate, APP_LAYER_PARSER_EOF);
429c6388
AS
1141
1142 end:
1143 SCReturn;
432c3317
AS
1144}
1145
3148ff34 1146int AppLayerParserHasDecoderEvents(const Flow *f,
9634e60e 1147 void *alstate, AppLayerParserState *pstate,
429c6388 1148 uint8_t flags)
432c3317 1149{
429c6388 1150 SCEnter();
432c3317 1151
429c6388
AS
1152 if (alstate == NULL || pstate == NULL)
1153 goto not_present;
7c31a232 1154
429c6388
AS
1155 AppLayerDecoderEvents *decoder_events;
1156 uint64_t tx_id;
1157 uint64_t max_id;
1158
3148ff34 1159 if (AppLayerParserProtocolIsTxEventAware(f->proto, f->alproto)) {
429c6388 1160 /* fast path if supported by alproto */
3148ff34
VJ
1161 if (alp_ctx.ctxs[f->protomap][f->alproto].StateHasEvents != NULL) {
1162 if (alp_ctx.ctxs[f->protomap][f->alproto].
429c6388
AS
1163 StateHasEvents(alstate) == 1)
1164 {
1165 goto present;
d9686fae 1166 }
429c6388
AS
1167 } else {
1168 /* check each tx */
1169 tx_id = AppLayerParserGetTransactionInspectId(pstate, flags);
5c01b409 1170 max_id = AppLayerParserGetTxCnt(f, alstate);
429c6388 1171 for ( ; tx_id < max_id; tx_id++) {
3148ff34 1172 decoder_events = AppLayerParserGetEventsByTx(f->proto, f->alproto, alstate, tx_id);
429c6388
AS
1173 if (decoder_events && decoder_events->cnt)
1174 goto present;
7c31a232 1175 }
7c31a232 1176 }
7c31a232
AS
1177 }
1178
429c6388
AS
1179 decoder_events = AppLayerParserGetDecoderEvents(pstate);
1180 if (decoder_events && decoder_events->cnt)
1181 goto present;
1182
1183 /* if we have reached here, we don't have events */
1184 not_present:
1185 SCReturnInt(0);
1186 present:
1187 SCReturnInt(1);
d9686fae
AS
1188}
1189
01913f6a
VJ
1190/** \brief simpler way to globally test if a alproto is registered
1191 * and fully enabled in the configuration.
1192 */
1193int AppLayerParserIsTxAware(AppProto alproto)
1194{
1195 return (alp_ctx.ctxs[FLOW_PROTO_DEFAULT][alproto]
1196 .StateGetProgressCompletionStatus != NULL);
1197}
1198
b2d420be
VJ
1199int AppLayerParserProtocolIsTxAware(uint8_t ipproto, AppProto alproto)
1200{
1201 SCEnter();
1202 int ipproto_map = FlowGetProtoMapping(ipproto);
1203 int r = (alp_ctx.ctxs[ipproto_map][alproto].StateGetTx == NULL) ? 0 : 1;
1204 SCReturnInt(r);
1205}
1206
5cdeadb3 1207int AppLayerParserProtocolIsTxEventAware(uint8_t ipproto, AppProto alproto)
d9686fae 1208{
429c6388
AS
1209 SCEnter();
1210 int ipproto_map = FlowGetProtoMapping(ipproto);
3967bd55 1211 int r = (alp_ctx.ctxs[ipproto_map][alproto].StateGetEvents == NULL) ? 0 : 1;
1cbd1cdf 1212 SCReturnInt(r);
429c6388 1213}
432c3317 1214
5cdeadb3 1215int AppLayerParserProtocolSupportsTxs(uint8_t ipproto, AppProto alproto)
429c6388
AS
1216{
1217 SCEnter();
1218 int ipproto_map = FlowGetProtoMapping(ipproto);
1cbd1cdf
VJ
1219 int r = (alp_ctx.ctxs[ipproto_map][alproto].StateTransactionFree == NULL) ? 0 : 1;
1220 SCReturnInt(r);
432c3317
AS
1221}
1222
078ff0c0
VJ
1223int AppLayerParserProtocolHasLogger(uint8_t ipproto, AppProto alproto)
1224{
1225 SCEnter();
1226 int ipproto_map = FlowGetProtoMapping(ipproto);
1227 int r = (alp_ctx.ctxs[ipproto_map][alproto].logger == 0) ? 0 : 1;
1228 SCReturnInt(r);
1229}
1230
2d223b69 1231void AppLayerParserTriggerRawStreamReassembly(Flow *f, int direction)
432c3317 1232{
429c6388 1233 SCEnter();
432c3317 1234
2d223b69 1235 SCLogDebug("f %p tcp %p direction %d", f, f ? f->protoctx : NULL, direction);
429c6388 1236 if (f != NULL && f->protoctx != NULL)
2d223b69 1237 StreamTcpReassembleTriggerRawReassembly(f->protoctx, direction);
d9686fae 1238
429c6388 1239 SCReturn;
7c31a232
AS
1240}
1241
b160c49e
GL
1242void AppLayerParserSetStreamDepth(uint8_t ipproto, AppProto alproto, uint32_t stream_depth)
1243{
1244 SCEnter();
1245
1246 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].stream_depth = stream_depth;
1247
1248 SCReturn;
1249}
1250
3148ff34 1251uint32_t AppLayerParserGetStreamDepth(const Flow *f)
b160c49e 1252{
3148ff34 1253 SCReturnInt(alp_ctx.ctxs[f->protomap][f->alproto].stream_depth);
b160c49e
GL
1254}
1255
429c6388
AS
1256/***** Cleanup *****/
1257
3148ff34 1258void AppLayerParserStateCleanup(const Flow *f, void *alstate,
9634e60e 1259 AppLayerParserState *pstate)
7c31a232 1260{
429c6388 1261 SCEnter();
7c31a232 1262
3148ff34 1263 AppLayerParserProtoCtx *ctx = &alp_ctx.ctxs[f->protomap][f->alproto];
7c31a232 1264
429c6388
AS
1265 if (ctx->StateFree != NULL && alstate != NULL)
1266 ctx->StateFree(alstate);
7c31a232 1267
429c6388
AS
1268 /* free the app layer parser api state */
1269 if (pstate != NULL)
8527b8e0 1270 AppLayerParserStateFree(pstate);
432c3317 1271
429c6388
AS
1272 SCReturn;
1273}
432c3317 1274
ed172985
VJ
1275static void ValidateParserProtoDump(AppProto alproto, uint8_t ipproto)
1276{
1277 uint8_t map = FlowGetProtoMapping(ipproto);
1278 const AppLayerParserProtoCtx *ctx = &alp_ctx.ctxs[map][alproto];
1279 const AppLayerParserProtoCtx *ctx_def = &alp_ctx.ctxs[FLOW_PROTO_DEFAULT][alproto];
1280 printf("ERROR: incomplete app-layer registration\n");
1281 printf("AppLayer protocol %s ipproto %u\n", AppProtoToString(alproto), ipproto);
1282 printf("- flags %"PRIx64"\n", ctx->flags);
1283 printf("- first_data_dir %"PRIx8"\n", ctx->first_data_dir);
1284 printf("Mandatory:\n");
1285 printf("- Parser[0] %p Parser[1] %p\n", ctx->Parser[0], ctx->Parser[1]);
1286 printf("- StateAlloc %p StateFree %p\n", ctx->StateAlloc, ctx->StateFree);
1287 printf("- StateGetTx %p StateGetTxCnt %p StateTransactionFree %p\n",
1288 ctx->StateGetTx, ctx->StateGetTxCnt, ctx->StateTransactionFree);
1289 printf("- StateGetProgress %p StateGetProgressCompletionStatus %p\n", ctx->StateGetProgress, ctx_def->StateGetProgressCompletionStatus);
e9305131 1290 printf("- GetTxDetectState %p SetTxDetectState %p\n", ctx->GetTxDetectState, ctx->SetTxDetectState);
ed172985 1291 printf("Optional:\n");
e9305131 1292 printf("- StateHasTxDetectState %p\n", ctx->StateHasTxDetectState);
ed172985
VJ
1293 printf("- LocalStorageAlloc %p LocalStorageFree %p\n", ctx->LocalStorageAlloc, ctx->LocalStorageFree);
1294 printf("- StateGetTxLogged %p StateSetTxLogged %p\n", ctx->StateGetTxLogged, ctx->StateSetTxLogged);
1295 printf("- SetTxMpmIDs %p GetTxMpmIDs %p\n", ctx->SetTxMpmIDs, ctx->GetTxMpmIDs);
ed172985
VJ
1296 printf("- StateGetEvents %p StateHasEvents %p StateGetEventInfo %p\n", ctx->StateGetEvents, ctx->StateHasEvents, ctx->StateGetEventInfo);
1297}
1298
1299#define BOTH_SET(a, b) ((a) != NULL && (b) != NULL)
1300#define BOTH_SET_OR_BOTH_UNSET(a, b) (((a) == NULL && (b) == NULL) || ((a) != NULL && (b) != NULL))
1301#define THREE_SET_OR_THREE_UNSET(a, b, c) (((a) == NULL && (b) == NULL && (c) == NULL) || ((a) != NULL && (b) != NULL && (c) != NULL))
1302
1303static void ValidateParserProto(AppProto alproto, uint8_t ipproto)
1304{
1305 uint8_t map = FlowGetProtoMapping(ipproto);
1306 const AppLayerParserProtoCtx *ctx = &alp_ctx.ctxs[map][alproto];
1307 const AppLayerParserProtoCtx *ctx_def = &alp_ctx.ctxs[FLOW_PROTO_DEFAULT][alproto];
1308
1309 if (ctx->Parser[0] == NULL && ctx->Parser[1] == NULL)
1310 return;
1311
1312 if (!(BOTH_SET(ctx->Parser[0], ctx->Parser[1]))) {
1313 goto bad;
1314 }
1315 if (!(BOTH_SET(ctx->StateFree, ctx->StateAlloc))) {
1316 goto bad;
1317 }
1318 if (!(THREE_SET_OR_THREE_UNSET(ctx->StateGetTx, ctx->StateGetTxCnt, ctx->StateTransactionFree))) {
1319 goto bad;
1320 }
1321 /* special case: StateGetProgressCompletionStatus is used from 'default'. */
1322 if (!(BOTH_SET(ctx->StateGetProgress, ctx_def->StateGetProgressCompletionStatus))) {
1323 goto bad;
1324 }
1325 /* local storage is optional, but needs both set if used */
1326 if (!(BOTH_SET_OR_BOTH_UNSET(ctx->LocalStorageAlloc, ctx->LocalStorageFree))) {
1327 goto bad;
1328 }
1329 if (!(BOTH_SET_OR_BOTH_UNSET(ctx->StateGetTxLogged, ctx->StateSetTxLogged))) {
1330 goto bad;
1331 }
1332 if (!(BOTH_SET_OR_BOTH_UNSET(ctx->SetTxMpmIDs, ctx->GetTxMpmIDs))) {
1333 goto bad;
1334 }
e9305131 1335 if (!(BOTH_SET(ctx->GetTxDetectState, ctx->SetTxDetectState))) {
ed172985
VJ
1336 goto bad;
1337 }
1338/* TODO: not yet mandatory to use StateHasTxDetectState
1339 if (!(THREE_SET_OR_THREE_UNSET(ctx->GetTxDetectState, ctx->SetTxDetectState, ctx->StateHasTxDetectState))) {
1340 goto bad;
1341 }
1342*/
1343
1344 return;
1345bad:
1346 ValidateParserProtoDump(alproto, ipproto);
1347 exit(EXIT_FAILURE);
1348}
1349#undef BOTH_SET
1350#undef BOTH_SET_OR_BOTH_UNSET
1351#undef THREE_SET_OR_THREE_UNSET
1352
1353static void ValidateParser(AppProto alproto)
1354{
1355 ValidateParserProto(alproto, IPPROTO_TCP);
1356 ValidateParserProto(alproto, IPPROTO_UDP);
1357}
1358
1359static void ValidateParsers(void)
1360{
1361 AppProto p = 0;
1362 for ( ; p < ALPROTO_MAX; p++) {
1363 ValidateParser(p);
1364 }
1365}
432c3317 1366
429c6388
AS
1367void AppLayerParserRegisterProtocolParsers(void)
1368{
1369 SCEnter();
d9686fae 1370
429c6388
AS
1371 RegisterHTPParsers();
1372 RegisterSSLParsers();
1373 RegisterSMBParsers();
1374 /** \todo bug 719 */
1375 //RegisterSMB2Parsers();
1376 RegisterDCERPCParsers();
1377 RegisterDCERPCUDPParsers();
1378 RegisterFTPParsers();
429c6388 1379 RegisterSSHParsers();
429c6388
AS
1380 RegisterSMTPParsers();
1381 RegisterDNSUDPParsers();
1382 RegisterDNSTCPParsers();
5a040995 1383 RegisterModbusParsers();
a3ffebd8 1384 RegisterENIPUDPParsers();
1385 RegisterENIPTCPParsers();
bbaa79b8 1386 RegisterDNP3Parsers();
0d79181d
VJ
1387 RegisterNFSTCPParsers();
1388 RegisterNFSUDPParsers();
c1b92126 1389 RegisterTemplateParsers();
432c3317 1390
429c6388
AS
1391 /** IMAP */
1392 AppLayerProtoDetectRegisterProtocol(ALPROTO_IMAP, "imap");
1393 if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", "imap")) {
1394 if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_IMAP,
1395 "1|20|capability", 12, 0, STREAM_TOSERVER) < 0)
1396 {
1397 SCLogInfo("imap proto registration failure\n");
1398 exit(EXIT_FAILURE);
d9686fae 1399 }
429c6388
AS
1400 } else {
1401 SCLogInfo("Protocol detection and parser disabled for %s protocol.",
1402 "imap");
d9686fae 1403 }
429c6388
AS
1404
1405 /** MSN Messenger */
1406 AppLayerProtoDetectRegisterProtocol(ALPROTO_MSN, "msn");
1407 if (AppLayerProtoDetectConfProtoDetectionEnabled("tcp", "msn")) {
1408 if (AppLayerProtoDetectPMRegisterPatternCS(IPPROTO_TCP, ALPROTO_MSN,
1409 "msn", 10, 6, STREAM_TOSERVER) < 0)
1410 {
1411 SCLogInfo("msn proto registration failure\n");
1412 exit(EXIT_FAILURE);
7c31a232 1413 }
d9686fae 1414 } else {
429c6388
AS
1415 SCLogInfo("Protocol detection and parser disabled for %s protocol.",
1416 "msn");
7c31a232 1417 }
432c3317 1418
ed172985 1419 ValidateParsers();
432c3317
AS
1420 return;
1421}
1422
0d7159b5 1423
9634e60e 1424void AppLayerParserStateSetFlag(AppLayerParserState *pstate, uint8_t flag)
429c6388
AS
1425{
1426 SCEnter();
9634e60e 1427 pstate->flags |= flag;
429c6388 1428 SCReturn;
0d7159b5
AS
1429}
1430
9634e60e 1431int AppLayerParserStateIssetFlag(AppLayerParserState *pstate, uint8_t flag)
0d7159b5 1432{
429c6388 1433 SCEnter();
9634e60e 1434 SCReturnInt(pstate->flags & flag);
0d7159b5
AS
1435}
1436
429c6388 1437
5cdeadb3 1438void AppLayerParserStreamTruncated(uint8_t ipproto, AppProto alproto, void *alstate,
429c6388 1439 uint8_t direction)
d9686fae 1440{
429c6388 1441 SCEnter();
432c3317 1442
429c6388
AS
1443
1444 if (alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].Truncate != NULL)
1445 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].Truncate(alstate, direction);
1446
1447 SCReturn;
7c31a232
AS
1448}
1449
429c6388 1450#ifdef DEBUG
9634e60e 1451void AppLayerParserStatePrintDetails(AppLayerParserState *pstate)
7c31a232 1452{
429c6388 1453 SCEnter();
980934d6 1454
429c6388
AS
1455 if (pstate == NULL)
1456 SCReturn;
7c31a232 1457
9634e60e 1458 AppLayerParserState *p = pstate;
429c6388
AS
1459 SCLogDebug("AppLayerParser parser state information for parser state p(%p). "
1460 "p->inspect_id[0](%"PRIu64"), "
1461 "p->inspect_id[1](%"PRIu64"), "
1462 "p->log_id(%"PRIu64"), "
429c6388
AS
1463 "p->decoder_events(%p).",
1464 pstate, p->inspect_id[0], p->inspect_id[1], p->log_id,
e24eb0f2 1465 p->decoder_events);
7c31a232 1466
429c6388 1467 SCReturn;
7c31a232 1468}
429c6388
AS
1469#endif
1470
077ac816 1471#ifdef AFLFUZZ_APPLAYER
4683b0e6 1472int AppLayerParserRequestFromFile(uint8_t ipproto, AppProto alproto, char *filename)
077ac816
VJ
1473{
1474 int result = 1;
1475 Flow *f = NULL;
1476 TcpSession ssn;
1477 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1478
1479 memset(&ssn, 0, sizeof(ssn));
1480
1481 f = SCCalloc(1, sizeof(Flow));
1482 if (f == NULL)
1483 goto end;
1484 FLOW_INITIALIZE(f);
1485
1486 f->flags |= FLOW_IPV4;
1487 f->src.addr_data32[0] = 0x01020304;
1488 f->dst.addr_data32[0] = 0x05060708;
1489 f->sp = 10000;
1490 f->dp = 80;
1491 f->protoctx = &ssn;
4683b0e6
VJ
1492 f->proto = ipproto;
1493 f->protomap = FlowGetProtoMapping(f->proto);
077ac816
VJ
1494 f->alproto = alproto;
1495
45d87d66 1496 uint8_t buffer[64];
077ac816 1497
45d87d66
MK
1498#ifdef AFLFUZZ_PERSISTANT_MODE
1499 while (__AFL_LOOP(1000)) {
1500 /* reset state */
1501 memset(buffer, 0, sizeof(buffer));
1502#endif /* AFLFUZZ_PERSISTANT_MODE */
077ac816 1503
45d87d66
MK
1504 FILE *fp = fopen(filename, "r");
1505 BUG_ON(fp == NULL);
077ac816 1506
45d87d66
MK
1507 int start = 1;
1508 while (1) {
1509 int done = 0;
c89ce170
VJ
1510 size_t size = fread(&buffer, 1, sizeof(buffer), fp);
1511 if (size < sizeof(buffer))
45d87d66 1512 done = 1;
077ac816 1513
45d87d66 1514 //SCLogInfo("result %u done %d start %d", (uint)result, done, start);
077ac816 1515
45d87d66
MK
1516 uint8_t flags = STREAM_TOSERVER;
1517
1518 if (start--) {
1519 flags |= STREAM_START;
1520 }
1521 if (done) {
1522 flags |= STREAM_EOF;
1523 }
1524 //PrintRawDataFp(stdout, buffer, result);
1525
675fa564 1526 (void)AppLayerParserParse(NULL, alp_tctx, f, alproto, flags,
c89ce170 1527 buffer, size);
45d87d66
MK
1528 if (done)
1529 break;
077ac816 1530 }
077ac816 1531
45d87d66
MK
1532 fclose(fp);
1533
1534#ifdef AFLFUZZ_PERSISTANT_MODE
077ac816 1535 }
45d87d66 1536#endif /* AFLFUZZ_PERSISTANT_MODE */
077ac816
VJ
1537
1538 result = 0;
45d87d66 1539
077ac816
VJ
1540end:
1541 if (alp_tctx != NULL)
1542 AppLayerParserThreadCtxFree(alp_tctx);
1543 if (f != NULL) {
1544 FlowFree(f);
1545 }
1546 return result;
1547}
1548
4683b0e6 1549int AppLayerParserFromFile(uint8_t ipproto, AppProto alproto, char *filename)
077ac816
VJ
1550{
1551 int result = 1;
1552 Flow *f = NULL;
1553 TcpSession ssn;
1554 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
1555
1556 memset(&ssn, 0, sizeof(ssn));
1557
1558 f = SCCalloc(1, sizeof(Flow));
1559 if (f == NULL)
1560 goto end;
1561 FLOW_INITIALIZE(f);
1562
1563 f->flags |= FLOW_IPV4;
1564 f->src.addr_data32[0] = 0x01020304;
1565 f->dst.addr_data32[0] = 0x05060708;
1566 f->sp = 10000;
1567 f->dp = 80;
1568 f->protoctx = &ssn;
4683b0e6
VJ
1569 f->proto = ipproto;
1570 f->protomap = FlowGetProtoMapping(f->proto);
077ac816
VJ
1571 f->alproto = alproto;
1572
077ac816
VJ
1573 uint8_t buffer[64];
1574
45d87d66
MK
1575#ifdef AFLFUZZ_PERSISTANT_MODE
1576 while (__AFL_LOOP(1000)) {
1577 /* reset state */
1578 memset(buffer, 0, sizeof(buffer));
1579#endif /* AFLFUZZ_PERSISTANT_MODE */
1580
1581 FILE *fp = fopen(filename, "r");
1582 BUG_ON(fp == NULL);
1583
1584 int start = 1;
1585 int flip = 0;
1586 while (1) {
1587 int done = 0;
c89ce170
VJ
1588 size_t size = fread(&buffer, 1, sizeof(buffer), fp);
1589 if (size < sizeof(buffer))
45d87d66
MK
1590 done = 1;
1591
1592 //SCLogInfo("result %u done %d start %d", (uint)result, done, start);
1593
1594 uint8_t flags = 0;
1595 if (flip) {
1596 flags = STREAM_TOCLIENT;
1597 flip = 0;
1598 } else {
1599 flags = STREAM_TOSERVER;
1600 flip = 1;
1601 }
077ac816 1602
45d87d66
MK
1603 if (start--) {
1604 flags |= STREAM_START;
1605 }
1606 if (done) {
1607 flags |= STREAM_EOF;
1608 }
1609 //PrintRawDataFp(stdout, buffer, result);
077ac816 1610
675fa564 1611 (void)AppLayerParserParse(NULL, alp_tctx, f, alproto, flags,
c89ce170 1612 buffer, size);
45d87d66
MK
1613 if (done)
1614 break;
077ac816
VJ
1615 }
1616
45d87d66 1617 fclose(fp);
077ac816 1618
45d87d66 1619#ifdef AFLFUZZ_PERSISTANT_MODE
077ac816 1620 }
45d87d66 1621#endif /* AFLFUZZ_PERSISTANT_MODE */
077ac816
VJ
1622
1623 result = 0;
077ac816
VJ
1624end:
1625 if (alp_tctx != NULL)
1626 AppLayerParserThreadCtxFree(alp_tctx);
1627 if (f != NULL) {
1628 FlowFree(f);
1629 }
1630 return result;
1631}
45d87d66 1632#endif /* AFLFUZZ_APPLAYER */
7c31a232 1633
429c6388 1634/***** Unittests *****/
7c31a232 1635
c1e485cc
GS
1636#ifdef UNITTESTS
1637
429c6388
AS
1638static AppLayerParserCtx alp_ctx_backup_unittest;
1639
c1e485cc
GS
1640typedef struct TestState_ {
1641 uint8_t test;
429c6388 1642} TestState;
c1e485cc
GS
1643
1644/**
1645 * \brief Test parser function to test the memory deallocation of app layer
1646 * parser of occurence of an error.
1647 */
9634e60e 1648static int TestProtocolParser(Flow *f, void *test_state, AppLayerParserState *pstate,
9a6aef45 1649 uint8_t *input, uint32_t input_len,
429c6388 1650 void *local_data)
c1e485cc 1651{
429c6388
AS
1652 SCEnter();
1653 SCReturnInt(-1);
c1e485cc
GS
1654}
1655
1656/** \brief Function to allocates the Test protocol state memory
1657 */
1658static void *TestProtocolStateAlloc(void)
1659{
429c6388 1660 SCEnter();
25a3a5c6 1661 void *s = SCMalloc(sizeof(TestState));
e176be6f 1662 if (unlikely(s == NULL))
429c6388 1663 goto end;
c1e485cc 1664 memset(s, 0, sizeof(TestState));
429c6388
AS
1665 end:
1666 SCReturnPtr(s, "TestState");
c1e485cc
GS
1667}
1668
1669/** \brief Function to free the Test Protocol state memory
1670 */
1671static void TestProtocolStateFree(void *s)
1672{
25a3a5c6 1673 SCFree(s);
c1e485cc
GS
1674}
1675
5cdeadb3 1676void AppLayerParserRegisterProtocolUnittests(uint8_t ipproto, AppProto alproto,
429c6388 1677 void (*RegisterUnittests)(void))
6cb00142 1678{
429c6388
AS
1679 SCEnter();
1680 alp_ctx.ctxs[FlowGetProtoMapping(ipproto)][alproto].
1681 RegisterUnittests = RegisterUnittests;
1682 SCReturn;
6cb00142
AS
1683}
1684
429c6388 1685void AppLayerParserBackupParserTable(void)
6cb00142 1686{
429c6388
AS
1687 SCEnter();
1688 alp_ctx_backup_unittest = alp_ctx;
1689 memset(&alp_ctx, 0, sizeof(alp_ctx));
1690 SCReturn;
1691}
6cb00142 1692
429c6388
AS
1693void AppLayerParserRestoreParserTable(void)
1694{
1695 SCEnter();
1696 alp_ctx = alp_ctx_backup_unittest;
1697 memset(&alp_ctx_backup_unittest, 0, sizeof(alp_ctx_backup_unittest));
1698 SCReturn;
6cb00142
AS
1699}
1700
1701/**
1702 * \test Test the deallocation of app layer parser memory on occurance of
1703 * error in the parsing process.
c1e485cc 1704 */
429c6388 1705static int AppLayerParserTest01(void)
c1e485cc 1706{
429c6388
AS
1707 AppLayerParserBackupParserTable();
1708
9f95ab74 1709 int result = 0;
262a7300 1710 Flow *f = NULL;
c1e485cc
GS
1711 uint8_t testbuf[] = { 0x11 };
1712 uint32_t testlen = sizeof(testbuf);
1713 TcpSession ssn;
8dbf7a0d 1714 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
c1e485cc 1715
c1e485cc 1716 memset(&ssn, 0, sizeof(ssn));
c1e485cc
GS
1717
1718 /* Register the Test protocol state and parser functions */
429c6388
AS
1719 AppLayerParserRegisterParser(IPPROTO_TCP, ALPROTO_TEST, STREAM_TOSERVER,
1720 TestProtocolParser);
1721 AppLayerParserRegisterStateFuncs(IPPROTO_TCP, ALPROTO_TEST,
1722 TestProtocolStateAlloc, TestProtocolStateFree);
c1e485cc 1723
262a7300
VJ
1724 f = UTHBuildFlow(AF_INET, "1.2.3.4", "4.3.2.1", 20, 40);
1725 if (f == NULL)
1726 goto end;
1727 f->protoctx = &ssn;
262a7300
VJ
1728 f->alproto = ALPROTO_TEST;
1729 f->proto = IPPROTO_TCP;
c1e485cc 1730
6a53ab9c 1731 StreamTcpInitConfig(TRUE);
6a53ab9c 1732
6530c3d0 1733 FLOWLOCK_WRLOCK(f);
675fa564
GL
1734 int r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_TEST,
1735 STREAM_TOSERVER | STREAM_EOF, testbuf,
1736 testlen);
c1e485cc 1737 if (r != -1) {
9f95ab74 1738 printf("returned %" PRId32 ", expected -1: ", r);
6530c3d0 1739 FLOWLOCK_UNLOCK(f);
c1e485cc
GS
1740 goto end;
1741 }
6530c3d0 1742 FLOWLOCK_UNLOCK(f);
c1e485cc 1743
c1558f5a 1744 if (!(ssn.flags & STREAMTCP_FLAG_APP_LAYER_DISABLED)) {
9f95ab74 1745 printf("flag should have been set, but is not: ");
c1e485cc
GS
1746 goto end;
1747 }
1748
9f95ab74 1749 result = 1;
429c6388
AS
1750 end:
1751 AppLayerParserRestoreParserTable();
8cc525c9 1752 StreamTcpFreeConfig(TRUE);
262a7300
VJ
1753
1754 UTHFreeFlow(f);
8cc525c9
PR
1755 return result;
1756}
1757
6cb00142
AS
1758/**
1759 * \test Test the deallocation of app layer parser memory on occurance of
1760 * error in the parsing process for UDP.
8cc525c9 1761 */
429c6388 1762static int AppLayerParserTest02(void)
8cc525c9 1763{
429c6388
AS
1764 AppLayerParserBackupParserTable();
1765
8cc525c9 1766 int result = 1;
262a7300 1767 Flow *f = NULL;
8cc525c9
PR
1768 uint8_t testbuf[] = { 0x11 };
1769 uint32_t testlen = sizeof(testbuf);
8dbf7a0d 1770 AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
8cc525c9
PR
1771
1772 /* Register the Test protocol state and parser functions */
429c6388
AS
1773 AppLayerParserRegisterParser(IPPROTO_UDP, ALPROTO_TEST, STREAM_TOSERVER,
1774 TestProtocolParser);
1775 AppLayerParserRegisterStateFuncs(IPPROTO_UDP, ALPROTO_TEST,
1776 TestProtocolStateAlloc, TestProtocolStateFree);
8cc525c9 1777
262a7300
VJ
1778 f = UTHBuildFlow(AF_INET, "1.2.3.4", "4.3.2.1", 20, 40);
1779 if (f == NULL)
1780 goto end;
1781 f->alproto = ALPROTO_TEST;
1782 f->proto = IPPROTO_UDP;
a77b9b36 1783 f->protomap = FlowGetProtoMapping(f->proto);
8cc525c9
PR
1784
1785 StreamTcpInitConfig(TRUE);
8cc525c9 1786
6530c3d0 1787 FLOWLOCK_WRLOCK(f);
675fa564
GL
1788 int r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_TEST,
1789 STREAM_TOSERVER | STREAM_EOF, testbuf,
1790 testlen);
8cc525c9
PR
1791 if (r != -1) {
1792 printf("returned %" PRId32 ", expected -1: \n", r);
1793 result = 0;
6530c3d0 1794 FLOWLOCK_UNLOCK(f);
8cc525c9
PR
1795 goto end;
1796 }
6530c3d0 1797 FLOWLOCK_UNLOCK(f);
8cc525c9 1798
429c6388
AS
1799 end:
1800 AppLayerParserRestoreParserTable();
6a53ab9c 1801 StreamTcpFreeConfig(TRUE);
262a7300 1802 UTHFreeFlow(f);
c1e485cc
GS
1803 return result;
1804}
1805
7c31a232 1806
429c6388 1807void AppLayerParserRegisterUnittests(void)
7c31a232 1808{
429c6388 1809 SCEnter();
9faa4b74 1810
429c6388 1811 int ip;
f5f14880 1812 AppProto alproto;
c23742a0 1813 AppLayerParserProtoCtx *ctx;
9faa4b74 1814
429c6388
AS
1815 for (ip = 0; ip < FLOW_PROTO_DEFAULT; ip++) {
1816 for (alproto = 0; alproto < ALPROTO_MAX; alproto++) {
1817 ctx = &alp_ctx.ctxs[ip][alproto];
1818 if (ctx->RegisterUnittests == NULL)
1819 continue;
1820 ctx->RegisterUnittests();
9faa4b74
VJ
1821 }
1822 }
1823
796dd522
JI
1824 UtRegisterTest("AppLayerParserTest01", AppLayerParserTest01);
1825 UtRegisterTest("AppLayerParserTest02", AppLayerParserTest02);
7c31a232 1826
429c6388 1827 SCReturn;
c1e485cc 1828}
429c6388
AS
1829
1830#endif