suricata
flow-util.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  * Flow utility functions
24  */
25 
26 #include "suricata-common.h"
27 #include "threads.h"
28 
29 #include "flow.h"
30 #include "flow-private.h"
31 #include "flow-util.h"
32 #include "flow-var.h"
33 #include "app-layer.h"
34 
35 #include "util-var.h"
36 #include "util-debug.h"
37 #include "flow-storage.h"
38 
39 #include "detect.h"
40 #include "detect-engine-state.h"
41 
42 #include "decode-icmpv4.h"
43 
44 /** \brief allocate a flow
45  *
46  * We check against the memuse counter. If it passes that check we increment
47  * the counter first, then we try to alloc.
48  *
49  * \retval f the flow or NULL on out of memory
50  */
52 {
53  Flow *f;
54  size_t size = sizeof(Flow) + FlowStorageSize();
55 
56  if (!(FLOW_CHECK_MEMCAP(size))) {
57  return NULL;
58  }
59 
60  (void) SC_ATOMIC_ADD(flow_memuse, size);
61 
62  f = SCMalloc(size);
63  if (unlikely(f == NULL)) {
64  (void)SC_ATOMIC_SUB(flow_memuse, size);
65  return NULL;
66  }
67  memset(f, 0, size);
68 
69  /* coverity[missing_lock] */
70  FLOW_INITIALIZE(f);
71  return f;
72 }
73 
74 
75 /**
76  * \brief cleanup & free the memory of a flow
77  *
78  * \param f flow to clear & destroy
79  */
80 void FlowFree(Flow *f)
81 {
82  FLOW_DESTROY(f);
83  SCFree(f);
84 
85  size_t size = sizeof(Flow) + FlowStorageSize();
86  (void) SC_ATOMIC_SUB(flow_memuse, size);
87 }
88 
89 /**
90  * \brief Function to map the protocol to the defined FLOW_PROTO_* enumeration.
91  *
92  * \param proto protocol which is needed to be mapped
93  */
94 
95 uint8_t FlowGetProtoMapping(uint8_t proto)
96 {
97  switch (proto) {
98  case IPPROTO_TCP:
99  return FLOW_PROTO_TCP;
100  case IPPROTO_UDP:
101  return FLOW_PROTO_UDP;
102  case IPPROTO_ICMP:
103  return FLOW_PROTO_ICMP;
104  default:
105  return FLOW_PROTO_DEFAULT;
106  }
107 }
108 
109 uint8_t FlowGetReverseProtoMapping(uint8_t rproto)
110 {
111  switch (rproto) {
112  case FLOW_PROTO_TCP:
113  return IPPROTO_TCP;
114  case FLOW_PROTO_UDP:
115  return IPPROTO_UDP;
116  case FLOW_PROTO_ICMP:
117  return IPPROTO_ICMP;
118  default:
119  exit(EXIT_FAILURE);
120  }
121 }
122 
123 static inline void FlowSetICMPv4CounterPart(Flow *f)
124 {
125  int ctype = ICMPv4GetCounterpart(f->icmp_s.type);
126  if (ctype == -1)
127  return;
128 
129  f->icmp_d.type = (uint8_t)ctype;
130 }
131 
132 static inline void FlowSetICMPv6CounterPart(Flow *f)
133 {
134  int ctype = ICMPv6GetCounterpart(f->icmp_s.type);
135  if (ctype == -1)
136  return;
137 
138  f->icmp_d.type = (uint8_t)ctype;
139 }
140 
141 /* initialize the flow from the first packet
142  * we see from it. */
143 void FlowInit(Flow *f, const Packet *p)
144 {
145  SCEnter();
146  SCLogDebug("flow %p", f);
147 
148  f->proto = p->proto;
150  f->vlan_id[0] = p->vlan_id[0];
151  f->vlan_id[1] = p->vlan_id[1];
152  f->vlan_idx = p->vlan_idx;
153  f->livedev = p->livedev;
154 
155  if (PKT_IS_IPV4(p)) {
159  f->flags |= FLOW_IPV4;
160  } else if (PKT_IS_IPV6(p)) {
164  f->flags |= FLOW_IPV6;
165  }
166 #ifdef DEBUG
167  /* XXX handle default */
168  else {
169  printf("FIXME: %s:%s:%" PRId32 "\n", __FILE__, __FUNCTION__, __LINE__);
170  }
171 #endif
172 
173  if (p->tcph != NULL) { /* XXX MACRO */
174  SET_TCP_SRC_PORT(p,&f->sp);
175  SET_TCP_DST_PORT(p,&f->dp);
176  } else if (p->udph != NULL) { /* XXX MACRO */
177  SET_UDP_SRC_PORT(p,&f->sp);
178  SET_UDP_DST_PORT(p,&f->dp);
179  } else if (p->icmpv4h != NULL) {
180  f->icmp_s.type = p->icmp_s.type;
181  f->icmp_s.code = p->icmp_s.code;
182  FlowSetICMPv4CounterPart(f);
183  } else if (p->icmpv6h != NULL) {
184  f->icmp_s.type = p->icmp_s.type;
185  f->icmp_s.code = p->icmp_s.code;
186  FlowSetICMPv6CounterPart(f);
187  } else if (p->sctph != NULL) { /* XXX MACRO */
188  SET_SCTP_SRC_PORT(p,&f->sp);
189  SET_SCTP_DST_PORT(p,&f->dp);
190  } /* XXX handle default */
191 #ifdef DEBUG
192  else {
193  printf("FIXME: %s:%s:%" PRId32 "\n", __FILE__, __FUNCTION__, __LINE__);
194  }
195 #endif
196  COPY_TIMESTAMP(&p->ts, &f->startts);
197 
199 
200  SCReturn;
201 }
202 
204 
206 {
207  return g_bypass_info_id;
208 }
209 
210 static void FlowBypassFree(void *x)
211 {
212  FlowBypassInfo *fb = (FlowBypassInfo *) x;
213 
214  if (fb == NULL)
215  return;
216 
217  if (fb->bypass_data && fb->BypassFree) {
218  fb->BypassFree(fb->bypass_data);
219  }
220  SCFree(fb);
221 }
222 
224 {
225  g_bypass_info_id = FlowStorageRegister("bypass_counters", sizeof(void *),
226  NULL, FlowBypassFree);
227 }
Packet_::proto
uint8_t proto
Definition: decode.h:433
SET_SCTP_DST_PORT
#define SET_SCTP_DST_PORT(pkt, prt)
Definition: decode.h:209
Flow_::recursion_level
uint8_t recursion_level
Definition: flow.h:362
FLOW_PROTO_DEFAULT
@ FLOW_PROTO_DEFAULT
Definition: flow-private.h:73
Packet_::sctph
SCTPHdr * sctph
Definition: decode.h:529
flow-util.h
Flow_::startts
struct timeval startts
Definition: flow.h:474
Packet_::vlan_id
uint16_t vlan_id[2]
Definition: decode.h:438
PKT_IS_IPV6
#define PKT_IS_IPV6(p)
Definition: decode.h:255
FlowBypassInfo_
Definition: flow.h:503
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
ICMPv6GetCounterpart
int ICMPv6GetCounterpart(uint8_t type)
Definition: decode-icmpv6.c:156
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
Flow_::proto
uint8_t proto
Definition: flow.h:361
threads.h
Packet_::vlan_idx
uint8_t vlan_idx
Definition: decode.h:439
flow-private.h
Flow_
Flow data structure.
Definition: flow.h:343
RegisterFlowBypassInfo
void RegisterFlowBypassInfo(void)
Definition: flow-util.c:223
Flow_::icmp_s
struct Flow_::@119::@123 icmp_s
Flow_::icmp_d
struct Flow_::@121::@124 icmp_d
Flow_::protomap
uint8_t protomap
Definition: flow.h:420
SC_ATOMIC_ADD
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
Definition: util-atomic.h:304
Flow_::vlan_id
uint16_t vlan_id[2]
Definition: flow.h:363
Flow
struct Flow_ Flow
Flow data structure.
Flow_::max_ttl_toserver
uint8_t max_ttl_toserver
Definition: flow.h:446
proto
uint8_t proto
Definition: decode-template.h:0
Flow_::dp
Port dp
Definition: flow.h:355
SET_UDP_DST_PORT
#define SET_UDP_DST_PORT(pkt, prt)
Definition: decode.h:199
util-var.h
FLOW_IPV4
#define FLOW_IPV4
Definition: flow.h:94
FlowGetReverseProtoMapping
uint8_t FlowGetReverseProtoMapping(uint8_t rproto)
Definition: flow-util.c:109
FLOW_SET_IPV6_DST_ADDR_FROM_PACKET
#define FLOW_SET_IPV6_DST_ADDR_FROM_PACKET(p, a)
Definition: flow.h:210
FLOW_CHECK_MEMCAP
#define FLOW_CHECK_MEMCAP(size)
check if a memory alloc would fit in the memcap
Definition: flow-util.h:135
FLOW_PROTO_ICMP
@ FLOW_PROTO_ICMP
Definition: flow-private.h:72
Flow_::dst
FlowAddress dst
Definition: flow.h:346
FLOW_INITIALIZE
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:39
Flow_::min_ttl_toserver
uint8_t min_ttl_toserver
Definition: flow.h:445
util-debug.h
SET_TCP_SRC_PORT
#define SET_TCP_SRC_PORT(pkt, prt)
Definition: decode.h:186
FlowBypassInfo_::BypassFree
void(* BypassFree)(void *data)
Definition: flow.h:505
FlowStorageRegister
int FlowStorageRegister(const char *name, const unsigned int size, void *(*Alloc)(unsigned int), void(*Free)(void *))
Definition: flow-storage.c:65
SET_UDP_SRC_PORT
#define SET_UDP_SRC_PORT(pkt, prt)
Definition: decode.h:196
FLOW_SET_IPV6_SRC_ADDR_FROM_PACKET
#define FLOW_SET_IPV6_SRC_ADDR_FROM_PACKET(p, a)
Definition: flow.h:203
SCEnter
#define SCEnter(...)
Definition: util-debug.h:300
detect.h
FlowStorageSize
unsigned int FlowStorageSize(void)
Definition: flow-storage.c:34
FlowBypassInfo_::bypass_data
void * bypass_data
Definition: flow.h:506
SC_ATOMIC_SUB
#define SC_ATOMIC_SUB(name, val)
sub a value from our atomic variable
Definition: util-atomic.h:313
SCReturn
#define SCReturn
Definition: util-debug.h:302
Packet_::icmpv6h
ICMPV6Hdr * icmpv6h
Definition: decode.h:533
FlowGetProtoMapping
uint8_t FlowGetProtoMapping(uint8_t proto)
Function to map the protocol to the defined FLOW_PROTO_* enumeration.
Definition: flow-util.c:95
Packet_
Definition: decode.h:411
FLOW_SET_IPV4_DST_ADDR_FROM_PACKET
#define FLOW_SET_IPV4_DST_ADDR_FROM_PACKET(p, a)
Definition: flow.h:186
decode-icmpv4.h
Packet_::livedev
struct LiveDevice_ * livedev
Definition: decode.h:556
Flow_::vlan_idx
uint8_t vlan_idx
Definition: flow.h:364
ICMPv4GetCounterpart
int ICMPv4GetCounterpart(uint8_t type)
Definition: decode-icmpv4.c:325
detect-engine-state.h
Data structures and function prototypes for keeping state for the detection engine.
Flow_::src
FlowAddress src
Definition: flow.h:346
FLOW_SET_IPV4_SRC_ADDR_FROM_PACKET
#define FLOW_SET_IPV4_SRC_ADDR_FROM_PACKET(p, a)
Definition: flow.h:179
Packet_::icmp_s
struct Packet_::@40::@49 icmp_s
SET_SCTP_SRC_PORT
#define SET_SCTP_SRC_PORT(pkt, prt)
Definition: decode.h:205
FLOW_PROTO_TCP
@ FLOW_PROTO_TCP
Definition: flow-private.h:70
flow-storage.h
Packet_::ts
struct timeval ts
Definition: decode.h:454
suricata-common.h
FlowFree
void FlowFree(Flow *f)
cleanup & free the memory of a flow
Definition: flow-util.c:80
FLOW_IPV6
#define FLOW_IPV6
Definition: flow.h:96
Packet_::tcph
TCPHdr * tcph
Definition: decode.h:525
Packet_::icmpv4h
ICMPV4Hdr * icmpv4h
Definition: decode.h:531
Flow_::livedev
struct LiveDevice_ * livedev
Definition: flow.h:367
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
SCFree
#define SCFree(p)
Definition: util-mem.h:61
Flow_::flags
uint32_t flags
Definition: flow.h:396
Packet_::recursion_level
uint8_t recursion_level
Definition: decode.h:436
IPV6_GET_HLIM
#define IPV6_GET_HLIM(p)
Definition: decode-ipv6.h:90
Packet_::udph
UDPHdr * udph
Definition: decode.h:527
COPY_TIMESTAMP
#define COPY_TIMESTAMP(src, dst)
Definition: flow-util.h:30
g_bypass_info_id
int g_bypass_info_id
Definition: flow-util.c:203
Flow_::sp
Port sp
Definition: flow.h:348
FLOW_PROTO_UDP
@ FLOW_PROTO_UDP
Definition: flow-private.h:71
flow.h
FlowAlloc
Flow * FlowAlloc(void)
allocate a flow
Definition: flow-util.c:51
GetFlowBypassInfoID
int GetFlowBypassInfoID(void)
Definition: flow-util.c:205
flow-var.h
PKT_IS_IPV4
#define PKT_IS_IPV4(p)
Definition: decode.h:254
SET_TCP_DST_PORT
#define SET_TCP_DST_PORT(pkt, prt)
Definition: decode.h:190
FlowInit
void FlowInit(Flow *f, const Packet *p)
Definition: flow-util.c:143
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:121
IPV4_GET_IPTTL
#define IPV4_GET_IPTTL(p)
Definition: decode-ipv4.h:146
app-layer.h