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#include "util-unittest.h"
44
45/* get the flowbit with idx from the flow */
46static FlowBit *FlowBitGet(Flow *f, uint32_t idx)
47{
48 GenericVar *gv = f->flowvar;
49 for ( ; gv != NULL; gv = gv->next) {
50 if (gv->type == DETECT_FLOWBITS && gv->idx == idx) {
51 return (FlowBit *)gv;
52 }
53 }
54
55 return NULL;
56}
57
58/** \brief add a flowbit to the flow
59 * \retval -1 error
60 * \retval 0 not added, already set before
61 * \retval 1 added */
62static int FlowBitAdd(Flow *f, uint32_t idx)
63{
64 FlowBit *fb = FlowBitGet(f, idx);
65 if (fb == NULL) {
66 fb = SCMalloc(sizeof(FlowBit));
67 if (unlikely(fb == NULL))
68 return -1;
69
71 fb->idx = idx;
72 fb->next = NULL;
74 return 1;
75 } else {
76 return 0;
77 }
78}
79
80static void FlowBitRemove(Flow *f, uint32_t idx)
81{
82 FlowBit *fb = FlowBitGet(f, idx);
83 if (fb == NULL)
84 return;
85
87 FlowBitFree(fb);
88}
89
90/** \brief add a flowbit to the flow
91 * \retval -1 error
92 * \retval 0 not added, already set before
93 * \retval 1 added */
94int FlowBitSet(Flow *f, uint32_t idx)
95{
96 return FlowBitAdd(f, idx);
97}
98
99void FlowBitUnset(Flow *f, uint32_t idx)
100{
101 FlowBitRemove(f, idx);
102}
103
104/**
105 * \retval bool true if bit is set, false is unset
106 */
107bool FlowBitToggle(Flow *f, uint32_t idx)
108{
109 FlowBit *fb = FlowBitGet(f, idx);
110 if (fb != NULL) {
111 FlowBitRemove(f, idx);
112 return false;
113 } else {
114 FlowBitAdd(f, idx);
115 return true;
116 }
117}
118
119int FlowBitIsset(Flow *f, uint32_t idx)
120{
121 int r = 0;
122
123 FlowBit *fb = FlowBitGet(f, idx);
124 if (fb != NULL) {
125 r = 1;
126 }
127
128 return r;
129}
130
131int FlowBitIsnotset(Flow *f, uint32_t idx)
132{
133 int r = 0;
134
135 FlowBit *fb = FlowBitGet(f, idx);
136 if (fb == NULL) {
137 r = 1;
138 }
139
140 return r;
141}
142
144{
145 if (fb == NULL)
146 return;
147
148 SCFree(fb);
149}
150
151
152/* TESTS */
153#ifdef UNITTESTS
154static int FlowBitTest01 (void)
155{
156 Flow f;
157 memset(&f, 0, sizeof(Flow));
158
159 FlowBitAdd(&f, 0);
160
161 FlowBit *fb = FlowBitGet(&f, 0);
162 FAIL_IF_NULL(fb);
163
165 PASS;
166}
167
168static int FlowBitTest02 (void)
169{
170 Flow f;
171 memset(&f, 0, sizeof(Flow));
172
173 FlowBit *fb = FlowBitGet(&f, 0);
175
177 PASS;
178}
179
180static int FlowBitTest03 (void)
181{
182 Flow f;
183 memset(&f, 0, sizeof(Flow));
184
185 FlowBitAdd(&f, 0);
186
187 FlowBit *fb = FlowBitGet(&f,0);
188 FAIL_IF_NULL(fb);
189
190 FlowBitRemove(&f, 0);
191
192 fb = FlowBitGet(&f, 0);
194
196 PASS;
197}
198
199static int FlowBitTest04 (void)
200{
201 Flow f;
202 memset(&f, 0, sizeof(Flow));
203
204 FlowBitAdd(&f, 0);
205 FlowBitAdd(&f, 1);
206 FlowBitAdd(&f, 2);
207 FlowBitAdd(&f, 3);
208
209 FlowBit *fb = FlowBitGet(&f, 0);
210 FAIL_IF_NULL(fb);
211
213 PASS;
214}
215
216static int FlowBitTest05 (void)
217{
218 Flow f;
219 memset(&f, 0, sizeof(Flow));
220
221 FlowBitAdd(&f, 0);
222 FlowBitAdd(&f, 1);
223 FlowBitAdd(&f, 2);
224 FlowBitAdd(&f, 3);
225
226 FlowBit *fb = FlowBitGet(&f, 1);
227 FAIL_IF_NULL(fb);
228
230 PASS;
231}
232
233static int FlowBitTest06 (void)
234{
235 Flow f;
236 memset(&f, 0, sizeof(Flow));
237
238 FlowBitAdd(&f, 0);
239 FlowBitAdd(&f, 1);
240 FlowBitAdd(&f, 2);
241 FlowBitAdd(&f, 3);
242
243 FlowBit *fb = FlowBitGet(&f, 2);
244 FAIL_IF_NULL(fb);
245
247 PASS;
248}
249
250static int FlowBitTest07 (void)
251{
252 Flow f;
253 memset(&f, 0, sizeof(Flow));
254
255 FlowBitAdd(&f, 0);
256 FlowBitAdd(&f, 1);
257 FlowBitAdd(&f, 2);
258 FlowBitAdd(&f, 3);
259
260 FlowBit *fb = FlowBitGet(&f, 3);
261 FAIL_IF_NULL(fb);
262
264 PASS;
265}
266
267static int FlowBitTest08 (void)
268{
269 Flow f;
270 memset(&f, 0, sizeof(Flow));
271
272 FlowBitAdd(&f, 0);
273 FlowBitAdd(&f, 1);
274 FlowBitAdd(&f, 2);
275 FlowBitAdd(&f, 3);
276
277 FlowBit *fb = FlowBitGet(&f,0);
278 FAIL_IF_NULL(fb);
279
280 FlowBitRemove(&f,0);
281
282 fb = FlowBitGet(&f, 0);
284
286 PASS;
287}
288
289static int FlowBitTest09 (void)
290{
291 Flow f;
292 memset(&f, 0, sizeof(Flow));
293
294 FlowBitAdd(&f, 0);
295 FlowBitAdd(&f, 1);
296 FlowBitAdd(&f, 2);
297 FlowBitAdd(&f, 3);
298
299 FlowBit *fb = FlowBitGet(&f,1);
300 FAIL_IF_NULL(fb);
301
302 FlowBitRemove(&f,1);
303
304 fb = FlowBitGet(&f, 1);
306
308 PASS;
309}
310
311static int FlowBitTest10 (void)
312{
313 Flow f;
314 memset(&f, 0, sizeof(Flow));
315
316 FlowBitAdd(&f, 0);
317 FlowBitAdd(&f, 1);
318 FlowBitAdd(&f, 2);
319 FlowBitAdd(&f, 3);
320
321 FlowBit *fb = FlowBitGet(&f,2);
322 FAIL_IF_NULL(fb);
323
324 FlowBitRemove(&f,2);
325
326 fb = FlowBitGet(&f, 2);
328
330 PASS;
331}
332
333static int FlowBitTest11 (void)
334{
335 Flow f;
336 memset(&f, 0, sizeof(Flow));
337
338 FlowBitAdd(&f, 0);
339 FlowBitAdd(&f, 1);
340 FlowBitAdd(&f, 2);
341 FlowBitAdd(&f, 3);
342
343 FlowBit *fb = FlowBitGet(&f,3);
344 FAIL_IF_NULL(fb);
345
346 FlowBitRemove(&f,3);
347
348 fb = FlowBitGet(&f, 3);
350
352 PASS;
353}
354
355#endif /* UNITTESTS */
356
358{
359#ifdef UNITTESTS
360 UtRegisterTest("FlowBitTest01", FlowBitTest01);
361 UtRegisterTest("FlowBitTest02", FlowBitTest02);
362 UtRegisterTest("FlowBitTest03", FlowBitTest03);
363 UtRegisterTest("FlowBitTest04", FlowBitTest04);
364 UtRegisterTest("FlowBitTest05", FlowBitTest05);
365 UtRegisterTest("FlowBitTest06", FlowBitTest06);
366 UtRegisterTest("FlowBitTest07", FlowBitTest07);
367 UtRegisterTest("FlowBitTest08", FlowBitTest08);
368 UtRegisterTest("FlowBitTest09", FlowBitTest09);
369 UtRegisterTest("FlowBitTest10", FlowBitTest10);
370 UtRegisterTest("FlowBitTest11", FlowBitTest11);
371#endif /* UNITTESTS */
372}
373
@ DETECT_FLOWBITS
int FlowBitSet(Flow *f, uint32_t idx)
add a flowbit to the flow
Definition flow-bit.c:94
void FlowBitRegisterTests(void)
Definition flow-bit.c:357
void FlowBitUnset(Flow *f, uint32_t idx)
Definition flow-bit.c:99
int FlowBitIsset(Flow *f, uint32_t idx)
Definition flow-bit.c:119
int FlowBitIsnotset(Flow *f, uint32_t idx)
Definition flow-bit.c:131
void FlowBitFree(FlowBit *fb)
Definition flow-bit.c:143
bool FlowBitToggle(Flow *f, uint32_t idx)
Definition flow-bit.c:107
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
#define PASS
Pass the test.
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
uint16_t type
Definition flow-bit.h:31
GenericVar * next
Definition flow-bit.h:34
uint32_t idx
Definition flow-bit.h:33
Flow data structure.
Definition flow.h:356
GenericVar * flowvar
Definition flow.h:489
uint16_t type
Definition util-var.h:54
uint32_t idx
Definition util-var.h:56
struct GenericVar_ * next
Definition util-var.h:57
#define SCMalloc(sz)
Definition util-mem.h:47
#define SCFree(p)
Definition util-mem.h:61
#define unlikely(expr)
void GenericVarAppend(GenericVar **list, GenericVar *gv)
Definition util-var.c:98
void GenericVarFree(GenericVar *gv)
Definition util-var.c:48
void GenericVarRemove(GenericVar **list, GenericVar *gv)
Definition util-var.c:117