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 /** \brief get the flowvar with index 'idx' from the flow
51  * \note flow is not locked by this function, caller is
52  * responsible
53  */
54 FlowVar *FlowVarGetByKey(Flow *f, const uint8_t *key, uint16_t keylen)
55 {
56  if (f == NULL)
57  return NULL;
58 
59  GenericVar *gv = f->flowvar;
60 
61  for ( ; gv != NULL; gv = gv->next) {
62  if (gv->type == DETECT_FLOWVAR && gv->idx == 0) {
63 
64  FlowVar *fv = (FlowVar *)gv;
65  if (fv->keylen == keylen && memcmp(key, fv->key, keylen) == 0) {
66  return fv;
67  }
68  }
69  }
70 
71  return NULL;
72 }
73 
74 /** \brief get the flowvar with index 'idx' from the flow
75  * \note flow is not locked by this function, caller is
76  * responsible
77  */
78 FlowVar *FlowVarGet(Flow *f, uint32_t idx)
79 {
80  if (f == NULL)
81  return NULL;
82 
83  GenericVar *gv = f->flowvar;
84 
85  for ( ; gv != NULL; gv = gv->next) {
86  if (gv->type == DETECT_FLOWVAR && gv->idx == idx)
87  return (FlowVar *)gv;
88  }
89 
90  return NULL;
91 }
92 
93 /* add a flowvar to the flow, or update it */
94 void FlowVarAddKeyValue(Flow *f, uint8_t *key, uint16_t keysize, uint8_t *value, uint16_t size)
95 {
96  FlowVar *fv = SCCalloc(1, sizeof(FlowVar));
97  if (unlikely(fv == NULL))
98  return;
99 
100  fv->type = DETECT_FLOWVAR;
102  fv->idx = 0;
103  fv->data.fv_str.value = value;
104  fv->data.fv_str.value_len = size;
105  fv->key = key;
106  fv->keylen = keysize;
107  fv->next = NULL;
108 
109  GenericVarAppend(&f->flowvar, (GenericVar *)fv);
110 }
111 
112 /* add a flowvar to the flow, or update it */
113 void FlowVarAddIdValue(Flow *f, uint32_t idx, uint8_t *value, uint16_t size)
114 {
115  FlowVar *fv = FlowVarGet(f, idx);
116  if (fv == NULL) {
117  fv = SCCalloc(1, sizeof(FlowVar));
118  if (unlikely(fv == NULL))
119  return;
120 
121  fv->type = DETECT_FLOWVAR;
123  fv->idx = idx;
124  fv->data.fv_str.value = value;
125  fv->data.fv_str.value_len = size;
126  fv->next = NULL;
127 
128  GenericVarAppend(&f->flowvar, (GenericVar *)fv);
129  } else {
130  FlowVarUpdateStr(fv, value, size);
131  }
132 }
133 
134 /* add a flowvar to the flow, or update it */
135 void FlowVarAddIntNoLock(Flow *f, uint32_t idx, uint32_t value)
136 {
137  FlowVar *fv = FlowVarGet(f, idx);
138  if (fv == NULL) {
139  fv = SCMalloc(sizeof(FlowVar));
140  if (unlikely(fv == NULL))
141  return;
142 
143  fv->type = DETECT_FLOWVAR;
145  fv->idx = idx;
146  fv->data.fv_int.value= value;
147  fv->next = NULL;
148 
149  GenericVarAppend(&f->flowvar, (GenericVar *)fv);
150  } else {
151  FlowVarUpdateInt(fv, value);
152  }
153 }
154 
155 /* add a flowvar to the flow, or update it */
156 void FlowVarAddInt(Flow *f, uint32_t idx, uint32_t value)
157 {
158  FlowVarAddIntNoLock(f, idx, value);
159 }
160 
162 {
163  if (fv == NULL)
164  return;
165 
166  if (fv->datatype == FLOWVAR_TYPE_STR) {
167  if (fv->data.fv_str.value != NULL)
168  SCFree(fv->data.fv_str.value);
169  }
170  SCFree(fv);
171 }
172 
174 {
175  uint16_t u;
176 
177  if (!SCLogDebugEnabled())
178  return;
179 
180  if (gv == NULL)
181  return;
182 
183  if (gv->type == DETECT_FLOWVAR || gv->type == DETECT_FLOWINT) {
184  FlowVar *fv = (FlowVar *)gv;
185 
186  if (fv->datatype == FLOWVAR_TYPE_STR) {
187  SCLogDebug("Name idx \"%" PRIu32 "\", Value \"", fv->idx);
188  for (u = 0; u < fv->data.fv_str.value_len; u++) {
189  if (isprint(fv->data.fv_str.value[u]))
190  SCLogDebug("%c", fv->data.fv_str.value[u]);
191  else
192  SCLogDebug("\\%02X", fv->data.fv_str.value[u]);
193  }
194  SCLogDebug("\", Len \"%" PRIu16 "\"\n", fv->data.fv_str.value_len);
195  } else if (fv->datatype == FLOWVAR_TYPE_INT) {
196  SCLogDebug("Name idx \"%" PRIu32 "\", Value \"%" PRIu32 "\"", fv->idx,
197  fv->data.fv_int.value);
198  } else {
199  SCLogDebug("Unknown data type at flowvars\n");
200  }
201  }
202  FlowVarPrint(gv->next);
203 }
204 
uint8_t type
Definition: util-var.h:49
#define FLOWVAR_TYPE_STR
Definition: flow-var.h:33
#define SCLogDebug(...)
Definition: util-debug.h:335
uint32_t idx
Definition: flow-var.h:52
uint16_t value_len
Definition: flow-var.h:39
#define unlikely(expr)
Definition: util-optimize.h:35
uint8_t * key
Definition: flow-var.h:60
void FlowVarAddInt(Flow *f, uint32_t idx, uint32_t value)
Definition: flow-var.c:156
void FlowVarPrint(GenericVar *gv)
Definition: flow-var.c:173
FlowVar * FlowVarGetByKey(Flow *f, const uint8_t *key, uint16_t keylen)
get the flowvar with index &#39;idx&#39; from the flow
Definition: flow-var.c:54
uint32_t idx
Definition: util-var.h:51
int SCLogDebugEnabled(void)
Returns whether debug messages are enabled to be logged or not.
Definition: util-debug.c:631
FlowVarTypeStr fv_str
Definition: flow-var.h:57
void FlowVarFree(FlowVar *fv)
Definition: flow-var.c:161
uint8_t datatype
Definition: flow-var.h:50
struct GenericVar_ * next
Definition: util-var.h:52
#define SCCalloc(nm, a)
Definition: util-mem.h:253
uint32_t value
Definition: flow-var.h:44
uint8_t type
Definition: flow-var.h:49
GenericVar * flowvar
Definition: flow.h:448
FlowVarTypeInt fv_int
Definition: flow-var.h:58
uint8_t * value
Definition: flow-var.h:38
#define SCMalloc(a)
Definition: util-mem.h:222
union FlowVar_::@116 data
FlowVar * FlowVarGet(Flow *f, uint32_t idx)
get the flowvar with index &#39;idx&#39; from the flow
Definition: flow-var.c:78
#define SCFree(a)
Definition: util-mem.h:322
GenericVar * next
Definition: flow-var.h:53
void FlowVarAddIdValue(Flow *f, uint32_t idx, uint8_t *value, uint16_t size)
Definition: flow-var.c:113
void GenericVarAppend(GenericVar **list, GenericVar *gv)
Definition: util-var.c:92
uint16_t keylen
Definition: flow-var.h:51
void FlowVarAddKeyValue(Flow *f, uint8_t *key, uint16_t keysize, uint8_t *value, uint16_t size)
Definition: flow-var.c:94
#define FLOWVAR_TYPE_INT
Definition: flow-var.h:34
Flow data structure.
Definition: flow.h:325
void FlowVarAddIntNoLock(Flow *f, uint32_t idx, uint32_t value)
Definition: flow-var.c:135