suricata
flow-var.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2010 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 * \author Pablo Rincon <pablo.rincon.crespo@gmail.com>
23 *
24 * Flow level variable support for complex detection rules
25 * Supported types atm are String and Integers
26 */
27
28#include "suricata-common.h"
29#include "threads.h"
30#include "flow-var.h"
31#include "flow.h"
32#include "detect.h"
33#include "util-debug.h"
34
35/* puts a new value into a flowvar */
36static void FlowVarUpdateStr(FlowVar *fv, uint8_t *value, uint16_t size)
37{
38 if (fv->data.fv_str.value)
40 fv->data.fv_str.value = value;
41 fv->data.fv_str.value_len = size;
42}
43
44/* puts a new value into a flowvar */
45static void FlowVarUpdateInt(FlowVar *fv, uint32_t value)
46{
47 fv->data.fv_int.value = value;
48}
49
50/* puts a new value into a flowvar */
51static void FlowVarUpdateFloat(FlowVar *fv, double value)
52{
53 fv->data.fv_float.value = value;
54}
55
56/** \brief get the flowvar with index 'idx' from the flow
57 * \note flow is not locked by this function, caller is
58 * responsible
59 */
60FlowVar *FlowVarGetByKey(Flow *f, const uint8_t *key, FlowVarKeyLenType keylen)
61{
62 if (f == NULL)
63 return NULL;
64
65 GenericVar *gv = f->flowvar;
66
67 for ( ; gv != NULL; gv = gv->next) {
68 if (gv->type == DETECT_FLOWVAR && gv->idx == 0) {
69
70 FlowVar *fv = (FlowVar *)gv;
71 if (fv->keylen == keylen && memcmp(key, fv->key, keylen) == 0) {
72 return fv;
73 }
74 }
75 }
76
77 return NULL;
78}
79
80/** \brief get the flowvar with index 'idx' from the flow
81 * \note flow is not locked by this function, caller is
82 * responsible
83 */
84FlowVar *FlowVarGet(Flow *f, uint32_t idx)
85{
86 if (f == NULL)
87 return NULL;
88
89 GenericVar *gv = f->flowvar;
90
91 for ( ; gv != NULL; gv = gv->next) {
92 if (gv->type == DETECT_FLOWVAR && gv->idx == idx)
93 return (FlowVar *)gv;
94 }
95
96 return NULL;
97}
98
99/* add a flowvar to the flow, or update it */
101 Flow *f, uint8_t *key, FlowVarKeyLenType keylen, uint8_t *value, uint16_t size)
102{
103 FlowVar *fv = SCCalloc(1, sizeof(FlowVar));
104 if (unlikely(fv == NULL))
105 return;
106
107 fv->type = DETECT_FLOWVAR;
109 fv->idx = 0;
110 fv->data.fv_str.value = value;
111 fv->data.fv_str.value_len = size;
112 fv->key = key;
113 fv->keylen = keylen;
114 fv->next = NULL;
115
117}
118
119/* add a flowvar to the flow, or update it */
120void FlowVarAddIdValue(Flow *f, uint32_t idx, uint8_t *value, uint16_t size)
121{
122 FlowVar *fv = FlowVarGet(f, idx);
123 if (fv == NULL) {
124 fv = SCCalloc(1, sizeof(FlowVar));
125 if (unlikely(fv == NULL))
126 return;
127
128 fv->type = DETECT_FLOWVAR;
130 fv->idx = idx;
131 fv->data.fv_str.value = value;
132 fv->data.fv_str.value_len = size;
133 fv->next = NULL;
134
136 } else {
137 FlowVarUpdateStr(fv, value, size);
138 }
139}
140
141/* add a flowvar to the flow, or update it */
142void FlowVarAddFloat(Flow *f, uint32_t idx, double value)
143{
144 FlowVar *fv = FlowVarGet(f, idx);
145 if (fv == NULL) {
146 fv = SCMalloc(sizeof(FlowVar));
147 if (unlikely(fv == NULL))
148 return;
149
150 fv->type = DETECT_FLOWVAR;
152 fv->idx = idx;
153 fv->data.fv_float.value = value;
154 fv->next = NULL;
155
157 } else {
158 FlowVarUpdateFloat(fv, value);
159 }
160}
161/* add a flowvar to the flow, or update it */
162void FlowVarAddIntNoLock(Flow *f, uint32_t idx, uint32_t value)
163{
164 FlowVar *fv = FlowVarGet(f, idx);
165 if (fv == NULL) {
166 fv = SCMalloc(sizeof(FlowVar));
167 if (unlikely(fv == NULL))
168 return;
169
170 fv->type = DETECT_FLOWVAR;
172 fv->idx = idx;
173 fv->data.fv_int.value= value;
174 fv->next = NULL;
175
177 } else {
178 FlowVarUpdateInt(fv, value);
179 }
180}
181
182/* add a flowvar to the flow, or update it */
183void FlowVarAddInt(Flow *f, uint32_t idx, uint32_t value)
184{
185 FlowVarAddIntNoLock(f, idx, value);
186}
187
189{
190 if (fv == NULL)
191 return;
192
193 if (fv->datatype == FLOWVAR_TYPE_STR) {
194 if (fv->data.fv_str.value != NULL)
195 SCFree(fv->data.fv_str.value);
196 SCFree(fv->key);
197 }
198 SCFree(fv);
199}
200
202{
203 uint16_t u;
204
205 if (!SCLogDebugEnabled())
206 return;
207
208 if (gv == NULL)
209 return;
210
211 if (gv->type == DETECT_FLOWVAR || gv->type == DETECT_FLOWINT) {
212 FlowVar *fv = (FlowVar *)gv;
213
214 if (fv->datatype == FLOWVAR_TYPE_STR) {
215 SCLogDebug("Name idx \"%" PRIu32 "\", Value \"", fv->idx);
216 for (u = 0; u < fv->data.fv_str.value_len; u++) {
217 if (isprint(fv->data.fv_str.value[u]))
218 SCLogDebug("%c", fv->data.fv_str.value[u]);
219 else
220 SCLogDebug("\\%02X", fv->data.fv_str.value[u]);
221 }
222 SCLogDebug("\", Len \"%" PRIu16 "\"\n", fv->data.fv_str.value_len);
223 } else if (fv->datatype == FLOWVAR_TYPE_INT) {
224 SCLogDebug("Name idx \"%" PRIu32 "\", Value \"%" PRIu32 "\"", fv->idx,
225 fv->data.fv_int.value);
226 } else {
227 SCLogDebug("Unknown data type at flowvars\n");
228 }
229 }
230 FlowVarPrint(gv->next);
231}
232
FlowVar * FlowVarGet(Flow *f, uint32_t idx)
get the flowvar with index 'idx' from the flow
Definition flow-var.c:84
void FlowVarFree(FlowVar *fv)
Definition flow-var.c:188
void FlowVarAddIdValue(Flow *f, uint32_t idx, uint8_t *value, uint16_t size)
Definition flow-var.c:120
void FlowVarAddFloat(Flow *f, uint32_t idx, double value)
Definition flow-var.c:142
FlowVar * FlowVarGetByKey(Flow *f, const uint8_t *key, FlowVarKeyLenType keylen)
get the flowvar with index 'idx' from the flow
Definition flow-var.c:60
void FlowVarAddKeyValue(Flow *f, uint8_t *key, FlowVarKeyLenType keylen, uint8_t *value, uint16_t size)
Definition flow-var.c:100
void FlowVarAddIntNoLock(Flow *f, uint32_t idx, uint32_t value)
Definition flow-var.c:162
void FlowVarAddInt(Flow *f, uint32_t idx, uint32_t value)
Definition flow-var.c:183
void FlowVarPrint(GenericVar *gv)
Definition flow-var.c:201
#define FLOWVAR_TYPE_INT
Definition flow-var.h:34
#define FLOWVAR_TYPE_STR
Definition flow-var.h:33
uint8_t FlowVarKeyLenType
Definition flow-var.h:37
#define FLOWVAR_TYPE_FLOAT
Definition flow-var.h:35
uint32_t value
Definition flow-var.h:46
uint16_t value_len
Definition flow-var.h:41
uint8_t * value
Definition flow-var.h:40
uint8_t datatype
Definition flow-var.h:57
uint32_t idx
Definition flow-var.h:59
FlowVarTypeInt fv_int
Definition flow-var.h:65
FlowVarKeyLenType keylen
Definition flow-var.h:58
uint8_t * key
Definition flow-var.h:68
FlowVarTypeStr fv_str
Definition flow-var.h:64
uint16_t type
Definition flow-var.h:56
GenericVar * next
Definition flow-var.h:60
FlowVarTypeFloat fv_float
Definition flow-var.h:66
union FlowVar_::@124 data
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
int SCLogDebugEnabled(void)
Returns whether debug messages are enabled to be logged or not.
Definition util-debug.c:767
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCMalloc(sz)
Definition util-mem.h:47
#define SCFree(p)
Definition util-mem.h:61
#define SCCalloc(nm, sz)
Definition util-mem.h:53
#define unlikely(expr)
void GenericVarAppend(GenericVar **list, GenericVar *gv)
Definition util-var.c:98