Coverage Report

Created: 2026-06-30 07:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata7/src/defrag-config.c
Line
Count
Source
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
30
static SCRadixTree *defrag_tree = NULL;
31
32
static int default_timeout = 0;
33
34
static void DefragPolicyFreeUserData(void *data)
35
0
{
36
0
    if (data != NULL)
37
0
        SCFree(data);
38
39
0
    return;
40
0
}
41
42
static void DefragPolicyAddHostInfo(char *host_ip_range, uint64_t timeout)
43
0
{
44
0
    uint64_t *user_data = NULL;
45
46
0
    if ( (user_data = SCMalloc(sizeof(uint64_t))) == NULL) {
47
0
        FatalError("Error allocating memory. Exiting");
48
0
    }
49
50
0
    *user_data = timeout;
51
52
0
    if (strchr(host_ip_range, ':') != NULL) {
53
0
        SCLogDebug("adding ipv6 host %s", host_ip_range);
54
0
        if (!SCRadixAddKeyIPV6String(host_ip_range, defrag_tree, (void *)user_data)) {
55
0
            SCFree(user_data);
56
0
            if (sc_errno != SC_EEXIST) {
57
0
                SCLogWarning("failed to add ipv6 host %s", host_ip_range);
58
0
            }
59
0
        }
60
0
    } else {
61
0
        SCLogDebug("adding ipv4 host %s", host_ip_range);
62
0
        if (!SCRadixAddKeyIPV4String(host_ip_range, defrag_tree, (void *)user_data)) {
63
0
            SCFree(user_data);
64
0
            if (sc_errno != SC_EEXIST) {
65
0
                SCLogWarning("failed to add ipv4 host %s", host_ip_range);
66
0
            }
67
0
        }
68
0
    }
69
0
}
70
71
static int DefragPolicyGetIPv4HostTimeout(uint8_t *ipv4_addr)
72
57.5k
{
73
57.5k
    void *user_data = NULL;
74
57.5k
    (void)SCRadixFindKeyIPV4BestMatch(ipv4_addr, defrag_tree, &user_data);
75
57.5k
    if (user_data == NULL)
76
57.5k
        return -1;
77
78
0
    return *((int *)user_data);
79
57.5k
}
80
81
static int DefragPolicyGetIPv6HostTimeout(uint8_t *ipv6_addr)
82
102k
{
83
102k
    void *user_data = NULL;
84
102k
    (void)SCRadixFindKeyIPV6BestMatch(ipv6_addr, defrag_tree, &user_data);
85
102k
    if (user_data == NULL)
86
102k
        return -1;
87
88
0
    return *((int *)user_data);
89
102k
}
90
91
int DefragPolicyGetHostTimeout(Packet *p)
92
51.2k
{
93
51.2k
    int timeout = 0;
94
95
51.2k
    if (PKT_IS_IPV4(p))
96
13.7k
        timeout = DefragPolicyGetIPv4HostTimeout((uint8_t *)GET_IPV4_DST_ADDR_PTR(p));
97
37.5k
    else if (PKT_IS_IPV6(p))
98
37.5k
        timeout = DefragPolicyGetIPv6HostTimeout((uint8_t *)GET_IPV6_DST_ADDR(p));
99
100
51.2k
    if (timeout <= 0)
101
51.2k
        timeout = default_timeout;
102
103
51.2k
    return timeout;
104
51.2k
}
105
106
static void DefragParseParameters(ConfNode *n)
107
0
{
108
0
    ConfNode *si;
109
0
    uint64_t timeout = 0;
110
111
0
    TAILQ_FOREACH(si, &n->head, next) {
112
0
        if (strcasecmp("timeout", si->name) == 0) {
113
0
            SCLogDebug("timeout value  %s", si->val);
114
0
            if (ParseSizeStringU64(si->val, &timeout) < 0) {
115
0
                SCLogError("Error parsing timeout "
116
0
                           "from conf file");
117
0
            }
118
0
        }
119
0
        if (strcasecmp("address", si->name) == 0) {
120
0
            ConfNode *pval;
121
0
            TAILQ_FOREACH(pval, &si->head, next) {
122
0
                DefragPolicyAddHostInfo(pval->val, timeout);
123
0
            }
124
0
        }
125
0
    }
126
0
}
127
128
void DefragSetDefaultTimeout(intmax_t timeout)
129
74
{
130
74
    default_timeout = timeout;
131
74
    SCLogDebug("default timeout %d", default_timeout);
132
74
}
133
134
void DefragPolicyLoadFromConfig(void)
135
33
{
136
33
    SCEnter();
137
138
33
    defrag_tree = SCRadixCreateRadixTree(DefragPolicyFreeUserData, NULL);
139
33
    if (defrag_tree == NULL) {
140
0
        FatalError("Can't alloc memory for the defrag config tree.");
141
0
    }
142
143
33
    ConfNode *server_config = ConfGetNode("defrag.host-config");
144
33
    if (server_config == NULL) {
145
33
        SCLogDebug("failed to read host config");
146
33
        SCReturn;
147
33
    }
148
149
0
    SCLogDebug("configuring host config %p", server_config);
150
0
    ConfNode *sc;
151
152
0
    TAILQ_FOREACH(sc, &server_config->head, next) {
153
0
        ConfNode *p = NULL;
154
155
0
        TAILQ_FOREACH(p, &sc->head, next) {
156
0
            SCLogDebug("parsing configuration for %s", p->name);
157
0
            DefragParseParameters(p);
158
0
        }
159
0
    }
160
0
}
161
162
void DefragTreeDestroy(void)
163
0
{
164
0
    if (defrag_tree != NULL) {
165
0
        SCRadixReleaseRadixTree(defrag_tree);
166
0
    }
167
    defrag_tree = NULL;
168
0
}