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