suricata
defrag-config.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 Giuseppe Longo <giuseppelng@gmail.com>
22  *
23  */
24 
25 #include "suricata-common.h"
26 #include "defrag-config.h"
27 #include "util-misc.h"
28 #include "util-radix-tree.h"
29 #include "conf.h"
30 
31 static SCRadixTree *defrag_tree = NULL;
32 
33 static int default_timeout = 0;
34 
35 static void DefragPolicyFreeUserData(void *data)
36 {
37  if (data != NULL)
38  SCFree(data);
39 
40  return;
41 }
42 
43 static void DefragPolicyAddHostInfo(char *host_ip_range, uint64_t timeout)
44 {
45  uint64_t *user_data = NULL;
46 
47  if ( (user_data = SCMalloc(sizeof(uint64_t))) == NULL) {
48  FatalError("Error allocating memory. Exiting");
49  }
50 
51  *user_data = timeout;
52 
53  if (strchr(host_ip_range, ':') != NULL) {
54  SCLogDebug("adding ipv6 host %s", host_ip_range);
55  if (!SCRadixAddKeyIPV6String(host_ip_range, defrag_tree, (void *)user_data)) {
56  SCFree(user_data);
57  if (sc_errno != SC_EEXIST) {
58  SCLogWarning("failed to add ipv6 host %s", host_ip_range);
59  }
60  }
61  } else {
62  SCLogDebug("adding ipv4 host %s", host_ip_range);
63  if (!SCRadixAddKeyIPV4String(host_ip_range, defrag_tree, (void *)user_data)) {
64  SCFree(user_data);
65  if (sc_errno != SC_EEXIST) {
66  SCLogWarning("failed to add ipv4 host %s", host_ip_range);
67  }
68  }
69  }
70 }
71 
72 static int DefragPolicyGetIPv4HostTimeout(uint8_t *ipv4_addr)
73 {
74  void *user_data = NULL;
75  (void)SCRadixFindKeyIPV4BestMatch(ipv4_addr, defrag_tree, &user_data);
76  if (user_data == NULL)
77  return -1;
78 
79  return *((int *)user_data);
80 }
81 
82 static int DefragPolicyGetIPv6HostTimeout(uint8_t *ipv6_addr)
83 {
84  void *user_data = NULL;
85  (void)SCRadixFindKeyIPV6BestMatch(ipv6_addr, defrag_tree, &user_data);
86  if (user_data == NULL)
87  return -1;
88 
89  return *((int *)user_data);
90 }
91 
93 {
94  int timeout = 0;
95 
96  if (PKT_IS_IPV4(p))
97  timeout = DefragPolicyGetIPv4HostTimeout((uint8_t *)GET_IPV4_DST_ADDR_PTR(p));
98  else if (PKT_IS_IPV6(p))
99  timeout = DefragPolicyGetIPv6HostTimeout((uint8_t *)GET_IPV6_DST_ADDR(p));
100 
101  if (timeout <= 0)
102  timeout = default_timeout;
103 
104  return timeout;
105 }
106 
107 static void DefragParseParameters(ConfNode *n)
108 {
109  ConfNode *si;
110  uint64_t timeout = 0;
111 
112  TAILQ_FOREACH(si, &n->head, next) {
113  if (strcasecmp("timeout", si->name) == 0) {
114  SCLogDebug("timeout value %s", si->val);
115  if (ParseSizeStringU64(si->val, &timeout) < 0) {
116  SCLogError("Error parsing timeout "
117  "from conf file");
118  }
119  }
120  if (strcasecmp("address", si->name) == 0) {
121  ConfNode *pval;
122  TAILQ_FOREACH(pval, &si->head, next) {
123  DefragPolicyAddHostInfo(pval->val, timeout);
124  }
125  }
126  }
127 }
128 
129 void DefragSetDefaultTimeout(intmax_t timeout)
130 {
131  default_timeout = timeout;
132  SCLogDebug("default timeout %d", default_timeout);
133 }
134 
136 {
137  SCEnter();
138 
139  defrag_tree = SCRadixCreateRadixTree(DefragPolicyFreeUserData, NULL);
140  if (defrag_tree == NULL) {
141  FatalError("Can't alloc memory for the defrag config tree.");
142  }
143 
144  ConfNode *server_config = ConfGetNode("defrag.host-config");
145  if (server_config == NULL) {
146  SCLogDebug("failed to read host config");
147  SCReturn;
148  }
149 
150  SCLogDebug("configuring host config %p", server_config);
151  ConfNode *sc;
152 
153  TAILQ_FOREACH(sc, &server_config->head, next) {
154  ConfNode *p = NULL;
155 
156  TAILQ_FOREACH(p, &sc->head, next) {
157  SCLogDebug("parsing configuration for %s", p->name);
158  DefragParseParameters(p);
159  }
160  }
161 }
162 
164 {
165  if (defrag_tree != NULL) {
166  SCRadixReleaseRadixTree(defrag_tree);
167  }
168  defrag_tree = NULL;
169 }
SCRadixAddKeyIPV6String
bool SCRadixAddKeyIPV6String(const char *str, SCRadixTree *tree, void *user)
Adds a new IPV6/netblock to the Radix tree from a string.
Definition: util-radix-tree.c:1064
PKT_IS_IPV6
#define PKT_IS_IPV6(p)
Definition: decode.h:246
ConfNode_::val
char * val
Definition: conf.h:34
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
ParseSizeStringU64
int ParseSizeStringU64(const char *size, uint64_t *res)
Definition: util-misc.c:198
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:0
ConfGetNode
ConfNode * ConfGetNode(const char *name)
Get a ConfNode by name.
Definition: conf.c:181
SCRadixTree_
Structure for the radix tree.
Definition: util-radix-tree.h:86
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:252
SCRadixFindKeyIPV4BestMatch
SCRadixNode * SCRadixFindKeyIPV4BestMatch(uint8_t *key_stream, SCRadixTree *tree, void **user_data_result)
Checks if an IPV4 address is present in the tree under a netblock.
Definition: util-radix-tree.c:1591
defrag-config.h
DefragPolicyGetHostTimeout
int DefragPolicyGetHostTimeout(Packet *p)
Definition: defrag-config.c:92
SCRadixFindKeyIPV6BestMatch
SCRadixNode * SCRadixFindKeyIPV6BestMatch(uint8_t *key_stream, SCRadixTree *tree, void **user_data_result)
Checks if an IPV6 address is present in the tree under a netblock.
Definition: util-radix-tree.c:1649
GET_IPV6_DST_ADDR
#define GET_IPV6_DST_ADDR(p)
Definition: decode.h:215
SCRadixAddKeyIPV4String
bool SCRadixAddKeyIPV4String(const char *str, SCRadixTree *tree, void *user)
Adds a new IPV4/netblock to the Radix tree from a string.
Definition: util-radix-tree.c:989
GET_IPV4_DST_ADDR_PTR
#define GET_IPV4_DST_ADDR_PTR(p)
Definition: decode.h:210
SCRadixReleaseRadixTree
void SCRadixReleaseRadixTree(SCRadixTree *tree)
Frees a Radix tree and all its nodes.
Definition: util-radix-tree.c:454
SCEnter
#define SCEnter(...)
Definition: util-debug.h:271
SCLogWarning
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition: util-debug.h:249
SCRadixCreateRadixTree
SCRadixTree * SCRadixCreateRadixTree(void(*Free)(void *), void(*PrintData)(void *))
Creates a new Radix tree.
Definition: util-radix-tree.c:417
SCReturn
#define SCReturn
Definition: util-debug.h:273
Packet_
Definition: decode.h:436
conf.h
util-radix-tree.h
DefragTreeDestroy
void DefragTreeDestroy(void)
Definition: defrag-config.c:163
suricata-common.h
ConfNode_::name
char * name
Definition: conf.h:33
FatalError
#define FatalError(...)
Definition: util-debug.h:502
DefragPolicyLoadFromConfig
void DefragPolicyLoadFromConfig(void)
Definition: defrag-config.c:135
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
SC_EEXIST
@ SC_EEXIST
Definition: util-error.h:32
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
SCFree
#define SCFree(p)
Definition: util-mem.h:61
ConfNode_
Definition: conf.h:32
sc_errno
thread_local SCError sc_errno
Definition: util-error.c:31
util-misc.h
DefragSetDefaultTimeout
void DefragSetDefaultTimeout(intmax_t timeout)
Definition: defrag-config.c:129
PKT_IS_IPV4
#define PKT_IS_IPV4(p)
Definition: decode.h:245