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