suricata
detect-engine-state.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2021 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \defgroup sigstate State support
20  *
21  * State is stored in the ::DetectEngineState structure. This is
22  * basically a container for storage item of type ::DeStateStore.
23  * They contains an array of ::DeStateStoreItem which store the
24  * state of match for an individual signature identified by
25  * DeStateStoreItem::sid.
26  *
27  * @{
28  */
29 
30 /**
31  * \file
32  *
33  * \author Victor Julien <victor@inliniac.net>
34  * \author Anoop Saldanha <anoopsaldanha@gmail.com>
35  *
36  * \brief State based signature handling.
37  */
38 
39 #include "suricata-common.h"
40 
41 #include "decode.h"
42 
43 #include "detect.h"
44 #include "detect-engine.h"
45 #include "detect-parse.h"
46 #include "detect-engine-state.h"
48 #include "detect-engine-build.h"
49 
50 #include "detect-flowvar.h"
51 
52 #include "stream-tcp.h"
53 #include "stream-tcp-private.h"
54 #include "stream-tcp-reassemble.h"
55 
56 #include "app-layer.h"
57 #include "app-layer-parser.h"
58 #include "app-layer-protos.h"
59 #include "app-layer-htp.h"
60 
61 #include "util-unittest.h"
62 #include "util-unittest-helper.h"
63 #include "util-profiling.h"
64 
65 #include "flow-util.h"
66 
67 /** convert enum to string */
68 #define CASE_CODE(E) case E: return #E
69 
70 static inline int StateIsValid(uint16_t alproto, void *alstate)
71 {
72  if (alstate != NULL) {
73  if (alproto == ALPROTO_HTTP1) {
74  HtpState *htp_state = (HtpState *)alstate;
75  if (htp_state->conn != NULL) {
76  return 1;
77  }
78  } else {
79  return 1;
80  }
81  }
82  return 0;
83 }
84 
85 static DeStateStore *DeStateStoreAlloc(void)
86 {
87  DeStateStore *d = SCCalloc(1, sizeof(DeStateStore));
88  if (unlikely(d == NULL))
89  return NULL;
90 
91  return d;
92 }
93 
94 #ifdef DEBUG_VALIDATION
95 static int DeStateSearchState(DetectEngineState *state, uint8_t direction, SigIntId num)
96 {
97  DetectEngineStateDirection *dir_state = &state->dir_state[direction & STREAM_TOSERVER ? 0 : 1];
98  DeStateStore *tx_store = dir_state->head;
99  SigIntId store_cnt;
100  SigIntId state_cnt = 0;
101 
102  for (; tx_store != NULL; tx_store = tx_store->next) {
103  SCLogDebug("tx_store %p", tx_store);
104  for (store_cnt = 0;
105  store_cnt < DE_STATE_CHUNK_SIZE && state_cnt < dir_state->cnt;
106  store_cnt++, state_cnt++)
107  {
108  DeStateStoreItem *item = &tx_store->store[store_cnt];
109  if (item->sid == num) {
110  SCLogDebug("sid %u already in state: %p %p %p %u %u, direction %s",
111  num, state, dir_state, tx_store, state_cnt,
112  store_cnt, direction & STREAM_TOSERVER ? "toserver" : "toclient");
113  return 1;
114  }
115  }
116  }
117  return 0;
118 }
119 #endif
120 
121 static void DeStateSignatureAppend(DetectEngineState *state,
122  const Signature *s, uint32_t inspect_flags, uint8_t direction)
123 {
124  SCEnter();
125 
126  DetectEngineStateDirection *dir_state =
127  &state->dir_state[(direction & STREAM_TOSERVER) ? 0 : 1];
128 
129 #ifdef DEBUG_VALIDATION
130  BUG_ON(DeStateSearchState(state, direction, s->num));
131 #endif
132  DeStateStore *store = dir_state->tail;
133  if (store == NULL) {
134  store = DeStateStoreAlloc();
135  dir_state->head = store;
136  dir_state->cur = store;
137  dir_state->tail = store;
138  } else if (dir_state->cur) {
139  store = dir_state->cur;
140  } else {
141  store = DeStateStoreAlloc();
142  if (store != NULL) {
143  dir_state->tail->next = store;
144  dir_state->tail = store;
145  dir_state->cur = store;
146  }
147  }
148  if (store == NULL)
149  SCReturn;
150 
151  SigIntId idx = dir_state->cnt % DE_STATE_CHUNK_SIZE;
152  store->store[idx].sid = s->num;
153  store->store[idx].flags = inspect_flags;
154  dir_state->cnt++;
155  /* if current chunk is full, progress cur */
156  if (dir_state->cnt % DE_STATE_CHUNK_SIZE == 0) {
157  dir_state->cur = dir_state->cur->next;
158  }
159 
160  SCReturn;
161 }
162 
164 {
166  if (unlikely(d == NULL))
167  return NULL;
168 
169  return d;
170 }
171 
173 {
174  DeStateStore *store;
175  DeStateStore *store_next;
176  int i = 0;
177 
178  for (i = 0; i < 2; i++) {
179  store = state->dir_state[i].head;
180  while (store != NULL) {
181  store_next = store->next;
182  SCFree(store);
183  store = store_next;
184  }
185  }
186  SCFree(state);
187 
188  return;
189 }
190 
191 static void StoreFileNoMatchCnt(DetectEngineState *de_state, uint16_t file_no_match, uint8_t direction)
192 {
193  de_state->dir_state[(direction & STREAM_TOSERVER) ? 0 : 1].filestore_cnt += file_no_match;
194 
195  return;
196 }
197 
198 static bool StoreFilestoreSigsCantMatch(const SigGroupHead *sgh, const DetectEngineState *de_state, uint8_t direction)
199 {
200  if (de_state->dir_state[(direction & STREAM_TOSERVER) ? 0 : 1].filestore_cnt ==
201  sgh->filestore_cnt)
202  return true;
203  else
204  return false;
205 }
206 
207 static void StoreStateTxHandleFiles(const SigGroupHead *sgh, Flow *f, DetectEngineState *destate,
208  const uint8_t flow_flags, void *tx, const uint64_t tx_id, const uint16_t file_no_match)
209 {
210  SCLogDebug("tx %"PRIu64", file_no_match %u", tx_id, file_no_match);
211  StoreFileNoMatchCnt(destate, file_no_match, flow_flags);
212  if (StoreFilestoreSigsCantMatch(sgh, destate, flow_flags)) {
213  SCLogDebug("filestore sigs can't match");
215  f, flow_flags & (STREAM_TOCLIENT | STREAM_TOSERVER), tx, tx_id);
216  } else {
217  SCLogDebug("filestore sigs can still match");
218  }
219 }
220 
222  const SigGroupHead *sgh,
223  Flow *f, void *tx, uint64_t tx_id,
224  const Signature *s,
225  uint32_t inspect_flags, uint8_t flow_flags,
226  const uint16_t file_no_match)
227 {
228  AppLayerTxData *tx_data = AppLayerParserGetTxData(f->proto, f->alproto, tx);
229  BUG_ON(tx_data == NULL);
230  if (tx_data == NULL) {
231  SCLogDebug("No TX data for %" PRIu64, tx_id);
232  return;
233  }
234  if (tx_data->de_state == NULL) {
235  tx_data->de_state = DetectEngineStateAlloc();
236  if (tx_data->de_state == NULL)
237  return;
238  SCLogDebug("destate created for %"PRIu64, tx_id);
239  }
240  DeStateSignatureAppend(tx_data->de_state, s, inspect_flags, flow_flags);
241  StoreStateTxHandleFiles(sgh, f, tx_data->de_state, flow_flags, tx, tx_id, file_no_match);
242 
243  SCLogDebug("Stored for TX %"PRIu64, tx_id);
244 }
245 
246 static inline void ResetTxState(DetectEngineState *s)
247 {
248  if (s) {
249  s->dir_state[0].cnt = 0;
250  s->dir_state[0].filestore_cnt = 0;
251  s->dir_state[0].flags = 0;
252  /* reset 'cur' back to the list head */
253  s->dir_state[0].cur = s->dir_state[0].head;
254 
255  s->dir_state[1].cnt = 0;
256  s->dir_state[1].filestore_cnt = 0;
257  s->dir_state[1].flags = 0;
258  /* reset 'cur' back to the list head */
259  s->dir_state[1].cur = s->dir_state[1].head;
260  }
261 }
262 
263 /** \brief Reset de state for active tx'
264  * To be used on detect engine reload.
265  * \param f write LOCKED flow
266  */
268 {
269  void *alstate = FlowGetAppState(f);
270  if (!StateIsValid(f->alproto, alstate)) {
271  return;
272  }
273 
274  uint64_t inspect_ts = AppLayerParserGetTransactionInspectId(f->alparser, STREAM_TOCLIENT);
275  uint64_t inspect_tc = AppLayerParserGetTransactionInspectId(f->alparser, STREAM_TOSERVER);
276 
277  uint64_t inspect_tx_id = MIN(inspect_ts, inspect_tc);
278 
279  uint64_t total_txs = AppLayerParserGetTxCnt(f, alstate);
280 
281  for ( ; inspect_tx_id < total_txs; inspect_tx_id++) {
282  void *inspect_tx = AppLayerParserGetTx(f->proto, f->alproto, alstate, inspect_tx_id);
283  if (inspect_tx != NULL) {
284  AppLayerTxData *txd = AppLayerParserGetTxData(f->proto, f->alproto, inspect_tx);
285  BUG_ON(txd == NULL);
286  if (txd) {
287  ResetTxState(txd->de_state);
288  }
289  }
290  }
291 }
292 
293 /*********Unittests*********/
294 
295 #ifdef UNITTESTS
296 #include "detect-engine-alert.h"
297 
298 static int DeStateTest01(void)
299 {
300  SCLogDebug("sizeof(DetectEngineState)\t\t%"PRIuMAX,
301  (uintmax_t)sizeof(DetectEngineState));
302  SCLogDebug("sizeof(DeStateStore)\t\t\t%"PRIuMAX,
303  (uintmax_t)sizeof(DeStateStore));
304  SCLogDebug("sizeof(DeStateStoreItem)\t\t%"PRIuMAX"",
305  (uintmax_t)sizeof(DeStateStoreItem));
306 
307  return 1;
308 }
309 
310 static int DeStateTest02(void)
311 {
312  uint8_t direction = STREAM_TOSERVER;
314  FAIL_IF_NULL(state);
315  FAIL_IF_NOT_NULL(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head);
316 
317  Signature s;
318  memset(&s, 0x00, sizeof(s));
319 
320  s.num = 0;
321  DeStateSignatureAppend(state, &s, 0, direction);
322  s.num = 11;
323  DeStateSignatureAppend(state, &s, 0, direction);
324  s.num = 22;
325  DeStateSignatureAppend(state, &s, 0, direction);
326  s.num = 33;
327  DeStateSignatureAppend(state, &s, 0, direction);
328  s.num = 44;
329  DeStateSignatureAppend(state, &s, 0, direction);
330  s.num = 55;
331  DeStateSignatureAppend(state, &s, 0, direction);
332  s.num = 66;
333  DeStateSignatureAppend(state, &s, 0, direction);
334  s.num = 77;
335  DeStateSignatureAppend(state, &s, 0, direction);
336  s.num = 88;
337  DeStateSignatureAppend(state, &s, 0, direction);
338  s.num = 99;
339  DeStateSignatureAppend(state, &s, 0, direction);
340  s.num = 100;
341  DeStateSignatureAppend(state, &s, 0, direction);
342  s.num = 111;
343  DeStateSignatureAppend(state, &s, 0, direction);
344  s.num = 122;
345  DeStateSignatureAppend(state, &s, 0, direction);
346  s.num = 133;
347  DeStateSignatureAppend(state, &s, 0, direction);
348  FAIL_IF_NOT(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head ==
349  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
350 
351  s.num = 144;
352  DeStateSignatureAppend(state, &s, 0, direction);
353 
354  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[14].sid != 144);
355  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head ==
356  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
357  FAIL_IF_NOT(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur == NULL);
358 
359  s.num = 155;
360  DeStateSignatureAppend(state, &s, 0, direction);
361 
362  FAIL_IF_NOT(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].tail ==
363  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
364 
365  s.num = 166;
366  DeStateSignatureAppend(state, &s, 0, direction);
367 
368  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head == NULL);
369  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[1].sid != 11);
370  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next == NULL);
371  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[14].sid != 144);
372  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next->store[0].sid != 155);
373  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next->store[1].sid != 166);
374 
375  ResetTxState(state);
376 
377  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head == NULL);
378  FAIL_IF_NOT(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head ==
379  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
380 
381  s.num = 0;
382  DeStateSignatureAppend(state, &s, 0, direction);
383  s.num = 11;
384  DeStateSignatureAppend(state, &s, 0, direction);
385  s.num = 22;
386  DeStateSignatureAppend(state, &s, 0, direction);
387  s.num = 33;
388  DeStateSignatureAppend(state, &s, 0, direction);
389  s.num = 44;
390  DeStateSignatureAppend(state, &s, 0, direction);
391  s.num = 55;
392  DeStateSignatureAppend(state, &s, 0, direction);
393  s.num = 66;
394  DeStateSignatureAppend(state, &s, 0, direction);
395  s.num = 77;
396  DeStateSignatureAppend(state, &s, 0, direction);
397  s.num = 88;
398  DeStateSignatureAppend(state, &s, 0, direction);
399  s.num = 99;
400  DeStateSignatureAppend(state, &s, 0, direction);
401  s.num = 100;
402  DeStateSignatureAppend(state, &s, 0, direction);
403  s.num = 111;
404  DeStateSignatureAppend(state, &s, 0, direction);
405  s.num = 122;
406  DeStateSignatureAppend(state, &s, 0, direction);
407  s.num = 133;
408  DeStateSignatureAppend(state, &s, 0, direction);
409  FAIL_IF_NOT(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head ==
410  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
411  s.num = 144;
412  DeStateSignatureAppend(state, &s, 0, direction);
413  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[14].sid != 144);
414  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head ==
415  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
416  FAIL_IF_NOT(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].tail ==
417  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
418  s.num = 155;
419  DeStateSignatureAppend(state, &s, 0, direction);
420  s.num = 166;
421  DeStateSignatureAppend(state, &s, 0, direction);
422 
423  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head == NULL);
424  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[1].sid != 11);
425  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next == NULL);
426  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[14].sid != 144);
427  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next->store[0].sid != 155);
428  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next->store[1].sid != 166);
429 
430  DetectEngineStateFree(state);
431 
432  PASS;
433 }
434 
435 static int DeStateTest03(void)
436 {
438  FAIL_IF_NULL(state);
439 
440  Signature s;
441  memset(&s, 0x00, sizeof(s));
442 
443  uint8_t direction = STREAM_TOSERVER;
444 
445  s.num = 11;
446  DeStateSignatureAppend(state, &s, 0, direction);
447  s.num = 22;
448  DeStateSignatureAppend(state, &s, BIT_U32(DE_STATE_FLAG_BASE), direction);
449 
450  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head == NULL);
451  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[0].sid != 11);
452  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[0].flags & BIT_U32(DE_STATE_FLAG_BASE));
453  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[1].sid != 22);
454  FAIL_IF(!(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[1].flags & BIT_U32(DE_STATE_FLAG_BASE)));
455 
456  DetectEngineStateFree(state);
457  PASS;
458 }
459 
460 static int DeStateSigTest01(void)
461 {
462  DetectEngineThreadCtx *det_ctx = NULL;
463  ThreadVars th_v;
464  Flow f;
465  TcpSession ssn;
466  Packet *p = NULL;
467  uint8_t httpbuf1[] = "POST / HTTP/1.0\r\n";
468  uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\n";
469  uint8_t httpbuf3[] = "Cookie: dummy\r\nContent-Length: 10\r\n\r\n";
470  uint8_t httpbuf4[] = "Http Body!";
471  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
472  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
473  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
474  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
475 
478 
479  memset(&th_v, 0, sizeof(th_v));
480  memset(&f, 0, sizeof(f));
481  memset(&ssn, 0, sizeof(ssn));
482 
483  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
484  FAIL_IF_NULL(p);
485 
486  FLOW_INITIALIZE(&f);
487  f.protoctx = (void *)&ssn;
488  f.proto = IPPROTO_TCP;
489  f.flags |= FLOW_IPV4;
491 
492  p->flow = &f;
496 
497  StreamTcpInitConfig(true);
498 
501  de_ctx->flags |= DE_QUIET;
502 
503  Signature *s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any (content:\"POST\"; http_method; content:\"dummy\"; http_cookie; sid:1; rev:1;)");
504  FAIL_IF_NULL(s);
505 
507  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
508  FAIL_IF_NULL(det_ctx);
509 
510  int r = AppLayerParserParse(
511  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
512  FAIL_IF_NOT(r == 0);
513  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
514  FAIL_IF(PacketAlertCheck(p, 1));
515 
516  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
517  FAIL_IF_NOT(r == 0);
518  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
519  FAIL_IF(PacketAlertCheck(p, 1));
520 
521  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
522  FAIL_IF_NOT(r == 0);
523  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
525 
526  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf4, httplen4);
527  FAIL_IF_NOT(r == 0);
528  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
529  FAIL_IF(PacketAlertCheck(p, 1));
530 
532  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
534  StreamTcpFreeConfig(true);
535  FLOW_DESTROY(&f);
536  UTHFreePacket(p);
537  PASS;
538 }
539 
540 /** \test multiple pipelined http transactions */
541 static int DeStateSigTest02(void)
542 {
543  DetectEngineThreadCtx *det_ctx = NULL;
544  ThreadVars th_v;
545  Flow f;
546  TcpSession ssn;
547  Packet *p = NULL;
548  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n";
549  uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n";
550  uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n";
551  uint8_t httpbuf4[] = "Http Body!";
552  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
553  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
554  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
555  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
556  uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n";
557  uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n";
558  uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nHttp Body!";
559  uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */
560  uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */
561  uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */
564 
565  memset(&th_v, 0, sizeof(th_v));
566  memset(&f, 0, sizeof(f));
567  memset(&ssn, 0, sizeof(ssn));
568 
569  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
570 
571  FLOW_INITIALIZE(&f);
572  f.protoctx = (void *)&ssn;
573  f.proto = IPPROTO_TCP;
574  f.flags |= FLOW_IPV4;
575 
576  p->flow = &f;
581 
582  StreamTcpInitConfig(true);
583 
586 
587  de_ctx->flags |= DE_QUIET;
588 
589  Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flow:to_server; content:\"POST\"; http_method; content:\"/\"; http_uri; content:\"Mozilla\"; http_header; content:\"dummy\"; http_cookie; content:\"body\"; nocase; http_client_body; sid:1; rev:1;)");
590  FAIL_IF_NULL(s);
591  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any (flow:to_server; content:\"GET\"; http_method; content:\"Firefox\"; http_header; content:\"dummy2\"; http_cookie; sid:2; rev:1;)");
592  FAIL_IF_NULL(s);
593 
595  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
596  FAIL_IF_NULL(det_ctx);
597 
598  int r = AppLayerParserParse(
599  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
600  FAIL_IF(r != 0);
601  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
602  FAIL_IF(PacketAlertCheck(p, 1));
603 
604  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
605  FAIL_IF(r != 0);
606  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
607  FAIL_IF(PacketAlertCheck(p, 1));
608 
609  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
610  FAIL_IF(r != 0);
611  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
612  FAIL_IF(PacketAlertCheck(p, 1));
613 
614  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f.alstate, 0);
615  FAIL_IF_NULL(tx);
616 
617  AppLayerTxData *tx_data = AppLayerParserGetTxData(IPPROTO_TCP, ALPROTO_HTTP1, tx);
618  FAIL_IF_NULL(tx_data);
619  DetectEngineState *tx_de_state = tx_data->de_state;
620  FAIL_IF_NULL(tx_de_state);
621  FAIL_IF(tx_de_state->dir_state[0].cnt != 1);
622  /* http_header(mpm): 5, uri: 3, method: 6, cookie: 7 */
623  uint32_t expected_flags = (BIT_U32(5) | BIT_U32(3) | BIT_U32(6) | BIT_U32(4));
624  FAIL_IF(tx_de_state->dir_state[0].head->store[0].flags != expected_flags);
625 
626  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf4, httplen4);
627  FAIL_IF(r != 0);
628  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
629  FAIL_IF(!(PacketAlertCheck(p, 1)));
630 
631  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf5, httplen5);
632  FAIL_IF(r != 0);
633  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
634  FAIL_IF(PacketAlertCheck(p, 1));
635 
636  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf6, httplen6);
637  FAIL_IF(r != 0);
638  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
639  FAIL_IF((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2)));
640 
641  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf7, httplen7);
642  FAIL_IF(r != 0);
643  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
644  FAIL_IF(!(PacketAlertCheck(p, 2)));
645 
647  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
649  StreamTcpFreeConfig(true);
650  FLOW_DESTROY(&f);
651  UTHFreePacket(p);
652  PASS;
653 }
654 
655 static int DeStateSigTest03(void)
656 {
657  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
658  "Host: www.server.lan\r\n"
659  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
660  "Content-Length: 215\r\n"
661  "\r\n"
662  "-----------------------------277531038314945\r\n"
663  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
664  "Content-Type: image/jpeg\r\n"
665  "\r\n"
666  "filecontent\r\n"
667  "-----------------------------277531038314945--";
668  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
669  ThreadVars th_v;
670  TcpSession ssn;
671  Flow *f = NULL;
672  Packet *p = NULL;
675 
676  memset(&th_v, 0, sizeof(th_v));
677  memset(&ssn, 0, sizeof(ssn));
678 
679  DetectEngineThreadCtx *det_ctx = NULL;
682 
683  de_ctx->flags |= DE_QUIET;
684 
685  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (flow:to_server; content:\"POST\"; http_method; content:\"upload.cgi\"; http_uri; filestore; sid:1; rev:1;)");
686  FAIL_IF_NULL(s);
687 
689  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
690 
691  f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
692  FAIL_IF_NULL(f);
693  f->protoctx = &ssn;
694  f->proto = IPPROTO_TCP;
695  f->alproto = ALPROTO_HTTP1;
696 
697  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
698  FAIL_IF_NULL(p);
699 
700  p->flow = f;
704 
705  StreamTcpInitConfig(true);
706 
707  int r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1,
708  STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
709  FAIL_IF(r != 0);
710 
711  HtpState *http_state = f->alstate;
712  FAIL_IF_NULL(http_state);
713  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
714  FAIL_IF_NULL(tx);
715  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
716  FAIL_IF_NULL(tx_ud);
717 
718  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
719  FAIL_IF(!(PacketAlertCheck(p, 1)));
720 
721  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, http_state, tx, STREAM_TOSERVER);
722  FileContainer *fc = files.fc;
723  FAIL_IF_NULL(fc);
724 
725  File *file = fc->head;
726  FAIL_IF_NULL(file);
727 
728  FAIL_IF(!(file->flags & FILE_STORE));
729 
731  UTHFreeFlow(f);
732 
733  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
735  StreamTcpFreeConfig(true);
736  PASS;
737 }
738 
739 static int DeStateSigTest04(void)
740 {
741  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
742  "Host: www.server.lan\r\n"
743  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
744  "Content-Length: 215\r\n"
745  "\r\n"
746  "-----------------------------277531038314945\r\n"
747  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
748  "Content-Type: image/jpeg\r\n"
749  "\r\n"
750  "filecontent\r\n"
751  "-----------------------------277531038314945--";
752  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
753  ThreadVars th_v;
754  TcpSession ssn;
757 
758  memset(&th_v, 0, sizeof(th_v));
759  memset(&ssn, 0, sizeof(ssn));
760 
761  DetectEngineThreadCtx *det_ctx = NULL;
764  de_ctx->flags |= DE_QUIET;
765 
766  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"GET\"; http_method; content:\"upload.cgi\"; http_uri; filestore; sid:1; rev:1;)");
767  FAIL_IF_NULL(s);
768 
770  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
771  FAIL_IF_NULL(det_ctx);
772 
773  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
774  FAIL_IF_NULL(f);
775  f->protoctx = &ssn;
776  f->proto = IPPROTO_TCP;
777  f->alproto = ALPROTO_HTTP1;
778 
779  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
780  FAIL_IF_NULL(p);
781  p->flow = f;
785 
786  StreamTcpInitConfig(true);
787 
788  int r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1,
789  STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
790  FAIL_IF(r != 0);
791  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
792  FAIL_IF(PacketAlertCheck(p, 1));
793 
794  HtpState *http_state = f->alstate;
795  FAIL_IF_NULL(http_state);
796  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
797  FAIL_IF_NULL(tx);
798  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
799  FAIL_IF_NULL(tx_ud);
800 
801  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, http_state, tx, STREAM_TOSERVER);
802  FileContainer *fc = files.fc;
803  FAIL_IF_NULL(fc);
804  File *file = fc->head;
805  FAIL_IF_NULL(file);
806 
807  FAIL_IF(file->flags & FILE_STORE);
808 
810  UTHFreeFlow(f);
811  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
813  StreamTcpFreeConfig(true);
814  PASS;
815 }
816 
817 static int DeStateSigTest05(void)
818 {
819  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
820  "Host: www.server.lan\r\n"
821  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
822  "Content-Length: 215\r\n"
823  "\r\n"
824  "-----------------------------277531038314945\r\n"
825  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
826  "Content-Type: image/jpeg\r\n"
827  "\r\n"
828  "filecontent\r\n"
829  "-----------------------------277531038314945--";
830  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
831  ThreadVars th_v;
832  TcpSession ssn;
833 
836 
837  memset(&th_v, 0, sizeof(th_v));
838  memset(&ssn, 0, sizeof(ssn));
839 
840  DetectEngineThreadCtx *det_ctx = NULL;
843  de_ctx->flags |= DE_QUIET;
844 
845  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"GET\"; http_method; content:\"upload.cgi\"; http_uri; filename:\"nomatch\"; sid:1; rev:1;)");
846  FAIL_IF_NULL(s);
847 
849  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
850 
851  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
852  FAIL_IF_NULL(f);
853  f->protoctx = &ssn;
854  f->proto = IPPROTO_TCP;
855  f->alproto = ALPROTO_HTTP1;
856 
857  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
858  FAIL_IF_NULL(p);
859  p->flow = f;
863 
864  StreamTcpInitConfig(true);
865 
866  int r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1,
867  STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
868  FAIL_IF_NOT(r == 0);
869  HtpState *http_state = f->alstate;
870  FAIL_IF_NULL(http_state);
871  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
872  FAIL_IF_NULL(tx);
873  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
874  FAIL_IF_NULL(tx_ud);
875 
876  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, http_state, tx, STREAM_TOSERVER);
877  FileContainer *fc = files.fc;
878  FAIL_IF_NULL(fc);
879  File *file = fc->head;
880  FAIL_IF_NULL(file);
881  FAIL_IF(http_state->state_data.file_flags & FLOWFILE_NO_STORE_TS);
882 
883  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
884  FAIL_IF(PacketAlertCheck(p, 1));
885 
886  /* detect will have set FLOWFILE_NO_STORE_TS, but it won't have had
887  * an opportunity to be applied to the file itself yet */
888  FAIL_IF_NOT(http_state->state_data.file_flags & FLOWFILE_NO_STORE_TS);
889  FAIL_IF(file->flags & FILE_NOSTORE);
890 
892  UTHFreeFlow(f);
893  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
895  StreamTcpFreeConfig(true);
896  PASS;
897 }
898 
899 static int DeStateSigTest06(void)
900 {
901  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
902  "Host: www.server.lan\r\n"
903  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
904  "Content-Length: 215\r\n"
905  "\r\n"
906  "-----------------------------277531038314945\r\n"
907  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
908  "Content-Type: image/jpeg\r\n"
909  "\r\n"
910  "filecontent\r\n"
911  "-----------------------------277531038314945--";
912  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
913  ThreadVars th_v;
914  TcpSession ssn;
915 
918 
919  memset(&th_v, 0, sizeof(th_v));
920  memset(&ssn, 0, sizeof(ssn));
921 
922  DetectEngineThreadCtx *det_ctx = NULL;
925  de_ctx->flags |= DE_QUIET;
926 
927  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"POST\"; http_method; content:\"upload.cgi\"; http_uri; filename:\"nomatch\"; filestore; sid:1; rev:1;)");
928  FAIL_IF_NULL(s);
929 
931  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
932  FAIL_IF_NULL(det_ctx);
933 
934  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
935  FAIL_IF_NULL(f);
936  f->protoctx = &ssn;
937  f->proto = IPPROTO_TCP;
938  f->alproto = ALPROTO_HTTP1;
939 
940  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
941  FAIL_IF_NULL(p);
942  p->flow = f;
946 
947  StreamTcpInitConfig(true);
948 
949  int r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1,
950  STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
951  FAIL_IF(r != 0);
952  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
953  FAIL_IF(PacketAlertCheck(p, 1));
954 
955  HtpState *http_state = f->alstate;
956  FAIL_IF_NULL(http_state);
957  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
958  FAIL_IF_NULL(tx);
959  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
960  FAIL_IF_NULL(tx_ud);
961 
962  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, http_state, tx, STREAM_TOSERVER);
963  FileContainer *fc = files.fc;
964  FAIL_IF_NULL(fc);
965  File *file = fc->head;
966  FAIL_IF_NULL(file);
967  /* detect will have set FLOWFILE_NO_STORE_TS, but it won't have had
968  * an opportunity to be applied to the file itself yet */
969  FAIL_IF_NOT(tx_ud->tx_data.file_flags & FLOWFILE_NO_STORE_TS);
970  FAIL_IF(file->flags & FILE_NOSTORE);
971 
973  UTHFreeFlow(f);
974  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
976  StreamTcpFreeConfig(true);
977  PASS;
978 }
979 
980 static int DeStateSigTest07(void)
981 {
982  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
983  "Host: www.server.lan\r\n"
984  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
985  "Content-Length: 215\r\n"
986  "\r\n"
987  "-----------------------------277531038314945\r\n"
988  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
989  "Content-Type: image/jpeg\r\n"
990  "\r\n";
991 
992  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
993  uint8_t httpbuf2[] = "filecontent\r\n"
994  "-----------------------------277531038314945--";
995  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
996  ThreadVars th_v;
997  TcpSession ssn;
998 
1001 
1002  memset(&th_v, 0, sizeof(th_v));
1003  memset(&ssn, 0, sizeof(ssn));
1004 
1005  DetectEngineThreadCtx *det_ctx = NULL;
1008  de_ctx->flags |= DE_QUIET;
1009 
1010  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"GET\"; http_method; content:\"upload.cgi\"; http_uri; filestore; sid:1; rev:1;)");
1011  FAIL_IF_NULL(s);
1012 
1014  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1015 
1016  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
1017  FAIL_IF_NULL(f);
1018  f->protoctx = &ssn;
1019  f->proto = IPPROTO_TCP;
1020  f->alproto = ALPROTO_HTTP1;
1021 
1022  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1023  FAIL_IF_NULL(p);
1024  p->flow = f;
1028 
1029  StreamTcpInitConfig(true);
1030 
1031  int r = AppLayerParserParse(
1032  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_START, httpbuf1, httplen1);
1033  FAIL_IF(r != 0);
1034  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1035  FAIL_IF(PacketAlertCheck(p, 1));
1036 
1037  r = AppLayerParserParse(
1038  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_EOF, httpbuf2, httplen2);
1039  FAIL_IF(r != 0);
1040  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1041  FAIL_IF(PacketAlertCheck(p, 1));
1042 
1043  HtpState *http_state = f->alstate;
1044  FAIL_IF_NULL(http_state);
1045  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1046  FAIL_IF_NULL(tx);
1047  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
1048  FAIL_IF_NULL(tx_ud);
1049 
1050  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, http_state, tx, STREAM_TOSERVER);
1051  FileContainer *fc = files.fc;
1052  FAIL_IF_NULL(fc);
1053  File *file = fc->head;
1054  FAIL_IF_NULL(file);
1055  FAIL_IF(file->flags & FILE_STORE);
1056 
1058  UTHFreeFlow(f);
1059  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1061  StreamTcpFreeConfig(true);
1062  PASS;
1063 }
1064 
1065 /**
1066  * \test multiple files in a tx
1067  */
1068 static int DeStateSigTest08(void)
1069 {
1070  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
1071  "Host: www.server.lan\r\n"
1072  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
1073  "Content-Length: 440\r\n"
1074  "\r\n"
1075  "-----------------------------277531038314945\r\n"
1076  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"AAAApicture1.jpg\"\r\n"
1077  "Content-Type: image/jpeg\r\n"
1078  "\r\n";
1079 
1080  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1081  uint8_t httpbuf2[] = "file";
1082  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1083  uint8_t httpbuf3[] = "content\r\n"
1084  "-----------------------------277531038314945\r\n";
1085  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
1086 
1087  uint8_t httpbuf4[] = "Content-Disposition: form-data; name=\"uploadfile_1\"; filename=\"BBBBpicture2.jpg\"\r\n"
1088  "Content-Type: image/jpeg\r\n"
1089  "\r\n"
1090  "filecontent2\r\n"
1091  "-----------------------------277531038314945--";
1092  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
1093 
1094  ThreadVars th_v;
1095  TcpSession ssn;
1096 
1099 
1100  memset(&th_v, 0, sizeof(th_v));
1101  memset(&ssn, 0, sizeof(ssn));
1102 
1103  DetectEngineThreadCtx *det_ctx = NULL;
1106  de_ctx->flags |= DE_QUIET;
1107 
1108  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"POST\"; http_method; content:\"upload.cgi\"; http_uri; filename:\"BBBBpicture\"; filestore; sid:1; rev:1;)");
1109  FAIL_IF_NULL(s);
1110 
1112  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1113 
1114  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
1115  FAIL_IF_NULL(f);
1116  f->protoctx = &ssn;
1117  f->proto = IPPROTO_TCP;
1118  f->alproto = ALPROTO_HTTP1;
1119 
1120  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1121  FAIL_IF_NULL(p);
1122  p->flow = f;
1126 
1127  StreamTcpInitConfig(true);
1128 
1129  /* HTTP request with 1st part of the multipart body */
1130 
1131  int r = AppLayerParserParse(
1132  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_START, httpbuf1, httplen1);
1133  FAIL_IF(r != 0);
1134  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1135  FAIL_IF(PacketAlertCheck(p, 1));
1136 
1137  r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1138  FAIL_IF(r != 0);
1139  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1140  FAIL_IF(PacketAlertCheck(p, 1));
1141 
1142  HtpState *http_state = f->alstate;
1143  FAIL_IF_NULL(http_state);
1144  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1145  FAIL_IF_NULL(tx);
1146  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
1147  FAIL_IF_NULL(tx_ud);
1148 
1149  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, http_state, tx, STREAM_TOSERVER);
1150  FileContainer *fc = files.fc;
1151  FAIL_IF_NULL(fc);
1152  File *file = fc->head;
1153  FAIL_IF_NULL(file);
1154  FAIL_IF(file->flags & FILE_STORE);
1155 
1156  /* 2nd multipart body file */
1157 
1158  r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
1159  FAIL_IF(r != 0);
1160  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1161  FAIL_IF(PacketAlertCheck(p, 1));
1162 
1163  r = AppLayerParserParse(
1164  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_EOF, httpbuf4, httplen4);
1165  FAIL_IF(r != 0);
1166  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1168 
1169  http_state = f->alstate;
1170  FAIL_IF_NULL(http_state);
1171  tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1172  FAIL_IF_NULL(tx);
1173  tx_ud = htp_tx_get_user_data(tx);
1174  FAIL_IF_NULL(tx_ud);
1175 
1176  files = AppLayerParserGetTxFiles(p->flow, http_state, tx, STREAM_TOSERVER);
1177  fc = files.fc;
1178  FAIL_IF_NULL(fc);
1179  file = fc->head;
1180  FAIL_IF_NULL(file);
1181  file = file->next;
1182  FAIL_IF_NULL(file);
1183  FAIL_IF_NOT(file->flags & FILE_STORE);
1184 
1186  UTHFreeFlow(f);
1187  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1189  StreamTcpFreeConfig(true);
1190  PASS;
1191 }
1192 
1193 /**
1194  * \test multiple files in a tx. Both files should match
1195  */
1196 static int DeStateSigTest09(void)
1197 {
1198  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
1199  "Host: www.server.lan\r\n"
1200  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
1201  "Content-Length: 440\r\n"
1202  "\r\n"
1203  "-----------------------------277531038314945\r\n"
1204  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
1205  "Content-Type: image/jpeg\r\n"
1206  "\r\n";
1207 
1208  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1209  uint8_t httpbuf2[] = "file";
1210  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1211  uint8_t httpbuf3[] = "content\r\n"
1212  "-----------------------------277531038314945\r\n";
1213  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
1214 
1215  uint8_t httpbuf4[] = "Content-Disposition: form-data; name=\"uploadfile_1\"; filename=\"somepicture2.jpg\"\r\n"
1216  "Content-Type: image/jpeg\r\n"
1217  "\r\n"
1218  "filecontent2\r\n"
1219  "-----------------------------277531038314945--";
1220  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
1221 
1222  ThreadVars th_v;
1223  TcpSession ssn;
1224 
1227 
1228  memset(&th_v, 0, sizeof(th_v));
1229  memset(&ssn, 0, sizeof(ssn));
1230 
1231  DetectEngineThreadCtx *det_ctx = NULL;
1234  de_ctx->flags |= DE_QUIET;
1235 
1236  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"POST\"; http_method; content:\"upload.cgi\"; http_uri; filename:\"somepicture\"; filestore; sid:1; rev:1;)");
1237  FAIL_IF_NULL(s);
1238 
1240  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1241 
1242  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
1243  FAIL_IF_NULL(f);
1244  f->protoctx = &ssn;
1245  f->proto = IPPROTO_TCP;
1246  f->alproto = ALPROTO_HTTP1;
1247 
1248  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1249  FAIL_IF_NULL(p);
1250  p->flow = f;
1254 
1255  StreamTcpInitConfig(true);
1256 
1257  /* HTTP request with 1st part of the multipart body */
1258 
1259  int r = AppLayerParserParse(
1260  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_START, httpbuf1, httplen1);
1261  FAIL_IF(r != 0);
1262  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1264 
1265  r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1266  FAIL_IF(r != 0);
1267  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1268  FAIL_IF(PacketAlertCheck(p, 1));
1269 
1270  HtpState *http_state = f->alstate;
1271  FAIL_IF_NULL(http_state);
1272  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1273  FAIL_IF_NULL(tx);
1274  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
1275  FAIL_IF_NULL(tx_ud);
1276 
1277  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, http_state, tx, STREAM_TOSERVER);
1278  FileContainer *fc = files.fc;
1279  FAIL_IF_NULL(fc);
1280  File *file = fc->head;
1281  FAIL_IF_NULL(file);
1282  FAIL_IF_NOT(file->flags & FILE_STORE);
1283 
1284  /* 2nd multipart body file */
1285 
1286  r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
1287  FAIL_IF(r != 0);
1288  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1289  FAIL_IF(PacketAlertCheck(p, 1));
1290 
1291  r = AppLayerParserParse(
1292  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_EOF, httpbuf4, httplen4);
1293  FAIL_IF(r != 0);
1294  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1296 
1297  http_state = f->alstate;
1298  FAIL_IF_NULL(http_state);
1299  tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1300  FAIL_IF_NULL(tx);
1301  tx_ud = htp_tx_get_user_data(tx);
1302  FAIL_IF_NULL(tx_ud);
1303 
1304  files = AppLayerParserGetTxFiles(p->flow, http_state, tx, STREAM_TOSERVER);
1305  fc = files.fc;
1306  FAIL_IF_NULL(fc);
1307  file = fc->head;
1308  FAIL_IF_NULL(file);
1309  FAIL_IF_NOT(file->flags & FILE_STORE);
1310 
1312  UTHFreeFlow(f);
1313  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1315  StreamTcpFreeConfig(true);
1316  PASS;
1317 }
1318 
1319 /**
1320  * \test multiple files in a tx. Both files should match. No other matches.
1321  */
1322 static int DeStateSigTest10(void)
1323 {
1324  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
1325  "Host: www.server.lan\r\n"
1326  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
1327  "Content-Length: 440\r\n"
1328  "\r\n"
1329  "-----------------------------277531038314945\r\n"
1330  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
1331  "Content-Type: image/jpeg\r\n"
1332  "\r\n";
1333 
1334  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1335  uint8_t httpbuf2[] = "file";
1336  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1337  uint8_t httpbuf3[] = "content\r\n"
1338  "-----------------------------277531038314945\r\n";
1339  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
1340 
1341  uint8_t httpbuf4[] = "Content-Disposition: form-data; name=\"uploadfile_1\"; filename=\"somepicture2.jpg\"\r\n"
1342  "Content-Type: image/jpeg\r\n"
1343  "\r\n"
1344  "filecontent2\r\n"
1345  "-----------------------------277531038314945--";
1346  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
1347 
1348  ThreadVars th_v;
1349  TcpSession ssn;
1350 
1353 
1354  memset(&th_v, 0, sizeof(th_v));
1355  memset(&ssn, 0, sizeof(ssn));
1356 
1357  DetectEngineThreadCtx *det_ctx = NULL;
1360  de_ctx->flags |= DE_QUIET;
1361 
1362  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (filename:\"somepicture\"; filestore; sid:1; rev:1;)");
1363  FAIL_IF_NULL(s);
1364 
1366  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1367 
1368  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
1369  FAIL_IF_NULL(f);
1370  f->protoctx = &ssn;
1371  f->proto = IPPROTO_TCP;
1372  f->alproto = ALPROTO_HTTP1;
1373 
1374  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1375  FAIL_IF_NULL(p);
1376  p->flow = f;
1380 
1381  StreamTcpInitConfig(true);
1382 
1383  /* HTTP request with 1st part of the multipart body */
1384 
1385  int r = AppLayerParserParse(
1386  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_START, httpbuf1, httplen1);
1387  FAIL_IF(r != 0);
1388  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1390 
1391  r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1392  FAIL_IF(r != 0);
1393  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1394  FAIL_IF(PacketAlertCheck(p, 1));
1395 
1396  HtpState *http_state = f->alstate;
1397  FAIL_IF_NULL(http_state);
1398  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1399  FAIL_IF_NULL(tx);
1400  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
1401  FAIL_IF_NULL(tx_ud);
1402 
1403  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, http_state, tx, STREAM_TOSERVER);
1404  FileContainer *fc = files.fc;
1405  FAIL_IF_NULL(fc);
1406  File *file = fc->head;
1407  FAIL_IF_NULL(file);
1408  FAIL_IF_NOT(file->flags & FILE_STORE);
1409 
1410  /* 2nd multipart body file */
1411 
1412  r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
1413  FAIL_IF(r != 0);
1414  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1415  FAIL_IF(PacketAlertCheck(p, 1));
1416 
1417  r = AppLayerParserParse(
1418  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_EOF, httpbuf4, httplen4);
1419  FAIL_IF(r != 0);
1420  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1422 
1423  http_state = f->alstate;
1424  FAIL_IF_NULL(http_state);
1425  tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1426  FAIL_IF_NULL(tx);
1427  tx_ud = htp_tx_get_user_data(tx);
1428  FAIL_IF_NULL(tx_ud);
1429 
1430  files = AppLayerParserGetTxFiles(p->flow, http_state, tx, STREAM_TOSERVER);
1431  fc = files.fc;
1432  FAIL_IF_NULL(fc);
1433  file = fc->head;
1434  FAIL_IF_NULL(file);
1435  FAIL_IF_NOT(file->flags & FILE_STORE);
1436 
1438  UTHFreeFlow(f);
1439  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1441  StreamTcpFreeConfig(true);
1442  PASS;
1443 }
1444 
1445 #endif
1446 
1448 {
1449 #ifdef UNITTESTS
1450  UtRegisterTest("DeStateTest01", DeStateTest01);
1451  UtRegisterTest("DeStateTest02", DeStateTest02);
1452  UtRegisterTest("DeStateTest03", DeStateTest03);
1453  UtRegisterTest("DeStateSigTest01", DeStateSigTest01);
1454  UtRegisterTest("DeStateSigTest02", DeStateSigTest02);
1455  UtRegisterTest("DeStateSigTest03", DeStateSigTest03);
1456  UtRegisterTest("DeStateSigTest04", DeStateSigTest04);
1457  UtRegisterTest("DeStateSigTest05", DeStateSigTest05);
1458  UtRegisterTest("DeStateSigTest06", DeStateSigTest06);
1459  UtRegisterTest("DeStateSigTest07", DeStateSigTest07);
1460  UtRegisterTest("DeStateSigTest08", DeStateSigTest08);
1461  UtRegisterTest("DeStateSigTest09", DeStateSigTest09);
1462  UtRegisterTest("DeStateSigTest10", DeStateSigTest10);
1463 #endif
1464 
1465  return;
1466 }
1467 
1468 /**
1469  * @}
1470  */
FileContainer_
Definition: util-file.h:113
DE_STATE_CHUNK_SIZE
#define DE_STATE_CHUNK_SIZE
Definition: detect-engine-state.h:52
detect-engine.h
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
DetectEngineStateDirection_::flags
uint8_t flags
Definition: detect-engine-state.h:88
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1021
flow-util.h
DetectEngineState_
Definition: detect-engine-state.h:92
Signature_::num
SigIntId num
Definition: detect.h:605
stream-tcp.h
SigGroupHead_
Container for matching data for a signature group.
Definition: detect.h:1445
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
DetectEngineStateDirection_::cnt
SigIntId cnt
Definition: detect-engine-state.h:86
Flow_::proto
uint8_t proto
Definition: flow.h:373
PacketAlertCheck
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
Definition: detect-engine-alert.c:141
Packet_::flags
uint32_t flags
Definition: decode.h:474
Flow_
Flow data structure.
Definition: flow.h:351
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:836
FILE_STORE
#define FILE_STORE
Definition: util-file.h:55
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2580
DetectEngineState_::dir_state
DetectEngineStateDirection dir_state[2]
Definition: detect-engine-state.h:93
AppLayerParserThreadCtxFree
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
Definition: app-layer-parser.c:312
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:223
MIN
#define MIN(x, y)
Definition: suricata-common.h:391
DE_QUIET
#define DE_QUIET
Definition: detect.h:321
stream-tcp-reassemble.h
UTHBuildPacket
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
Definition: util-unittest-helper.c:340
SigMatchSignatures
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1884
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:2620
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:468
Flow_::protoctx
void * protoctx
Definition: flow.h:441
DeStateStoreItem_::sid
SigIntId sid
Definition: detect-engine-state.h:74
FLOW_IPV4
#define FLOW_IPV4
Definition: flow.h:97
AppLayerParserGetTransactionInspectId
uint64_t AppLayerParserGetTransactionInspectId(AppLayerParserState *pstate, uint8_t direction)
Definition: app-layer-parser.c:727
util-unittest.h
DetectEngineStateDirection_::cur
DeStateStore * cur
Definition: detect-engine-state.h:84
HtpState_
Definition: app-layer-htp.h:244
util-unittest-helper.h
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:82
detect-flowvar.h
DetectRunStoreStateTx
void DetectRunStoreStateTx(const SigGroupHead *sgh, Flow *f, void *tx, uint64_t tx_id, const Signature *s, uint32_t inspect_flags, uint8_t flow_flags, const uint16_t file_no_match)
Definition: detect-engine-state.c:221
Flow_::alparser
AppLayerParserState * alparser
Definition: flow.h:475
StreamTcpInitConfig
void StreamTcpInitConfig(bool)
To initialize the stream global configuration data.
Definition: stream-tcp.c:463
UTHBuildFlow
Flow * UTHBuildFlow(int family, const char *src, const char *dst, Port sp, Port dp)
Definition: util-unittest-helper.c:503
FLOW_INITIALIZE
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:38
app-layer-htp.h
decode.h
FAIL_IF_NOT_NULL
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
Definition: util-unittest.h:96
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DetectEngineThreadCtx_
Definition: detect.h:1092
DeStateStoreItem_::flags
uint32_t flags
Definition: detect-engine-state.h:73
FLOWFILE_NO_STORE_TS
#define FLOWFILE_NO_STORE_TS
Definition: flow.h:128
BIT_U32
#define BIT_U32(n)
Definition: suricata-common.h:400
alp_tctx
AppLayerParserThreadCtx * alp_tctx
Definition: fuzz_applayerparserparse.c:22
SCEnter
#define SCEnter(...)
Definition: util-debug.h:271
FileContainer_::head
File * head
Definition: util-file.h:114
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
DeStateStore_::next
struct DeStateStore_ * next
Definition: detect-engine-state.h:79
HtpState_::conn
htp_conn_t * conn
Definition: app-layer-htp.h:248
HtpTxUserData_::tx_data
AppLayerTxData tx_data
Definition: app-layer-htp.h:239
HtpState_::state_data
AppLayerStateData state_data
Definition: app-layer-htp.h:268
SigInit
Signature * SigInit(DetectEngineCtx *de_ctx, const char *sigstr)
Parses a signature and adds it to the Detection Engine Context.
Definition: detect-parse.c:2314
app-layer-parser.h
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:300
util-profiling.h
DetectEngineStateAlloc
DetectEngineState * DetectEngineStateAlloc(void)
Alloc a DetectEngineState object.
Definition: detect-engine-state.c:163
SCReturn
#define SCReturn
Definition: util-debug.h:273
Packet_
Definition: decode.h:437
DE_STATE_FLAG_BASE
#define DE_STATE_FLAG_BASE
Definition: detect-engine-state.h:63
detect-engine-build.h
stream-tcp-private.h
detect-engine-alert.h
detect-engine-state.h
Data structures and function prototypes for keeping state for the detection engine.
AppLayerParserGetTx
void * AppLayerParserGetTx(uint8_t ipproto, AppProto alproto, void *alstate, uint64_t tx_id)
Definition: app-layer-parser.c:1125
DetectEngineStateFree
void DetectEngineStateFree(DetectEngineState *state)
Frees a DetectEngineState object.
Definition: detect-engine-state.c:172
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:2149
UTHFreeFlow
void UTHFreeFlow(Flow *flow)
Definition: util-unittest-helper.c:508
AppLayerParserThreadCtxAlloc
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
Definition: app-layer-parser.c:291
FileDisableStoringForTransaction
void FileDisableStoringForTransaction(Flow *f, const uint8_t direction, void *tx, uint64_t tx_id)
disable file storing for files in a transaction
Definition: util-file.c:1154
File_::flags
uint16_t flags
Definition: util-file.h:80
DetectEngineStateDirection_::head
DeStateStore * head
Definition: detect-engine-state.h:83
File_
Definition: util-file.h:79
AppLayerTxData
struct AppLayerTxData AppLayerTxData
Definition: detect.h:1355
Packet_::flow
struct Flow_ * flow
Definition: decode.h:476
DetectEngineStateResetTxs
void DetectEngineStateResetTxs(Flow *f)
Reset de state for active tx' To be used on detect engine reload.
Definition: detect-engine-state.c:267
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Definition: detect-engine.c:3291
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
StreamTcpFreeConfig
void StreamTcpFreeConfig(bool quiet)
Definition: stream-tcp.c:794
AppLayerParserParse
int AppLayerParserParse(ThreadVars *tv, AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alproto, uint8_t flags, const uint8_t *input, uint32_t input_len)
Definition: app-layer-parser.c:1303
suricata-common.h
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
Definition: detect-engine.c:3501
DeStateStore_
Definition: detect-engine-state.h:77
ALPROTO_HTTP1
@ ALPROTO_HTTP1
Definition: app-layer-protos.h:30
File_::next
struct File_ * next
Definition: util-file.h:92
DetectEngineStateDirection_
Definition: detect-engine-state.h:82
AppLayerParserGetTxData
AppLayerTxData * AppLayerParserGetTxData(uint8_t ipproto, AppProto alproto, void *tx)
Definition: app-layer-parser.c:1195
DetectEngineCtx_::sig_list
Signature * sig_list
Definition: detect.h:844
HtpTxUserData_
Definition: app-layer-htp.h:207
DetectEngineStateDirection_::filestore_cnt
uint16_t filestore_cnt
Definition: detect-engine-state.h:87
SCFree
#define SCFree(p)
Definition: util-mem.h:61
UTHFreePacket
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:488
Flow_::alstate
void * alstate
Definition: flow.h:476
DeStateStore_::store
DeStateStoreItem store[DE_STATE_CHUNK_SIZE]
Definition: detect-engine-state.h:78
Flow_::flags
uint32_t flags
Definition: flow.h:421
detect-parse.h
Signature_
Signature container.
Definition: detect.h:593
FLOW_PKT_ESTABLISHED
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:225
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2541
app-layer-protos.h
FILE_NOSTORE
#define FILE_NOSTORE
Definition: util-file.h:54
AppLayerParserGetTxFiles
AppLayerGetFileState AppLayerParserGetTxFiles(const Flow *f, void *state, void *tx, const uint8_t direction)
Definition: app-layer-parser.c:888
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:838
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:65
TcpSession_
Definition: stream-tcp-private.h:283
SigIntId
#define SigIntId
Definition: suricata-common.h:315
DeStateStoreItem_
Definition: detect-engine-state.h:72
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:450
DeStateRegisterTests
void DeStateRegisterTests(void)
Definition: detect-engine-state.c:1447
detect-engine-dcepayload.h
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
SigGroupHead_::filestore_cnt
uint16_t filestore_cnt
Definition: detect.h:1451
AppLayerParserGetTxCnt
uint64_t AppLayerParserGetTxCnt(const Flow *f, void *alstate)
Definition: app-layer-parser.c:1118
DetectEngineStateDirection_::tail
DeStateStore * tail
Definition: detect-engine-state.h:85
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:121
PKT_STREAM_EST
#define PKT_STREAM_EST
Definition: decode.h:1018
app-layer.h