]> git.ipfire.org Git - people/ms/suricata.git/blame - src/app-layer-parser.c
Reenable --enable-htp-debug option for libhtp so Suricata's --enable-debug won't...
[people/ms/suricata.git] / src / app-layer-parser.c
CommitLineData
8e10844f
VJ
1/* Copyright (c) 2009 Victor Julien */
2
ecf86f9c 3#include "suricata-common.h"
8e10844f 4#include "debug.h"
c1e485cc 5#include "util-unittest.h"
8e10844f
VJ
6#include "decode.h"
7#include "threads.h"
8
9#include "util-print.h"
10#include "util-pool.h"
11
6a53ab9c 12#include "stream-tcp.h"
8e10844f
VJ
13#include "stream-tcp-private.h"
14#include "stream.h"
a16e7b74 15#include "stream-tcp-reassemble.h"
8e10844f
VJ
16
17#include "app-layer-protos.h"
18#include "app-layer-parser.h"
19
705471e4 20#include "util-spm.h"
9f78d47c 21
91bc83e5
VJ
22#include "util-debug.h"
23
cae8e06c 24static uint16_t app_layer_sid = 0;
356a8bf3
GS
25static AppLayerProto al_proto_table[ALPROTO_MAX]; /**< Application layer protocol
26 table mapped to their
27 corresponding parsers */
cae8e06c
VJ
28
29#define MAX_PARSERS 100
30static AppLayerParserTableElement al_parser_table[MAX_PARSERS];
31static uint16_t al_max_parsers = 0; /* incremented for every registered parser */
32
5a9a23f9 33static Pool *al_result_pool = NULL;
cae8e06c
VJ
34static SCMutex al_result_pool_mutex = PTHREAD_MUTEX_INITIALIZER;
35#ifdef DEBUG
36static uint32_t al_result_pool_elmts = 0;
37#endif /* DEBUG */
38
5a9a23f9 39
9f78d47c 40/** \brief Alloc a AppLayerParserResultElmt func for the pool */
c1e485cc
GS
41static void *AlpResultElmtPoolAlloc(void *null)
42{
43 AppLayerParserResultElmt *e = (AppLayerParserResultElmt *)malloc
44 (sizeof(AppLayerParserResultElmt));
5a9a23f9
VJ
45 if (e == NULL) {
46 return NULL;
47 }
48
9f78d47c 49 memset(e, 0, sizeof(AppLayerParserResultElmt));
cae8e06c
VJ
50
51#ifdef DEBUG
52 al_result_pool_elmts++;
53 SCLogDebug("al_result_pool_elmts %"PRIu32"", al_result_pool_elmts);
54#endif /* DEBUG */
5a9a23f9
VJ
55 return e;
56}
5a9a23f9 57
c1e485cc
GS
58static void AlpResultElmtPoolFree(void *e)
59{
9f78d47c
VJ
60 AppLayerParserResultElmt *re = (AppLayerParserResultElmt *)e;
61
62 if (re->flags & ALP_RESULT_ELMT_ALLOC) {
63 if (re->data_ptr != NULL)
64 free(re->data_ptr);
65 }
66 free(re);
cae8e06c
VJ
67
68#ifdef DEBUG
69 al_result_pool_elmts--;
70 SCLogDebug("al_result_pool_elmts %"PRIu32"", al_result_pool_elmts);
71#endif /* DEBUG */
9f78d47c
VJ
72}
73
c1e485cc
GS
74static AppLayerParserResultElmt *AlpGetResultElmt(void)
75{
cae8e06c 76 SCMutexLock(&al_result_pool_mutex);
9f78d47c 77 AppLayerParserResultElmt *e = (AppLayerParserResultElmt *)PoolGet(al_result_pool);
cae8e06c
VJ
78 SCMutexUnlock(&al_result_pool_mutex);
79
4914d8d9 80 if (e == NULL) {
bcc5bbef 81 return NULL;
4914d8d9 82 }
9f78d47c 83 e->next = NULL;
5a9a23f9
VJ
84 return e;
85}
86
c1e485cc
GS
87static void AlpReturnResultElmt(AppLayerParserResultElmt *e)
88{
9f78d47c
VJ
89 if (e->flags & ALP_RESULT_ELMT_ALLOC) {
90 if (e->data_ptr != NULL)
91 free(e->data_ptr);
92 }
93 e->flags = 0;
94 e->data_ptr = NULL;
95 e->data_len = 0;
96 e->next = NULL;
97
cae8e06c 98 SCMutexLock(&al_result_pool_mutex);
9f78d47c 99 PoolReturn(al_result_pool, (void *)e);
cae8e06c 100 SCMutexUnlock(&al_result_pool_mutex);
9f78d47c
VJ
101}
102
c1e485cc
GS
103static void AlpAppendResultElmt(AppLayerParserResult *r, AppLayerParserResultElmt *e)
104{
9f78d47c
VJ
105 if (r->head == NULL) {
106 r->head = e;
107 r->tail = e;
108 r->cnt = 1;
109 } else {
110 r->tail->next = e;
111 r->tail = e;
112 r->cnt++;
113 }
114}
115
116/**
117 * \param alloc Is ptr alloc'd (1) or a ptr to static mem (0).
574bcea0
VJ
118 * \retval -1 error
119 * \retval 0 ok
9f78d47c 120 */
c1e485cc
GS
121static int AlpStoreField(AppLayerParserResult *output, uint16_t idx,
122 uint8_t *ptr, uint32_t len, uint8_t alloc)
123{
574bcea0
VJ
124 SCEnter();
125
9f78d47c 126 AppLayerParserResultElmt *e = AlpGetResultElmt();
fc2f7f29 127 if (e == NULL) {
d8433c72 128 SCLogError(SC_ERR_POOL_EMPTY, "App layer \"al_result_pool\" is empty");
574bcea0 129 SCReturnInt(-1);
fc2f7f29 130 }
9f78d47c
VJ
131
132 if (alloc == 1)
133 e->flags |= ALP_RESULT_ELMT_ALLOC;
134
135 e->name_idx = idx;
136 e->data_ptr = ptr;
137 e->data_len = len;
138 AlpAppendResultElmt(output, e);
139
574bcea0 140 SCReturnInt(0);
9f78d47c
VJ
141}
142
086ba5f4
VJ
143/** \brief Parse a field up to we reach the size limit
144 *
145 * \retval 1 Field found and stored.
146 * \retval 0 Field parsing in progress.
147 * \retval -1 error
148 */
c1e485cc
GS
149int AlpParseFieldBySize(AppLayerParserResult *output, AppLayerParserState *pstate,
150 uint16_t field_idx, uint32_t size, uint8_t *input,
151 uint32_t input_len, uint32_t *offset)
152{
574bcea0
VJ
153 SCEnter();
154
086ba5f4
VJ
155 if ((pstate->store_len + input_len) < size) {
156 if (pstate->store_len == 0) {
157 pstate->store = malloc(input_len);
574bcea0 158 if (pstate->store == NULL) {
fc2f7f29 159 SCLogError(SC_ERR_MEM_ALLOC, "Memory allocation failed!");
574bcea0
VJ
160 SCReturnInt(-1);
161 }
086ba5f4
VJ
162
163 memcpy(pstate->store, input, input_len);
164 pstate->store_len = input_len;
165 } else {
166 pstate->store = realloc(pstate->store, (input_len + pstate->store_len));
574bcea0 167 if (pstate->store == NULL) {
fc2f7f29 168 SCLogError(SC_ERR_MEM_ALLOC, "Memory reallocation failed!");
574bcea0
VJ
169 SCReturnInt(-1);
170 }
086ba5f4
VJ
171
172 memcpy(pstate->store+pstate->store_len, input, input_len);
173 pstate->store_len += input_len;
174 }
175 } else {
176 if (pstate->store_len == 0) {
574bcea0
VJ
177 int r = AlpStoreField(output, field_idx, input, size, /* static mem */0);
178 if (r == -1) {
d0404d84 179 SCLogError(SC_ERR_ALPARSER, "Failed to store field value");
574bcea0
VJ
180 SCReturnInt(-1);
181 }
086ba5f4 182 (*offset) += size;
574bcea0
VJ
183
184 SCReturnInt(1);
086ba5f4
VJ
185 } else {
186 uint32_t diff = size - pstate->store_len;
187
188 pstate->store = realloc(pstate->store, (diff + pstate->store_len));
574bcea0 189 if (pstate->store == NULL) {
fc2f7f29 190 SCLogError(SC_ERR_MEM_ALLOC, "Memory reallocation failed!");
574bcea0
VJ
191 SCReturnInt(-1);
192 }
086ba5f4
VJ
193
194 memcpy(pstate->store+pstate->store_len, input, diff);
195 pstate->store_len += diff;
196
c1e485cc
GS
197 int r = AlpStoreField(output, field_idx, pstate->store,
198 pstate->store_len, /* alloc mem */1);
574bcea0 199 if (r == -1) {
d0404d84 200 SCLogError(SC_ERR_ALPARSER, "Failed to store field value");
574bcea0
VJ
201 SCReturnInt(-1);
202 }
086ba5f4
VJ
203
204 (*offset) += diff;
205
206 pstate->store = NULL;
207 pstate->store_len = 0;
574bcea0
VJ
208
209 SCReturnInt(1);
086ba5f4
VJ
210 }
211 }
212
574bcea0 213 SCReturnInt(0);
086ba5f4
VJ
214}
215
9f78d47c
VJ
216/** \brief Parse a field up to the EOF
217 *
218 * \retval 1 Field found and stored.
219 * \retval 0 Field parsing in progress.
220 * \retval -1 error
221 */
c1e485cc
GS
222int AlpParseFieldByEOF(AppLayerParserResult *output, AppLayerParserState *pstate,
223 uint16_t field_idx, uint8_t *input, uint32_t input_len)
224{
574bcea0
VJ
225 SCEnter();
226
9f78d47c
VJ
227 if (pstate->store_len == 0) {
228 if (pstate->flags & APP_LAYER_PARSER_EOF) {
574bcea0
VJ
229 SCLogDebug("store_len 0 and EOF");
230
231 int r = AlpStoreField(output, field_idx, input, input_len, 0);
232 if (r == -1) {
d0404d84 233 SCLogError(SC_ERR_ALPARSER, "Failed to store field value");
574bcea0
VJ
234 SCReturnInt(-1);
235 }
236
237 SCReturnInt(1);
9f78d47c 238 } else {
574bcea0
VJ
239 SCLogDebug("store_len 0 but no EOF");
240
9f78d47c
VJ
241 /* delimiter field not found, so store the result for the next run */
242 pstate->store = malloc(input_len);
574bcea0 243 if (pstate->store == NULL) {
fc2f7f29 244 SCLogError(SC_ERR_MEM_ALLOC, "Memory allocation failed!");
574bcea0
VJ
245 SCReturnInt(-1);
246 }
9f78d47c
VJ
247
248 memcpy(pstate->store, input, input_len);
249 pstate->store_len = input_len;
250 }
251 } else {
252 if (pstate->flags & APP_LAYER_PARSER_EOF) {
574bcea0
VJ
253 SCLogDebug("store_len %" PRIu32 " and EOF", pstate->store_len);
254
9f78d47c 255 pstate->store = realloc(pstate->store, (input_len + pstate->store_len));
574bcea0 256 if (pstate->store == NULL) {
fc2f7f29 257 SCLogError(SC_ERR_MEM_ALLOC, "Memory reallocation failed!");
574bcea0
VJ
258 SCReturnInt(-1);
259 }
9f78d47c
VJ
260
261 memcpy(pstate->store+pstate->store_len, input, input_len);
262 pstate->store_len += input_len;
263
574bcea0
VJ
264 int r = AlpStoreField(output, field_idx, pstate->store, pstate->store_len, 1);
265 if (r == -1) {
d0404d84 266 SCLogError(SC_ERR_ALPARSER, "Failed to store field value");
574bcea0
VJ
267 SCReturnInt(-1);
268 }
269
9f78d47c
VJ
270 pstate->store = NULL;
271 pstate->store_len = 0;
574bcea0
VJ
272
273 SCReturnInt(1);
9f78d47c 274 } else {
574bcea0
VJ
275 SCLogDebug("store_len %" PRIu32 " but no EOF", pstate->store_len);
276
9f78d47c
VJ
277 /* delimiter field not found, so store the result for the next run */
278 pstate->store = realloc(pstate->store, (input_len + pstate->store_len));
574bcea0 279 if (pstate->store == NULL) {
fc2f7f29 280 SCLogError(SC_ERR_MEM_ALLOC, "Memory reallocation failed!");
574bcea0
VJ
281 SCReturnInt(-1);
282 }
9f78d47c
VJ
283
284 memcpy(pstate->store+pstate->store_len, input, input_len);
285 pstate->store_len += input_len;
286 }
287
288 }
289
574bcea0 290 SCReturnInt(0);
9f78d47c
VJ
291}
292
293/** \brief Parse a field up to a delimeter.
294 *
295 * \retval 1 Field found and stored.
296 * \retval 0 Field parsing in progress.
297 * \retval -1 error
298 */
c1e485cc
GS
299int AlpParseFieldByDelimiter(AppLayerParserResult *output, AppLayerParserState *pstate,
300 uint16_t field_idx, const uint8_t *delim, uint8_t delim_len,
301 uint8_t *input, uint32_t input_len, uint32_t *offset)
302{
574bcea0 303 SCEnter();
c1e485cc
GS
304 SCLogDebug("pstate->store_len %" PRIu32 ", delim_len %" PRIu32 "",
305 pstate->store_len, delim_len);
9f78d47c
VJ
306
307 if (pstate->store_len == 0) {
705471e4 308 uint8_t *ptr = SpmSearch(input, input_len, (uint8_t*)delim, delim_len);
9f78d47c 309 if (ptr != NULL) {
fa5939ca 310 uint32_t len = ptr - input;
c1e485cc 311 SCLogDebug(" len %" PRIu32 "", len);
9f78d47c 312
574bcea0
VJ
313 int r = AlpStoreField(output, field_idx, input, len, 0);
314 if (r == -1) {
d0404d84 315 SCLogError(SC_ERR_ALPARSER, "Failed to store field value");
574bcea0
VJ
316 SCReturnInt(-1);
317 }
9f78d47c 318 (*offset) += (len + delim_len);
574bcea0 319 SCReturnInt(1);
9f78d47c
VJ
320 } else {
321 if (pstate->flags & APP_LAYER_PARSER_EOF) {
c1e485cc 322 SCLogDebug("delim not found and EOF");
574bcea0 323 SCReturnInt(0);
9f78d47c
VJ
324 }
325
c1e485cc 326 SCLogDebug("delim not found, continue");
9f78d47c
VJ
327
328 /* delimiter field not found, so store the result for the next run */
329 pstate->store = malloc(input_len);
574bcea0 330 if (pstate->store == NULL) {
fc2f7f29 331 SCLogError(SC_ERR_MEM_ALLOC, "Memory allocation failed!");
574bcea0
VJ
332 SCReturnInt(-1);
333 }
9f78d47c
VJ
334
335 memcpy(pstate->store, input, input_len);
336 pstate->store_len = input_len;
337 }
338 } else {
705471e4 339 uint8_t *ptr = SpmSearch(input, input_len, (uint8_t*)delim, delim_len);
9f78d47c 340 if (ptr != NULL) {
fa5939ca 341 uint32_t len = ptr - input;
c1e485cc
GS
342 SCLogDebug("len %" PRIu32 " + %" PRIu32 " = %" PRIu32 "", len,
343 pstate->store_len, len + pstate->store_len);
9f78d47c
VJ
344
345 pstate->store = realloc(pstate->store, (len + pstate->store_len));
574bcea0 346 if (pstate->store == NULL) {
fc2f7f29 347 SCLogError(SC_ERR_MEM_ALLOC, "Memory reallocation failed!");
574bcea0
VJ
348 SCReturnInt(-1);
349 }
9f78d47c
VJ
350
351 memcpy(pstate->store+pstate->store_len, input, len);
352 pstate->store_len += len;
353
c1e485cc
GS
354 int r = AlpStoreField(output, field_idx, pstate->store,
355 pstate->store_len, 1);
574bcea0 356 if (r == -1) {
d0404d84 357 SCLogError(SC_ERR_ALPARSER, "Failed to store field value");
574bcea0
VJ
358 SCReturnInt(-1);
359 }
9f78d47c
VJ
360 pstate->store = NULL;
361 pstate->store_len = 0;
362
363 (*offset) += (len + delim_len);
574bcea0 364 SCReturnInt(1);
9f78d47c
VJ
365 } else {
366 if (pstate->flags & APP_LAYER_PARSER_EOF) {
367 /* if the input len is smaller than the delim len we search the
368 * pstate->store since we may match there. */
369 if (delim_len > input_len) {
c1e485cc
GS
370 /* delimiter field not found, so store the result for the
371 * next run */
372 pstate->store = realloc(pstate->store, (input_len +
373 pstate->store_len));
574bcea0 374 if (pstate->store == NULL) {
fc2f7f29 375 SCLogError(SC_ERR_MEM_ALLOC, "Memory reallocation failed!");
574bcea0
VJ
376 SCReturnInt(-1);
377 }
9f78d47c
VJ
378
379 memcpy(pstate->store+pstate->store_len, input, input_len);
380 pstate->store_len += input_len;
c1e485cc 381 SCLogDebug("input_len < delim_len, checking pstate->store");
9f78d47c
VJ
382
383 if (pstate->store_len >= delim_len) {
705471e4 384 ptr = SpmSearch(pstate->store, pstate->store_len, (uint8_t*)delim,
c1e485cc 385 delim_len);
9f78d47c 386 if (ptr != NULL) {
c1e485cc 387 SCLogDebug("now we found the delim");
9f78d47c 388
fa5939ca 389 uint32_t len = ptr - pstate->store;
c1e485cc
GS
390 int r = AlpStoreField(output, field_idx,
391 pstate->store, len, 1);
574bcea0 392 if (r == -1) {
d0404d84 393 SCLogError(SC_ERR_ALPARSER, "Failed to store "
fc2f7f29 394 "field value");
574bcea0
VJ
395 SCReturnInt(-1);
396 }
397
9f78d47c
VJ
398 pstate->store = NULL;
399 pstate->store_len = 0;
400
401 (*offset) += (input_len);
402
c1e485cc 403 SCLogDebug("offset %" PRIu32 "", (*offset));
574bcea0 404 SCReturnInt(1);
9f78d47c
VJ
405 }
406 goto free_and_return;
407 }
408 goto free_and_return;
409 }
410 free_and_return:
c1e485cc 411 SCLogDebug("not found and EOF, so free what we have so far.");
9f78d47c
VJ
412 free(pstate->store);
413 pstate->store = NULL;
414 pstate->store_len = 0;
574bcea0 415 SCReturnInt(0);
9f78d47c
VJ
416 }
417
418 /* delimiter field not found, so store the result for the next run */
419 pstate->store = realloc(pstate->store, (input_len + pstate->store_len));
574bcea0 420 if (pstate->store == NULL) {
fc2f7f29 421 SCLogError(SC_ERR_MEM_ALLOC, "Memory reallocation failed!");
574bcea0
VJ
422 SCReturnInt(-1);
423 }
9f78d47c
VJ
424
425 memcpy(pstate->store+pstate->store_len, input, input_len);
426 pstate->store_len += input_len;
427
428 /* if the input len is smaller than the delim len we search the
429 * pstate->store since we may match there. */
430 if (delim_len > input_len && delim_len <= pstate->store_len) {
c1e485cc 431 SCLogDebug("input_len < delim_len, checking pstate->store");
9f78d47c 432
705471e4 433 ptr = SpmSearch(pstate->store, pstate->store_len, (uint8_t*)delim, delim_len);
9f78d47c 434 if (ptr != NULL) {
c1e485cc 435 SCLogDebug("now we found the delim");
9f78d47c 436
fa5939ca 437 uint32_t len = ptr - pstate->store;
574bcea0
VJ
438 int r = AlpStoreField(output, field_idx, pstate->store, len, 1);
439 if (r == -1) {
d0404d84 440 SCLogError(SC_ERR_ALPARSER, "Failed to store field value");
574bcea0
VJ
441 SCReturnInt(-1);
442 }
9f78d47c
VJ
443 pstate->store = NULL;
444 pstate->store_len = 0;
445
446 (*offset) += (input_len);
447
c1e485cc 448 SCLogDebug("ffset %" PRIu32 "", (*offset));
574bcea0 449 SCReturnInt(1);
9f78d47c
VJ
450 }
451 }
452 }
453
454 }
455
574bcea0 456 SCReturnInt(0);
9f78d47c
VJ
457}
458
8e10844f
VJ
459/** \brief Get the Parsers id for storing the parser state.
460 *
461 * \retval Parser subsys id
462 */
c1e485cc
GS
463uint16_t AppLayerParserGetStorageId(void)
464{
8e10844f
VJ
465 return app_layer_sid;
466}
467
c1e485cc
GS
468uint16_t AppLayerGetProtoByName(const char *name)
469{
f1f7df07
VJ
470 uint8_t u = 1;
471 SCLogDebug("looking for name %s", name);
472
473 for ( ; u < ALPROTO_MAX; u++) {
474 if (al_proto_table[u].name == NULL)
475 continue;
476
477 SCLogDebug("name %s proto %"PRIu16"",
478 al_proto_table[u].name, u);
479
480 if (strcasecmp(name,al_proto_table[u].name) == 0) {
481 SCLogDebug("match, returning %"PRIu16"", u);
482 return u;
483 }
484 }
485
486 return ALPROTO_UNKNOWN;
487}
488
8e10844f
VJ
489/** \brief Description: register a parser.
490 *
491 * \param name full parser name, e.g. "http.request_line"
c1e485cc
GS
492 * \todo do we need recursive, so a "http" and a "request_line" where the engine
493 * knows it's actually "http.request_line"... same difference maybe.
8e10844f
VJ
494 * \param AppLayerParser pointer to the parser function
495 * \param max_outputs max number of unique outputs the parser can generate
496 *
497 * \retval 0 on success
498 * \retval -1 on error
499 */
c1e485cc 500int AppLayerRegisterParser(char *name, uint16_t proto, uint16_t parser_id,
fc2f7f29 501 int (*AppLayerParser)(Flow *f, void *protocol_state,
c1e485cc 502 AppLayerParserState *parser_state, uint8_t *input,
18fe3818
VJ
503 uint32_t input_len, AppLayerParserResult *output),
504 char *dependency)
c1e485cc 505{
8e10844f
VJ
506
507 al_max_parsers++;
508
5fc30051
WM
509 if(al_max_parsers >= MAX_PARSERS){
510 SCLogInfo("Failed to register %s al_parser_table array full",name);
511 exit(EXIT_FAILURE);
512 }
513
8e10844f 514 al_parser_table[al_max_parsers].name = name;
5a9a23f9
VJ
515 al_parser_table[al_max_parsers].proto = proto;
516 al_parser_table[al_max_parsers].parser_local_id = parser_id;
8e10844f 517 al_parser_table[al_max_parsers].AppLayerParser = AppLayerParser;
5a9a23f9 518
c1e485cc
GS
519 SCLogDebug("registered %p at proto %" PRIu32 ", al_proto_table idx "
520 "%" PRIu32 ", storage_id %" PRIu32 ", parser_local_id %" PRIu32 "",
521 AppLayerParser, proto, al_max_parsers,
522 al_proto_table[proto].storage_id, parser_id);
8e10844f
VJ
523 return 0;
524}
525
526/** \brief Description: register a protocol parser.
527 *
528 * \param name full parser name, e.g. "http.request_line"
c1e485cc
GS
529 * \todo do we need recursive, so a "http" and a "request_line" where the engine
530 * knows it's actually "http.request_line"... same difference maybe.
8e10844f 531 * \param AppLayerParser pointer to the parser function
8e10844f
VJ
532 *
533 * \retval 0 on success
534 * \retval -1 on error
535 */
c1e485cc 536int AppLayerRegisterProto(char *name, uint8_t proto, uint8_t flags,
fc2f7f29 537 int (*AppLayerParser)(Flow *f, void *protocol_state,
c1e485cc 538 AppLayerParserState *parser_state, uint8_t *input,
18fe3818 539 uint32_t input_len, AppLayerParserResult *output))
c1e485cc 540{
8e10844f
VJ
541
542 al_max_parsers++;
543
5fc30051
WM
544 if(al_max_parsers >= MAX_PARSERS){
545 SCLogInfo("Failed to register %s al_parser_table array full",name);
546 exit(EXIT_FAILURE);
547 }
548
8e10844f
VJ
549 al_parser_table[al_max_parsers].name = name;
550 al_parser_table[al_max_parsers].AppLayerParser = AppLayerParser;
551
f1f7df07
VJ
552 al_proto_table[proto].name = name;
553
8e10844f
VJ
554 /* create proto, direction -- parser mapping */
555 if (flags & STREAM_TOSERVER) {
556 al_proto_table[proto].to_server = al_max_parsers;
557 } else if (flags & STREAM_TOCLIENT) {
558 al_proto_table[proto].to_client = al_max_parsers;
559 }
560
561 if (al_proto_table[proto].storage_id == 0) {
562 al_proto_table[proto].storage_id = StreamL7RegisterModule();
563 }
564
c1e485cc 565 SCLogDebug("registered %p at proto %" PRIu32 " flags %02X, al_proto_table "
48248687 566 "idx %" PRIu32 ", storage_id %" PRIu32 " %s", AppLayerParser, proto,
c1e485cc 567 flags, al_max_parsers, al_proto_table[proto].storage_id, name);
8e10844f
VJ
568 return 0;
569}
570
c1e485cc
GS
571void AppLayerRegisterStateFuncs(uint16_t proto, void *(*StateAlloc)(void),
572 void (*StateFree)(void *))
573{
9f78d47c
VJ
574 al_proto_table[proto].StateAlloc = StateAlloc;
575 al_proto_table[proto].StateFree = StateFree;
576}
577
c1e485cc
GS
578uint16_t AlpGetStateIdx(uint16_t proto)
579{
9f78d47c
VJ
580 return al_proto_table[proto].storage_id;
581}
582
c1e485cc
GS
583AppLayerParserStateStore *AppLayerParserStateStoreAlloc(void)
584{
585 AppLayerParserStateStore *s = (AppLayerParserStateStore *)malloc
586 (sizeof(AppLayerParserStateStore));
8e10844f
VJ
587 if (s == NULL)
588 return NULL;
589
9f78d47c 590 memset(s, 0, sizeof(AppLayerParserStateStore));
8e10844f
VJ
591 return s;
592}
593
b102ea21
VJ
594/** \brief free a AppLayerParserStateStore structure
595 * \param s AppLayerParserStateStore structure to free */
c1e485cc
GS
596void AppLayerParserStateStoreFree(AppLayerParserStateStore *s)
597{
b102ea21
VJ
598 if (s->to_server.store != NULL)
599 free(s->to_server.store);
600 if (s->to_client.store != NULL)
601 free(s->to_client.store);
602
603 free(s);
604}
605
c1e485cc
GS
606static void AppLayerParserResultCleanup(AppLayerParserResult *result)
607{
9f78d47c
VJ
608 AppLayerParserResultElmt *e = result->head;
609 while (e != NULL) {
610 AppLayerParserResultElmt *next_e = e->next;
611
612 result->head = next_e;
613 if (next_e == NULL)
614 result->tail = NULL;
615 result->cnt--;
616
617 AlpReturnResultElmt(e);
618 e = next_e;
619 }
620}
621
fc2f7f29 622static int AppLayerDoParse(Flow *f, void *app_layer_state, AppLayerParserState *parser_state,
c1e485cc 623 uint8_t *input, uint32_t input_len, uint16_t parser_idx,
c352bff6 624 uint16_t proto)
c1e485cc
GS
625{
626 SCEnter();
9f78d47c
VJ
627 int retval = 0;
628 AppLayerParserResult result = { NULL, NULL, 0 };
629
c1e485cc 630 SCLogDebug("parser_idx %" PRIu32 "", parser_idx);
9f78d47c
VJ
631 //PrintRawDataFp(stdout, input,input_len);
632
633 /* invoke the parser */
fc2f7f29 634 int r = al_parser_table[parser_idx].AppLayerParser(f, app_layer_state,
18fe3818 635 parser_state, input, input_len, &result);
c1e485cc
GS
636 if (r < 0) {
637 if (r == -1) {
638 AppLayerParserResultCleanup(&result);
639 SCReturnInt(-1);
640 } else {
641 BUG_ON(r); /* this is not supposed to happen!! */
642 }
643 }
9f78d47c
VJ
644
645 /* process the result elements */
646 AppLayerParserResultElmt *e = result.head;
647 for (; e != NULL; e = e->next) {
c1e485cc
GS
648 SCLogDebug("e %p e->name_idx %" PRIu32 ", e->data_ptr %p, e->data_len "
649 "%" PRIu32 ", map_size %" PRIu32 "", e, e->name_idx,
650 e->data_ptr, e->data_len, al_proto_table[proto].map_size);
9f78d47c
VJ
651
652 /* no parser defined for this field. */
c1e485cc
GS
653 if (e->name_idx >= al_proto_table[proto].map_size ||
654 al_proto_table[proto].map[e->name_idx] == NULL)
655 {
656 SCLogDebug("no parser for proto %" PRIu32 ", parser_local_id "
657 "%" PRIu32 "", proto, e->name_idx);
9f78d47c
VJ
658 continue;
659 }
660
fa5939ca 661 uint16_t idx = al_proto_table[proto].map[e->name_idx]->parser_id;
9f78d47c
VJ
662
663 /* prepare */
fa5939ca 664 uint16_t tmp = parser_state->parse_field;
9f78d47c
VJ
665 parser_state->parse_field = 0;
666 parser_state->flags |= APP_LAYER_PARSER_EOF;
667
fc2f7f29 668 r = AppLayerDoParse(f, app_layer_state, parser_state, e->data_ptr,
c352bff6 669 e->data_len, idx, proto);
9f78d47c
VJ
670
671 /* restore */
672 parser_state->flags &= ~APP_LAYER_PARSER_EOF;
673 parser_state->parse_field = tmp;
674
675 /* bail out on a serious error */
676 if (r < 0) {
c1e485cc
GS
677 if (r == -1) {
678 retval = -1;
679 break;
680 } else {
681 BUG_ON(r);
682 }
9f78d47c
VJ
683 }
684 }
685
686 AppLayerParserResultCleanup(&result);
c1e485cc 687 SCReturnInt(retval);
9f78d47c
VJ
688}
689
8e10844f
VJ
690/**
691 * \brief Layer 7 Parsing main entry point.
692 *
9f78d47c
VJ
693 * \param f Properly initialized and locked flow.
694 * \param proto L7 proto, e.g. ALPROTO_HTTP
695 * \param flags Stream flags
696 * \param input Input L7 data
697 * \param input_len Length of the input data.
698 *
699 * \retval -1 error
700 * \retval 0 ok
8e10844f 701 */
c1e485cc 702int AppLayerParse(Flow *f, uint8_t proto, uint8_t flags, uint8_t *input,
c352bff6 703 uint32_t input_len)
c1e485cc 704{
91bc83e5 705 SCEnter();
8e10844f 706
fa5939ca 707 uint16_t parser_idx = 0;
8e10844f
VJ
708 AppLayerProto *p = &al_proto_table[proto];
709
b102ea21 710 TcpSession *ssn = f->protoctx;
8e10844f 711 if (ssn == NULL) {
c1e485cc 712 SCLogDebug("no TCP session");
91bc83e5 713 goto error;
8e10844f
VJ
714 }
715
716 /* Get the parser state (if any) */
c1e485cc 717 AppLayerParserStateStore *parser_state_store = NULL;
8e10844f 718
c1e485cc
GS
719 if (ssn->aldata != NULL) {
720 parser_state_store = (AppLayerParserStateStore *)
721 ssn->aldata[app_layer_sid];
722 if (parser_state_store == NULL) {
723 parser_state_store = AppLayerParserStateStoreAlloc();
724 if (parser_state_store == NULL)
725 goto error;
726
c1e485cc 727 ssn->aldata[app_layer_sid] = (void *)parser_state_store;
c1e485cc
GS
728 }
729 } else {
730 SCLogDebug("No App Layer Data");
1b39e602
GS
731 /* Nothing is there to clean up, so just return from here after setting
732 * up the no reassembly flags */
733 StreamTcpSetSessionNoReassemblyFlag(ssn, flags & STREAM_TOCLIENT ? 1 : 0);
734 StreamTcpSetSessionNoReassemblyFlag(ssn, flags & STREAM_TOSERVER ? 1 : 0);
735 SCReturnInt(-1);
9f78d47c
VJ
736 }
737
738 AppLayerParserState *parser_state = NULL;
739 if (flags & STREAM_TOSERVER) {
48248687 740 SCLogDebug("to_server msg (flow %p)", f);
ba7e8012 741
9f78d47c
VJ
742 parser_state = &parser_state_store->to_server;
743 if (!(parser_state->flags & APP_LAYER_PARSER_USE)) {
8e10844f 744 parser_idx = p->to_server;
9f78d47c
VJ
745 parser_state->cur_parser = parser_idx;
746 parser_state->flags |= APP_LAYER_PARSER_USE;
747 } else {
c1e485cc
GS
748 SCLogDebug("using parser %" PRIu32 " we stored before (to_server)",
749 parser_state->cur_parser);
9f78d47c 750 parser_idx = parser_state->cur_parser;
8e10844f
VJ
751 }
752 } else {
48248687 753 SCLogDebug("to_client msg (flow %p)", f);
ba7e8012 754
9f78d47c
VJ
755 parser_state = &parser_state_store->to_client;
756 if (!(parser_state->flags & APP_LAYER_PARSER_USE)) {
757 parser_idx = p->to_client;
758 parser_state->cur_parser = parser_idx;
759 parser_state->flags |= APP_LAYER_PARSER_USE;
760 } else {
c1e485cc
GS
761 SCLogDebug("using parser %" PRIu32 " we stored before (to_client)",
762 parser_state->cur_parser);
9f78d47c
VJ
763 parser_idx = parser_state->cur_parser;
764 }
8e10844f
VJ
765 }
766
086ba5f4 767 if (parser_idx == 0 || parser_state->flags & APP_LAYER_PARSER_DONE) {
c1e485cc 768 SCLogDebug("no parser for protocol %" PRIu32 "", proto);
91bc83e5 769 SCReturnInt(0);
8e10844f
VJ
770 }
771
9f78d47c
VJ
772 if (flags & STREAM_EOF)
773 parser_state->flags |= APP_LAYER_PARSER_EOF;
8e10844f 774
9f78d47c 775 /* See if we already have a 'app layer' state */
7715e8f0 776 void *app_layer_state = NULL;
b102ea21 777 app_layer_state = ssn->aldata[p->storage_id];
b3cb29b7 778
9f78d47c 779 if (app_layer_state == NULL) {
48248687
VJ
780 /* lock the allocation of state as we may
781 * alloc more than one otherwise */
9f78d47c 782 app_layer_state = p->StateAlloc();
48248687 783 if (app_layer_state == NULL) {
91bc83e5 784 goto error;
48248687 785 }
9f78d47c 786
b102ea21 787 ssn->aldata[p->storage_id] = app_layer_state;
48248687
VJ
788 SCLogDebug("alloced new app layer state %p (p->storage_id %u, name %s)", app_layer_state, p->storage_id, al_proto_table[ssn->alproto].name);
789 } else {
790 SCLogDebug("using existing app layer state %p (p->storage_id %u, name %s))", app_layer_state, p->storage_id, al_proto_table[ssn->alproto].name);
8e10844f
VJ
791 }
792
9f78d47c 793 /* invoke the recursive parser */
fc2f7f29 794 int r = AppLayerDoParse(f, app_layer_state, parser_state, input, input_len,
c352bff6 795 parser_idx, proto);
8e10844f 796 if (r < 0)
91bc83e5 797 goto error;
8e10844f 798
a16e7b74
GS
799 /* set the packets to no inspection and reassembly for the TLS sessions */
800 if (parser_state->flags & APP_LAYER_PARSER_NO_INSPECTION) {
a16e7b74 801 FlowSetNoPayloadInspectionFlag(f);
a16e7b74
GS
802
803 /* Set the no reassembly flag for both the stream in this TcpSession */
804 if (parser_state->flags & APP_LAYER_PARSER_NO_REASSEMBLY) {
805 StreamTcpSetSessionNoReassemblyFlag(ssn,
806 flags & STREAM_TOCLIENT ? 1 : 0);
807 StreamTcpSetSessionNoReassemblyFlag(ssn,
808 flags & STREAM_TOSERVER ? 1 : 0);
809 }
810 }
811
91bc83e5
VJ
812 SCReturnInt(0);
813error:
c1e485cc 814 if (ssn != NULL) {
c1e485cc
GS
815 /* Clear the app layer protocol state memory and the given function also
816 * cleans the parser state memory */
48248687
VJ
817 if (f->use_cnt == 0)
818 AppLayerParserCleanupState(ssn);
c1e485cc
GS
819
820 /* Set the no reassembly flag for both the stream in this TcpSession */
821 StreamTcpSetSessionNoReassemblyFlag(ssn, flags & STREAM_TOCLIENT ? 1 : 0);
822 StreamTcpSetSessionNoReassemblyFlag(ssn, flags & STREAM_TOSERVER ? 1 : 0);
823
824 if (f->src.family == AF_INET) {
ba7e8012
VJ
825 char src[16];
826 char dst[16];
ad3e4639 827 inet_ntop(AF_INET, (const void*)&f->src.addr_data32[0], src,
c1e485cc 828 sizeof (src));
ad3e4639 829 inet_ntop(AF_INET, (const void*)&f->dst.addr_data32[0], dst,
c1e485cc 830 sizeof (dst));
c1e485cc 831
d0404d84 832 SCLogError(SC_ERR_ALPARSER, "Error occured in parsing \"%s\" app layer "
c1e485cc
GS
833 "protocol, using network protocol %"PRIu8", source IP "
834 "address %s, destination IP address %s, src port %"PRIu16" and "
835 "dst port %"PRIu16"", al_proto_table[ssn->alproto].name,
1b39e602 836 f->proto, src, dst, f->sp, f->dp);
ad3e4639
GS
837
838 } else {
ba7e8012
VJ
839 char dst6[46];
840 char src6[46];
841
ad3e4639
GS
842 inet_ntop(AF_INET6, (const void*)&f->src.addr_data32, src6,
843 sizeof (src6));
844 inet_ntop(AF_INET6, (const void*)&f->dst.addr_data32, dst6,
845 sizeof (dst6));
846
d0404d84 847 SCLogError(SC_ERR_ALPARSER, "Error occured in parsing \"%s\" app layer "
ad3e4639
GS
848 "protocol, using network protocol %"PRIu8", source IPv6 "
849 "address %s, destination IPv6 address %s, src port %"PRIu16" and "
850 "dst port %"PRIu16"", al_proto_table[ssn->alproto].name,
851 f->proto, src6, dst6, f->sp, f->dp);
852 }
c1e485cc
GS
853 }
854
91bc83e5 855 SCReturnInt(-1);
8e10844f
VJ
856}
857
c1e485cc
GS
858void RegisterAppLayerParsers(void)
859{
8e10844f
VJ
860 /** \todo move to general init function */
861 memset(&al_proto_table, 0, sizeof(al_proto_table));
862 memset(&al_parser_table, 0, sizeof(al_parser_table));
863
864 app_layer_sid = StreamL7RegisterModule();
5a9a23f9
VJ
865
866 /** setup result pool
867 * \todo Per thread pool */
66cc3921 868 al_result_pool = PoolInit(1000,250,AlpResultElmtPoolAlloc,NULL,AlpResultElmtPoolFree);
5a9a23f9
VJ
869}
870
c1e485cc
GS
871void AppLayerParserCleanupState(TcpSession *ssn)
872{
b102ea21 873 if (ssn == NULL) {
c1e485cc 874 SCLogDebug("no ssn");
b102ea21
VJ
875 return;
876 }
877
878 AppLayerProto *p = &al_proto_table[ssn->alproto];
879 if (p == NULL) {
c1e485cc 880 SCLogDebug("no parser state for %"PRIu16"", ssn->alproto);
b102ea21
VJ
881 return;
882 }
883
884 /* free the parser protocol state */
c1e485cc 885 if (p->StateFree != NULL && ssn->aldata != NULL) {
b102ea21 886 if (ssn->aldata[p->storage_id] != NULL) {
c1e485cc 887 SCLogDebug("calling StateFree");
b102ea21
VJ
888 p->StateFree(ssn->aldata[p->storage_id]);
889 ssn->aldata[p->storage_id] = NULL;
890 }
891 }
892
893 if (ssn->aldata != NULL) {
894 if (ssn->aldata[app_layer_sid] != NULL) {
c1e485cc 895 SCLogDebug("calling AppLayerParserStateStoreFree");
b102ea21
VJ
896 AppLayerParserStateStoreFree(ssn->aldata[app_layer_sid]);
897 ssn->aldata[app_layer_sid] = NULL;
898 }
899
6a53ab9c 900 StreamTcpDecrMemuse((uint32_t)(StreamL7GetStorageSize() * sizeof(void *)));
b102ea21
VJ
901 free(ssn->aldata);
902 ssn->aldata = NULL;
903 }
904}
905
9f78d47c
VJ
906/** \brief Create a mapping between the individual parsers local field id's
907 * and the global field parser id's.
908 *
909 */
c1e485cc
GS
910void AppLayerParsersInitPostProcess(void)
911{
fa5939ca 912 uint16_t u16 = 0;
5a9a23f9
VJ
913
914 /* build local->global mapping */
915 for (u16 = 1; u16 <= al_max_parsers; u16++) {
916 /* no local parser */
917 if (al_parser_table[u16].parser_local_id == 0)
918 continue;
919
c1e485cc
GS
920 if (al_parser_table[u16].parser_local_id >
921 al_proto_table[al_parser_table[u16].proto].map_size)
922 {
923 al_proto_table[al_parser_table[u16].proto].map_size =
924 al_parser_table[u16].parser_local_id;
925 }
926 SCLogDebug("map_size %" PRIu32 "", al_proto_table
927 [al_parser_table[u16].proto].map_size);
5a9a23f9
VJ
928 }
929
930 /* for each proto, alloc the map array */
931 for (u16 = 0; u16 < ALPROTO_MAX; u16++) {
932 if (al_proto_table[u16].map_size == 0)
933 continue;
934
935 al_proto_table[u16].map_size++;
c1e485cc
GS
936 al_proto_table[u16].map = (AppLayerLocalMap **)malloc
937 (al_proto_table[u16].map_size *
938 sizeof(AppLayerLocalMap *));
5a9a23f9 939 if (al_proto_table[u16].map == NULL) {
c1e485cc 940 SCLogError(SC_ERR_MEM_ALLOC, "memory error");
5a9a23f9
VJ
941 exit(1);
942 }
c1e485cc
GS
943 memset(al_proto_table[u16].map, 0, al_proto_table[u16].map_size *
944 sizeof(AppLayerLocalMap *));
5a9a23f9 945
fa5939ca 946 uint16_t u = 0;
5a9a23f9
VJ
947 for (u = 1; u <= al_max_parsers; u++) {
948 /* no local parser */
949 if (al_parser_table[u].parser_local_id == 0)
950 continue;
951
952 if (al_parser_table[u].proto != u16)
953 continue;
954
fa5939ca 955 uint16_t parser_local_id = al_parser_table[u].parser_local_id;
c1e485cc 956 SCLogDebug("parser_local_id: %" PRIu32 "", parser_local_id);
5a9a23f9
VJ
957
958 if (parser_local_id < al_proto_table[u16].map_size) {
959 al_proto_table[u16].map[parser_local_id] = malloc(sizeof(AppLayerLocalMap));
960 if (al_proto_table[u16].map[parser_local_id] == NULL) {
c1e485cc 961 SCLogError(SC_ERR_MEM_ALLOC, "XXX memory error");
5a9a23f9
VJ
962 exit(1);
963 }
964
965 al_proto_table[u16].map[parser_local_id]->parser_id = u;
966 }
967 }
968 }
969
970 for (u16 = 0; u16 < ALPROTO_MAX; u16++) {
971 if (al_proto_table[u16].map_size == 0)
972 continue;
973
974 if (al_proto_table[u16].map == NULL)
975 continue;
976
fa5939ca 977 uint16_t x = 0;
5a9a23f9
VJ
978 for (x = 0; x < al_proto_table[u16].map_size; x++) {
979 if (al_proto_table[u16].map[x] == NULL)
980 continue;
981
c1e485cc 982 SCLogDebug("al_proto_table[%" PRIu32 "].map[%" PRIu32 "]->parser_id:"
48248687 983 " %" PRIu32 "", u16, x, al_proto_table[u16].map[x]->parser_id);
5a9a23f9
VJ
984 }
985 }
8e10844f
VJ
986}
987
c1e485cc
GS
988/* UNITTESTS*/
989#ifdef UNITTESTS
990
991typedef struct TestState_ {
992 uint8_t test;
993}TestState;
994
995/**
996 * \brief Test parser function to test the memory deallocation of app layer
997 * parser of occurence of an error.
998 */
fc2f7f29 999static int TestProtocolParser(Flow *f, void *test_state, AppLayerParserState *pstate,
c1e485cc 1000 uint8_t *input, uint32_t input_len,
18fe3818 1001 AppLayerParserResult *output)
c1e485cc
GS
1002{
1003 return -1;
1004}
1005
1006/** \brief Function to allocates the Test protocol state memory
1007 */
1008static void *TestProtocolStateAlloc(void)
1009{
1010 void *s = malloc(sizeof(TestState));
1011 if (s == NULL)
1012 return NULL;
1013
1014 memset(s, 0, sizeof(TestState));
1015 return s;
1016}
1017
1018/** \brief Function to free the Test Protocol state memory
1019 */
1020static void TestProtocolStateFree(void *s)
1021{
1022 free(s);
1023}
1024
1025/** \test Test the deallocation of app layer parser memory on occurance of
1026 * error in the parsing process.
1027 */
1028static int AppLayerParserTest01 (void)
1029{
1030 int result = 1;
1031 Flow f;
1032 uint8_t testbuf[] = { 0x11 };
1033 uint32_t testlen = sizeof(testbuf);
1034 TcpSession ssn;
1035 struct in_addr addr;
1036 struct in_addr addr1;
1037 Address src;
1038 Address dst;
1039
1040 memset(&f, 0, sizeof(f));
1041 memset(&ssn, 0, sizeof(ssn));
1042 memset(&src, 0, sizeof(src));
1043 memset(&dst, 0, sizeof(dst));
1044
1045 /* Register the Test protocol state and parser functions */
1046 AppLayerRegisterProto("test", ALPROTO_TEST, STREAM_TOSERVER,
1047 TestProtocolParser);
1048 AppLayerRegisterStateFuncs(ALPROTO_TEST, TestProtocolStateAlloc,
1049 TestProtocolStateFree);
1050
1051 ssn.alproto = ALPROTO_TEST;
c1e485cc
GS
1052 f.protoctx = (void *)&ssn;
1053
1054 inet_pton(AF_INET, "1.2.3.4", &addr.s_addr);
1055 src.family = AF_INET;
1056 src.addr_data32[0] = addr.s_addr;
1057 inet_pton(AF_INET, "4.3.2.1", &addr1.s_addr);
1058 dst.family = AF_INET;
1059 dst.addr_data32[0] = addr1.s_addr;
1060 f.src = src;
1061 f.dst = dst;
1062 f.sp = htons(20);
1063 f.dp = htons(40);
1064 f.proto = IPPROTO_TCP;
1065
6a53ab9c
VJ
1066 StreamTcpInitConfig(TRUE);
1067 StreamL7DataPtrInit(&ssn);
1068
c1e485cc 1069 int r = AppLayerParse(&f, ALPROTO_TEST, STREAM_TOSERVER|STREAM_EOF, testbuf,
c352bff6 1070 testlen);
c1e485cc
GS
1071 if (r != -1) {
1072 printf("returned %" PRId32 ", expected -1: \n", r);
1073 result = 0;
1074 goto end;
1075 }
1076
1077 if (!(ssn.flags & STREAMTCP_FLAG_NOSERVER_REASSEMBLY) ||
1078 !(ssn.flags & STREAMTCP_FLAG_NOCLIENT_REASSEMBLY))
1079 {
1080 printf("flags should be set, but they are not !\n");
1081 result = 0;
1082 goto end;
1083 }
1084
1085 if (ssn.aldata != NULL) {
1086 printf("App Layer state has not been cleared\n");
1087 result = 0;
1088 goto end;
1089 }
1090end:
6a53ab9c
VJ
1091 StreamL7DataPtrFree(&ssn);
1092 StreamTcpFreeConfig(TRUE);
c1e485cc
GS
1093 return result;
1094}
1095
1096#endif /* UNITESTS */
1097
1098void AppLayerParserRegisterTests(void)
1099{
1100#ifdef UNITTESTS
1101 UtRegisterTest("AppLayerParserTest01", AppLayerParserTest01, 1);
1102#endif /* UNITTESTS */
1103}