suricata
defrag-config.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2022 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 "conf.h"
29#include "util-radix4-tree.h"
30#include "util-radix6-tree.h"
31
32static void DefragPolicyFreeUserData(void *data)
33{
34 if (data != NULL)
35 SCFree(data);
36}
37
38static SCRadix4Tree defrag4_tree = SC_RADIX4_TREE_INITIALIZER;
39static SCRadix6Tree defrag6_tree = SC_RADIX6_TREE_INITIALIZER;
40static SCRadix4Config defrag4_config = { DefragPolicyFreeUserData, NULL };
41static SCRadix6Config defrag6_config = { DefragPolicyFreeUserData, NULL };
42
43static int default_timeout = 0;
44
45static void DefragPolicyAddHostInfo(const char *host_ip_range, uint64_t timeout)
46{
47 uint64_t *user_data = NULL;
48
49 if ( (user_data = SCMalloc(sizeof(uint64_t))) == NULL) {
50 FatalError("Error allocating memory. Exiting");
51 }
52
53 *user_data = timeout;
54
55 if (strchr(host_ip_range, ':') != NULL) {
56 SCLogDebug("adding ipv6 host %s", host_ip_range);
58 &defrag6_tree, &defrag6_config, host_ip_range, (void *)user_data)) {
59 SCFree(user_data);
60 if (sc_errno != SC_EEXIST) {
61 SCLogWarning("failed to add ipv6 host %s", host_ip_range);
62 }
63 }
64 } else {
65 SCLogDebug("adding ipv4 host %s", host_ip_range);
67 &defrag4_tree, &defrag4_config, host_ip_range, (void *)user_data)) {
68 if (sc_errno != SC_EEXIST) {
69 SCLogWarning("failed to add ipv4 host %s", host_ip_range);
70 }
71 }
72 }
73}
74
75static int DefragPolicyGetIPv4HostTimeout(const uint8_t *ipv4_addr)
76{
77 void *user_data = NULL;
78 (void)SCRadix4TreeFindBestMatch(&defrag4_tree, ipv4_addr, &user_data);
79 if (user_data == NULL)
80 return -1;
81
82 return *((int *)user_data);
83}
84
85static int DefragPolicyGetIPv6HostTimeout(const uint8_t *ipv6_addr)
86{
87 void *user_data = NULL;
88 (void)SCRadix6TreeFindBestMatch(&defrag6_tree, ipv6_addr, &user_data);
89 if (user_data == NULL)
90 return -1;
91
92 return *((int *)user_data);
93}
94
96{
97 int timeout = 0;
98
99 if (PacketIsIPv4(p))
100 timeout = DefragPolicyGetIPv4HostTimeout((const uint8_t *)GET_IPV4_DST_ADDR_PTR(p));
101 else if (PacketIsIPv6(p))
102 timeout = DefragPolicyGetIPv6HostTimeout((const uint8_t *)GET_IPV6_DST_ADDR(p));
103
104 if (timeout <= 0)
105 timeout = default_timeout;
106
107 return timeout;
108}
109
110static void DefragParseParameters(SCConfNode *n)
111{
112 SCConfNode *si;
113 uint64_t timeout = 0;
114
115 TAILQ_FOREACH(si, &n->head, next) {
116 if (strcasecmp("timeout", si->name) == 0) {
117 SCLogDebug("timeout value %s", si->val);
118 if (ParseSizeStringU64(si->val, &timeout) < 0) {
119 SCLogError("Error parsing timeout "
120 "from conf file");
121 }
122 }
123 if (strcasecmp("address", si->name) == 0) {
124 SCConfNode *pval;
125 TAILQ_FOREACH(pval, &si->head, next) {
126 DefragPolicyAddHostInfo(pval->val, timeout);
127 }
128 }
129 }
130}
131
132void DefragSetDefaultTimeout(int timeout)
133{
134 default_timeout = timeout;
135 SCLogDebug("default timeout %d", default_timeout);
136}
137
139{
140 SCEnter();
141
142 SCConfNode *server_config = SCConfGetNode("defrag.host-config");
143 if (server_config == NULL) {
144 SCLogDebug("failed to read host config");
145 SCReturn;
146 }
147
148 SCLogDebug("configuring host config %p", server_config);
149 SCConfNode *sc;
150
151 TAILQ_FOREACH(sc, &server_config->head, next) {
152 SCConfNode *p = NULL;
153
154 TAILQ_FOREACH(p, &sc->head, next) {
155 SCLogDebug("parsing configuration for %s", p->name);
156 DefragParseParameters(p);
157 }
158 }
159}
160
162{
163 SCRadix4TreeRelease(&defrag4_tree, &defrag4_config);
164 SCRadix6TreeRelease(&defrag6_tree, &defrag6_config);
165}
struct HtpBodyChunk_ * next
SCConfNode * SCConfGetNode(const char *name)
Get a SCConfNode by name.
Definition conf.c:181
#define GET_IPV6_DST_ADDR(p)
Definition decode.h:204
#define GET_IPV4_DST_ADDR_PTR(p)
Definition decode.h:199
int DefragPolicyGetHostTimeout(Packet *p)
void DefragPolicyLoadFromConfig(void)
void DefragTreeDestroy(void)
void DefragSetDefaultTimeout(int timeout)
#define TAILQ_FOREACH(var, head, field)
Definition queue.h:252
char * name
Definition conf.h:38
char * val
Definition conf.h:39
Structure for the radix tree.
Structure for the radix tree.
#define SCEnter(...)
Definition util-debug.h:277
#define FatalError(...)
Definition util-debug.h:510
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition util-debug.h:255
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267
#define SCReturn
Definition util-debug.h:279
thread_local SCError sc_errno
Definition util-error.c:31
@ SC_EEXIST
Definition util-error.h:32
#define SCMalloc(sz)
Definition util-mem.h:47
#define SCFree(p)
Definition util-mem.h:61
int ParseSizeStringU64(const char *size, uint64_t *res)
Definition util-misc.c:190
SCRadix4Node * SCRadix4TreeFindBestMatch(const SCRadix4Tree *tree, const uint8_t *key, void **user_data)
bool SCRadix4AddKeyIPV4String(SCRadix4Tree *tree, const SCRadix4Config *config, const char *str, void *user)
Adds a new IPV4/netblock to the Radix4 tree from a string.
void SCRadix4TreeRelease(SCRadix4Tree *tree, const SCRadix4Config *config)
#define SC_RADIX4_TREE_INITIALIZER
SCRadix6Node * SCRadix6TreeFindBestMatch(const SCRadix6Tree *tree, const uint8_t *key, void **user_data)
void SCRadix6TreeRelease(SCRadix6Tree *tree, const SCRadix6Config *config)
bool SCRadix6AddKeyIPV6String(SCRadix6Tree *tree, const SCRadix6Config *config, const char *str, void *user)
Adds a new IPV6/netblock to the Radix6 tree from a string.
#define SC_RADIX6_TREE_INITIALIZER