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, FlowVarKeyLenType 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 */
95  Flow *f, uint8_t *key, FlowVarKeyLenType keylen, uint8_t *value, uint16_t size)
96 {
97  FlowVar *fv = SCCalloc(1, sizeof(FlowVar));
98  if (unlikely(fv == NULL))
99  return;
100 
101  fv->type = DETECT_FLOWVAR;
103  fv->idx = 0;
104  fv->data.fv_str.value = value;
105  fv->data.fv_str.value_len = size;
106  fv->key = key;
107  fv->keylen = keylen;
108  fv->next = NULL;
109 
110  GenericVarAppend(&f->flowvar, (GenericVar *)fv);
111 }
112 
113 /* add a flowvar to the flow, or update it */
114 void FlowVarAddIdValue(Flow *f, uint32_t idx, uint8_t *value, uint16_t size)
115 {
116  FlowVar *fv = FlowVarGet(f, idx);
117  if (fv == NULL) {
118  fv = SCCalloc(1, sizeof(FlowVar));
119  if (unlikely(fv == NULL))
120  return;
121 
122  fv->type = DETECT_FLOWVAR;
124  fv->idx = idx;
125  fv->data.fv_str.value = value;
126  fv->data.fv_str.value_len = size;
127  fv->next = NULL;
128 
129  GenericVarAppend(&f->flowvar, (GenericVar *)fv);
130  } else {
131  FlowVarUpdateStr(fv, value, size);
132  }
133 }
134 
135 /* add a flowvar to the flow, or update it */
136 void FlowVarAddIntNoLock(Flow *f, uint32_t idx, uint32_t value)
137 {
138  FlowVar *fv = FlowVarGet(f, idx);
139  if (fv == NULL) {
140  fv = SCMalloc(sizeof(FlowVar));
141  if (unlikely(fv == NULL))
142  return;
143 
144  fv->type = DETECT_FLOWVAR;
146  fv->idx = idx;
147  fv->data.fv_int.value= value;
148  fv->next = NULL;
149 
150  GenericVarAppend(&f->flowvar, (GenericVar *)fv);
151  } else {
152  FlowVarUpdateInt(fv, value);
153  }
154 }
155 
156 /* add a flowvar to the flow, or update it */
157 void FlowVarAddInt(Flow *f, uint32_t idx, uint32_t value)
158 {
159  FlowVarAddIntNoLock(f, idx, value);
160 }
161 
163 {
164  if (fv == NULL)
165  return;
166 
167  if (fv->datatype == FLOWVAR_TYPE_STR) {
168  if (fv->data.fv_str.value != NULL)
169  SCFree(fv->data.fv_str.value);
170  SCFree(fv->key);
171  }
172  SCFree(fv);
173 }
174 
176 {
177  uint16_t u;
178 
179  if (!SCLogDebugEnabled())
180  return;
181 
182  if (gv == NULL)
183  return;
184 
185  if (gv->type == DETECT_FLOWVAR || gv->type == DETECT_FLOWINT) {
186  FlowVar *fv = (FlowVar *)gv;
187 
188  if (fv->datatype == FLOWVAR_TYPE_STR) {
189  SCLogDebug("Name idx \"%" PRIu32 "\", Value \"", fv->idx);
190  for (u = 0; u < fv->data.fv_str.value_len; u++) {
191  if (isprint(fv->data.fv_str.value[u]))
192  SCLogDebug("%c", fv->data.fv_str.value[u]);
193  else
194  SCLogDebug("\\%02X", fv->data.fv_str.value[u]);
195  }
196  SCLogDebug("\", Len \"%" PRIu16 "\"\n", fv->data.fv_str.value_len);
197  } else if (fv->datatype == FLOWVAR_TYPE_INT) {
198  SCLogDebug("Name idx \"%" PRIu32 "\", Value \"%" PRIu32 "\"", fv->idx,
199  fv->data.fv_int.value);
200  } else {
201  SCLogDebug("Unknown data type at flowvars\n");
202  }
203  }
204  FlowVarPrint(gv->next);
205 }
206 
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:269
FlowVarGetByKey
FlowVar * FlowVarGetByKey(Flow *f, const uint8_t *key, FlowVarKeyLenType keylen)
get the flowvar with index 'idx' from the flow
Definition: flow-var.c:54
FlowVarTypeStr::value_len
uint16_t value_len
Definition: flow-var.h:40
FLOWVAR_TYPE_STR
#define FLOWVAR_TYPE_STR
Definition: flow-var.h:33
threads.h
Flow_
Flow data structure.
Definition: flow.h:354
FlowVarFree
void FlowVarFree(FlowVar *fv)
Definition: flow-var.c:162
FlowVar_::fv_str
FlowVarTypeStr fv_str
Definition: flow-var.h:58
FlowVar_::keylen
FlowVarKeyLenType keylen
Definition: flow-var.h:52
FlowVarAddKeyValue
void FlowVarAddKeyValue(Flow *f, uint8_t *key, FlowVarKeyLenType keylen, uint8_t *value, uint16_t size)
Definition: flow-var.c:94
FLOWVAR_TYPE_INT
#define FLOWVAR_TYPE_INT
Definition: flow-var.h:34
FlowVar_::fv_int
FlowVarTypeInt fv_int
Definition: flow-var.h:59
util-debug.h
GenericVar_::next
struct GenericVar_ * next
Definition: util-var.h:53
DETECT_FLOWINT
@ DETECT_FLOWINT
Definition: detect-engine-register.h:64
DETECT_FLOWVAR
@ DETECT_FLOWVAR
Definition: detect-engine-register.h:62
FlowVar_::idx
uint32_t idx
Definition: flow-var.h:53
FlowVar_::key
uint8_t * key
Definition: flow-var.h:61
detect.h
GenericVar_::idx
uint32_t idx
Definition: util-var.h:52
FlowVarAddIdValue
void FlowVarAddIdValue(Flow *f, uint32_t idx, uint8_t *value, uint16_t size)
Definition: flow-var.c:114
FlowVarTypeInt_::value
uint32_t value
Definition: flow-var.h:45
Flow_::flowvar
GenericVar * flowvar
Definition: flow.h:487
FlowVar_::data
union FlowVar_::@107 data
FlowVarTypeStr::value
uint8_t * value
Definition: flow-var.h:39
FlowVarPrint
void FlowVarPrint(GenericVar *gv)
Definition: flow-var.c:175
suricata-common.h
GenericVar_
Definition: util-var.h:49
FlowVarKeyLenType
uint8_t FlowVarKeyLenType
Definition: flow-var.h:36
FlowVar_::next
GenericVar * next
Definition: flow-var.h:54
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:50
FlowVarAddInt
void FlowVarAddInt(Flow *f, uint32_t idx, uint32_t value)
Definition: flow-var.c:157
FlowVarAddIntNoLock
void FlowVarAddIntNoLock(Flow *f, uint32_t idx, uint32_t value)
Definition: flow-var.c:136
GenericVar_::type
uint16_t type
Definition: util-var.h:50
FlowVarGet
FlowVar * FlowVarGet(Flow *f, uint32_t idx)
get the flowvar with index 'idx' from the flow
Definition: flow-var.c:78
flow.h
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
flow-var.h
FlowVar_
Definition: flow-var.h:49
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:51