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 */
36 static void FlowVarUpdateStr(FlowVar *fv, uint8_t *value, uint16_t size)
37 {
38  if (fv->data.fv_str.value)
39  SCFree(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 */
45 static 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 */
51 static 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  */
60 FlowVar *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  */
84 FlowVar *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 
116  GenericVarAppend(&f->flowvar, (GenericVar *)fv);
117 }
118 
119 /* add a flowvar to the flow, or update it */
120 void 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 
135  GenericVarAppend(&f->flowvar, (GenericVar *)fv);
136  } else {
137  FlowVarUpdateStr(fv, value, size);
138  }
139 }
140 
141 /* add a flowvar to the flow, or update it */
142 void 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 
156  GenericVarAppend(&f->flowvar, (GenericVar *)fv);
157  } else {
158  FlowVarUpdateFloat(fv, value);
159  }
160 }
161 /* add a flowvar to the flow, or update it */
162 void 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 
176  GenericVarAppend(&f->flowvar, (GenericVar *)fv);
177  } else {
178  FlowVarUpdateInt(fv, value);
179  }
180 }
181 
182 /* add a flowvar to the flow, or update it */
183 void 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_::fv_float
FlowVarTypeFloat fv_float
Definition: flow-var.h:66
GenericVarAppend
void GenericVarAppend(GenericVar **list, GenericVar *gv)
Definition: util-var.c:98
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:275
FlowVarGetByKey
FlowVar * FlowVarGetByKey(Flow *f, const uint8_t *key, FlowVarKeyLenType keylen)
get the flowvar with index 'idx' from the flow
Definition: flow-var.c:60
FlowVarTypeStr::value_len
uint16_t value_len
Definition: flow-var.h:41
FLOWVAR_TYPE_STR
#define FLOWVAR_TYPE_STR
Definition: flow-var.h:33
threads.h
Flow_
Flow data structure.
Definition: flow.h:356
FlowVarFree
void FlowVarFree(FlowVar *fv)
Definition: flow-var.c:188
FlowVar_::fv_str
FlowVarTypeStr fv_str
Definition: flow-var.h:64
FlowVar_::keylen
FlowVarKeyLenType keylen
Definition: flow-var.h:58
FlowVarAddKeyValue
void FlowVarAddKeyValue(Flow *f, uint8_t *key, FlowVarKeyLenType keylen, uint8_t *value, uint16_t size)
Definition: flow-var.c:100
FLOWVAR_TYPE_INT
#define FLOWVAR_TYPE_INT
Definition: flow-var.h:34
FlowVar_::fv_int
FlowVarTypeInt fv_int
Definition: flow-var.h:65
util-debug.h
GenericVar_::next
struct GenericVar_ * next
Definition: util-var.h:57
DETECT_FLOWINT
@ DETECT_FLOWINT
Definition: detect-engine-register.h:62
DETECT_FLOWVAR
@ DETECT_FLOWVAR
Definition: detect-engine-register.h:60
FlowVar_::idx
uint32_t idx
Definition: flow-var.h:59
FlowVar_::key
uint8_t * key
Definition: flow-var.h:68
detect.h
FlowVarTypeFloat_::value
double value
Definition: flow-var.h:51
GenericVar_::idx
uint32_t idx
Definition: util-var.h:56
FlowVarAddIdValue
void FlowVarAddIdValue(Flow *f, uint32_t idx, uint8_t *value, uint16_t size)
Definition: flow-var.c:120
FlowVar_::data
union FlowVar_::@124 data
FlowVarTypeInt_::value
uint32_t value
Definition: flow-var.h:46
Flow_::flowvar
GenericVar * flowvar
Definition: flow.h:489
FlowVarTypeStr::value
uint8_t * value
Definition: flow-var.h:40
FlowVarPrint
void FlowVarPrint(GenericVar *gv)
Definition: flow-var.c:201
suricata-common.h
GenericVar_
Definition: util-var.h:53
FLOWVAR_TYPE_FLOAT
#define FLOWVAR_TYPE_FLOAT
Definition: flow-var.h:35
FlowVarKeyLenType
uint8_t FlowVarKeyLenType
Definition: flow-var.h:37
FlowVar_::next
GenericVar * next
Definition: flow-var.h:60
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
SCFree
#define SCFree(p)
Definition: util-mem.h:61
FlowVar_::type
uint16_t type
Definition: flow-var.h:56
FlowVarAddInt
void FlowVarAddInt(Flow *f, uint32_t idx, uint32_t value)
Definition: flow-var.c:183
FlowVarAddIntNoLock
void FlowVarAddIntNoLock(Flow *f, uint32_t idx, uint32_t value)
Definition: flow-var.c:162
GenericVar_::type
uint16_t type
Definition: util-var.h:54
FlowVarAddFloat
void FlowVarAddFloat(Flow *f, uint32_t idx, double value)
Definition: flow-var.c:142
FlowVarGet
FlowVar * FlowVarGet(Flow *f, uint32_t idx)
get the flowvar with index 'idx' from the flow
Definition: flow-var.c:84
flow.h
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
flow-var.h
FlowVar_
Definition: flow-var.h:55
SCLogDebugEnabled
int SCLogDebugEnabled(void)
Returns whether debug messages are enabled to be logged or not.
Definition: util-debug.c:767
FlowVar_::datatype
uint8_t datatype
Definition: flow-var.h:57