suricata
flow-bit.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2013 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Victor Julien <victor@inliniac.net>
22  *
23  * Implements per flow bits. Actually, not a bit,
24  * but called that way because of Snort's flowbits.
25  * It's a binary storage.
26  *
27  * \todo move away from a linked list implementation
28  * \todo use different datatypes, such as string, int, etc.
29  * \todo have more than one instance of the same var, and be able to match on a
30  * specific one, or one all at a time. So if a certain capture matches
31  * multiple times, we can operate on all of them.
32  */
33 
34 #include "suricata-common.h"
35 #include "threads.h"
36 #include "flow-bit.h"
37 #include "flow.h"
38 #include "flow-util.h"
39 #include "flow-private.h"
40 #include "detect.h"
41 #include "util-var.h"
42 #include "util-debug.h"
43 
44 /* get the flowbit with idx from the flow */
45 static FlowBit *FlowBitGet(Flow *f, uint32_t idx)
46 {
47  GenericVar *gv = f->flowvar;
48  for ( ; gv != NULL; gv = gv->next) {
49  if (gv->type == DETECT_FLOWBITS && gv->idx == idx) {
50  return (FlowBit *)gv;
51  }
52  }
53 
54  return NULL;
55 }
56 
57 /** \brief add a flowbit to the flow
58  * \retval -1 error
59  * \retval 0 not added, already set before
60  * \retval 1 added */
61 static int FlowBitAdd(Flow *f, uint32_t idx)
62 {
63  FlowBit *fb = FlowBitGet(f, idx);
64  if (fb == NULL) {
65  fb = SCMalloc(sizeof(FlowBit));
66  if (unlikely(fb == NULL))
67  return -1;
68 
69  fb->type = DETECT_FLOWBITS;
70  fb->idx = idx;
71  fb->next = NULL;
73  return 1;
74  } else {
75  return 0;
76  }
77 }
78 
79 static void FlowBitRemove(Flow *f, uint32_t idx)
80 {
81  FlowBit *fb = FlowBitGet(f, idx);
82  if (fb == NULL)
83  return;
84 
86  FlowBitFree(fb);
87 }
88 
89 /** \brief add a flowbit to the flow
90  * \retval -1 error
91  * \retval 0 not added, already set before
92  * \retval 1 added */
93 int FlowBitSet(Flow *f, uint32_t idx)
94 {
95  return FlowBitAdd(f, idx);
96 }
97 
98 void FlowBitUnset(Flow *f, uint32_t idx)
99 {
100  FlowBitRemove(f, idx);
101 }
102 
103 int FlowBitIsset(Flow *f, uint32_t idx)
104 {
105  int r = 0;
106 
107  FlowBit *fb = FlowBitGet(f, idx);
108  if (fb != NULL) {
109  r = 1;
110  }
111 
112  return r;
113 }
114 
115 int FlowBitIsnotset(Flow *f, uint32_t idx)
116 {
117  int r = 0;
118 
119  FlowBit *fb = FlowBitGet(f, idx);
120  if (fb == NULL) {
121  r = 1;
122  }
123 
124  return r;
125 }
126 
128 {
129  if (fb == NULL)
130  return;
131 
132  SCFree(fb);
133 }
134 
135 
136 /* TESTS */
137 #ifdef UNITTESTS
138 static int FlowBitTest01 (void)
139 {
140  Flow f;
141  memset(&f, 0, sizeof(Flow));
142 
143  FlowBitAdd(&f, 0);
144 
145  FlowBit *fb = FlowBitGet(&f, 0);
146  FAIL_IF_NULL(fb);
147 
149  PASS;
150 }
151 
152 static int FlowBitTest02 (void)
153 {
154  Flow f;
155  memset(&f, 0, sizeof(Flow));
156 
157  FlowBit *fb = FlowBitGet(&f, 0);
159 
161  PASS;
162 }
163 
164 static int FlowBitTest03 (void)
165 {
166  Flow f;
167  memset(&f, 0, sizeof(Flow));
168 
169  FlowBitAdd(&f, 0);
170 
171  FlowBit *fb = FlowBitGet(&f,0);
172  FAIL_IF_NULL(fb);
173 
174  FlowBitRemove(&f, 0);
175 
176  fb = FlowBitGet(&f, 0);
178 
180  PASS;
181 }
182 
183 static int FlowBitTest04 (void)
184 {
185  Flow f;
186  memset(&f, 0, sizeof(Flow));
187 
188  FlowBitAdd(&f, 0);
189  FlowBitAdd(&f, 1);
190  FlowBitAdd(&f, 2);
191  FlowBitAdd(&f, 3);
192 
193  FlowBit *fb = FlowBitGet(&f, 0);
194  FAIL_IF_NULL(fb);
195 
197  PASS;
198 }
199 
200 static int FlowBitTest05 (void)
201 {
202  Flow f;
203  memset(&f, 0, sizeof(Flow));
204 
205  FlowBitAdd(&f, 0);
206  FlowBitAdd(&f, 1);
207  FlowBitAdd(&f, 2);
208  FlowBitAdd(&f, 3);
209 
210  FlowBit *fb = FlowBitGet(&f, 1);
211  FAIL_IF_NULL(fb);
212 
214  PASS;
215 }
216 
217 static int FlowBitTest06 (void)
218 {
219  Flow f;
220  memset(&f, 0, sizeof(Flow));
221 
222  FlowBitAdd(&f, 0);
223  FlowBitAdd(&f, 1);
224  FlowBitAdd(&f, 2);
225  FlowBitAdd(&f, 3);
226 
227  FlowBit *fb = FlowBitGet(&f, 2);
228  FAIL_IF_NULL(fb);
229 
231  PASS;
232 }
233 
234 static int FlowBitTest07 (void)
235 {
236  Flow f;
237  memset(&f, 0, sizeof(Flow));
238 
239  FlowBitAdd(&f, 0);
240  FlowBitAdd(&f, 1);
241  FlowBitAdd(&f, 2);
242  FlowBitAdd(&f, 3);
243 
244  FlowBit *fb = FlowBitGet(&f, 3);
245  FAIL_IF_NULL(fb);
246 
248  PASS;
249 }
250 
251 static int FlowBitTest08 (void)
252 {
253  Flow f;
254  memset(&f, 0, sizeof(Flow));
255 
256  FlowBitAdd(&f, 0);
257  FlowBitAdd(&f, 1);
258  FlowBitAdd(&f, 2);
259  FlowBitAdd(&f, 3);
260 
261  FlowBit *fb = FlowBitGet(&f,0);
262  FAIL_IF_NULL(fb);
263 
264  FlowBitRemove(&f,0);
265 
266  fb = FlowBitGet(&f, 0);
268 
270  PASS;
271 }
272 
273 static int FlowBitTest09 (void)
274 {
275  Flow f;
276  memset(&f, 0, sizeof(Flow));
277 
278  FlowBitAdd(&f, 0);
279  FlowBitAdd(&f, 1);
280  FlowBitAdd(&f, 2);
281  FlowBitAdd(&f, 3);
282 
283  FlowBit *fb = FlowBitGet(&f,1);
284  FAIL_IF_NULL(fb);
285 
286  FlowBitRemove(&f,1);
287 
288  fb = FlowBitGet(&f, 1);
290 
292  PASS;
293 }
294 
295 static int FlowBitTest10 (void)
296 {
297  Flow f;
298  memset(&f, 0, sizeof(Flow));
299 
300  FlowBitAdd(&f, 0);
301  FlowBitAdd(&f, 1);
302  FlowBitAdd(&f, 2);
303  FlowBitAdd(&f, 3);
304 
305  FlowBit *fb = FlowBitGet(&f,2);
306  FAIL_IF_NULL(fb);
307 
308  FlowBitRemove(&f,2);
309 
310  fb = FlowBitGet(&f, 2);
312 
314  PASS;
315 }
316 
317 static int FlowBitTest11 (void)
318 {
319  Flow f;
320  memset(&f, 0, sizeof(Flow));
321 
322  FlowBitAdd(&f, 0);
323  FlowBitAdd(&f, 1);
324  FlowBitAdd(&f, 2);
325  FlowBitAdd(&f, 3);
326 
327  FlowBit *fb = FlowBitGet(&f,3);
328  FAIL_IF_NULL(fb);
329 
330  FlowBitRemove(&f,3);
331 
332  fb = FlowBitGet(&f, 3);
334 
336  PASS;
337 }
338 
339 #endif /* UNITTESTS */
340 
342 {
343 #ifdef UNITTESTS
344  UtRegisterTest("FlowBitTest01", FlowBitTest01);
345  UtRegisterTest("FlowBitTest02", FlowBitTest02);
346  UtRegisterTest("FlowBitTest03", FlowBitTest03);
347  UtRegisterTest("FlowBitTest04", FlowBitTest04);
348  UtRegisterTest("FlowBitTest05", FlowBitTest05);
349  UtRegisterTest("FlowBitTest06", FlowBitTest06);
350  UtRegisterTest("FlowBitTest07", FlowBitTest07);
351  UtRegisterTest("FlowBitTest08", FlowBitTest08);
352  UtRegisterTest("FlowBitTest09", FlowBitTest09);
353  UtRegisterTest("FlowBitTest10", FlowBitTest10);
354  UtRegisterTest("FlowBitTest11", FlowBitTest11);
355 #endif /* UNITTESTS */
356 }
357 
GenericVarAppend
void GenericVarAppend(GenericVar **list, GenericVar *gv)
Definition: util-var.c:98
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
flow-util.h
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:101
threads.h
flow-private.h
Flow_
Flow data structure.
Definition: flow.h:359
flow-bit.h
util-var.h
FlowBitSet
int FlowBitSet(Flow *f, uint32_t idx)
add a flowbit to the flow
Definition: flow-bit.c:93
FlowBitRegisterTests
void FlowBitRegisterTests(void)
Definition: flow-bit.c:341
FlowBitUnset
void FlowBitUnset(Flow *f, uint32_t idx)
Definition: flow-bit.c:98
Flow_::fb
struct FlowBucket_ * fb
Definition: flow.h:496
FAIL_IF_NOT_NULL
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
Definition: util-unittest.h:96
util-debug.h
GenericVar_::next
struct GenericVar_ * next
Definition: util-var.h:57
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
detect.h
GenericVar_::idx
uint32_t idx
Definition: util-var.h:56
GenericVarRemove
void GenericVarRemove(GenericVar **list, GenericVar *gv)
Definition: util-var.c:117
Flow_::flowvar
GenericVar * flowvar
Definition: flow.h:494
SCGenericVarFree
void SCGenericVarFree(GenericVar *gv)
Definition: util-var.c:48
suricata-common.h
GenericVar_
Definition: util-var.h:53
DETECT_FLOWBITS
@ DETECT_FLOWBITS
Definition: detect-engine-register.h:68
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
FlowBitIsset
int FlowBitIsset(Flow *f, uint32_t idx)
Definition: flow-bit.c:103
FlowBit_
Definition: flow-bit.h:30
FlowBitFree
void FlowBitFree(FlowBit *fb)
Definition: flow-bit.c:127
SCFree
#define SCFree(p)
Definition: util-mem.h:61
GenericVar_::type
uint16_t type
Definition: util-var.h:54
flow.h
FlowBitIsnotset
int FlowBitIsnotset(Flow *f, uint32_t idx)
Definition: flow-bit.c:115
f
Flow f
Definition: fuzz_dataset.c:32