1 /* $Id$ */
2 /****************************************************************************
3 *
4 * Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
5 * Copyright (C) 2005-2013 Sourcefire, Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License Version 2 as
9 * published by the Free Software Foundation. You may not use, modify or
10 * distribute this program under any other version of the GNU General
11 * Public License.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 *
22 ****************************************************************************/
23
24 // @file sfdaq.c
25 // @author Russ Combs <rcombs@sourcefire.com>
26
27 #include <string.h>
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include "sfdaq.h"
34 #include "snort.h"
35 #include "decode.h"
36 #include "util.h"
37 #include "sfutil/strvec.h"
38 #include "sfcontrol_funcs.h"
39
40 #define PKT_SNAPLEN 1514
41
42 #ifdef DEFAULT_DAQ
43 #define XSTR(s) STR(s)
44 #define STR(s) #s
45 #define DAQ_DEFAULT XSTR(DEFAULT_DAQ)
46 #else
47 #define DAQ_DEFAULT "pcap"
48 #endif
49
50 #ifdef REG_TEST
51 #ifndef DAQ_CAPA_INJECT_RAW
52 #define DAQ_CAPA_INJECT_RAW 0x200
53 #endif
54 #endif
55
56 static char* interface_spec = NULL;
57 static const DAQ_Module_t* daq_mod = NULL;
58 static void* daq_hand = NULL;
59 static DAQ_Mode daq_mode = DAQ_MODE_PASSIVE;
60 static uint32_t snap = PKT_SNAPLEN;
61 static int daq_dlt = -1;
62 static int loaded = 0;
63 static int s_error = DAQ_SUCCESS;
64 static DAQ_Stats_t daq_stats, tot_stats;
65
66 uint8_t file_io_buffer1[UINT16_MAX];
67
68 static void DAQ_Accumulate(void);
69
70 typedef struct _MsgHeader_test
71 {
72 uint8_t event;
73 uint8_t version;
74 uint16_t total_length;
75 uint8_t key_type;
76 uint8_t key_size;
77 } MsgHeader_test;
78
79 #ifdef HAVE_DAQ_QUERYFLOW
Read_test(int fd,void * buf,size_t count)80 static inline ssize_t Read_test(int fd, void *buf, size_t count)
81 {
82 ssize_t n;
83 errno = 0;
84
85 while ((n = read(fd, buf, count)) <= (ssize_t) count)
86 {
87 if (n == (ssize_t) count)
88 return 0;
89
90 if (n > 0)
91 {
92 buf = (uint8_t *) buf + n;
93 count -= n;
94 }
95 else if (n == 0)
96 break;
97 else if (errno != EINTR)
98 {
99 ErrorMessage("Error reading from Stream HA message file: %s (%d)\n", strerror(errno), errno);
100 break;
101 }
102 }
103 return -1;
104 }
105 #endif
106 //--------------------------------------------------------------------
107
DAQ_Load(const SnortConfig * sc)108 void DAQ_Load (const SnortConfig* sc)
109 {
110 const char** dirs = StringVector_GetVector(sc->daq_dirs);
111
112 int err = daq_load_modules(dirs);
113
114 if ( err )
115 FatalError("Can't load DAQ modules = %d\n", err);
116
117 loaded = 1;
118 }
119
DAQ_Unload()120 void DAQ_Unload ()
121 {
122 daq_unload_modules();
123 loaded = 0;
124 }
125
126 //--------------------------------------------------------------------
127
DAQ_PrintTypes(FILE * f)128 int DAQ_PrintTypes (FILE* f)
129 {
130 DAQ_Module_Info_t* list = NULL;
131 int i, nMods = daq_get_module_list(&list);
132
133 if ( nMods )
134 fprintf(f, "Available DAQ modules:\n");
135 else
136 fprintf(f, "No available DAQ modules "
137 "(try adding directories with --daq-dir).\n");
138
139 for ( i = 0; i < nMods; i++ )
140 {
141 fprintf(f, "%s(v%u):", list[i].name, list[i].version);
142
143 if ( list[i].type & DAQ_TYPE_FILE_CAPABLE )
144 fprintf(f, " %s", "readback");
145
146 if ( list[i].type & DAQ_TYPE_INTF_CAPABLE )
147 fprintf(f, " %s", "live");
148
149 if ( list[i].type & DAQ_TYPE_INLINE_CAPABLE )
150 fprintf(f, " %s", "inline");
151
152 if ( list[i].type & DAQ_TYPE_MULTI_INSTANCE )
153 fprintf(f, " %s", "multi");
154
155 if ( !(list[i].type & DAQ_TYPE_NO_UNPRIV) )
156 fprintf(f, " %s", "unpriv");
157
158 fprintf(f, "\n");
159 }
160 daq_free_module_list(list, nMods);
161 return 0;
162 }
163
DAQ_GetInterfaceMode(const DAQ_PktHdr_t * h)164 DAQ_Mode DAQ_GetInterfaceMode(const DAQ_PktHdr_t *h)
165 {
166 #ifdef DAQ_PKT_FLAG_NOT_FORWARDING
167 // interface is not inline, so return passive
168 if (h->flags & DAQ_PKT_FLAG_NOT_FORWARDING)
169 return DAQ_MODE_PASSIVE;
170 #endif
171 // interface is inline
172 if ( ScAdapterInlineMode() )
173 {
174 return DAQ_MODE_INLINE;
175 }
176
177 // interface is passive or readback
178 return DAQ_MODE_PASSIVE;
179 }
180
DAQ_GetMode(const SnortConfig * sc)181 DAQ_Mode DAQ_GetMode (const SnortConfig* sc)
182 {
183 if ( sc->daq_mode )
184 {
185 int i;
186
187 for ( i = 0; i < MAX_DAQ_MODE; i++ )
188 {
189 if ( !strcasecmp(daq_mode_string((DAQ_Mode)i), sc->daq_mode) )
190 {
191 if ( ScAdapterInlineMode() && (i != DAQ_MODE_INLINE) )
192 FatalError("DAQ '%s' mode incompatible with -Q!\n", sc->daq_mode);
193 return (DAQ_Mode)i;
194 }
195 }
196 FatalError("Bad DAQ mode '%s'!\n", sc->daq_mode);
197 }
198 if ( ScAdapterInlineMode() )
199 return DAQ_MODE_INLINE;
200
201 if ( ScReadMode() )
202 return DAQ_MODE_READ_FILE;
203
204 return DAQ_MODE_PASSIVE;
205 }
206
207 //--------------------------------------------------------------------
208
DAQ_ValidateModule(DAQ_Mode mode)209 static int DAQ_ValidateModule (DAQ_Mode mode)
210 {
211 uint32_t have = daq_get_type(daq_mod);
212 uint32_t need = 0;
213
214 if ( mode == DAQ_MODE_READ_FILE )
215 need |= DAQ_TYPE_FILE_CAPABLE;
216
217 else if ( mode == DAQ_MODE_PASSIVE )
218 need |= DAQ_TYPE_INTF_CAPABLE;
219
220 else
221 need |= DAQ_TYPE_INLINE_CAPABLE;
222
223 return ( (have & need) != 0 );
224 }
225
DAQ_ValidateInstance()226 static int DAQ_ValidateInstance ()
227 {
228 uint32_t caps = daq_get_capabilities(daq_mod, daq_hand);
229
230 if ( !ScAdapterInlineMode() )
231 return 1;
232
233 if ( !(caps & DAQ_CAPA_BLOCK) )
234 LogMessage("WARNING: inline mode configured but DAQ can't "
235 "block packets.\n");
236
237 #if 0
238 // this is checked in normalize.c and sp_respond.c
239 // and warned/disabled only if it was configured
240 if ( !(caps & DAQ_CAPA_REPLACE) )
241 {
242 LogMessage("WARNING: normalizations/replacements disabled "
243 " because DAQ can't replace packets.\n");
244 }
245
246 // this is checked in spp_stream5.c and active.c
247 // and warned/disabled only if it was configured
248 if ( !(caps & DAQ_CAPA_INJECT) )
249 LogMessage("WARNING: inline mode configured but DAQ can't "
250 "inject packets.\n");
251 #endif
252
253 return 1;
254 }
255
DAQ_UpdateTunnelBypass(SnortConfig * sc)256 void DAQ_UpdateTunnelBypass(SnortConfig* sc)
257 {
258 #ifdef HAVE_DAQ_REAL_ADDRESSES
259
260 if (daq_mod && daq_hand)
261 {
262 uint32_t caps = daq_get_capabilities(daq_mod, daq_hand);
263
264 if (caps & DAQ_CAPA_DECODE_GTP)
265 {
266 sc->tunnel_mask |= TUNNEL_GTP;
267 LogMessage("DAQ tracking internal GTP sessions.\n");
268 }
269 if (caps & DAQ_CAPA_DECODE_TEREDO)
270 {
271 sc->tunnel_mask |= TUNNEL_TEREDO;
272 LogMessage("DAQ tracking internal TEREDO sessions.\n");
273 }
274 if (caps & DAQ_CAPA_DECODE_GRE)
275 {
276 sc->tunnel_mask |= TUNNEL_GRE;
277 LogMessage("DAQ tracking internal GRE sessions.\n");
278 }
279 if (caps & DAQ_CAPA_DECODE_4IN4)
280 {
281 sc->tunnel_mask |= TUNNEL_4IN4;
282 LogMessage("DAQ tracking internal IPv4 within IPv4 sessions.\n");
283 }
284 if (caps & DAQ_CAPA_DECODE_6IN4)
285 {
286 sc->tunnel_mask |= TUNNEL_6IN4;
287 LogMessage("DAQ tracking internal IPv6 within IPv4 sessions.\n");
288 }
289 if (caps & DAQ_CAPA_DECODE_4IN6)
290 {
291 sc->tunnel_mask |= TUNNEL_4IN6;
292 LogMessage("DAQ tracking internal IPv4 within IPv6 sessions.\n");
293 }
294 if (caps & DAQ_CAPA_DECODE_6IN6)
295 {
296 sc->tunnel_mask |= TUNNEL_6IN6;
297 LogMessage("DAQ tracking internal IPv6 within IPv6 sessions.\n");
298 }
299 #ifdef DAQ_CAPA_DECODE_MPLS
300 if (caps & DAQ_CAPA_DECODE_MPLS)
301 {
302 sc->tunnel_mask |= TUNNEL_MPLS;
303 LogMessage("DAQ tracking internal MPLS sessions.\n");
304 }
305 #endif
306 }
307
308 #endif
309 }
310
311 //--------------------------------------------------------------------
312
313 #if HAVE_DAQ_HUP_APPLY
DAQ_PreControl(uint16_t type,const uint8_t * data,uint32_t length,void ** new_config,char * statusBuf,int statusBuf_len)314 static int DAQ_PreControl(uint16_t type, const uint8_t *data, uint32_t length, void **new_config, char *statusBuf, int statusBuf_len)
315 {
316 if (daq_mod && daq_hand)
317 return daq_hup_prep(daq_mod, daq_hand, new_config);
318 return -1;
319 }
320
DAQ_Control(uint16_t type,void * new_config,void ** old_config)321 static int DAQ_Control(uint16_t type, void *new_config, void **old_config)
322 {
323 if (daq_mod && daq_hand)
324 return daq_hup_apply(daq_mod, daq_hand, new_config, old_config);
325 return -1;
326 }
327
DAQ_PostControl(uint16_t type,void * old_config,struct _THREAD_ELEMENT * te,ControlDataSendFunc f)328 static void DAQ_PostControl(uint16_t type, void *old_config, struct _THREAD_ELEMENT *te, ControlDataSendFunc f)
329 {
330 if (daq_mod && daq_hand)
331 daq_hup_post(daq_mod, daq_hand, old_config);
332 }
333 #endif
334
335 //--------------------------------------------------------------------
336
DAQ_Init(const SnortConfig * sc)337 void DAQ_Init (const SnortConfig* sc)
338 {
339 const char* type = DAQ_DEFAULT;
340 if ( !loaded )
341 DAQ_Load(sc);
342
343 if ( sc->daq_type ) type = sc->daq_type;
344
345 daq_mod = daq_find_module(type);
346
347 if ( !daq_mod )
348 FatalError("Can't find %s DAQ!\n", type);
349
350 snap = ( sc->pkt_snaplen > 0 ) ? sc->pkt_snaplen : PKT_SNAPLEN;
351 daq_mode = DAQ_GetMode(sc);
352
353 if ( !DAQ_ValidateModule(daq_mode) )
354 FatalError("%s DAQ does not support %s.\n",
355 type, daq_mode_string(daq_mode));
356
357 memset(&daq_stats, 0, sizeof(daq_stats));
358 memset(&tot_stats, 0, sizeof(tot_stats));
359
360 LogMessage("%s DAQ configured to %s.\n",
361 type, daq_mode_string(daq_mode));
362
363 #if HAVE_DAQ_HUP_APPLY
364 if (ControlSocketRegisterHandler(CS_TYPE_HUP_DAQ, &DAQ_PreControl, &DAQ_Control, &DAQ_PostControl))
365 {
366 LogMessage("Failed to register the DAQ control handler.\n");
367 }
368 #else
369 LogMessage("The DAQ version does not support reload.\n");
370 #endif
371 }
372
DAQ_Term()373 void DAQ_Term ()
374 {
375 #ifndef WIN32
376 # ifndef DISABLE_DLCLOSE_FOR_VALGRIND_TESTING
377 if ( loaded )
378 DAQ_Unload();
379 daq_mod = NULL;
380 # endif
381 #endif
382 }
383
DAQ_Abort()384 void DAQ_Abort ()
385 {
386 if ( DAQ_WasStarted() )
387 DAQ_Stop();
388
389 DAQ_Delete();
390 DAQ_Term();
391 }
392
393 //--------------------------------------------------------------------
394
DAQ_GetInterfaceSpec(void)395 const char* DAQ_GetInterfaceSpec (void)
396 {
397 return interface_spec ? interface_spec : "";
398 }
399
DAQ_GetType(void)400 const char* DAQ_GetType(void)
401 {
402 return daq_mod ? daq_get_name(daq_mod) : "error";
403 }
404
405 // Snort has its own snap applied to packets it acquires via the DAQ. This
406 // should not be confused with the snap that was used to capture a pcap which
407 // may be different.
DAQ_GetSnapLen(void)408 uint32_t DAQ_GetSnapLen (void)
409 {
410 return snap;
411 }
412
413 // That distinction does not hold with datalink types. Snort must use whatever
414 // datalink type the DAQ coughs up as its base protocol decoder. For pcaps,
415 // the datalink type in the file must be used - which may not be known until
416 // start. The value is cached here since it used for packet operations like
417 // logging and is needed at shutdown. this avoids sequencing issues.
DAQ_GetBaseProtocol(void)418 int DAQ_GetBaseProtocol (void)
419 {
420 return daq_dlt;
421 }
422
DAQ_Unprivileged(void)423 int DAQ_Unprivileged (void)
424 {
425 return !( daq_get_type(daq_mod) & DAQ_TYPE_NO_UNPRIV );
426 }
427
DAQ_UnprivilegedStart(void)428 int DAQ_UnprivilegedStart (void)
429 {
430 #ifdef INLINE_FAILOPEN
431 return ( (daq_get_capabilities(daq_mod, daq_hand) & DAQ_CAPA_UNPRIV_START) || (ScUid() == -1 && ScGid() == -1) );
432 #else
433 return ( (daq_get_capabilities(daq_mod, daq_hand) & DAQ_CAPA_UNPRIV_START) );
434 #endif
435 }
436
DAQ_CanReplace(void)437 int DAQ_CanReplace (void)
438 {
439 return ( daq_get_capabilities(daq_mod, daq_hand) & DAQ_CAPA_REPLACE );
440 }
441
DAQ_CanInject(void)442 int DAQ_CanInject (void)
443 {
444 return ( daq_get_capabilities(daq_mod, daq_hand) & DAQ_CAPA_INJECT );
445 }
446
DAQ_GetCapabilities(void)447 uint32_t DAQ_GetCapabilities(void)
448 {
449 return ( daq_get_capabilities(daq_mod, daq_hand));
450 }
451
452 #if defined(DAQ_CAPA_CST_TIMEOUT)
DAQ_CanGetTimeout(void)453 int DAQ_CanGetTimeout(void)
454 {
455 return ( daq_get_capabilities(daq_mod, daq_hand) & DAQ_CAPA_CST_TIMEOUT);
456 }
457 #endif
458
459 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
DAQ_CanGetVrf(void)460 int DAQ_CanGetVrf(void)
461 {
462 return ( daq_get_capabilities(daq_mod, daq_hand) & DAQ_CAPA_VRF );
463 }
464 #endif
465
DAQ_CanWhitelist(void)466 int DAQ_CanWhitelist (void)
467 {
468 #ifdef DAQ_CAPA_WHITELIST
469 return ( daq_get_capabilities(daq_mod, daq_hand) & DAQ_CAPA_WHITELIST );
470 #else
471 return 0;
472 #endif
473 }
474
DAQ_CanRetry(void)475 int DAQ_CanRetry (void)
476 {
477 #ifdef HAVE_DAQ_VERDICT_RETRY
478 return ( daq_get_capabilities(daq_mod, daq_hand) & DAQ_CAPA_RETRY );
479 #else
480 return 0;
481 #endif
482 }
483
DAQ_RawInjection(void)484 int DAQ_RawInjection (void)
485 {
486 return ( daq_get_capabilities(daq_mod, daq_hand) & DAQ_CAPA_INJECT_RAW );
487 }
488
DAQ_SetFilter(const char * bpf)489 int DAQ_SetFilter(const char* bpf)
490 {
491 int err = 0;
492
493 if ( bpf )
494 err = daq_set_filter(daq_mod, daq_hand, bpf);
495
496 if ( err )
497 FatalError("Can't set DAQ BPF filter to '%s' (%s)!\n",
498 bpf, daq_get_error(daq_mod, daq_hand));
499
500 return err;
501 }
502
503 //--------------------------------------------------------------------
504
DAQ_LoadVars(DAQ_Config_t * cfg,const SnortConfig * sc)505 static void DAQ_LoadVars (DAQ_Config_t* cfg, const SnortConfig* sc)
506 {
507 unsigned i = 0;
508
509 do
510 {
511 char* key = StringVector_Get(sc->daq_vars, i++);
512 char* val = NULL;
513
514 if ( !key )
515 break;
516
517 val = strchr(key, '=');
518
519 if ( val )
520 *val++ = '\0';
521
522 daq_config_set_value(cfg, key, val);
523
524 if ( val )
525 *--val = '=';
526 }
527 while ( 1 );
528 }
529
DAQ_Config(DAQ_Config_t * cfg)530 static int DAQ_Config (DAQ_Config_t* cfg)
531 {
532 int err;
533 char buf[256] = "";
534 const char* type = daq_get_name(daq_mod);
535
536 // ideally this would be configurable ...
537 if ( !strcasecmp(type, "dump") )
538 cfg->extra = (char*)daq_find_module("pcap");
539
540 err = daq_initialize(daq_mod, cfg, &daq_hand, buf, sizeof(buf));
541
542 if ( err )
543 FatalError("Can't initialize DAQ %s (%d) - %s\n",
544 type, err, buf);
545
546 return err;
547 }
548
549 //--------------------------------------------------------------------
550
DAQ_New(const SnortConfig * sc,const char * intf)551 int DAQ_New (const SnortConfig* sc, const char* intf)
552 {
553 DAQ_Config_t cfg;
554
555 if ( !daq_mod )
556 FatalError("DAQ_Init not called!\n");
557
558 if ( intf )
559 interface_spec = SnortStrdup(intf);
560 intf = DAQ_GetInterfaceSpec();
561
562 memset(&cfg, 0, sizeof(cfg));
563 cfg.name = (char*)intf;
564 cfg.snaplen = snap;
565 cfg.timeout = PKT_TIMEOUT;
566 cfg.mode = daq_mode;
567 cfg.extra = NULL;
568 cfg.flags = 0;
569
570 DAQ_LoadVars(&cfg, sc);
571
572 if ( !ScReadMode() )
573 {
574 if ( !(sc->run_flags & RUN_FLAG__NO_PROMISCUOUS) )
575 cfg.flags |= DAQ_CFG_PROMISC;
576 }
577
578 DAQ_Config(&cfg);
579
580 if ( !DAQ_ValidateInstance() )
581 FatalError("DAQ configuration incompatible with intended operation.\n");
582
583 if ( DAQ_UnprivilegedStart() )
584 daq_dlt = daq_get_datalink_type(daq_mod, daq_hand);
585
586 if ( intf && *intf )
587 {
588 LogMessage("Acquiring network traffic from \"%s\".\n",
589 strcmp(intf, "-") == 0 ? "stdin" : intf);
590 }
591 DAQ_SetFilter(sc->bpf_filter);
592 daq_config_clear_values(&cfg);
593
594 return 0;
595 }
596
DAQ_Delete(void)597 int DAQ_Delete(void)
598 {
599 if ( daq_hand )
600 {
601 DAQ_Accumulate();
602 daq_shutdown(daq_mod, daq_hand);
603 daq_hand = NULL;
604 }
605 if ( interface_spec )
606 {
607 free(interface_spec);
608 interface_spec = NULL;
609 }
610 return 0;
611 }
612
613 //--------------------------------------------------------------------
614
DAQ_Start()615 int DAQ_Start ()
616 {
617 int err = daq_start(daq_mod, daq_hand);
618
619 if ( err )
620 FatalError("Can't start DAQ (%d) - %s!\n",
621 err, daq_get_error(daq_mod, daq_hand));
622
623 else if ( !DAQ_UnprivilegedStart() )
624 daq_dlt = daq_get_datalink_type(daq_mod, daq_hand);
625
626 return err;
627 }
628
DAQ_WasStarted(void)629 int DAQ_WasStarted (void)
630 {
631 DAQ_State s;
632
633 if ( !daq_mod || !daq_hand )
634 return 0;
635
636 s = daq_check_status(daq_mod, daq_hand);
637
638 return ( DAQ_STATE_STARTED == s );
639 }
640
DAQ_Stop()641 int DAQ_Stop ()
642 {
643 int err = daq_stop(daq_mod, daq_hand);
644
645 if ( err )
646 LogMessage("Can't stop DAQ (%d) - %s!\n",
647 err, daq_get_error(daq_mod, daq_hand));
648
649 return err;
650 }
651
652 //--------------------------------------------------------------------
653
654 #ifdef HAVE_DAQ_ACQUIRE_WITH_META
655 static DAQ_Meta_Func_t daq_meta_callback = NULL;
DAQ_Set_MetaCallback(DAQ_Meta_Func_t meta_callback)656 void DAQ_Set_MetaCallback(DAQ_Meta_Func_t meta_callback)
657 {
658 daq_meta_callback = meta_callback;
659 }
660 #endif
661
DAQ_Acquire(int max,DAQ_Analysis_Func_t callback,uint8_t * user)662 int DAQ_Acquire (int max, DAQ_Analysis_Func_t callback, uint8_t* user)
663 {
664 #if HAVE_DAQ_ACQUIRE_WITH_META
665 int err = daq_acquire_with_meta(daq_mod, daq_hand, max, callback, daq_meta_callback, user);
666 #else
667 int err = daq_acquire(daq_mod, daq_hand, max, callback, user);
668 #endif
669
670 if ( err && err != DAQ_READFILE_EOF )
671 LogMessage("Can't acquire (%d) - %s!\n",
672 err, daq_get_error(daq_mod, daq_hand));
673
674 if ( s_error != DAQ_SUCCESS )
675 {
676 err = s_error;
677 s_error = DAQ_SUCCESS;
678 }
679 return err;
680 }
681
DAQ_Inject(const DAQ_PktHdr_t * h,int rev,const uint8_t * buf,uint32_t len)682 int DAQ_Inject(const DAQ_PktHdr_t* h, int rev, const uint8_t* buf, uint32_t len)
683 {
684 int err = daq_inject(daq_mod, daq_hand, (DAQ_PktHdr_t*)h, buf, len, rev);
685 #ifdef DEBUG
686 if ( err )
687 LogMessage("Can't inject (%d) - %s!\n",
688 err, daq_get_error(daq_mod, daq_hand));
689 #endif
690 return err;
691 }
692
DAQ_BreakLoop(int error)693 int DAQ_BreakLoop (int error)
694 {
695 s_error = error;
696 return ( daq_breakloop(daq_mod, daq_hand) == DAQ_SUCCESS );
697 }
698
699 //--------------------------------------------------------------------
700
DAQ_Accumulate(void)701 static void DAQ_Accumulate (void)
702 {
703 int i;
704 const DAQ_Stats_t* ps = DAQ_GetStats();
705
706 tot_stats.hw_packets_received += ps->hw_packets_received;
707 tot_stats.hw_packets_dropped += ps->hw_packets_dropped;
708 tot_stats.packets_received += ps->packets_received;
709 tot_stats.packets_filtered += ps->packets_filtered;
710 tot_stats.packets_injected += ps->packets_injected;
711
712 for ( i = 0; i < MAX_DAQ_VERDICT; i++ )
713 tot_stats.verdicts[i] += ps->verdicts[i];
714 }
715
716 // returns statically allocated stats - don't free
DAQ_GetStats(void)717 const DAQ_Stats_t* DAQ_GetStats (void)
718 {
719 int err = 0;
720
721 if ( !daq_hand && !ScPcapReset() )
722 return &tot_stats;
723
724 if ( !daq_hand )
725 return &daq_stats;
726
727 err = daq_get_stats(daq_mod, daq_hand, &daq_stats);
728
729 if ( err )
730 LogMessage("Can't get DAQ stats (%d) - %s!\n",
731 err, daq_get_error(daq_mod, daq_hand));
732
733 if ( !daq_stats.hw_packets_received )
734 // some DAQs don't provide hw numbers
735 // so we default hw rx to the sw equivalent
736 // (this means outstanding packets = 0)
737 daq_stats.hw_packets_received =
738 daq_stats.packets_received + daq_stats.packets_filtered;
739
740 return &daq_stats;
741 }
742
743 //--------------------------------------------------------------------
744
745 #ifdef HAVE_DAQ_EXT_MODFLOW
DAQ_ModifyFlowOpaque(const DAQ_PktHdr_t * hdr,uint32_t opaque)746 int DAQ_ModifyFlowOpaque(const DAQ_PktHdr_t *hdr, uint32_t opaque)
747 {
748 DAQ_ModFlow_t mod;
749
750 mod.type = DAQ_MODFLOW_TYPE_OPAQUE;
751 mod.length = sizeof(opaque);
752 mod.value = &opaque;
753
754 return daq_modify_flow(daq_mod, daq_hand, hdr, &mod);
755 }
756
DAQ_ModifyFlowHAState(const DAQ_PktHdr_t * hdr,const void * data,uint32_t length)757 int DAQ_ModifyFlowHAState(const DAQ_PktHdr_t *hdr, const void *data, uint32_t length)
758 {
759 #ifdef REG_TEST
760 return 0;
761 #else
762 DAQ_ModFlow_t mod;
763
764 mod.type = DAQ_MODFLOW_TYPE_HA_STATE;
765 mod.length = length;
766 mod.value = data;
767 return daq_modify_flow(daq_mod, daq_hand, hdr, &mod);
768 #endif
769 }
770
DAQ_ModifyFlow(const DAQ_PktHdr_t * hdr,const DAQ_ModFlow_t * mod)771 int DAQ_ModifyFlow(const DAQ_PktHdr_t *hdr, const DAQ_ModFlow_t* mod)
772 {
773 return daq_modify_flow(daq_mod, daq_hand, hdr, mod);
774 }
775 #else
DAQ_ModifyFlowOpaque(const DAQ_PktHdr_t * hdr,uint32_t opaque)776 int DAQ_ModifyFlowOpaque(const DAQ_PktHdr_t *hdr, uint32_t opaque)
777 {
778 #ifdef HAVE_DAQ_ACQUIRE_WITH_META
779 DAQ_ModFlow_t mod;
780
781 mod.opaque = opaque;
782 return daq_modify_flow(daq_mod, daq_hand, hdr, &mod);
783 #else
784 return DAQ_ERROR_NOTSUP;
785 #endif
786 }
787 #endif
788
789 #ifdef HAVE_DAQ_QUERYFLOW
790 #ifndef REG_TEST
DAQ_QueryFlow(const DAQ_PktHdr_t * hdr,DAQ_QueryFlow_t * query)791 int DAQ_QueryFlow(const DAQ_PktHdr_t *hdr, DAQ_QueryFlow_t* query)
792 {
793 return daq_query_flow(daq_mod, daq_hand, hdr, query);
794 }
795 #else
DAQ_QueryFlow(DAQ_PktHdr_t * hdr,DAQ_QueryFlow_t * query)796 int DAQ_QueryFlow(DAQ_PktHdr_t *hdr, DAQ_QueryFlow_t* query)
797 {
798 int rval,fd;
799 MsgHeader_test *msg_header;
800 uint8_t *msg;
801 #if defined DAQ_QUERYFLOW_TYPE_IS_CONN_META_VALID
802 if (query->type == DAQ_QUERYFLOW_TYPE_IS_CONN_META_VALID)
803 return DAQ_ERROR_NOTSUP;
804 #endif
805
806 fd = * ((int * )hdr->priv_ptr);
807 if (fd < 0)
808 {
809 return -1;
810 }
811
812 msg = file_io_buffer1;
813 while ((rval = Read_test(fd, msg, sizeof(*msg_header))) == 0)
814 {
815 msg_header = (MsgHeader_test *) msg;
816 if (msg_header->total_length < sizeof(*msg_header))
817 {
818 ErrorMessage("Stream HA Message total length (%hu) is way too short!\n", msg_header->total_length);
819 close(fd);
820 return -1;
821 }
822 else if (msg_header->total_length > (UINT16_MAX - sizeof(*msg_header)))
823 {
824 ErrorMessage("Stream HA Message total length (%hu) is too long!\n", msg_header->total_length);
825 close(fd);
826 return -1;
827 }
828 else if (msg_header->total_length > sizeof(*msg_header) && (query->type == DAQ_QUERYFLOW_TYPE_HA_STATE))
829 {
830 if ((rval = Read_test(fd, msg + sizeof(*msg_header), msg_header->total_length - sizeof(*msg_header))) != 0)
831 {
832 ErrorMessage("Error reading the remaining %zu bytes of an HA message from file: %s (%d)\n",
833 msg_header->total_length - sizeof(*msg_header), strerror(errno), errno);
834 close(fd);
835 return rval;
836 }
837 DAQ_HA_State_Data_t *haState;
838 haState = (DAQ_HA_State_Data_t *)query->value;
839 haState->length = msg_header->total_length;
840 haState->data = msg_header;
841 return 0;
842 }
843 }
844 return 0;
845 }
846 #endif
847 #endif
848
849 #if defined(DAQ_VERSION) && DAQ_VERSION > 8
DAQ_DebugPkt(uint8_t moduleId,uint8_t logLevel,const DAQ_Debug_Packet_Params_t * params,const char * msg,...)850 void DAQ_DebugPkt(uint8_t moduleId, uint8_t logLevel, const DAQ_Debug_Packet_Params_t *params, const char *msg, ...)
851 {
852 #ifdef LOGC_DEBUG_PACKET
853 va_list args_copy;
854 va_start(args_copy, msg);
855
856 daq_debug_packet(daq_mod,daq_hand, moduleId, logLevel, params, msg, args_copy);
857
858 va_end(args_copy);
859 #else
860 {
861 //do nothing here.
862 }
863 #endif
864 }
865 #endif
866
867 #ifdef HAVE_DAQ_DP_ADD_DC
868 /*
869 * Initialize key for dynamic channel and call daq api method to notify firmware
870 * of the expected dynamic channel.
871 */
DAQ_Add_Dynamic_Protocol_Channel(const Packet * ctrlPkt,sfaddr_t * cliIP,uint16_t cliPort,sfaddr_t * srvIP,uint16_t srvPort,uint8_t protocol,DAQ_DC_Params * params)872 void DAQ_Add_Dynamic_Protocol_Channel(const Packet *ctrlPkt, sfaddr_t* cliIP, uint16_t cliPort,
873 sfaddr_t* srvIP, uint16_t srvPort, uint8_t protocol,
874 DAQ_DC_Params* params)
875 {
876
877 DAQ_DP_key_t dp_key;
878 #ifdef HAVE_DAQ_DATA_CHANNEL_SEPARATE_IP_VERSIONS
879 dp_key.src_af = sfaddr_family(cliIP);
880 if (AF_INET == dp_key.src_af)
881 {
882 dp_key.sa.src_ip4.s_addr = sfaddr_get_ip4_value(cliIP);
883 }
884 else
885 {
886 memcpy(&dp_key.sa.src_ip6, sfaddr_get_ip6_ptr(cliIP), sizeof(dp_key.sa.src_ip6));
887 }
888 dp_key.dst_af = sfaddr_family(srvIP);
889 if (AF_INET == dp_key.dst_af)
890 {
891 dp_key.da.dst_ip4.s_addr = sfaddr_get_ip4_value(srvIP);
892 }
893 else
894 {
895 memcpy(&dp_key.da.dst_ip6, sfaddr_get_ip6_ptr(srvIP), sizeof(dp_key.da.dst_ip6));
896 }
897 #else
898 dp_key.af = sfaddr_family(cliIP);
899 if( dp_key.af == AF_INET )
900 {
901 dp_key.sa.src_ip4.s_addr = sfaddr_get_ip4_value(cliIP);
902 dp_key.da.dst_ip4.s_addr = sfaddr_get_ip4_value(srvIP);
903 }
904 else
905 {
906 memcpy( &dp_key.sa.src_ip6, sfaddr_get_ip6_ptr(cliIP), sizeof( dp_key.sa.src_ip6 ) );
907 memcpy( &dp_key.da.dst_ip6, sfaddr_get_ip6_ptr(srvIP), sizeof( dp_key.da.dst_ip6 ) );
908 }
909 #endif
910
911 dp_key.protocol = protocol;
912 dp_key.src_port = cliPort;
913 dp_key.dst_port = srvPort;
914 dp_key.vlan_cnots = 1;
915 if( ctrlPkt->vh )
916 dp_key.vlan_id = VTH_VLAN( ctrlPkt->vh );
917 else
918 dp_key.vlan_id = 0xFFFF;
919
920 if( ctrlPkt->GTPencapsulated )
921 dp_key.tunnel_type = DAQ_DP_TUNNEL_TYPE_GTP_TUNNEL;
922 #ifdef DAQ_DP_TUNNEL_TYPE_MPLS_TUNNEL
923 else if ( ctrlPkt->mpls )
924 dp_key.tunnel_type = DAQ_DP_TUNNEL_TYPE_MPLS_TUNNEL;
925 #endif
926 #ifdef DAQ_DP_TUNNEL_TYPE_GRE_TUNNEL
927 // Checking non_ip_pkt to make sure eth-ip-gre-pppoe case doesn't hit
928 else if ( ctrlPkt->GREencapsulated && !ctrlPkt->non_ip_pkt)
929 dp_key.tunnel_type = DAQ_DP_TUNNEL_TYPE_GRE_TUNNEL;
930 #endif
931 #ifdef DAQ_DP_TUNNEL_TYPE_IPnIP_TUNNEL
932 else if ( ctrlPkt->IPnIPencapsulated )
933 dp_key.tunnel_type = DAQ_DP_TUNNEL_TYPE_IPnIP_TUNNEL;
934 #endif
935 else if ( ctrlPkt->encapsulated )
936 dp_key.tunnel_type = DAQ_DP_TUNNEL_TYPE_OTHER_TUNNEL;
937 else
938 dp_key.tunnel_type = DAQ_DP_TUNNEL_TYPE_NON_TUNNEL;
939
940 // notify the firmware to add expected flow for this dynamic channel
941 #ifdef HAVE_DAQ_DATA_CHANNEL_PARAMS
942 {
943 DAQ_Data_Channel_Params_t daq_params;
944
945 memset(&daq_params, 0, sizeof(daq_params));
946 daq_params.timeout_ms = params->timeout_ms;
947 if (params->flags & DAQ_DC_FLOAT)
948 daq_params.flags |= DAQ_DATA_CHANNEL_FLOAT;
949 if (params->flags & DAQ_DC_ALLOW_MULTIPLE)
950 daq_params.flags |= DAQ_DATA_CHANNEL_ALLOW_MULTIPLE;
951 if (params->flags & DAQ_DC_PERSIST)
952 daq_params.flags |= DAQ_DATA_CHANNEL_PERSIST;
953 daq_dp_add_dc(daq_mod, daq_hand, ctrlPkt->pkth, &dp_key, ctrlPkt->pkt,
954 &daq_params);
955 }
956 #else
957 daq_dp_add_dc( daq_mod, daq_hand, ctrlPkt->pkth, &dp_key, ctrlPkt->pkt );
958 #endif
959 }
960 #endif
961
962 #if defined(DAQ_VERSION) && DAQ_VERSION > 9
DAQ_Ioctl(unsigned int type,char * buf,size_t * size)963 int DAQ_Ioctl(unsigned int type, char *buf, size_t *size)
964 {
965 return daq_ioctl(daq_mod, daq_hand, type, buf, size);
966 }
967 #endif
968