Coverage Report

Created: 2026-05-16 07:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata7/src/feature.c
Line
Count
Source
1
/* Copyright (C) 2019 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 Jeff Lucovsky <jeff@lucovsky.org>
22
 *
23
 * Implements feature tracking
24
 */
25
26
#include "suricata-common.h"
27
#include "feature.h"
28
#include "threads.h"
29
30
#include "util-debug.h"
31
#include "util-hashlist.h"
32
33
typedef struct FeatureEntryType {
34
  const char *feature;
35
} FeatureEntryType;
36
37
static SCMutex feature_table_mutex = SCMUTEX_INITIALIZER;
38
static HashListTable *feature_hash_table;
39
40
static uint32_t FeatureHashFunc(HashListTable *ht, void *data,
41
                                uint16_t datalen)
42
9.08k
{
43
9.08k
    FeatureEntryType *f = (FeatureEntryType *)data;
44
9.08k
    uint32_t hash = 0;
45
9.08k
    int len = strlen(f->feature);
46
47
122k
    for (int i = 0; i < len; i++)
48
113k
        hash += u8_tolower((unsigned char)f->feature[i]);
49
50
9.08k
    return (hash % ht->array_size);
51
9.08k
}
52
53
static char FeatureHashCompareFunc(void *data1, uint16_t datalen1,
54
                                   void *data2, uint16_t datalen2)
55
4.51k
{
56
4.51k
    FeatureEntryType *f1 = (FeatureEntryType *)data1;
57
4.51k
    FeatureEntryType *f2 = (FeatureEntryType *)data2;
58
4.51k
    int len1 = 0;
59
4.51k
    int len2 = 0;
60
61
4.51k
    if (f1 == NULL || f2 == NULL)
62
0
        return 0;
63
64
4.51k
    if (f1->feature == NULL || f2->feature == NULL)
65
0
        return 0;
66
67
4.51k
    len1 = strlen(f1->feature);
68
4.51k
    len2 = strlen(f2->feature);
69
70
4.51k
    return (len1 == len2 && memcmp(f1->feature, f2->feature, len1) == 0);
71
4.51k
}
72
73
static void FeatureHashFreeFunc(void *data)
74
6
{
75
6
    FeatureEntryType *f = data;
76
6
    if (f->feature) {
77
6
        SCFree((void *)f->feature);
78
6
    }
79
6
    SCFree(data);
80
6
}
81
82
71
static void FeatureInit(void) {
83
71
    feature_hash_table = HashListTableInit(256, FeatureHashFunc,
84
71
                                           FeatureHashCompareFunc,
85
71
                                           FeatureHashFreeFunc);
86
87
71
    if (!feature_hash_table) {
88
0
        FatalError("Unable to allocate feature hash table.");
89
0
    }
90
71
}
91
92
static void FeatureAddEntry(const char *feature_name)
93
152
{
94
152
    int rc;
95
96
152
    FeatureEntryType *feature = SCCalloc(1, sizeof(*feature));
97
152
    if (!feature) {
98
0
        FatalError("Unable to allocate feature entry memory.");
99
0
    }
100
101
152
    feature->feature = SCStrdup(feature_name);
102
152
    if (feature->feature) {
103
152
        rc = HashListTableAdd(feature_hash_table, feature, sizeof(*feature));
104
152
        if (rc == 0)
105
146
            return;
106
152
    }
107
108
6
    FeatureHashFreeFunc(feature);
109
6
}
110
111
void ProvidesFeature(const char *feature_name)
112
152
{
113
152
    FeatureEntryType f = { feature_name };
114
115
152
    SCMutexLock(&feature_table_mutex);
116
117
152
    FeatureEntryType *feature = HashListTableLookup(feature_hash_table, &f, sizeof(f));
118
119
152
    if (!feature) {
120
152
        FeatureAddEntry(feature_name);
121
152
    }
122
123
152
    SCMutexUnlock(&feature_table_mutex);
124
152
}
125
126
bool RequiresFeature(const char *feature_name)
127
5.05k
{
128
5.05k
    FeatureEntryType f = { feature_name };
129
130
5.05k
    SCMutexLock(&feature_table_mutex);
131
5.05k
    FeatureEntryType *feature = HashListTableLookup(feature_hash_table, &f, sizeof(f));
132
5.05k
    SCMutexUnlock(&feature_table_mutex);
133
5.05k
    return feature != NULL;
134
5.05k
}
135
136
void FeatureTrackingRelease(void)
137
0
{
138
0
    if (feature_hash_table != NULL) {
139
0
        HashListTableFree(feature_hash_table);
140
0
        feature_hash_table = NULL;
141
0
    }
142
0
}
143
144
void FeatureDump(void)
145
0
{
146
0
    HashListTableBucket *hb = HashListTableGetListHead(feature_hash_table);
147
0
    for (; hb != NULL; hb = HashListTableGetListNext(hb)) {
148
0
        FeatureEntryType *f = HashListTableGetListData(hb);
149
0
        printf("provided feature name: %s\n", f->feature);
150
0
    }
151
0
}
152
void FeatureTrackingRegister(void)
153
71
{
154
71
    FeatureInit();
155
71
}