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 = SCMalloc(sizeof(DeStateStore));
88  if (unlikely(d == NULL))
89  return NULL;
90  memset(d, 0, sizeof(DeStateStore));
91 
92  return d;
93 }
94 
95 #ifdef DEBUG_VALIDATION
96 static int DeStateSearchState(DetectEngineState *state, uint8_t direction, SigIntId num)
97 {
98  DetectEngineStateDirection *dir_state = &state->dir_state[direction & STREAM_TOSERVER ? 0 : 1];
99  DeStateStore *tx_store = dir_state->head;
100  SigIntId store_cnt;
101  SigIntId state_cnt = 0;
102 
103  for (; tx_store != NULL; tx_store = tx_store->next) {
104  SCLogDebug("tx_store %p", tx_store);
105  for (store_cnt = 0;
106  store_cnt < DE_STATE_CHUNK_SIZE && state_cnt < dir_state->cnt;
107  store_cnt++, state_cnt++)
108  {
109  DeStateStoreItem *item = &tx_store->store[store_cnt];
110  if (item->sid == num) {
111  SCLogDebug("sid %u already in state: %p %p %p %u %u, direction %s",
112  num, state, dir_state, tx_store, state_cnt,
113  store_cnt, direction & STREAM_TOSERVER ? "toserver" : "toclient");
114  return 1;
115  }
116  }
117  }
118  return 0;
119 }
120 #endif
121 
122 static void DeStateSignatureAppend(DetectEngineState *state,
123  const Signature *s, uint32_t inspect_flags, uint8_t direction)
124 {
125  SCEnter();
126 
127  DetectEngineStateDirection *dir_state =
128  &state->dir_state[(direction & STREAM_TOSERVER) ? 0 : 1];
129 
130 #ifdef DEBUG_VALIDATION
131  BUG_ON(DeStateSearchState(state, direction, s->num));
132 #endif
133  DeStateStore *store = dir_state->tail;
134  if (store == NULL) {
135  store = DeStateStoreAlloc();
136  dir_state->head = store;
137  dir_state->cur = store;
138  dir_state->tail = store;
139  } else if (dir_state->cur) {
140  store = dir_state->cur;
141  } else {
142  store = DeStateStoreAlloc();
143  if (store != NULL) {
144  dir_state->tail->next = store;
145  dir_state->tail = store;
146  dir_state->cur = store;
147  }
148  }
149  if (store == NULL)
150  SCReturn;
151 
152  SigIntId idx = dir_state->cnt % DE_STATE_CHUNK_SIZE;
153  store->store[idx].sid = s->num;
154  store->store[idx].flags = inspect_flags;
155  dir_state->cnt++;
156  /* if current chunk is full, progress cur */
157  if (dir_state->cnt % DE_STATE_CHUNK_SIZE == 0) {
158  dir_state->cur = dir_state->cur->next;
159  }
160 
161  SCReturn;
162 }
163 
165 {
167  if (unlikely(d == NULL))
168  return NULL;
169  memset(d, 0, sizeof(DetectEngineState));
170 
171  return d;
172 }
173 
175 {
176  DeStateStore *store;
177  DeStateStore *store_next;
178  int i = 0;
179 
180  for (i = 0; i < 2; i++) {
181  store = state->dir_state[i].head;
182  while (store != NULL) {
183  store_next = store->next;
184  SCFree(store);
185  store = store_next;
186  }
187  }
188  SCFree(state);
189 
190  return;
191 }
192 
193 static void StoreFileNoMatchCnt(DetectEngineState *de_state, uint16_t file_no_match, uint8_t direction)
194 {
195  de_state->dir_state[(direction & STREAM_TOSERVER) ? 0 : 1].filestore_cnt += file_no_match;
196 
197  return;
198 }
199 
200 static bool StoreFilestoreSigsCantMatch(const SigGroupHead *sgh, const DetectEngineState *de_state, uint8_t direction)
201 {
202  if (de_state->dir_state[(direction & STREAM_TOSERVER) ? 0 : 1].filestore_cnt ==
203  sgh->filestore_cnt)
204  return true;
205  else
206  return false;
207 }
208 
209 static void StoreStateTxHandleFiles(const SigGroupHead *sgh, Flow *f, DetectEngineState *destate,
210  const uint8_t flow_flags, void *tx, const uint64_t tx_id, const uint16_t file_no_match)
211 {
212  SCLogDebug("tx %"PRIu64", file_no_match %u", tx_id, file_no_match);
213  StoreFileNoMatchCnt(destate, file_no_match, flow_flags);
214  if (StoreFilestoreSigsCantMatch(sgh, destate, flow_flags)) {
215  SCLogDebug("filestore sigs can't match");
217  f, flow_flags & (STREAM_TOCLIENT | STREAM_TOSERVER), tx, tx_id);
218  } else {
219  SCLogDebug("filestore sigs can still match");
220  }
221 }
222 
224  const SigGroupHead *sgh,
225  Flow *f, void *tx, uint64_t tx_id,
226  const Signature *s,
227  uint32_t inspect_flags, uint8_t flow_flags,
228  const uint16_t file_no_match)
229 {
230  AppLayerTxData *tx_data = AppLayerParserGetTxData(f->proto, f->alproto, tx);
231  BUG_ON(tx_data == NULL);
232  if (tx_data == NULL) {
233  SCLogDebug("No TX data for %" PRIu64, tx_id);
234  return;
235  }
236  if (tx_data->de_state == NULL) {
237  tx_data->de_state = DetectEngineStateAlloc();
238  if (tx_data->de_state == NULL)
239  return;
240  SCLogDebug("destate created for %"PRIu64, tx_id);
241  }
242  DeStateSignatureAppend(tx_data->de_state, s, inspect_flags, flow_flags);
243  StoreStateTxHandleFiles(sgh, f, tx_data->de_state, flow_flags, tx, tx_id, file_no_match);
244 
245  SCLogDebug("Stored for TX %"PRIu64, tx_id);
246 }
247 
248 static inline void ResetTxState(DetectEngineState *s)
249 {
250  if (s) {
251  s->dir_state[0].cnt = 0;
252  s->dir_state[0].filestore_cnt = 0;
253  s->dir_state[0].flags = 0;
254  /* reset 'cur' back to the list head */
255  s->dir_state[0].cur = s->dir_state[0].head;
256 
257  s->dir_state[1].cnt = 0;
258  s->dir_state[1].filestore_cnt = 0;
259  s->dir_state[1].flags = 0;
260  /* reset 'cur' back to the list head */
261  s->dir_state[1].cur = s->dir_state[1].head;
262  }
263 }
264 
265 /** \brief Reset de state for active tx'
266  * To be used on detect engine reload.
267  * \param f write LOCKED flow
268  */
270 {
271  void *alstate = FlowGetAppState(f);
272  if (!StateIsValid(f->alproto, alstate)) {
273  return;
274  }
275 
276  uint64_t inspect_ts = AppLayerParserGetTransactionInspectId(f->alparser, STREAM_TOCLIENT);
277  uint64_t inspect_tc = AppLayerParserGetTransactionInspectId(f->alparser, STREAM_TOSERVER);
278 
279  uint64_t inspect_tx_id = MIN(inspect_ts, inspect_tc);
280 
281  uint64_t total_txs = AppLayerParserGetTxCnt(f, alstate);
282 
283  for ( ; inspect_tx_id < total_txs; inspect_tx_id++) {
284  void *inspect_tx = AppLayerParserGetTx(f->proto, f->alproto, alstate, inspect_tx_id);
285  if (inspect_tx != NULL) {
286  AppLayerTxData *txd = AppLayerParserGetTxData(f->proto, f->alproto, inspect_tx);
287  BUG_ON(txd == NULL);
288  if (txd) {
289  ResetTxState(txd->de_state);
290  }
291  }
292  }
293 }
294 
295 /*********Unittests*********/
296 
297 #ifdef UNITTESTS
298 #include "detect-engine-alert.h"
299 
300 static int DeStateTest01(void)
301 {
302  SCLogDebug("sizeof(DetectEngineState)\t\t%"PRIuMAX,
303  (uintmax_t)sizeof(DetectEngineState));
304  SCLogDebug("sizeof(DeStateStore)\t\t\t%"PRIuMAX,
305  (uintmax_t)sizeof(DeStateStore));
306  SCLogDebug("sizeof(DeStateStoreItem)\t\t%"PRIuMAX"",
307  (uintmax_t)sizeof(DeStateStoreItem));
308 
309  return 1;
310 }
311 
312 static int DeStateTest02(void)
313 {
314  uint8_t direction = STREAM_TOSERVER;
316  FAIL_IF_NULL(state);
317  FAIL_IF_NOT_NULL(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head);
318 
319  Signature s;
320  memset(&s, 0x00, sizeof(s));
321 
322  s.num = 0;
323  DeStateSignatureAppend(state, &s, 0, direction);
324  s.num = 11;
325  DeStateSignatureAppend(state, &s, 0, direction);
326  s.num = 22;
327  DeStateSignatureAppend(state, &s, 0, direction);
328  s.num = 33;
329  DeStateSignatureAppend(state, &s, 0, direction);
330  s.num = 44;
331  DeStateSignatureAppend(state, &s, 0, direction);
332  s.num = 55;
333  DeStateSignatureAppend(state, &s, 0, direction);
334  s.num = 66;
335  DeStateSignatureAppend(state, &s, 0, direction);
336  s.num = 77;
337  DeStateSignatureAppend(state, &s, 0, direction);
338  s.num = 88;
339  DeStateSignatureAppend(state, &s, 0, direction);
340  s.num = 99;
341  DeStateSignatureAppend(state, &s, 0, direction);
342  s.num = 100;
343  DeStateSignatureAppend(state, &s, 0, direction);
344  s.num = 111;
345  DeStateSignatureAppend(state, &s, 0, direction);
346  s.num = 122;
347  DeStateSignatureAppend(state, &s, 0, direction);
348  s.num = 133;
349  DeStateSignatureAppend(state, &s, 0, direction);
350  FAIL_IF_NOT(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head ==
351  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
352 
353  s.num = 144;
354  DeStateSignatureAppend(state, &s, 0, direction);
355 
356  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[14].sid != 144);
357  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head ==
358  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
359  FAIL_IF_NOT(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur == NULL);
360 
361  s.num = 155;
362  DeStateSignatureAppend(state, &s, 0, direction);
363 
364  FAIL_IF_NOT(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].tail ==
365  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
366 
367  s.num = 166;
368  DeStateSignatureAppend(state, &s, 0, direction);
369 
370  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head == NULL);
371  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[1].sid != 11);
372  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next == NULL);
373  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[14].sid != 144);
374  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next->store[0].sid != 155);
375  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next->store[1].sid != 166);
376 
377  ResetTxState(state);
378 
379  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head == NULL);
380  FAIL_IF_NOT(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head ==
381  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
382 
383  s.num = 0;
384  DeStateSignatureAppend(state, &s, 0, direction);
385  s.num = 11;
386  DeStateSignatureAppend(state, &s, 0, direction);
387  s.num = 22;
388  DeStateSignatureAppend(state, &s, 0, direction);
389  s.num = 33;
390  DeStateSignatureAppend(state, &s, 0, direction);
391  s.num = 44;
392  DeStateSignatureAppend(state, &s, 0, direction);
393  s.num = 55;
394  DeStateSignatureAppend(state, &s, 0, direction);
395  s.num = 66;
396  DeStateSignatureAppend(state, &s, 0, direction);
397  s.num = 77;
398  DeStateSignatureAppend(state, &s, 0, direction);
399  s.num = 88;
400  DeStateSignatureAppend(state, &s, 0, direction);
401  s.num = 99;
402  DeStateSignatureAppend(state, &s, 0, direction);
403  s.num = 100;
404  DeStateSignatureAppend(state, &s, 0, direction);
405  s.num = 111;
406  DeStateSignatureAppend(state, &s, 0, direction);
407  s.num = 122;
408  DeStateSignatureAppend(state, &s, 0, direction);
409  s.num = 133;
410  DeStateSignatureAppend(state, &s, 0, direction);
411  FAIL_IF_NOT(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head ==
412  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
413  s.num = 144;
414  DeStateSignatureAppend(state, &s, 0, direction);
415  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[14].sid != 144);
416  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head ==
417  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
418  FAIL_IF_NOT(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].tail ==
419  state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].cur);
420  s.num = 155;
421  DeStateSignatureAppend(state, &s, 0, direction);
422  s.num = 166;
423  DeStateSignatureAppend(state, &s, 0, direction);
424 
425  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head == NULL);
426  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[1].sid != 11);
427  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next == NULL);
428  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[14].sid != 144);
429  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next->store[0].sid != 155);
430  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->next->store[1].sid != 166);
431 
432  DetectEngineStateFree(state);
433 
434  PASS;
435 }
436 
437 static int DeStateTest03(void)
438 {
440  FAIL_IF_NULL(state);
441 
442  Signature s;
443  memset(&s, 0x00, sizeof(s));
444 
445  uint8_t direction = STREAM_TOSERVER;
446 
447  s.num = 11;
448  DeStateSignatureAppend(state, &s, 0, direction);
449  s.num = 22;
450  DeStateSignatureAppend(state, &s, BIT_U32(DE_STATE_FLAG_BASE), direction);
451 
452  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head == NULL);
453  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[0].sid != 11);
454  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[0].flags & BIT_U32(DE_STATE_FLAG_BASE));
455  FAIL_IF(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[1].sid != 22);
456  FAIL_IF(!(state->dir_state[direction & STREAM_TOSERVER ? 0 : 1].head->store[1].flags & BIT_U32(DE_STATE_FLAG_BASE)));
457 
458  DetectEngineStateFree(state);
459  PASS;
460 }
461 
462 static int DeStateSigTest01(void)
463 {
464  DetectEngineThreadCtx *det_ctx = NULL;
465  ThreadVars th_v;
466  Flow f;
467  TcpSession ssn;
468  Packet *p = NULL;
469  uint8_t httpbuf1[] = "POST / HTTP/1.0\r\n";
470  uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\n";
471  uint8_t httpbuf3[] = "Cookie: dummy\r\nContent-Length: 10\r\n\r\n";
472  uint8_t httpbuf4[] = "Http Body!";
473  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
474  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
475  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
476  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
477 
480 
481  memset(&th_v, 0, sizeof(th_v));
482  memset(&f, 0, sizeof(f));
483  memset(&ssn, 0, sizeof(ssn));
484 
485  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
486  FAIL_IF_NULL(p);
487 
488  FLOW_INITIALIZE(&f);
489  f.protoctx = (void *)&ssn;
490  f.proto = IPPROTO_TCP;
491  f.flags |= FLOW_IPV4;
493 
494  p->flow = &f;
498 
499  StreamTcpInitConfig(true);
500 
503  de_ctx->flags |= DE_QUIET;
504 
505  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;)");
506  FAIL_IF_NULL(s);
507 
509  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
510  FAIL_IF_NULL(det_ctx);
511 
512  int r = AppLayerParserParse(
513  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
514  FAIL_IF_NOT(r == 0);
515  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
516  FAIL_IF(PacketAlertCheck(p, 1));
517 
518  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
519  FAIL_IF_NOT(r == 0);
520  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
521  FAIL_IF(PacketAlertCheck(p, 1));
522 
523  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
524  FAIL_IF_NOT(r == 0);
525  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
527 
528  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf4, httplen4);
529  FAIL_IF_NOT(r == 0);
530  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
531  FAIL_IF(PacketAlertCheck(p, 1));
532 
534  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
536  StreamTcpFreeConfig(true);
537  FLOW_DESTROY(&f);
538  UTHFreePacket(p);
539  PASS;
540 }
541 
542 /** \test multiple pipelined http transactions */
543 static int DeStateSigTest02(void)
544 {
545  DetectEngineThreadCtx *det_ctx = NULL;
546  ThreadVars th_v;
547  Flow f;
548  TcpSession ssn;
549  Packet *p = NULL;
550  uint8_t httpbuf1[] = "POST / HTTP/1.1\r\n";
551  uint8_t httpbuf2[] = "User-Agent: Mozilla/1.0\r\nContent-Length: 10\r\n";
552  uint8_t httpbuf3[] = "Cookie: dummy\r\n\r\n";
553  uint8_t httpbuf4[] = "Http Body!";
554  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
555  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
556  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
557  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
558  uint8_t httpbuf5[] = "GET /?var=val HTTP/1.1\r\n";
559  uint8_t httpbuf6[] = "User-Agent: Firefox/1.0\r\n";
560  uint8_t httpbuf7[] = "Cookie: dummy2\r\nContent-Length: 10\r\n\r\nHttp Body!";
561  uint32_t httplen5 = sizeof(httpbuf5) - 1; /* minus the \0 */
562  uint32_t httplen6 = sizeof(httpbuf6) - 1; /* minus the \0 */
563  uint32_t httplen7 = sizeof(httpbuf7) - 1; /* minus the \0 */
566 
567  memset(&th_v, 0, sizeof(th_v));
568  memset(&f, 0, sizeof(f));
569  memset(&ssn, 0, sizeof(ssn));
570 
571  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
572 
573  FLOW_INITIALIZE(&f);
574  f.protoctx = (void *)&ssn;
575  f.proto = IPPROTO_TCP;
576  f.flags |= FLOW_IPV4;
577 
578  p->flow = &f;
583 
584  StreamTcpInitConfig(true);
585 
588 
589  de_ctx->flags |= DE_QUIET;
590 
591  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;)");
592  FAIL_IF_NULL(s);
593  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;)");
594  FAIL_IF_NULL(s);
595 
597  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
598  FAIL_IF_NULL(det_ctx);
599 
600  int r = AppLayerParserParse(
601  NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf1, httplen1);
602  FAIL_IF(r != 0);
603  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
604  FAIL_IF(PacketAlertCheck(p, 1));
605 
606  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
607  FAIL_IF(r != 0);
608  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
609  FAIL_IF(PacketAlertCheck(p, 1));
610 
611  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
612  FAIL_IF(r != 0);
613  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
614  FAIL_IF(PacketAlertCheck(p, 1));
615 
616  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f.alstate, 0);
617  FAIL_IF_NULL(tx);
618 
619  AppLayerTxData *tx_data = AppLayerParserGetTxData(IPPROTO_TCP, ALPROTO_HTTP1, tx);
620  FAIL_IF_NULL(tx_data);
621  DetectEngineState *tx_de_state = tx_data->de_state;
622  FAIL_IF_NULL(tx_de_state);
623  FAIL_IF(tx_de_state->dir_state[0].cnt != 1);
624  /* http_header(mpm): 5, uri: 3, method: 6, cookie: 7 */
625  uint32_t expected_flags = (BIT_U32(5) | BIT_U32(3) | BIT_U32(6) | BIT_U32(4));
626  FAIL_IF(tx_de_state->dir_state[0].head->store[0].flags != expected_flags);
627 
628  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf4, httplen4);
629  FAIL_IF(r != 0);
630  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
631  FAIL_IF(!(PacketAlertCheck(p, 1)));
632 
633  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf5, httplen5);
634  FAIL_IF(r != 0);
635  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
636  FAIL_IF(PacketAlertCheck(p, 1));
637 
638  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf6, httplen6);
639  FAIL_IF(r != 0);
640  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
641  FAIL_IF((PacketAlertCheck(p, 1)) || (PacketAlertCheck(p, 2)));
642 
643  r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf7, httplen7);
644  FAIL_IF(r != 0);
645  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
646  FAIL_IF(!(PacketAlertCheck(p, 2)));
647 
649  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
651  StreamTcpFreeConfig(true);
652  FLOW_DESTROY(&f);
653  UTHFreePacket(p);
654  PASS;
655 }
656 
657 static int DeStateSigTest03(void)
658 {
659  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
660  "Host: www.server.lan\r\n"
661  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
662  "Content-Length: 215\r\n"
663  "\r\n"
664  "-----------------------------277531038314945\r\n"
665  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
666  "Content-Type: image/jpeg\r\n"
667  "\r\n"
668  "filecontent\r\n"
669  "-----------------------------277531038314945--";
670  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
671  ThreadVars th_v;
672  TcpSession ssn;
673  Flow *f = NULL;
674  Packet *p = NULL;
677 
678  memset(&th_v, 0, sizeof(th_v));
679  memset(&ssn, 0, sizeof(ssn));
680 
681  DetectEngineThreadCtx *det_ctx = NULL;
684 
685  de_ctx->flags |= DE_QUIET;
686 
687  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;)");
688  FAIL_IF_NULL(s);
689 
691  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
692 
693  f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
694  FAIL_IF_NULL(f);
695  f->protoctx = &ssn;
696  f->proto = IPPROTO_TCP;
697  f->alproto = ALPROTO_HTTP1;
698 
699  p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
700  FAIL_IF_NULL(p);
701 
702  p->flow = f;
706 
707  StreamTcpInitConfig(true);
708 
709  int r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1,
710  STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
711  FAIL_IF(r != 0);
712 
713  HtpState *http_state = f->alstate;
714  FAIL_IF_NULL(http_state);
715  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
716  FAIL_IF_NULL(tx);
717  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
718  FAIL_IF_NULL(tx_ud);
719 
720  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
721  FAIL_IF(!(PacketAlertCheck(p, 1)));
722 
723  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, http_state, tx, STREAM_TOSERVER);
724  FileContainer *fc = files.fc;
725  FAIL_IF_NULL(fc);
726 
727  File *file = fc->head;
728  FAIL_IF_NULL(file);
729 
730  FAIL_IF(!(file->flags & FILE_STORE));
731 
733  UTHFreeFlow(f);
734 
735  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
737  StreamTcpFreeConfig(true);
738  PASS;
739 }
740 
741 static int DeStateSigTest04(void)
742 {
743  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
744  "Host: www.server.lan\r\n"
745  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
746  "Content-Length: 215\r\n"
747  "\r\n"
748  "-----------------------------277531038314945\r\n"
749  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
750  "Content-Type: image/jpeg\r\n"
751  "\r\n"
752  "filecontent\r\n"
753  "-----------------------------277531038314945--";
754  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
755  ThreadVars th_v;
756  TcpSession ssn;
759 
760  memset(&th_v, 0, sizeof(th_v));
761  memset(&ssn, 0, sizeof(ssn));
762 
763  DetectEngineThreadCtx *det_ctx = NULL;
766  de_ctx->flags |= DE_QUIET;
767 
768  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;)");
769  FAIL_IF_NULL(s);
770 
772  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
773  FAIL_IF_NULL(det_ctx);
774 
775  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
776  FAIL_IF_NULL(f);
777  f->protoctx = &ssn;
778  f->proto = IPPROTO_TCP;
779  f->alproto = ALPROTO_HTTP1;
780 
781  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
782  FAIL_IF_NULL(p);
783  p->flow = f;
787 
788  StreamTcpInitConfig(true);
789 
790  int r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1,
791  STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
792  FAIL_IF(r != 0);
793  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
794  FAIL_IF(PacketAlertCheck(p, 1));
795 
796  HtpState *http_state = f->alstate;
797  FAIL_IF_NULL(http_state);
798  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
799  FAIL_IF_NULL(tx);
800  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
801  FAIL_IF_NULL(tx_ud);
802 
803  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, http_state, tx, STREAM_TOSERVER);
804  FileContainer *fc = files.fc;
805  FAIL_IF_NULL(fc);
806  File *file = fc->head;
807  FAIL_IF_NULL(file);
808 
809  FAIL_IF(file->flags & FILE_STORE);
810 
812  UTHFreeFlow(f);
813  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
815  StreamTcpFreeConfig(true);
816  PASS;
817 }
818 
819 static int DeStateSigTest05(void)
820 {
821  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
822  "Host: www.server.lan\r\n"
823  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
824  "Content-Length: 215\r\n"
825  "\r\n"
826  "-----------------------------277531038314945\r\n"
827  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
828  "Content-Type: image/jpeg\r\n"
829  "\r\n"
830  "filecontent\r\n"
831  "-----------------------------277531038314945--";
832  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
833  ThreadVars th_v;
834  TcpSession ssn;
835 
838 
839  memset(&th_v, 0, sizeof(th_v));
840  memset(&ssn, 0, sizeof(ssn));
841 
842  DetectEngineThreadCtx *det_ctx = NULL;
845  de_ctx->flags |= DE_QUIET;
846 
847  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;)");
848  FAIL_IF_NULL(s);
849 
851  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
852 
853  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
854  FAIL_IF_NULL(f);
855  f->protoctx = &ssn;
856  f->proto = IPPROTO_TCP;
857  f->alproto = ALPROTO_HTTP1;
858 
859  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
860  FAIL_IF_NULL(p);
861  p->flow = f;
865 
866  StreamTcpInitConfig(true);
867 
868  int r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1,
869  STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
870  FAIL_IF_NOT(r == 0);
871  HtpState *http_state = f->alstate;
872  FAIL_IF_NULL(http_state);
873  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
874  FAIL_IF_NULL(tx);
875  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
876  FAIL_IF_NULL(tx_ud);
877 
878  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, http_state, tx, STREAM_TOSERVER);
879  FileContainer *fc = files.fc;
880  FAIL_IF_NULL(fc);
881  File *file = fc->head;
882  FAIL_IF_NULL(file);
883  FAIL_IF(http_state->state_data.file_flags & FLOWFILE_NO_STORE_TS);
884 
885  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
886  FAIL_IF(PacketAlertCheck(p, 1));
887 
888  /* detect will have set FLOWFILE_NO_STORE_TS, but it won't have had
889  * an opportunity to be applied to the file itself yet */
890  FAIL_IF_NOT(http_state->state_data.file_flags & FLOWFILE_NO_STORE_TS);
891  FAIL_IF(file->flags & FILE_NOSTORE);
892 
894  UTHFreeFlow(f);
895  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
897  StreamTcpFreeConfig(true);
898  PASS;
899 }
900 
901 static int DeStateSigTest06(void)
902 {
903  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
904  "Host: www.server.lan\r\n"
905  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
906  "Content-Length: 215\r\n"
907  "\r\n"
908  "-----------------------------277531038314945\r\n"
909  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
910  "Content-Type: image/jpeg\r\n"
911  "\r\n"
912  "filecontent\r\n"
913  "-----------------------------277531038314945--";
914  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
915  ThreadVars th_v;
916  TcpSession ssn;
917 
920 
921  memset(&th_v, 0, sizeof(th_v));
922  memset(&ssn, 0, sizeof(ssn));
923 
924  DetectEngineThreadCtx *det_ctx = NULL;
927  de_ctx->flags |= DE_QUIET;
928 
929  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;)");
930  FAIL_IF_NULL(s);
931 
933  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
934  FAIL_IF_NULL(det_ctx);
935 
936  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
937  FAIL_IF_NULL(f);
938  f->protoctx = &ssn;
939  f->proto = IPPROTO_TCP;
940  f->alproto = ALPROTO_HTTP1;
941 
942  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
943  FAIL_IF_NULL(p);
944  p->flow = f;
948 
949  StreamTcpInitConfig(true);
950 
951  int r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1,
952  STREAM_TOSERVER | STREAM_START | STREAM_EOF, httpbuf1, httplen1);
953  FAIL_IF(r != 0);
954  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
955  FAIL_IF(PacketAlertCheck(p, 1));
956 
957  HtpState *http_state = f->alstate;
958  FAIL_IF_NULL(http_state);
959  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
960  FAIL_IF_NULL(tx);
961  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
962  FAIL_IF_NULL(tx_ud);
963 
964  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, http_state, tx, STREAM_TOSERVER);
965  FileContainer *fc = files.fc;
966  FAIL_IF_NULL(fc);
967  File *file = fc->head;
968  FAIL_IF_NULL(file);
969  /* detect will have set FLOWFILE_NO_STORE_TS, but it won't have had
970  * an opportunity to be applied to the file itself yet */
971  FAIL_IF_NOT(tx_ud->tx_data.file_flags & FLOWFILE_NO_STORE_TS);
972  FAIL_IF(file->flags & FILE_NOSTORE);
973 
975  UTHFreeFlow(f);
976  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
978  StreamTcpFreeConfig(true);
979  PASS;
980 }
981 
982 static int DeStateSigTest07(void)
983 {
984  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
985  "Host: www.server.lan\r\n"
986  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
987  "Content-Length: 215\r\n"
988  "\r\n"
989  "-----------------------------277531038314945\r\n"
990  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
991  "Content-Type: image/jpeg\r\n"
992  "\r\n";
993 
994  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
995  uint8_t httpbuf2[] = "filecontent\r\n"
996  "-----------------------------277531038314945--";
997  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
998  ThreadVars th_v;
999  TcpSession ssn;
1000 
1003 
1004  memset(&th_v, 0, sizeof(th_v));
1005  memset(&ssn, 0, sizeof(ssn));
1006 
1007  DetectEngineThreadCtx *det_ctx = NULL;
1010  de_ctx->flags |= DE_QUIET;
1011 
1012  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;)");
1013  FAIL_IF_NULL(s);
1014 
1016  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1017 
1018  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
1019  FAIL_IF_NULL(f);
1020  f->protoctx = &ssn;
1021  f->proto = IPPROTO_TCP;
1022  f->alproto = ALPROTO_HTTP1;
1023 
1024  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1025  FAIL_IF_NULL(p);
1026  p->flow = f;
1030 
1031  StreamTcpInitConfig(true);
1032 
1033  int r = AppLayerParserParse(
1034  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_START, httpbuf1, httplen1);
1035  FAIL_IF(r != 0);
1036  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1037  FAIL_IF(PacketAlertCheck(p, 1));
1038 
1039  r = AppLayerParserParse(
1040  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_EOF, httpbuf2, httplen2);
1041  FAIL_IF(r != 0);
1042  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1043  FAIL_IF(PacketAlertCheck(p, 1));
1044 
1045  HtpState *http_state = f->alstate;
1046  FAIL_IF_NULL(http_state);
1047  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1048  FAIL_IF_NULL(tx);
1049  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
1050  FAIL_IF_NULL(tx_ud);
1051 
1052  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, http_state, tx, STREAM_TOSERVER);
1053  FileContainer *fc = files.fc;
1054  FAIL_IF_NULL(fc);
1055  File *file = fc->head;
1056  FAIL_IF_NULL(file);
1057  FAIL_IF(file->flags & FILE_STORE);
1058 
1060  UTHFreeFlow(f);
1061  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1063  StreamTcpFreeConfig(true);
1064  PASS;
1065 }
1066 
1067 /**
1068  * \test multiple files in a tx
1069  */
1070 static int DeStateSigTest08(void)
1071 {
1072  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
1073  "Host: www.server.lan\r\n"
1074  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
1075  "Content-Length: 440\r\n"
1076  "\r\n"
1077  "-----------------------------277531038314945\r\n"
1078  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"AAAApicture1.jpg\"\r\n"
1079  "Content-Type: image/jpeg\r\n"
1080  "\r\n";
1081 
1082  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1083  uint8_t httpbuf2[] = "file";
1084  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1085  uint8_t httpbuf3[] = "content\r\n"
1086  "-----------------------------277531038314945\r\n";
1087  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
1088 
1089  uint8_t httpbuf4[] = "Content-Disposition: form-data; name=\"uploadfile_1\"; filename=\"BBBBpicture2.jpg\"\r\n"
1090  "Content-Type: image/jpeg\r\n"
1091  "\r\n"
1092  "filecontent2\r\n"
1093  "-----------------------------277531038314945--";
1094  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
1095 
1096  ThreadVars th_v;
1097  TcpSession ssn;
1098 
1101 
1102  memset(&th_v, 0, sizeof(th_v));
1103  memset(&ssn, 0, sizeof(ssn));
1104 
1105  DetectEngineThreadCtx *det_ctx = NULL;
1108  de_ctx->flags |= DE_QUIET;
1109 
1110  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;)");
1111  FAIL_IF_NULL(s);
1112 
1114  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1115 
1116  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
1117  FAIL_IF_NULL(f);
1118  f->protoctx = &ssn;
1119  f->proto = IPPROTO_TCP;
1120  f->alproto = ALPROTO_HTTP1;
1121 
1122  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1123  FAIL_IF_NULL(p);
1124  p->flow = f;
1128 
1129  StreamTcpInitConfig(true);
1130 
1131  /* HTTP request with 1st part of the multipart body */
1132 
1133  int r = AppLayerParserParse(
1134  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_START, httpbuf1, httplen1);
1135  FAIL_IF(r != 0);
1136  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1137  FAIL_IF(PacketAlertCheck(p, 1));
1138 
1139  r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1140  FAIL_IF(r != 0);
1141  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1142  FAIL_IF(PacketAlertCheck(p, 1));
1143 
1144  HtpState *http_state = f->alstate;
1145  FAIL_IF_NULL(http_state);
1146  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1147  FAIL_IF_NULL(tx);
1148  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
1149  FAIL_IF_NULL(tx_ud);
1150 
1151  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, http_state, tx, STREAM_TOSERVER);
1152  FileContainer *fc = files.fc;
1153  FAIL_IF_NULL(fc);
1154  File *file = fc->head;
1155  FAIL_IF_NULL(file);
1156  FAIL_IF(file->flags & FILE_STORE);
1157 
1158  /* 2nd multipart body file */
1159 
1160  r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
1161  FAIL_IF(r != 0);
1162  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1163  FAIL_IF(PacketAlertCheck(p, 1));
1164 
1165  r = AppLayerParserParse(
1166  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_EOF, httpbuf4, httplen4);
1167  FAIL_IF(r != 0);
1168  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1170 
1171  http_state = f->alstate;
1172  FAIL_IF_NULL(http_state);
1173  tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1174  FAIL_IF_NULL(tx);
1175  tx_ud = htp_tx_get_user_data(tx);
1176  FAIL_IF_NULL(tx_ud);
1177 
1178  files = AppLayerParserGetTxFiles(p->flow, http_state, tx, STREAM_TOSERVER);
1179  fc = files.fc;
1180  FAIL_IF_NULL(fc);
1181  file = fc->head;
1182  FAIL_IF_NULL(file);
1183  file = file->next;
1184  FAIL_IF_NULL(file);
1185  FAIL_IF_NOT(file->flags & FILE_STORE);
1186 
1188  UTHFreeFlow(f);
1189  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1191  StreamTcpFreeConfig(true);
1192  PASS;
1193 }
1194 
1195 /**
1196  * \test multiple files in a tx. Both files should match
1197  */
1198 static int DeStateSigTest09(void)
1199 {
1200  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
1201  "Host: www.server.lan\r\n"
1202  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
1203  "Content-Length: 440\r\n"
1204  "\r\n"
1205  "-----------------------------277531038314945\r\n"
1206  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
1207  "Content-Type: image/jpeg\r\n"
1208  "\r\n";
1209 
1210  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1211  uint8_t httpbuf2[] = "file";
1212  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1213  uint8_t httpbuf3[] = "content\r\n"
1214  "-----------------------------277531038314945\r\n";
1215  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
1216 
1217  uint8_t httpbuf4[] = "Content-Disposition: form-data; name=\"uploadfile_1\"; filename=\"somepicture2.jpg\"\r\n"
1218  "Content-Type: image/jpeg\r\n"
1219  "\r\n"
1220  "filecontent2\r\n"
1221  "-----------------------------277531038314945--";
1222  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
1223 
1224  ThreadVars th_v;
1225  TcpSession ssn;
1226 
1229 
1230  memset(&th_v, 0, sizeof(th_v));
1231  memset(&ssn, 0, sizeof(ssn));
1232 
1233  DetectEngineThreadCtx *det_ctx = NULL;
1236  de_ctx->flags |= DE_QUIET;
1237 
1238  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;)");
1239  FAIL_IF_NULL(s);
1240 
1242  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1243 
1244  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
1245  FAIL_IF_NULL(f);
1246  f->protoctx = &ssn;
1247  f->proto = IPPROTO_TCP;
1248  f->alproto = ALPROTO_HTTP1;
1249 
1250  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1251  FAIL_IF_NULL(p);
1252  p->flow = f;
1256 
1257  StreamTcpInitConfig(true);
1258 
1259  /* HTTP request with 1st part of the multipart body */
1260 
1261  int r = AppLayerParserParse(
1262  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_START, httpbuf1, httplen1);
1263  FAIL_IF(r != 0);
1264  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1266 
1267  r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1268  FAIL_IF(r != 0);
1269  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1270  FAIL_IF(PacketAlertCheck(p, 1));
1271 
1272  HtpState *http_state = f->alstate;
1273  FAIL_IF_NULL(http_state);
1274  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1275  FAIL_IF_NULL(tx);
1276  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
1277  FAIL_IF_NULL(tx_ud);
1278 
1279  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, http_state, tx, STREAM_TOSERVER);
1280  FileContainer *fc = files.fc;
1281  FAIL_IF_NULL(fc);
1282  File *file = fc->head;
1283  FAIL_IF_NULL(file);
1284  FAIL_IF_NOT(file->flags & FILE_STORE);
1285 
1286  /* 2nd multipart body file */
1287 
1288  r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
1289  FAIL_IF(r != 0);
1290  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1291  FAIL_IF(PacketAlertCheck(p, 1));
1292 
1293  r = AppLayerParserParse(
1294  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_EOF, httpbuf4, httplen4);
1295  FAIL_IF(r != 0);
1296  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1298 
1299  http_state = f->alstate;
1300  FAIL_IF_NULL(http_state);
1301  tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1302  FAIL_IF_NULL(tx);
1303  tx_ud = htp_tx_get_user_data(tx);
1304  FAIL_IF_NULL(tx_ud);
1305 
1306  files = AppLayerParserGetTxFiles(p->flow, http_state, tx, STREAM_TOSERVER);
1307  fc = files.fc;
1308  FAIL_IF_NULL(fc);
1309  file = fc->head;
1310  FAIL_IF_NULL(file);
1311  FAIL_IF_NOT(file->flags & FILE_STORE);
1312 
1314  UTHFreeFlow(f);
1315  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1317  StreamTcpFreeConfig(true);
1318  PASS;
1319 }
1320 
1321 /**
1322  * \test multiple files in a tx. Both files should match. No other matches.
1323  */
1324 static int DeStateSigTest10(void)
1325 {
1326  uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
1327  "Host: www.server.lan\r\n"
1328  "Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
1329  "Content-Length: 440\r\n"
1330  "\r\n"
1331  "-----------------------------277531038314945\r\n"
1332  "Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
1333  "Content-Type: image/jpeg\r\n"
1334  "\r\n";
1335 
1336  uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
1337  uint8_t httpbuf2[] = "file";
1338  uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
1339  uint8_t httpbuf3[] = "content\r\n"
1340  "-----------------------------277531038314945\r\n";
1341  uint32_t httplen3 = sizeof(httpbuf3) - 1; /* minus the \0 */
1342 
1343  uint8_t httpbuf4[] = "Content-Disposition: form-data; name=\"uploadfile_1\"; filename=\"somepicture2.jpg\"\r\n"
1344  "Content-Type: image/jpeg\r\n"
1345  "\r\n"
1346  "filecontent2\r\n"
1347  "-----------------------------277531038314945--";
1348  uint32_t httplen4 = sizeof(httpbuf4) - 1; /* minus the \0 */
1349 
1350  ThreadVars th_v;
1351  TcpSession ssn;
1352 
1355 
1356  memset(&th_v, 0, sizeof(th_v));
1357  memset(&ssn, 0, sizeof(ssn));
1358 
1359  DetectEngineThreadCtx *det_ctx = NULL;
1362  de_ctx->flags |= DE_QUIET;
1363 
1364  Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (filename:\"somepicture\"; filestore; sid:1; rev:1;)");
1365  FAIL_IF_NULL(s);
1366 
1368  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1369 
1370  Flow *f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
1371  FAIL_IF_NULL(f);
1372  f->protoctx = &ssn;
1373  f->proto = IPPROTO_TCP;
1374  f->alproto = ALPROTO_HTTP1;
1375 
1376  Packet *p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1377  FAIL_IF_NULL(p);
1378  p->flow = f;
1382 
1383  StreamTcpInitConfig(true);
1384 
1385  /* HTTP request with 1st part of the multipart body */
1386 
1387  int r = AppLayerParserParse(
1388  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_START, httpbuf1, httplen1);
1389  FAIL_IF(r != 0);
1390  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1392 
1393  r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf2, httplen2);
1394  FAIL_IF(r != 0);
1395  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1396  FAIL_IF(PacketAlertCheck(p, 1));
1397 
1398  HtpState *http_state = f->alstate;
1399  FAIL_IF_NULL(http_state);
1400  void *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1401  FAIL_IF_NULL(tx);
1402  HtpTxUserData *tx_ud = htp_tx_get_user_data(tx);
1403  FAIL_IF_NULL(tx_ud);
1404 
1405  AppLayerGetFileState files = AppLayerParserGetTxFiles(p->flow, http_state, tx, STREAM_TOSERVER);
1406  FileContainer *fc = files.fc;
1407  FAIL_IF_NULL(fc);
1408  File *file = fc->head;
1409  FAIL_IF_NULL(file);
1410  FAIL_IF_NOT(file->flags & FILE_STORE);
1411 
1412  /* 2nd multipart body file */
1413 
1414  r = AppLayerParserParse(NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER, httpbuf3, httplen3);
1415  FAIL_IF(r != 0);
1416  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1417  FAIL_IF(PacketAlertCheck(p, 1));
1418 
1419  r = AppLayerParserParse(
1420  NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER | STREAM_EOF, httpbuf4, httplen4);
1421  FAIL_IF(r != 0);
1422  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1424 
1425  http_state = f->alstate;
1426  FAIL_IF_NULL(http_state);
1427  tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, f->alstate, 0);
1428  FAIL_IF_NULL(tx);
1429  tx_ud = htp_tx_get_user_data(tx);
1430  FAIL_IF_NULL(tx_ud);
1431 
1432  files = AppLayerParserGetTxFiles(p->flow, http_state, tx, STREAM_TOSERVER);
1433  fc = files.fc;
1434  FAIL_IF_NULL(fc);
1435  file = fc->head;
1436  FAIL_IF_NULL(file);
1437  FAIL_IF_NOT(file->flags & FILE_STORE);
1438 
1440  UTHFreeFlow(f);
1441  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1443  StreamTcpFreeConfig(true);
1444  PASS;
1445 }
1446 
1447 #endif
1448 
1450 {
1451 #ifdef UNITTESTS
1452  UtRegisterTest("DeStateTest01", DeStateTest01);
1453  UtRegisterTest("DeStateTest02", DeStateTest02);
1454  UtRegisterTest("DeStateTest03", DeStateTest03);
1455  UtRegisterTest("DeStateSigTest01", DeStateSigTest01);
1456  UtRegisterTest("DeStateSigTest02", DeStateSigTest02);
1457  UtRegisterTest("DeStateSigTest03", DeStateSigTest03);
1458  UtRegisterTest("DeStateSigTest04", DeStateSigTest04);
1459  UtRegisterTest("DeStateSigTest05", DeStateSigTest05);
1460  UtRegisterTest("DeStateSigTest06", DeStateSigTest06);
1461  UtRegisterTest("DeStateSigTest07", DeStateSigTest07);
1462  UtRegisterTest("DeStateSigTest08", DeStateSigTest08);
1463  UtRegisterTest("DeStateSigTest09", DeStateSigTest09);
1464  UtRegisterTest("DeStateSigTest10", DeStateSigTest10);
1465 #endif
1466 
1467  return;
1468 }
1469 
1470 /**
1471  * @}
1472  */
FileContainer_
Definition: util-file.h:113
DE_STATE_CHUNK_SIZE
#define DE_STATE_CHUNK_SIZE
Definition: detect-engine-state.h:53
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:89
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1000
flow-util.h
DetectEngineState_
Definition: detect-engine-state.h:93
Signature_::num
SigIntId num
Definition: detect.h:594
stream-tcp.h
SigGroupHead_
Container for matching data for a signature group.
Definition: detect.h:1439
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:87
Flow_::proto
uint8_t proto
Definition: flow.h:369
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:467
Flow_
Flow data structure.
Definition: flow.h:347
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:827
FILE_STORE
#define FILE_STORE
Definition: util-file.h:55
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2592
DetectEngineState_::dir_state
DetectEngineStateDirection dir_state[2]
Definition: detect-engine-state.h:94
AppLayerParserThreadCtxFree
void AppLayerParserThreadCtxFree(AppLayerParserThreadCtx *tctx)
Destroys the app layer parser thread context obtained using AppLayerParserThreadCtxAlloc().
Definition: app-layer-parser.c:314
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:221
MIN
#define MIN(x, y)
Definition: suricata-common.h:386
DE_QUIET
#define DE_QUIET
Definition: detect.h:315
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:337
SigMatchSignatures
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1824
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:2575
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:461
Flow_::protoctx
void * protoctx
Definition: flow.h:437
DeStateStoreItem_::sid
SigIntId sid
Definition: detect-engine-state.h:75
FLOW_IPV4
#define FLOW_IPV4
Definition: flow.h:96
AppLayerParserGetTransactionInspectId
uint64_t AppLayerParserGetTransactionInspectId(AppLayerParserState *pstate, uint8_t direction)
Definition: app-layer-parser.c:729
util-unittest.h
DetectEngineStateDirection_::cur
DeStateStore * cur
Definition: detect-engine-state.h:85
HtpState_
Definition: app-layer-htp.h:243
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:223
Flow_::alparser
AppLayerParserState * alparser
Definition: flow.h:471
StreamTcpInitConfig
void StreamTcpInitConfig(bool)
To initialize the stream global configuration data.
Definition: stream-tcp.c:359
UTHBuildFlow
Flow * UTHBuildFlow(int family, const char *src, const char *dst, Port sp, Port dp)
Definition: util-unittest-helper.c:521
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:1075
DeStateStoreItem_::flags
uint32_t flags
Definition: detect-engine-state.h:74
FLOWFILE_NO_STORE_TS
#define FLOWFILE_NO_STORE_TS
Definition: flow.h:127
BIT_U32
#define BIT_U32(n)
Definition: suricata-common.h:395
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:80
HtpState_::conn
htp_conn_t * conn
Definition: app-layer-htp.h:247
HtpTxUserData_::tx_data
AppLayerTxData tx_data
Definition: app-layer-htp.h:238
HtpState_::state_data
AppLayerStateData state_data
Definition: app-layer-htp.h:260
SigInit
Signature * SigInit(DetectEngineCtx *de_ctx, const char *sigstr)
Parses a signature and adds it to the Detection Engine Context.
Definition: detect-parse.c:2270
app-layer-parser.h
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:295
util-profiling.h
DetectEngineStateAlloc
DetectEngineState * DetectEngineStateAlloc(void)
Alloc a DetectEngineState object.
Definition: detect-engine-state.c:164
SCReturn
#define SCReturn
Definition: util-debug.h:273
Packet_
Definition: decode.h:430
DE_STATE_FLAG_BASE
#define DE_STATE_FLAG_BASE
Definition: detect-engine-state.h:64
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:1127
DetectEngineStateFree
void DetectEngineStateFree(DetectEngineState *state)
Frees a DetectEngineState object.
Definition: detect-engine-state.c:174
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:1971
UTHFreeFlow
void UTHFreeFlow(Flow *flow)
Definition: util-unittest-helper.c:526
AppLayerParserThreadCtxAlloc
AppLayerParserThreadCtx * AppLayerParserThreadCtxAlloc(void)
Gets a new app layer protocol's parser thread context.
Definition: app-layer-parser.c:293
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:1153
File_::flags
uint16_t flags
Definition: util-file.h:80
DetectEngineStateDirection_::head
DeStateStore * head
Definition: detect-engine-state.h:84
File_
Definition: util-file.h:79
AppLayerTxData
struct AppLayerTxData AppLayerTxData
Definition: detect.h:1347
Packet_::flow
struct Flow_ * flow
Definition: decode.h:469
DetectEngineStateResetTxs
void DetectEngineStateResetTxs(Flow *f)
Reset de state for active tx' To be used on detect engine reload.
Definition: detect-engine-state.c:269
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Definition: detect-engine.c:3308
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:690
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:1307
suricata-common.h
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
Definition: detect-engine.c:3522
DeStateStore_
Definition: detect-engine-state.h:78
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:83
AppLayerParserGetTxData
AppLayerTxData * AppLayerParserGetTxData(uint8_t ipproto, AppProto alproto, void *tx)
Definition: app-layer-parser.c:1199
DetectEngineCtx_::sig_list
Signature * sig_list
Definition: detect.h:835
HtpTxUserData_
Definition: app-layer-htp.h:206
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
DetectEngineStateDirection_::filestore_cnt
uint16_t filestore_cnt
Definition: detect-engine-state.h:88
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:485
Flow_::alstate
void * alstate
Definition: flow.h:472
DeStateStore_::store
DeStateStoreItem store[DE_STATE_CHUNK_SIZE]
Definition: detect-engine-state.h:79
Flow_::flags
uint32_t flags
Definition: flow.h:417
detect-parse.h
Signature_
Signature container.
Definition: detect.h:582
FLOW_PKT_ESTABLISHED
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:223
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2553
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:890
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:829
AppLayerParserThreadCtx_
Definition: app-layer-parser.c:66
TcpSession_
Definition: stream-tcp-private.h:283
SigIntId
#define SigIntId
Definition: suricata-common.h:310
DeStateStoreItem_
Definition: detect-engine-state.h:73
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:446
DeStateRegisterTests
void DeStateRegisterTests(void)
Definition: detect-engine-state.c:1449
detect-engine-dcepayload.h
SigGroupHead_::filestore_cnt
uint16_t filestore_cnt
Definition: detect.h:1452
AppLayerParserGetTxCnt
uint64_t AppLayerParserGetTxCnt(const Flow *f, void *alstate)
Definition: app-layer-parser.c:1120
DetectEngineStateDirection_::tail
DeStateStore * tail
Definition: detect-engine-state.h:86
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:127
PKT_STREAM_EST
#define PKT_STREAM_EST
Definition: decode.h:997
app-layer.h