1 /* Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
2 ** Copyright (C) 2010-2013 Sourcefire, Inc.
3 ** Author: Michael R. Altizer <mialtize@cisco.com>
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License Version 2 as
7 ** published by the Free Software Foundation. You may not use, modify or
8 ** distribute this program under any other version of the GNU General
9 ** Public License.
10 **
11 ** This program is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ** GNU General Public License for more details.
15 **
16 ** You should have received a copy of the GNU General Public License
17 ** along with this program; if not, write to the Free Software
18 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <stdio.h>
26 #include "daq.h"
27 #include "daq_api.h"
28
29 /*
30 * Functions that apply to instances of DAQ modules go here.
31 */
daq_initialize(const DAQ_Module_t * module,const DAQ_Config_t * config,void ** handle,char * errbuf,size_t len)32 DAQ_LINKAGE int daq_initialize(const DAQ_Module_t *module, const DAQ_Config_t *config, void **handle, char *errbuf, size_t len)
33 {
34 /* Don't do this. */
35 if (!errbuf)
36 return DAQ_ERROR;
37
38 if (!module)
39 return DAQ_ERROR_NOMOD;
40
41 if (!config)
42 {
43 snprintf(errbuf, len, "Can't initialize without a configuration!");
44 return DAQ_ERROR_INVAL;
45 }
46
47 if (!handle)
48 {
49 snprintf(errbuf, len, "Can't initialize without a context pointer!");
50 return DAQ_ERROR_INVAL;
51 }
52
53 if ((config->mode == DAQ_MODE_PASSIVE && !(module->type & DAQ_TYPE_INTF_CAPABLE)) ||
54 (config->mode == DAQ_MODE_INLINE && !(module->type & DAQ_TYPE_INLINE_CAPABLE)) ||
55 (config->mode == DAQ_MODE_READ_FILE && !(module->type & DAQ_TYPE_FILE_CAPABLE)))
56 {
57 snprintf(errbuf, len, "The %s DAQ module does not support %s mode!", module->name, daq_mode_string(config->mode));
58 return DAQ_ERROR_INVAL;
59 }
60
61
62 return module->initialize(config, handle, errbuf, len);
63 }
64
daq_set_filter(const DAQ_Module_t * module,void * handle,const char * filter)65 DAQ_LINKAGE int daq_set_filter(const DAQ_Module_t *module, void *handle, const char *filter)
66 {
67 if (!module)
68 return DAQ_ERROR_NOMOD;
69
70 if (!handle)
71 return DAQ_ERROR_NOCTX;
72
73 if (!filter)
74 {
75 module->set_errbuf(handle, "No filter string specified!");
76 return DAQ_ERROR_INVAL;
77 }
78
79 return module->set_filter(handle, filter);
80 }
81
daq_start(const DAQ_Module_t * module,void * handle)82 DAQ_LINKAGE int daq_start(const DAQ_Module_t *module, void *handle)
83 {
84 if (!module)
85 return DAQ_ERROR_NOMOD;
86
87 if (!handle)
88 return DAQ_ERROR_NOCTX;
89
90 if (module->check_status(handle) != DAQ_STATE_INITIALIZED)
91 {
92 module->set_errbuf(handle, "Can't start an instance that isn't initialized!");
93 return DAQ_ERROR;
94 }
95
96 return module->start(handle);
97 }
98
daq_acquire(const DAQ_Module_t * module,void * handle,int cnt,DAQ_Analysis_Func_t callback,void * user)99 DAQ_LINKAGE int daq_acquire(const DAQ_Module_t *module, void *handle, int cnt,
100 DAQ_Analysis_Func_t callback, void *user)
101 {
102 if (!module)
103 return DAQ_ERROR_NOMOD;
104
105 if (!handle)
106 return DAQ_ERROR_NOCTX;
107
108 if (module->check_status(handle) != DAQ_STATE_STARTED)
109 {
110 module->set_errbuf(handle, "Can't acquire packets from an instance that isn't started!");
111 return DAQ_ERROR;
112 }
113
114 return module->acquire(handle, cnt, callback, NULL, user);
115 }
116
daq_acquire_with_meta(const DAQ_Module_t * module,void * handle,int cnt,DAQ_Analysis_Func_t callback,DAQ_Meta_Func_t metaback,void * user)117 DAQ_LINKAGE int daq_acquire_with_meta(const DAQ_Module_t *module, void *handle, int cnt,
118 DAQ_Analysis_Func_t callback,
119 DAQ_Meta_Func_t metaback, void *user)
120 {
121 if (!module)
122 return DAQ_ERROR_NOMOD;
123
124 if (!handle)
125 return DAQ_ERROR_NOCTX;
126
127 if (module->check_status(handle) != DAQ_STATE_STARTED)
128 {
129 module->set_errbuf(handle, "Can't acquire packets from an instance that isn't started!");
130 return DAQ_ERROR;
131 }
132
133 return module->acquire(handle, cnt, callback, metaback, user);
134 }
135
daq_inject(const DAQ_Module_t * module,void * handle,const DAQ_PktHdr_t * hdr,const uint8_t * packet_data,uint32_t len,int reverse)136 DAQ_LINKAGE int daq_inject(const DAQ_Module_t *module, void *handle, const DAQ_PktHdr_t *hdr, const uint8_t *packet_data, uint32_t len, int reverse)
137 {
138 if (!module)
139 return DAQ_ERROR_NOMOD;
140
141 if (!handle)
142 return DAQ_ERROR_NOCTX;
143
144 if (!hdr)
145 {
146 module->set_errbuf(handle, "No originating packet header specified!");
147 return DAQ_ERROR_INVAL;
148 }
149
150 if (!packet_data)
151 {
152 module->set_errbuf(handle, "No packet data specified!");
153 return DAQ_ERROR_INVAL;
154 }
155
156 return module->inject(handle, hdr, packet_data, len, reverse);
157 }
158
daq_breakloop(const DAQ_Module_t * module,void * handle)159 DAQ_LINKAGE int daq_breakloop(const DAQ_Module_t *module, void *handle)
160 {
161 if (!module)
162 return DAQ_ERROR_NOMOD;
163
164 if (!handle)
165 return DAQ_ERROR_NOCTX;
166
167 return module->breakloop(handle);
168 }
169
daq_stop(const DAQ_Module_t * module,void * handle)170 DAQ_LINKAGE int daq_stop(const DAQ_Module_t *module, void *handle)
171 {
172 if (!module)
173 return DAQ_ERROR_NOMOD;
174
175 if (!handle)
176 return DAQ_ERROR_NOCTX;
177
178 if (module->check_status(handle) != DAQ_STATE_STARTED)
179 {
180 module->set_errbuf(handle, "Can't stop an instance that hasn't started!");
181 return DAQ_ERROR;
182 }
183
184 return module->stop(handle);
185 }
186
daq_shutdown(const DAQ_Module_t * module,void * handle)187 DAQ_LINKAGE int daq_shutdown(const DAQ_Module_t *module, void *handle)
188 {
189 if (!module)
190 return DAQ_ERROR_NOMOD;
191 if (!handle)
192 return DAQ_ERROR_NOCTX;
193
194 module->shutdown(handle);
195
196 return DAQ_SUCCESS;
197 }
198
daq_check_status(const DAQ_Module_t * module,void * handle)199 DAQ_LINKAGE DAQ_State daq_check_status(const DAQ_Module_t *module, void *handle)
200 {
201 if (!module || !handle)
202 return DAQ_STATE_UNKNOWN;
203
204 return module->check_status(handle);
205 }
206
daq_get_stats(const DAQ_Module_t * module,void * handle,DAQ_Stats_t * stats)207 DAQ_LINKAGE int daq_get_stats(const DAQ_Module_t *module, void *handle, DAQ_Stats_t *stats)
208 {
209 if (!module)
210 return DAQ_ERROR_NOMOD;
211
212 if (!handle)
213 return DAQ_ERROR_NOCTX;
214
215 if (!stats)
216 {
217 module->set_errbuf(handle, "No place to put the statistics!");
218 return DAQ_ERROR_INVAL;
219 }
220
221 return module->get_stats(handle, stats);
222 }
223
daq_reset_stats(const DAQ_Module_t * module,void * handle)224 DAQ_LINKAGE void daq_reset_stats(const DAQ_Module_t *module, void *handle)
225 {
226 if (module && handle)
227 module->reset_stats(handle);
228 }
229
daq_get_snaplen(const DAQ_Module_t * module,void * handle)230 DAQ_LINKAGE int daq_get_snaplen(const DAQ_Module_t *module, void *handle)
231 {
232 if (!module)
233 return DAQ_ERROR_NOMOD;
234
235 if (!handle)
236 return DAQ_ERROR_NOCTX;
237
238 return module->get_snaplen(handle);
239 }
240
daq_get_capabilities(const DAQ_Module_t * module,void * handle)241 DAQ_LINKAGE uint32_t daq_get_capabilities(const DAQ_Module_t *module, void *handle)
242 {
243 if (!module)
244 return DAQ_ERROR_NOMOD;
245
246 if (!handle)
247 return DAQ_ERROR_NOCTX;
248
249 return module->get_capabilities(handle);
250 }
251
daq_get_datalink_type(const DAQ_Module_t * module,void * handle)252 DAQ_LINKAGE int daq_get_datalink_type(const DAQ_Module_t *module, void *handle)
253 {
254 if (!module)
255 return DAQ_ERROR_NOMOD;
256
257 if (!handle)
258 return DAQ_ERROR_NOCTX;
259
260 return module->get_datalink_type(handle);
261 }
262
daq_get_error(const DAQ_Module_t * module,void * handle)263 DAQ_LINKAGE const char *daq_get_error(const DAQ_Module_t *module, void *handle)
264 {
265 if (!module || !handle)
266 return NULL;
267
268 return module->get_errbuf(handle);
269 }
270
daq_clear_error(const DAQ_Module_t * module,void * handle)271 DAQ_LINKAGE void daq_clear_error(const DAQ_Module_t *module, void *handle)
272 {
273 if (!module || !handle)
274 return;
275
276 module->set_errbuf(handle, "");
277 }
278
daq_get_device_index(const DAQ_Module_t * module,void * handle,const char * device)279 DAQ_LINKAGE int daq_get_device_index(const DAQ_Module_t *module, void *handle, const char *device)
280 {
281 if (!module)
282 return DAQ_ERROR_NOMOD;
283
284 if (!handle)
285 return DAQ_ERROR_NOCTX;
286
287 if (!device)
288 {
289 module->set_errbuf(handle, "No device name to find the index of!");
290 return DAQ_ERROR_INVAL;
291 }
292
293 return module->get_device_index(handle, device);
294 }
295
daq_hup_prep(const DAQ_Module_t * module,void * handle,void ** new_config)296 DAQ_LINKAGE int daq_hup_prep(const DAQ_Module_t *module, void *handle, void **new_config)
297 {
298 if (!module)
299 return DAQ_ERROR_NOMOD;
300
301 if (!handle)
302 return DAQ_ERROR_NOCTX;
303
304 if (!module->hup_prep)
305 {
306 if (!module->hup_apply)
307 return 1;
308 return DAQ_SUCCESS;
309 }
310
311 return module->hup_prep(handle, new_config);
312 }
313
daq_hup_apply(const DAQ_Module_t * module,void * handle,void * new_config,void ** old_config)314 DAQ_LINKAGE int daq_hup_apply(const DAQ_Module_t *module, void *handle, void *new_config, void **old_config)
315 {
316 if (!module)
317 return DAQ_ERROR_NOMOD;
318
319 if (!handle)
320 return DAQ_ERROR_NOCTX;
321
322 if (!module->hup_apply)
323 return DAQ_SUCCESS;
324
325 return module->hup_apply(handle, new_config, old_config);
326 }
327
daq_hup_post(const DAQ_Module_t * module,void * handle,void * old_config)328 DAQ_LINKAGE int daq_hup_post(const DAQ_Module_t *module, void *handle, void *old_config)
329 {
330 if (!module)
331 return DAQ_ERROR_NOMOD;
332
333 if (!handle)
334 return DAQ_ERROR_NOCTX;
335
336 if (!module->hup_post)
337 return DAQ_SUCCESS;
338
339 return module->hup_post(handle, old_config);
340 }
341
daq_modify_flow(const DAQ_Module_t * module,void * handle,const DAQ_PktHdr_t * hdr,const DAQ_ModFlow_t * modify)342 DAQ_LINKAGE int daq_modify_flow(const DAQ_Module_t *module, void *handle, const DAQ_PktHdr_t *hdr, const DAQ_ModFlow_t *modify)
343 {
344 if (!module)
345 return DAQ_ERROR_NOMOD;
346
347 if (!module->modify_flow)
348 return DAQ_SUCCESS;
349
350 return module->modify_flow(handle, hdr, modify);
351 }
352
daq_query_flow(const DAQ_Module_t * module,void * handle,const DAQ_PktHdr_t * hdr,DAQ_QueryFlow_t * query)353 DAQ_LINKAGE int daq_query_flow(const DAQ_Module_t *module, void *handle, const DAQ_PktHdr_t *hdr, DAQ_QueryFlow_t *query)
354 {
355 if (!module)
356 return DAQ_ERROR_NOMOD;
357
358 if (!module->query_flow)
359 return DAQ_ERROR_NOTSUP;
360
361 return module->query_flow(handle, hdr, query);
362 }
363
364 /*
365 * Functions that apply to DAQ modules themselves go here.
366 */
daq_get_name(const DAQ_Module_t * module)367 DAQ_LINKAGE const char *daq_get_name(const DAQ_Module_t *module)
368 {
369 if (!module)
370 return NULL;
371
372 return module->name;
373 }
374
daq_get_type(const DAQ_Module_t * module)375 DAQ_LINKAGE uint32_t daq_get_type(const DAQ_Module_t *module)
376 {
377 if (!module)
378 return DAQ_ERROR_NOMOD;
379
380 return module->type;
381 }
382
daq_dp_add_dc(const DAQ_Module_t * module,void * handle,const DAQ_PktHdr_t * hdr,DAQ_DP_key_t * dp_key,const uint8_t * packet_data,DAQ_Data_Channel_Params_t * params)383 DAQ_LINKAGE int daq_dp_add_dc(const DAQ_Module_t *module, void *handle, const DAQ_PktHdr_t *hdr,
384 DAQ_DP_key_t *dp_key, const uint8_t *packet_data, DAQ_Data_Channel_Params_t *params)
385 {
386 if (!module)
387 return DAQ_ERROR_NOMOD;
388
389 if (!handle)
390 return DAQ_ERROR_NOCTX;
391
392 if (!module->dp_add_dc)
393 return DAQ_SUCCESS;
394
395 return module->dp_add_dc(handle, hdr, dp_key, packet_data, params);
396 }
397