/src/suricata/src/host-storage.c
Line | Count | Source |
1 | | /* Copyright (C) 2007-2021 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 | | * Host wrapper around storage api |
24 | | */ |
25 | | |
26 | | #include "suricata-common.h" |
27 | | #include "host-storage.h" |
28 | | #include "util-unittest.h" |
29 | | |
30 | | unsigned int SCHostStorageSize(void) |
31 | 120 | { |
32 | 120 | return SCStorageGetSize(STORAGE_HOST); |
33 | 120 | } |
34 | | |
35 | | /** \defgroup hoststorage Host storage API |
36 | | * |
37 | | * The Host storage API is a per-host storage. It is a mean to extend |
38 | | * the Host structure with arbitrary data. |
39 | | * |
40 | | * You have first to register the storage via SCHostStorageRegister() during |
41 | | * the init of your module. Then you can attach data via SCHostSetStorageById() |
42 | | * and access them via SCHostGetStorageById(). |
43 | | * @{ |
44 | | */ |
45 | | |
46 | | /** |
47 | | * \brief Register a Host storage |
48 | | * |
49 | | * \param name the name of the storage |
50 | | * \param Free free function for the new storage |
51 | | * |
52 | | * \retval The ID of the newly register storage that will be used to access data |
53 | | * |
54 | | * It has to be called once during the init of the sub system |
55 | | */ |
56 | | |
57 | | SCHostStorageId SCHostStorageRegister(const char *name, void (*Free)(void *)) |
58 | 80 | { |
59 | 80 | int id = SCStorageRegister(STORAGE_HOST, name, Free); |
60 | 80 | SCHostStorageId hsi = { .id = id }; |
61 | 80 | return hsi; |
62 | 80 | } |
63 | | |
64 | | /** |
65 | | * \brief Store a pointer in a given Host storage |
66 | | * |
67 | | * \param h a pointer to the Host |
68 | | * \param id the id of the storage (return of SCHostStorageRegister() call) |
69 | | * \param ptr pointer to the data to store |
70 | | */ |
71 | | |
72 | | int SCHostSetStorageById(Host *h, SCHostStorageId id, void *ptr) |
73 | 71 | { |
74 | 71 | return SCStorageSetById(h->storage, STORAGE_HOST, id.id, ptr); |
75 | 71 | } |
76 | | |
77 | | /** |
78 | | * \brief Get a value from a given Host storage |
79 | | * |
80 | | * \param h a pointer to the Host |
81 | | * \param id the id of the storage (return of SCHostStorageRegister() call) |
82 | | * |
83 | | */ |
84 | | |
85 | | void *SCHostGetStorageById(Host *h, SCHostStorageId id) |
86 | 49.8k | { |
87 | 49.8k | return SCStorageGetById(h->storage, STORAGE_HOST, id.id); |
88 | 49.8k | } |
89 | | |
90 | | /** |
91 | | * @} |
92 | | */ |
93 | | |
94 | | /* Start of "private" function */ |
95 | | |
96 | | void SCHostFreeStorage(Host *h) |
97 | 0 | { |
98 | 0 | if (SCHostStorageSize() > 0) |
99 | 0 | SCStorageFreeAll(h->storage, STORAGE_HOST); |
100 | 0 | } |
101 | | |
102 | | |
103 | | #ifdef UNITTESTS |
104 | | |
105 | | static void StorageTestFree(void *x) |
106 | | { |
107 | | if (x) |
108 | | SCFree(x); |
109 | | } |
110 | | |
111 | | static int HostStorageTest01(void) |
112 | | { |
113 | | SCStorageCleanup(); |
114 | | SCStorageInit(); |
115 | | |
116 | | SCHostStorageId id1 = SCHostStorageRegister("test", StorageTestFree); |
117 | | FAIL_IF(id1.id < 0); |
118 | | SCHostStorageId id2 = SCHostStorageRegister("variable", StorageTestFree); |
119 | | FAIL_IF(id2.id < 0); |
120 | | SCHostStorageId id3 = SCHostStorageRegister("store", StorageTestFree); |
121 | | FAIL_IF(id3.id < 0); |
122 | | |
123 | | FAIL_IF(SCStorageFinalize() < 0); |
124 | | |
125 | | HostInitConfig(1); |
126 | | |
127 | | Address a; |
128 | | memset(&a, 0x00, sizeof(a)); |
129 | | a.addr_data32[0] = 0x01020304; |
130 | | a.family = AF_INET; |
131 | | Host *h = HostGetHostFromHash(&a); |
132 | | FAIL_IF_NULL(h); |
133 | | |
134 | | void *ptr = SCHostGetStorageById(h, id1); |
135 | | FAIL_IF_NOT_NULL(ptr); |
136 | | ptr = SCHostGetStorageById(h, id2); |
137 | | FAIL_IF_NOT_NULL(ptr); |
138 | | ptr = SCHostGetStorageById(h, id3); |
139 | | FAIL_IF_NOT_NULL(ptr); |
140 | | |
141 | | void *ptr1a = SCMalloc(8); |
142 | | FAIL_IF_NULL(ptr1a); |
143 | | FAIL_IF(SCHostSetStorageById(h, id1, ptr1a) != 0); |
144 | | void *ptr2a = SCMalloc(24); |
145 | | FAIL_IF_NULL(ptr2a); |
146 | | FAIL_IF(SCHostSetStorageById(h, id2, ptr2a) != 0); |
147 | | void *ptr3a = SCMalloc(16); |
148 | | FAIL_IF_NULL(ptr3a); |
149 | | FAIL_IF(SCHostSetStorageById(h, id3, ptr3a) != 0); |
150 | | |
151 | | void *ptr1b = SCHostGetStorageById(h, id1); |
152 | | FAIL_IF(ptr1a != ptr1b); |
153 | | void *ptr2b = SCHostGetStorageById(h, id2); |
154 | | FAIL_IF(ptr2a != ptr2b); |
155 | | void *ptr3b = SCHostGetStorageById(h, id3); |
156 | | FAIL_IF(ptr3a != ptr3b); |
157 | | |
158 | | HostRelease(h); |
159 | | |
160 | | HostShutdown(); |
161 | | SCStorageCleanup(); |
162 | | PASS; |
163 | | } |
164 | | |
165 | | static int HostStorageTest02(void) |
166 | | { |
167 | | SCStorageCleanup(); |
168 | | SCStorageInit(); |
169 | | |
170 | | SCHostStorageId id1 = SCHostStorageRegister("test", StorageTestFree); |
171 | | FAIL_IF(id1.id < 0); |
172 | | |
173 | | FAIL_IF(SCStorageFinalize() < 0); |
174 | | |
175 | | HostInitConfig(1); |
176 | | |
177 | | Address a; |
178 | | memset(&a, 0x00, sizeof(a)); |
179 | | a.addr_data32[0] = 0x01020304; |
180 | | a.family = AF_INET; |
181 | | Host *h = HostGetHostFromHash(&a); |
182 | | FAIL_IF_NULL(h); |
183 | | |
184 | | void *ptr = SCHostGetStorageById(h, id1); |
185 | | FAIL_IF_NOT_NULL(ptr); |
186 | | |
187 | | void *ptr1a = SCMalloc(128); |
188 | | FAIL_IF_NULL(ptr1a); |
189 | | SCHostSetStorageById(h, id1, ptr1a); |
190 | | |
191 | | void *ptr1b = SCHostGetStorageById(h, id1); |
192 | | FAIL_IF(ptr1a != ptr1b); |
193 | | |
194 | | HostRelease(h); |
195 | | |
196 | | HostShutdown(); |
197 | | SCStorageCleanup(); |
198 | | PASS; |
199 | | } |
200 | | |
201 | | static int HostStorageTest03(void) |
202 | | { |
203 | | SCStorageCleanup(); |
204 | | SCStorageInit(); |
205 | | |
206 | | SCHostStorageId id1 = SCHostStorageRegister("test1", StorageTestFree); |
207 | | FAIL_IF(id1.id < 0); |
208 | | SCHostStorageId id2 = SCHostStorageRegister("test2", StorageTestFree); |
209 | | FAIL_IF(id2.id < 0); |
210 | | SCHostStorageId id3 = SCHostStorageRegister("test3", StorageTestFree); |
211 | | FAIL_IF(id3.id < 0); |
212 | | |
213 | | FAIL_IF(SCStorageFinalize() < 0); |
214 | | |
215 | | HostInitConfig(1); |
216 | | |
217 | | Address a; |
218 | | memset(&a, 0x00, sizeof(a)); |
219 | | a.addr_data32[0] = 0x01020304; |
220 | | a.family = AF_INET; |
221 | | Host *h = HostGetHostFromHash(&a); |
222 | | FAIL_IF_NULL(h); |
223 | | |
224 | | void *ptr = SCHostGetStorageById(h, id1); |
225 | | FAIL_IF_NOT_NULL(ptr); |
226 | | |
227 | | void *ptr1a = SCMalloc(128); |
228 | | FAIL_IF_NULL(ptr1a); |
229 | | SCHostSetStorageById(h, id1, ptr1a); |
230 | | |
231 | | void *ptr2a = SCMalloc(256); |
232 | | FAIL_IF_NULL(ptr2a); |
233 | | SCHostSetStorageById(h, id2, ptr2a); |
234 | | |
235 | | void *ptr3a = SCMalloc(32); |
236 | | FAIL_IF_NULL(ptr3a); |
237 | | SCHostSetStorageById(h, id3, ptr3a); |
238 | | |
239 | | void *ptr1b = SCHostGetStorageById(h, id1); |
240 | | FAIL_IF(ptr1a != ptr1b); |
241 | | void *ptr2b = SCHostGetStorageById(h, id2); |
242 | | FAIL_IF(ptr2a != ptr2b); |
243 | | void *ptr3b = SCHostGetStorageById(h, id3); |
244 | | FAIL_IF(ptr3a != ptr3b); |
245 | | |
246 | | HostRelease(h); |
247 | | |
248 | | HostShutdown(); |
249 | | SCStorageCleanup(); |
250 | | PASS; |
251 | | } |
252 | | #endif |
253 | | |
254 | | void SCRegisterHostStorageTests(void) |
255 | 0 | { |
256 | | #ifdef UNITTESTS |
257 | | UtRegisterTest("HostStorageTest01", HostStorageTest01); |
258 | | UtRegisterTest("HostStorageTest02", HostStorageTest02); |
259 | | UtRegisterTest("HostStorageTest03", HostStorageTest03); |
260 | | #endif |
261 | 0 | } |