suricata
source-pcap-file-helper.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2020 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 Danny Browning <danny.browning@protectwise.com>
22  *
23  * File based pcap packet acquisition support
24  */
25 
27 #include "suricata.h"
28 #include "util-datalink.h"
29 #include "util-checksum.h"
30 #include "util-profiling.h"
31 #include "util-exception-policy.h"
32 #include "conf-yaml-loader.h"
33 #include "capture-hooks.h"
34 #include "threads.h"
35 
36 extern uint32_t max_pending_packets;
38 
39 static PcapFileFileVars *pcap_current_pfv = NULL;
40 
41 static void PcapFileCallbackLoop(char *user, struct pcap_pkthdr *h, u_char *pkt);
42 
43 static void PcapFileReleasePacket(Packet *p)
44 {
45  PcapFileFileVars *pfv = p->pcap_v.pfv;
46  if (pfv != NULL) {
48  }
49 
51 }
52 
54 {
55  PcapFileFileVars *pfv = p->pcap_v.pfv;
56  /* Alerts are counted in PacketAlertFinalize via PcapFileAddAlertCount, so
57  * avoid double-counting here. Decrement refcount if we held one. */
58  if (pfv != NULL) {
59  uint32_t prev = SC_ATOMIC_SUB(pfv->ref_cnt, 1);
60  if (prev == 1 && pfv->cleanup_requested) {
62  }
63  }
65 }
66 
68 {
69  if (pfv == NULL) {
70  return;
71  }
72 
73  /* If there are still packets in flight, defer ALL cleanup actions, including
74  * the deletion decision, until the last packet completes. */
75  if (SC_ATOMIC_GET(pfv->ref_cnt) != 0) {
76  pfv->cleanup_requested = true;
77  return;
78  }
79 
80  /* No packets in flight anymore: it's now safe to close, decide, and delete. */
81  if (pfv->pcap_handle != NULL) {
82  pcap_close(pfv->pcap_handle);
83  pfv->pcap_handle = NULL;
84  }
85 
86  if (pfv->filename != NULL) {
88  SCLogDebug("Deleting pcap file %s", pfv->filename);
89  if (unlink(pfv->filename) != 0) {
90  SCLogWarning("Failed to delete %s: %s", pfv->filename, strerror(errno));
91  }
92  }
93  SCFree(pfv->filename);
94  pfv->filename = NULL;
95  }
96 
97  pfv->shared = NULL;
98  if (pcap_current_pfv == pfv) {
99  pcap_current_pfv = NULL;
100  }
101  SCFree(pfv);
102 }
103 
104 void PcapFileCallbackLoop(char *user, struct pcap_pkthdr *h, u_char *pkt)
105 {
106  SCEnter();
107 #ifdef DEBUG
108  if (unlikely((pcap_g.cnt + 1ULL) == g_eps_pcap_packet_loss)) {
109  SCLogNotice("skipping packet %" PRIu64, g_eps_pcap_packet_loss);
110  pcap_g.cnt++;
111  SCReturn;
112  }
113 #endif
114  PcapFileFileVars *ptv = (PcapFileFileVars *)user;
116 
117  if (unlikely(p == NULL)) {
118  SCReturn;
119  }
120  SC_ATOMIC_ADD(ptv->ref_cnt, 1);
121  SCLogDebug("pcap-file: got packet, pfv=%p filename=%s ref_cnt now=%u p=%p", (void *)ptv,
122  ptv->filename, SC_ATOMIC_GET(ptv->ref_cnt), (void *)p);
123 
125 
127  p->ts = SCTIME_FROM_TIMEVAL_UNTRUSTED(&h->ts);
128  SCLogDebug("p->ts.tv_sec %" PRIuMAX "", (uintmax_t)SCTIME_SECS(p->ts));
129  p->datalink = ptv->datalink;
130  p->pcap_v.pcap_cnt = ++pcap_g.cnt;
131 
132  p->pcap_v.tenant_id = ptv->shared->tenant_id;
133  p->pcap_v.pfv = ptv;
134  ptv->shared->pkts++;
135  ptv->shared->bytes += h->caplen;
136 
137  p->ReleasePacket = PcapFileReleasePacket;
138 
139  if (unlikely(PacketCopyData(p, pkt, h->caplen))) {
140  TmqhOutputPacketpool(ptv->shared->tv, p);
142  SCReturn;
143  }
144 
145  /* We only check for checksum disable */
149  if (ChecksumAutoModeCheck(ptv->shared->pkts, p->pcap_v.pcap_cnt,
150  SC_ATOMIC_GET(pcap_g.invalid_checksums))) {
153  }
154  }
155 
157 
158  if (TmThreadsSlotProcessPkt(ptv->shared->tv, ptv->shared->slot, p) != TM_ECODE_OK) {
159  pcap_breakloop(ptv->pcap_handle);
160  ptv->shared->cb_result = TM_ECODE_FAILED;
161  }
162 
163  SCReturn;
164 }
165 
166 char pcap_filename[PATH_MAX] = "unknown";
167 
168 const char *PcapFileGetFilename(void)
169 {
170  return pcap_filename;
171 }
172 
174 {
175  pcap_current_pfv = pfv;
176 }
177 
179 {
180  return pcap_current_pfv;
181 }
182 
183 /**
184  * \brief Main PCAP file reading Loop function
185  */
187 {
188  SCEnter();
189 
191  /* initialize all the thread's initial timestamp */
192  if (likely(ptv->first_pkt_hdr != NULL)) {
194  PcapFileCallbackLoop((char *)ptv, ptv->first_pkt_hdr,
195  (u_char *)ptv->first_pkt_data);
196  ptv->first_pkt_hdr = NULL;
197  ptv->first_pkt_data = NULL;
198  }
199 
200  int packet_q_len = 64;
201  TmEcode loop_result = TM_ECODE_OK;
203 
204  while (loop_result == TM_ECODE_OK) {
207  }
208 
209  /* make sure we have at least one packet in the packet pool, to prevent
210  * us from alloc'ing packets at line rate */
211  PacketPoolWait();
212 
213  /* Right now we just support reading packets one at a time. */
214  int r = pcap_dispatch(ptv->pcap_handle, packet_q_len,
215  (pcap_handler)PcapFileCallbackLoop, (u_char *)ptv);
216  if (unlikely(r == -1)) {
217  SCLogError("error code %" PRId32 " %s for %s", r, pcap_geterr(ptv->pcap_handle),
218  ptv->filename);
219  if (ptv->shared->cb_result == TM_ECODE_FAILED) {
221  }
222  loop_result = TM_ECODE_DONE;
223  } else if (unlikely(r == 0)) {
224  SCLogInfo("pcap file %s end of file reached (pcap err code %" PRId32 ")",
225  ptv->filename, r);
226  ptv->shared->files++;
227  loop_result = TM_ECODE_DONE;
228  } else if (ptv->shared->cb_result == TM_ECODE_FAILED) {
229  SCLogError("Pcap callback PcapFileCallbackLoop failed for %s", ptv->filename);
230  loop_result = TM_ECODE_FAILED;
231  }
232  StatsSyncCountersIfSignalled(&ptv->shared->tv->stats);
233  }
234 
235  SCReturnInt(loop_result);
236 }
237 
238 /** \internal
239  * \brief get the timestamp of the first packet and rewind
240  * \param pfv pcap file variables for storing the timestamp
241  * \retval bool true on success, false on error
242  */
243 static bool PeekFirstPacketTimestamp(PcapFileFileVars *pfv)
244 {
245  int r = pcap_next_ex(pfv->pcap_handle, &pfv->first_pkt_hdr, &pfv->first_pkt_data);
246  if (r <= 0 || pfv->first_pkt_hdr == NULL) {
247  SCLogError("failed to get first packet timestamp. pcap_next_ex(): %d", r);
248  return false;
249  }
250  /* timestamp in pfv->first_pkt_hdr may not be 'struct timeval' so
251  * do a manual copy of the members. */
252  pfv->first_pkt_ts.tv_sec = pfv->first_pkt_hdr->ts.tv_sec;
253  pfv->first_pkt_ts.tv_usec = pfv->first_pkt_hdr->ts.tv_usec;
254  return true;
255 }
256 
258 {
259  char errbuf[PCAP_ERRBUF_SIZE] = "";
260 
261  if(unlikely(pfv->filename == NULL)) {
262  SCLogError("Filename was null");
264  }
265 
266  pfv->pcap_handle = pcap_open_offline(pfv->filename, errbuf);
267  if (pfv->pcap_handle == NULL) {
268  SCLogError("%s", errbuf);
270  }
271 
272 #if defined(HAVE_SETVBUF) && defined(OS_LINUX)
273  if (pcap_g.read_buffer_size > 0) {
274  errno = 0;
275  if (setvbuf(pcap_file(pfv->pcap_handle), pfv->buffer, _IOFBF, pcap_g.read_buffer_size) <
276  0) {
277  SCLogWarning("Failed to setvbuf on PCAP file handle: %s", strerror(errno));
278  }
279  }
280 #endif
281 
282  if (pfv->shared != NULL && pfv->shared->bpf_string != NULL) {
283  SCLogInfo("using bpf-filter \"%s\"", pfv->shared->bpf_string);
284 
285  if (pcap_compile(pfv->pcap_handle, &pfv->filter, pfv->shared->bpf_string, 1, 0) < 0) {
286  SCLogError("bpf compilation error %s for %s", pcap_geterr(pfv->pcap_handle),
287  pfv->filename);
289  }
290 
291  if (pcap_setfilter(pfv->pcap_handle, &pfv->filter) < 0) {
292  SCLogError("could not set bpf filter %s for %s", pcap_geterr(pfv->pcap_handle),
293  pfv->filename);
294  pcap_freecode(&pfv->filter);
296  }
297  pcap_freecode(&pfv->filter);
298  }
299 
300  SC_ATOMIC_INIT(pfv->alerts_count);
301  SC_ATOMIC_SET(pfv->alerts_count, 0);
302 
303  SC_ATOMIC_INIT(pfv->ref_cnt);
304  SC_ATOMIC_SET(pfv->ref_cnt, 0);
305 
306  pfv->cleanup_requested = false;
307 
308  pfv->datalink = pcap_datalink(pfv->pcap_handle);
309  SCLogDebug("datalink %" PRId32 "", pfv->datalink);
311 
312  if (!PeekFirstPacketTimestamp(pfv))
314 
315  DecoderFunc UnusedFnPtr;
316  TmEcode validated = ValidateLinkType(pfv->datalink, &UnusedFnPtr);
317  SCReturnInt(validated);
318 }
319 
320 TmEcode ValidateLinkType(int datalink, DecoderFunc *DecoderFn)
321 {
322  switch (datalink) {
323  case LINKTYPE_LINUX_SLL2:
324  *DecoderFn = DecodeSll2;
325  break;
326  case LINKTYPE_LINUX_SLL:
327  *DecoderFn = DecodeSll;
328  break;
329  case LINKTYPE_ETHERNET:
330  *DecoderFn = DecodeEthernet;
331  break;
332  case LINKTYPE_PPP:
333  *DecoderFn = DecodePPP;
334  break;
335  case LINKTYPE_IPV4:
336  case LINKTYPE_IPV6:
337  case LINKTYPE_RAW:
338  case LINKTYPE_RAW2:
340  *DecoderFn = DecodeRaw;
341  break;
342  case LINKTYPE_NULL:
343  *DecoderFn = DecodeNull;
344  break;
345  case LINKTYPE_CISCO_HDLC:
346  *DecoderFn = DecodeCHDLC;
347  break;
348 
349  default:
350  SCLogError(
351  "datalink type %" PRId32 " not (yet) supported in module PcapFile.", datalink);
353  }
354 
356 }
357 
359 {
360  if (pfv == NULL || pfv->shared == NULL) {
361  return false;
362  }
363 
365  return false;
366  }
367 
369  return true;
370  }
371 
372  /* PCAP_FILE_DELETE_NON_ALERTS mode */
373  uint64_t file_alerts = SC_ATOMIC_GET(pfv->alerts_count);
374 
375  if (file_alerts != 0) {
376  SCLogDebug("Skipping deletion of %s due to %" PRIu64 " alert(s) generated.", pfv->filename,
377  file_alerts);
378  return false;
379  }
380 
381  SCLogDebug("pcap-file: will delete %s (no alerts counted)", pfv->filename);
382 
383  return true;
384 }
385 
387 {
388  if (pfv != NULL) {
389  /* decrease ref count as packet is done */
390  uint32_t prev = SC_ATOMIC_SUB(pfv->ref_cnt, 1);
391  SCLogDebug("pcap-file: packet done pfv=%p filename=%s ref_cnt was=%u now=%u", (void *)pfv,
392  pfv->filename, prev, prev - 1);
393  if (prev == 1) {
394  if (pfv->cleanup_requested) {
396  }
397  }
398  }
399 }
400 
401 void PcapFileAddAlertCount(PcapFileFileVars *pfv, uint16_t alert_count)
402 {
403  if (pfv != NULL && alert_count > 0) {
404  SC_ATOMIC_ADD(pfv->alerts_count, alert_count);
405  }
406 }
407 
408 static void PcapCaptureOnPacketWithAlerts(const Packet *p)
409 {
410  PcapFileFileVars *pfv = p->pcap_v.pfv;
411  if (pfv == NULL) {
412  pfv = PcapFileGetCurrentPfv();
413  }
414  if (pfv != NULL) {
415  /* alerts.cnt is uint16_t; count alerts for delete-on-non-alerts logic */
417  }
418 }
419 
420 static void PcapCaptureOnPseudoPacketCreated(Packet *p)
421 {
422  /* For pseudo packets created by generic layers, associate with current pfv
423  * and ensure refcount held so deletion defers. */
424  if (p->pcap_v.pfv == NULL) {
426  if (pfv != NULL) {
427  p->pcap_v.pfv = pfv;
429  SC_ATOMIC_ADD(pfv->ref_cnt, 1);
430  }
431  }
432 }
433 
435 {
436  CaptureHooksSet(PcapCaptureOnPacketWithAlerts, PcapCaptureOnPseudoPacketCreated);
437 }
438 
440 {
442  const char *delete_when_done_str = NULL;
443 
444  if (SCConfGet("pcap-file.delete-when-done", &delete_when_done_str) == 1) {
445  if (strcmp(delete_when_done_str, "non-alerts") == 0) {
446  delete_mode = PCAP_FILE_DELETE_NON_ALERTS;
447  } else {
448  int delete_always = 0;
449  if (SCConfGetBool("pcap-file.delete-when-done", &delete_always) == 1) {
450  if (delete_always == 1) {
451  delete_mode = PCAP_FILE_DELETE_ALWAYS;
452  }
453  }
454  }
455  }
456 
457  return delete_mode;
458 }
459 
460 #ifdef UNITTESTS
461 #include "util-unittest-helper.h"
462 /**
463  * \test Tests that the PcapFileShouldDeletePcapFile function correctly applies the
464  * delete mode configuration.
465  */
466 static int SourcePcapFileHelperTest01(void)
467 {
468  PcapFileSharedVars shared;
469  memset(&shared, 0, sizeof(shared));
471 
472  PcapFileFileVars pfv;
473  memset(&pfv, 0, sizeof(pfv));
474  pfv.shared = &shared;
475  pfv.filename = SCStrdup("test.pcap");
476  SC_ATOMIC_INIT(pfv.alerts_count);
477  SC_ATOMIC_SET(pfv.alerts_count, 0);
478 
479  /* Test case 1: Always delete mode */
480  int result1 = PcapFileShouldDeletePcapFile(&pfv);
481  FAIL_IF_NOT(result1);
482 
483  /* Test case 2: Non-alerts mode with no alerts */
485  int result2 = PcapFileShouldDeletePcapFile(&pfv);
486  FAIL_IF_NOT(result2);
487 
488  /* Test case 3: Non-alerts mode with alerts */
489  SC_ATOMIC_ADD(pfv.alerts_count, 1);
490  int result3 = PcapFileShouldDeletePcapFile(&pfv);
491  FAIL_IF(result3);
492 
493  /* Test case 4: Always delete mode with alerts */
495  int result4 = PcapFileShouldDeletePcapFile(&pfv);
496  FAIL_IF_NOT(result4);
497 
498  /* Test case 5: No delete mode */
500  int result5 = PcapFileShouldDeletePcapFile(&pfv);
501  FAIL_IF(result5);
502 
503  SCFree(pfv.filename);
504 
505  PASS;
506 }
507 
508 /**
509  * \test Test PcapFileFinalizePacket function with reference counting
510  */
511 static int SourcePcapFileHelperTest02(void)
512 {
513  PcapFileFileVars pfv;
514  memset(&pfv, 0, sizeof(pfv));
515  SC_ATOMIC_INIT(pfv.alerts_count);
516  SC_ATOMIC_SET(pfv.alerts_count, 0);
517  SC_ATOMIC_INIT(pfv.ref_cnt);
518  SC_ATOMIC_SET(pfv.ref_cnt, 0);
519  pfv.cleanup_requested = false;
520 
521  /* Test adding alerts with reference counting */
522  SC_ATOMIC_ADD(pfv.ref_cnt, 1); /* simulate packet in flight */
523  PcapFileAddAlertCount(&pfv, 5);
525  uint64_t count = SC_ATOMIC_GET(pfv.alerts_count);
526  FAIL_IF_NOT(count == 5);
527  FAIL_IF_NOT(SC_ATOMIC_GET(pfv.ref_cnt) == 0); /* should be decremented */
528 
529  /* Test adding more alerts */
530  SC_ATOMIC_ADD(pfv.ref_cnt, 1);
531  PcapFileAddAlertCount(&pfv, 3);
533  count = SC_ATOMIC_GET(pfv.alerts_count);
534  FAIL_IF_NOT(count == 8);
535 
536  /* Test with zero alerts (should not increment count) */
537  SC_ATOMIC_ADD(pfv.ref_cnt, 1);
539  count = SC_ATOMIC_GET(pfv.alerts_count);
540  FAIL_IF_NOT(count == 8);
541 
542  /* Test with NULL pfv (should not crash) */
544 
545  PASS;
546 }
547 
548 /* Mock for configuration testing */
549 static int SetupYamlConf(const char *conf_string)
550 {
552  SCConfInit();
553 
554  return SCConfYamlLoadString(conf_string, strlen(conf_string));
555 }
556 
557 static void CleanupYamlConf(void)
558 {
559  SCConfDeInit();
561 }
562 
563 /**
564  * \test Test PcapFileParseDeleteMode with all configuration combinations
565  */
566 static int SourcePcapFileHelperTest03(void)
567 {
568  /* Test 1: No configuration (should default to NONE) */
570  SCConfInit();
571 
574 
575  SCConfDeInit();
577 
578  /* Test 2: "false" configuration */
579  const char *conf_false = "%YAML 1.1\n"
580  "---\n"
581  "pcap-file:\n"
582  " delete-when-done: false\n";
583 
584  SetupYamlConf(conf_false);
585  result = PcapFileParseDeleteMode();
587  CleanupYamlConf();
588 
589  /* Test 3: "true" configuration */
590  const char *conf_true = "%YAML 1.1\n"
591  "---\n"
592  "pcap-file:\n"
593  " delete-when-done: true\n";
594 
595  SetupYamlConf(conf_true);
596  result = PcapFileParseDeleteMode();
598  CleanupYamlConf();
599 
600  /* Test 4: "non-alerts" configuration */
601  const char *conf_non_alerts = "%YAML 1.1\n"
602  "---\n"
603  "pcap-file:\n"
604  " delete-when-done: \"non-alerts\"\n";
605 
606  SetupYamlConf(conf_non_alerts);
607  result = PcapFileParseDeleteMode();
609  CleanupYamlConf();
610 
611  /* Test 5: Invalid configuration (should default to NONE) */
612  const char *conf_invalid = "%YAML 1.1\n"
613  "---\n"
614  "pcap-file:\n"
615  " delete-when-done: \"invalid-value\"\n";
616 
617  SetupYamlConf(conf_invalid);
618  result = PcapFileParseDeleteMode();
620  CleanupYamlConf();
621 
622  PASS;
623 }
624 
625 /**
626  * \test pfv is NULL.
627  */
628 static int SourcePcapFileHelperTest04(void)
629 {
630  int rc = PcapFileShouldDeletePcapFile(NULL);
631  FAIL_IF(rc);
632  PASS;
633 }
634 
635 /**
636  * \test pfv->shared is NULL.
637  */
638 static int SourcePcapFileHelperTest05(void)
639 {
640  PcapFileFileVars pfv;
641  memset(&pfv, 0, sizeof(pfv));
642 
643  int rc = PcapFileShouldDeletePcapFile(&pfv);
644  FAIL_IF(rc);
645  PASS;
646 }
647 
648 /**
649  * \test Test cleanup with reference counting and deferred deletion
650  */
651 static int SourcePcapFileHelperTest06(void)
652 {
653  PcapFileFileVars pfv;
654  memset(&pfv, 0, sizeof(pfv));
655  SC_ATOMIC_INIT(pfv.alerts_count);
656  SC_ATOMIC_SET(pfv.alerts_count, 0);
657  SC_ATOMIC_INIT(pfv.ref_cnt);
658  SC_ATOMIC_SET(pfv.ref_cnt, 2); /* simulate 2 packets in flight */
659  pfv.cleanup_requested = false;
660 
661  /* Simulate first packet completion - should not cleanup yet */
662  SC_ATOMIC_SUB(pfv.ref_cnt, 1);
663  FAIL_IF_NOT(SC_ATOMIC_GET(pfv.ref_cnt) == 1);
664 
665  /* Request cleanup while packets are still in flight */
666  pfv.cleanup_requested = true;
667 
668  /* Simulate second packet completion - should trigger cleanup */
669  if (SC_ATOMIC_SUB(pfv.ref_cnt, 1) == 1) {
670  FAIL_IF_NOT(pfv.cleanup_requested); /* cleanup should have been requested */
671  /* In real code, CleanupPcapFileFileVars would be called here */
672  }
673 
674  PASS;
675 }
676 
677 /**
678  * \test Test edge cases and error conditions
679  */
680 static int SourcePcapFileHelperTest07(void)
681 {
682  /* Test 1: PcapFileShouldDeletePcapFile with very high alert count */
683  PcapFileSharedVars shared;
684  memset(&shared, 0, sizeof(shared));
686 
687  PcapFileFileVars pfv;
688  memset(&pfv, 0, sizeof(pfv));
689  pfv.shared = &shared;
690  pfv.filename = SCStrdup("test.pcap");
691  SC_ATOMIC_INIT(pfv.alerts_count);
692  SC_ATOMIC_SET(pfv.alerts_count, UINT64_MAX); /* max value */
693 
694  int result = PcapFileShouldDeletePcapFile(&pfv);
695  FAIL_IF(result); /* should not delete with max alerts */
696 
697  /* Test 2: PcapFileFinalizePacket with max alert count */
698  SC_ATOMIC_INIT(pfv.ref_cnt);
699  SC_ATOMIC_ADD(pfv.ref_cnt, 1);
700  PcapFileAddAlertCount(&pfv, UINT16_MAX); /* max uint16_t */
702  /* Should not overflow or crash */
703 
704  SCFree(pfv.filename);
705  PASS;
706 }
707 
708 /**
709  * \test Test command-line --pcap-file-delete override behavior
710  */
711 static int SourcePcapFileHelperTest08(void)
712 {
713  /* Test 1: Command line overrides YAML "false" */
714  const char *conf_false = "%YAML 1.1\n"
715  "---\n"
716  "pcap-file:\n"
717  " delete-when-done: false\n";
718 
719  SetupYamlConf(conf_false);
720 
721  /* Simulate --pcap-file-delete command line option */
722  int set_result = SCConfSetFinal("pcap-file.delete-when-done", "true");
723  FAIL_IF_NOT(set_result == 1);
724 
726  FAIL_IF_NOT(result == PCAP_FILE_DELETE_ALWAYS); /* Should override YAML false */
727  CleanupYamlConf();
728 
729  /* Test 2: Command line overrides YAML "non-alerts" */
730  const char *conf_non_alerts = "%YAML 1.1\n"
731  "---\n"
732  "pcap-file:\n"
733  " delete-when-done: \"non-alerts\"\n";
734 
735  SetupYamlConf(conf_non_alerts);
736 
737  /* Simulate --pcap-file-delete command line option */
738  set_result = SCConfSetFinal("pcap-file.delete-when-done", "true");
739  FAIL_IF_NOT(set_result == 1);
740 
741  result = PcapFileParseDeleteMode();
742  FAIL_IF_NOT(result == PCAP_FILE_DELETE_ALWAYS); /* Should override YAML "non-alerts" */
743  CleanupYamlConf();
744 
745  /* Test 3: Command line overrides no YAML config */
747  SCConfInit();
748 
749  /* Simulate --pcap-file-delete command line option with no YAML config */
750  set_result = SCConfSetFinal("pcap-file.delete-when-done", "true");
751  FAIL_IF_NOT(set_result == 1);
752 
753  result = PcapFileParseDeleteMode();
754  FAIL_IF_NOT(result == PCAP_FILE_DELETE_ALWAYS); /* Should set to always delete */
755 
756  SCConfDeInit();
758 
759  PASS;
760 }
761 
762 /**
763  * \test Test that cleanup defers while packets are in flight and that a file
764  * with alerts is not deleted in NON_ALERTS mode.
765  */
766 static int SourcePcapFileHelperTest09(void)
767 {
768  PcapFileSharedVars *shared = SCCalloc(1, sizeof(*shared));
769  FAIL_IF_NULL(shared);
771 
772  PcapFileFileVars *pfv = SCCalloc(1, sizeof(*pfv));
773  FAIL_IF_NULL(pfv);
774  pfv->shared = shared;
775  pfv->filename = SCStrdup("unit_del_test.pcap");
776  FAIL_IF_NULL(pfv->filename);
777 
778  SC_ATOMIC_INIT(pfv->alerts_count);
779  SC_ATOMIC_SET(pfv->alerts_count, 0);
780  SC_ATOMIC_INIT(pfv->ref_cnt);
781  SC_ATOMIC_SET(pfv->ref_cnt, 2); /* two packets in flight */
782  pfv->cleanup_requested = false;
783 
784  /* Request cleanup while packets still in flight: should defer. */
787  FAIL_IF_NULL(pfv->filename); /* not freed yet */
788 
789  /* First packet completes and generates an alert. */
790  PcapFileAddAlertCount(pfv, 1);
792  FAIL_IF_NOT(SC_ATOMIC_GET(pfv->alerts_count) == 1);
793 
794  /* Second (last) packet completes: triggers final cleanup. */
796 
797  /* pfv memory is freed at this point; only free shared. */
798  SCFree(shared);
799 
800  PASS;
801 }
802 
803 /**
804  * \test Cover unlink-on-ALWAYS branch (ref_cnt == 0) and deferred deletion when ref_cnt > 0
805  */
806 static int SourcePcapFileHelperTest10(void)
807 {
808  /* Create a temporary file that we expect to be deleted. */
809  const char *tmpname = "suri_ut_delete_always.pcap";
810  const uint8_t dummy[] = { 0x00 };
811  int rc = TestHelperBufferToFile(tmpname, dummy, sizeof(dummy));
812  FAIL_IF_NOT(rc >= 0);
813 
814  /* Case 1: delete ALWAYS with no packets in flight -> file unlinked immediately */
815  PcapFileSharedVars *shared1 = SCCalloc(1, sizeof(*shared1));
816  FAIL_IF_NULL(shared1);
818 
819  PcapFileFileVars *pfv1 = SCCalloc(1, sizeof(*pfv1));
820  FAIL_IF_NULL(pfv1);
821  pfv1->shared = shared1;
822  pfv1->filename = SCStrdup(tmpname);
823  FAIL_IF_NULL(pfv1->filename);
824 
825  SC_ATOMIC_INIT(pfv1->alerts_count);
826  SC_ATOMIC_SET(pfv1->alerts_count, 0);
827  SC_ATOMIC_INIT(pfv1->ref_cnt);
828  SC_ATOMIC_SET(pfv1->ref_cnt, 0);
829 
830  /* Provide a closable handle to cover close path. */
831  pfv1->pcap_handle = pcap_open_dead(DLT_EN10MB, 65535);
832  FAIL_IF_NULL(pfv1->pcap_handle);
833 
835 
836  /* File should be gone. */
837  FILE *f = fopen(tmpname, "rb");
838  FAIL_IF_NOT_NULL(f);
839  if (f != NULL)
840  fclose(f);
841 
842  /* Case 2: delete ALWAYS but ref_cnt > 0 -> defer until finalize. */
843  /* Recreate the file. */
844  rc = TestHelperBufferToFile(tmpname, dummy, sizeof(dummy));
845  FAIL_IF_NOT(rc >= 0);
846 
847  PcapFileSharedVars *shared2 = SCCalloc(1, sizeof(*shared2));
848  FAIL_IF_NULL(shared2);
850 
851  PcapFileFileVars *pfv2 = SCCalloc(1, sizeof(*pfv2));
852  FAIL_IF_NULL(pfv2);
853  pfv2->shared = shared2;
854  pfv2->filename = SCStrdup(tmpname);
855  FAIL_IF_NULL(pfv2->filename);
856 
857  SC_ATOMIC_INIT(pfv2->alerts_count);
858  SC_ATOMIC_SET(pfv2->alerts_count, 0);
859  SC_ATOMIC_INIT(pfv2->ref_cnt);
860  SC_ATOMIC_SET(pfv2->ref_cnt, 1);
861  pfv2->pcap_handle = pcap_open_dead(DLT_EN10MB, 65535);
862  FAIL_IF_NULL(pfv2->pcap_handle);
863 
865 
866  /* Still exists now because deletion should be deferred. */
867  f = fopen(tmpname, "rb");
868  FAIL_IF_NULL(f);
869  if (f != NULL)
870  fclose(f);
871 
872  /* Finalize the last packet which should trigger final cleanup & unlink. */
874 
875  /* Now the file should be gone. */
876  f = fopen(tmpname, "rb");
877  FAIL_IF_NOT_NULL(f);
878  if (f != NULL)
879  fclose(f);
880 
881  SCFree(shared1);
882  SCFree(shared2);
883 
884  PASS;
885 }
886 
887 /**
888  * \test Test PcapFileReleasePseudoPacket refcount decrement without cleanup
889  */
890 static int SourcePcapFileHelperTest11(void)
891 {
892  /* Setup pfv with ref_cnt=2 so release does not trigger cleanup */
893  PcapFileFileVars pfv;
894  memset(&pfv, 0, sizeof(pfv));
895  SC_ATOMIC_INIT(pfv.ref_cnt);
896  SC_ATOMIC_SET(pfv.ref_cnt, 2);
897  pfv.cleanup_requested = false;
898 
899  /* Allocate a packet from the pool to allow safe release */
900  Packet *p = PacketGetFromAlloc();
901  FAIL_IF_NULL(p);
902  p->pcap_v.pfv = &pfv;
903 
904  /* Call release and ensure ref count decremented by 1 */
906  FAIL_IF_NOT(SC_ATOMIC_GET(pfv.ref_cnt) == 1);
907 
908  PASS;
909 }
910 
911 /**
912  * \test Test adding alert count and that cleanup after refcnt reaches zero
913  * does not delete when alerts exist in NON_ALERTS mode.
914  */
915 static int SourcePcapFileHelperTest12(void)
916 {
917  PcapFileSharedVars shared;
918  memset(&shared, 0, sizeof(shared));
920 
921  PcapFileFileVars *pfv = SCCalloc(1, sizeof(*pfv));
922  FAIL_IF_NULL(pfv);
923  pfv->shared = &shared;
924  pfv->filename = SCStrdup("ut_non_alerts.pcap");
925  FAIL_IF_NULL(pfv->filename);
926 
927  SC_ATOMIC_INIT(pfv->alerts_count);
928  SC_ATOMIC_SET(pfv->alerts_count, 0);
929  SC_ATOMIC_INIT(pfv->ref_cnt);
930  SC_ATOMIC_SET(pfv->ref_cnt, 1);
931  pfv->cleanup_requested = true;
932 
933  /* Simulate pseudo alert */
934  PcapFileAddAlertCount(pfv, 2);
935  FAIL_IF_NOT(SC_ATOMIC_GET(pfv->alerts_count) == 2);
936 
937  /* Simulate last ref release triggering cleanup; file shouldn't be deleted
938  * due to alerts > 0. We cannot check unlink here; rely on return value. */
939  if (SC_ATOMIC_SUB(pfv->ref_cnt, 1) == 1) {
941  }
942  /* Success if no crash. */
943  PASS;
944 }
945 
946 /**
947  * \test Test global current pfv pointer lifecycle
948  */
949 static int SourcePcapFileHelperTest13(void)
950 {
951  PcapFileFileVars *pfv = SCCalloc(1, sizeof(*pfv));
952  FAIL_IF_NULL(pfv);
953  pfv->filename = SCStrdup("ut_global_clear.pcap");
954  FAIL_IF_NULL(pfv->filename);
955 
958 
959  /* Cleanup should clear global reference when pointing to this pfv */
961  /* Global accessor must be NULL after cleanup. */
963  PASS;
964 }
965 
966 /**
967  * \test Exercise unlink failure branch in CleanupPcapFileFileVars
968  */
969 static int SourcePcapFileHelperTest14(void)
970 {
971  PcapFileSharedVars shared;
972  memset(&shared, 0, sizeof(shared));
974 
975  PcapFileFileVars *pfv = SCCalloc(1, sizeof(*pfv));
976  FAIL_IF_NULL(pfv);
977  pfv->shared = &shared;
978  pfv->filename = SCStrdup("does-not-exist-ut.pcap");
979  FAIL_IF_NULL(pfv->filename);
980 
981  SC_ATOMIC_INIT(pfv->ref_cnt);
982  SC_ATOMIC_SET(pfv->ref_cnt, 0);
983 
984  /* Attempt cleanup; unlink should fail but must not crash */
986  PASS;
987 }
988 
989 /**
990  * \test Cover alerts hook fallback using current PFV
991  */
992 static int SourcePcapFileHelperTest15(void)
993 {
995 
996  PcapFileFileVars *pfv = SCCalloc(1, sizeof(*pfv));
997  FAIL_IF_NULL(pfv);
998  SC_ATOMIC_INIT(pfv->alerts_count);
999  SC_ATOMIC_SET(pfv->alerts_count, 0);
1000 
1001  /* Set current PFV to exercise fallback path */
1002  PcapFileSetCurrentPfv(pfv);
1003 
1004  Packet *p = PacketGetFromAlloc();
1005  FAIL_IF_NULL(p);
1006  p->alerts.cnt = 3; /* simulate 3 alerts */
1007  p->pcap_v.pfv = NULL; /* force fallback */
1008 
1009  /* Call hook: it should update pfv->alerts_count */
1011  FAIL_IF_NOT(SC_ATOMIC_GET(pfv->alerts_count) == 3);
1012 
1013  /* Cleanup */
1016  PASS;
1017 }
1018 
1019 /**
1020  * \brief Register unit tests for pcap file helper
1021  */
1023 {
1024  UtRegisterTest("SourcePcapFileHelperTest01", SourcePcapFileHelperTest01);
1025  UtRegisterTest("SourcePcapFileHelperTest02", SourcePcapFileHelperTest02);
1026  UtRegisterTest("SourcePcapFileHelperTest03", SourcePcapFileHelperTest03);
1027  UtRegisterTest("SourcePcapFileHelperTest04", SourcePcapFileHelperTest04);
1028  UtRegisterTest("SourcePcapFileHelperTest05", SourcePcapFileHelperTest05);
1029  UtRegisterTest("SourcePcapFileHelperTest06", SourcePcapFileHelperTest06);
1030  UtRegisterTest("SourcePcapFileHelperTest07", SourcePcapFileHelperTest07);
1031  UtRegisterTest("SourcePcapFileHelperTest08", SourcePcapFileHelperTest08);
1032  UtRegisterTest("SourcePcapFileHelperTest09", SourcePcapFileHelperTest09);
1033  UtRegisterTest("SourcePcapFileHelperTest10", SourcePcapFileHelperTest10);
1034  UtRegisterTest("SourcePcapFileHelperTest11", SourcePcapFileHelperTest11);
1035  UtRegisterTest("SourcePcapFileHelperTest12", SourcePcapFileHelperTest12);
1036  UtRegisterTest("SourcePcapFileHelperTest13", SourcePcapFileHelperTest13);
1037  UtRegisterTest("SourcePcapFileHelperTest14", SourcePcapFileHelperTest14);
1038  UtRegisterTest("SourcePcapFileHelperTest15", SourcePcapFileHelperTest15);
1039 }
1040 #endif /* UNITTESTS */
PcapPacketVars_::pcap_cnt
uint64_t pcap_cnt
Definition: source-pcap.h:38
SCConfYamlLoadString
int SCConfYamlLoadString(const char *string, size_t len)
Load configuration from a YAML string.
Definition: conf-yaml-loader.c:535
PcapFileDispatch
TmEcode PcapFileDispatch(PcapFileFileVars *ptv)
Main PCAP file reading Loop function.
Definition: source-pcap-file-helper.c:186
PcapFileFileVars_::filename
char * filename
Definition: source-pcap-file-helper.h:78
PcapFileSharedVars_
Definition: source-pcap-file-helper.h:49
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
PcapFileGetCurrentPfv
PcapFileFileVars * PcapFileGetCurrentPfv(void)
Definition: source-pcap-file-helper.c:178
PacketFreeOrRelease
void PacketFreeOrRelease(Packet *p)
Return a packet to where it was allocated.
Definition: decode.c:280
StatsSyncCountersIfSignalled
void StatsSyncCountersIfSignalled(StatsThreadContext *stats)
Definition: counters.c:482
PcapFileFinalizePacket
void PcapFileFinalizePacket(PcapFileFileVars *pfv)
Definition: source-pcap-file-helper.c:386
PcapFileGlobalVars_
Definition: source-pcap-file-helper.h:37
PcapFileFileVars_::first_pkt_data
const u_char * first_pkt_data
Definition: source-pcap-file-helper.h:96
PcapFileFileVars_::datalink
int datalink
Definition: source-pcap-file-helper.h:81
SC_ATOMIC_INIT
#define SC_ATOMIC_INIT(name)
wrapper for initializing an atomic variable.
Definition: util-atomic.h:314
DecodePPP
int DecodePPP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Definition: decode-ppp.c:177
PacketCopyData
int PacketCopyData(Packet *p, const uint8_t *pktdata, uint32_t pktlen)
Copy data to Packet payload and set packet length.
Definition: decode.c:381
ValidateLinkType
TmEcode ValidateLinkType(int datalink, DecoderFunc *DecoderFn)
Definition: source-pcap-file-helper.c:320
PcapFileFileVars_::shared
PcapFileSharedVars * shared
Definition: source-pcap-file-helper.h:84
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
SC_ATOMIC_SET
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
Definition: util-atomic.h:386
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:282
util-checksum.h
PacketAlerts_::cnt
uint16_t cnt
Definition: decode.h:287
TM_ECODE_DONE
@ TM_ECODE_DONE
Definition: tm-threads-common.h:83
Packet_::flags
uint32_t flags
Definition: decode.h:544
PcapFileShouldDeletePcapFile
bool PcapFileShouldDeletePcapFile(PcapFileFileVars *pfv)
Definition: source-pcap-file-helper.c:358
threads.h
PcapFileAddAlertCount
void PcapFileAddAlertCount(PcapFileFileVars *pfv, uint16_t alert_count)
Definition: source-pcap-file-helper.c:401
SC_ATOMIC_ADD
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
Definition: util-atomic.h:332
SCConfGet
int SCConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
Definition: conf.c:351
DecoderFunc
int(* DecoderFunc)(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Definition: decode.h:1181
SURICATA_STOP
#define SURICATA_STOP
Definition: suricata.h:94
SCConfGetBool
int SCConfGetBool(const char *name, int *val)
Retrieve a configuration value as a boolean.
Definition: conf.c:498
CaptureHooksOnPacketWithAlerts
void CaptureHooksOnPacketWithAlerts(const Packet *p)
Definition: capture-hooks.c:53
DecodeCHDLC
int DecodeCHDLC(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Definition: decode-chdlc.c:42
CHECKSUM_VALIDATION_DISABLE
@ CHECKSUM_VALIDATION_DISABLE
Definition: decode.h:43
PcapFileReleasePseudoPacket
void PcapFileReleasePseudoPacket(Packet *p)
Definition: source-pcap-file-helper.c:53
TmqhOutputPacketpool
void TmqhOutputPacketpool(ThreadVars *t, Packet *p)
Definition: tmqh-packetpool.c:305
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:82
Packet_::alerts
PacketAlerts alerts
Definition: decode.h:620
ChecksumAutoModeCheck
int ChecksumAutoModeCheck(uint64_t thread_count, uint64_t iface_count, uint64_t iface_fail)
Check if the number of invalid checksums indicate checksum offloading in place.
Definition: util-checksum.c:69
PCAP_FILE_DELETE_ALWAYS
@ PCAP_FILE_DELETE_ALWAYS
Definition: source-pcap-file-helper.h:33
util-unittest-helper.h
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:82
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:81
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
SCTIME_FROM_TIMEVAL_UNTRUSTED
#define SCTIME_FROM_TIMEVAL_UNTRUSTED(tv)
variant to deal with potentially bad timestamps, like from pcap files
Definition: util-time.h:85
SourcePcapFileHelperRegisterTests
void SourcePcapFileHelperRegisterTests(void)
Register unit tests for pcap file helper.
Definition: source-pcap-file-helper.c:1022
Packet_::datalink
int datalink
Definition: decode.h:635
PKT_SET_SRC
#define PKT_SET_SRC(p, src_val)
Definition: decode.h:1326
SCConfInit
void SCConfInit(void)
Initialize the configuration system.
Definition: conf.c:121
PCAP_FILE_DELETE_NONE
@ PCAP_FILE_DELETE_NONE
Definition: source-pcap-file-helper.h:32
DecodeNull
int DecodeNull(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Definition: decode-null.c:51
CHECKSUM_VALIDATION_AUTO
@ CHECKSUM_VALIDATION_AUTO
Definition: decode.h:45
capture-hooks.h
PcapFileGlobalVars_::cnt
uint64_t cnt
Definition: source-pcap-file-helper.h:38
FAIL_IF_NOT_NULL
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
Definition: util-unittest.h:96
PKT_SRC_WIRE
@ PKT_SRC_WIRE
Definition: decode.h:52
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
PcapFileSetCurrentPfv
void PcapFileSetCurrentPfv(PcapFileFileVars *pfv)
Definition: source-pcap-file-helper.c:173
Packet_::ts
SCTime_t ts
Definition: decode.h:555
util-exception-policy.h
TMM_RECEIVEPCAPFILE
@ TMM_RECEIVEPCAPFILE
Definition: tm-threads-common.h:39
PcapFileGlobalVars_::checksum_mode
ChecksumValidationMode checksum_mode
Definition: source-pcap-file-helper.h:40
Packet_::pcap_v
PcapPacketVars pcap_v
Definition: decode.h:587
SCEnter
#define SCEnter(...)
Definition: util-debug.h:284
SCTIME_FROM_TIMEVAL
#define SCTIME_FROM_TIMEVAL(tv)
Definition: util-time.h:79
PCAP_FILE_DELETE_NON_ALERTS
@ PCAP_FILE_DELETE_NON_ALERTS
Definition: source-pcap-file-helper.h:34
InitPcapFile
TmEcode InitPcapFile(PcapFileFileVars *pfv)
Definition: source-pcap-file-helper.c:257
TestHelperBufferToFile
int TestHelperBufferToFile(const char *name, const uint8_t *data, size_t size)
writes the contents of a buffer into a file
Definition: util-unittest-helper.c:103
SCLogWarning
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition: util-debug.h:262
util-profiling.h
SC_ATOMIC_SUB
#define SC_ATOMIC_SUB(name, val)
sub a value from our atomic variable
Definition: util-atomic.h:341
PacketPoolWait
void PacketPoolWait(void)
Definition: tmqh-packetpool.c:71
SCReturn
#define SCReturn
Definition: util-debug.h:286
PcapFileInstallCaptureHooks
void PcapFileInstallCaptureHooks(void)
Definition: source-pcap-file-helper.c:434
PACKET_PROFILING_TMM_END
#define PACKET_PROFILING_TMM_END(p, id)
Definition: util-profiling.h:139
source-pcap-file-helper.h
Packet_
Definition: decode.h:501
conf-yaml-loader.h
PcapPacketVars_::tenant_id
uint32_t tenant_id
Definition: source-pcap.h:39
PKT_IGNORE_CHECKSUM
#define PKT_IGNORE_CHECKSUM
Definition: decode.h:1283
PcapFileFileVars_
Definition: source-pcap-file-helper.h:77
TmEcode
TmEcode
Definition: tm-threads-common.h:80
max_pending_packets
uint32_t max_pending_packets
Definition: suricata.c:187
SCConfCreateContextBackup
void SCConfCreateContextBackup(void)
Creates a backup of the conf_hash hash_table used by the conf API.
Definition: conf.c:715
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:232
SCConfSetFinal
int SCConfSetFinal(const char *name, const char *val)
Set a final configuration value.
Definition: conf.c:319
TmThreadsInitThreadsTimestamp
void TmThreadsInitThreadsTimestamp(const SCTime_t ts)
Definition: tm-threads.c:2324
PcapFileSharedVars_::bpf_string
char * bpf_string
Definition: source-pcap-file-helper.h:50
Packet_::ReleasePacket
void(* ReleasePacket)(struct Packet_ *)
Definition: decode.h:591
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
pcap_filename
char pcap_filename[PATH_MAX]
Definition: source-pcap-file-helper.c:166
SCTIME_SECS
#define SCTIME_SECS(t)
Definition: util-time.h:57
DecodeSll
int DecodeSll(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Definition: decode-sll.c:41
SCConfDeInit
void SCConfDeInit(void)
De-initializes the configuration system.
Definition: conf.c:734
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
PcapFileFileVars_::first_pkt_ts
struct timeval first_pkt_ts
Definition: source-pcap-file-helper.h:98
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:262
PACKET_PROFILING_TMM_START
#define PACKET_PROFILING_TMM_START(p, id)
Definition: util-profiling.h:131
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:274
SCFree
#define SCFree(p)
Definition: util-mem.h:61
SCConfRestoreContextBackup
void SCConfRestoreContextBackup(void)
Restores the backup of the hash_table present in backup_conf_hash back to conf_hash.
Definition: conf.c:725
PcapFileFileVars_::pcap_handle
pcap_t * pcap_handle
Definition: source-pcap-file-helper.h:79
PcapFileGetFilename
const char * PcapFileGetFilename(void)
Definition: source-pcap-file-helper.c:168
suricata.h
DecodeRaw
int DecodeRaw(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Definition: decode-raw.c:42
PcapFileFileVars_::first_pkt_hdr
struct pcap_pkthdr * first_pkt_hdr
Definition: source-pcap-file-helper.h:97
pcap_g
PcapFileGlobalVars pcap_g
Definition: source-pcap-file.c:39
PcapFileParseDeleteMode
PcapFileDeleteMode PcapFileParseDeleteMode(void)
Definition: source-pcap-file-helper.c:439
PcapFileFileVars_::filter
struct bpf_program filter
Definition: source-pcap-file-helper.h:82
likely
#define likely(expr)
Definition: util-optimize.h:32
SC_ATOMIC_GET
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
Definition: util-atomic.h:375
CaptureHooksSet
void CaptureHooksSet(CaptureOnPacketWithAlertsHook OnAlerts, CaptureOnPseudoPacketCreatedHook OnPseudoCreated)
Definition: capture-hooks.c:37
CleanupPcapFileFileVars
void CleanupPcapFileFileVars(PcapFileFileVars *pfv)
Definition: source-pcap-file-helper.c:67
SCLogNotice
#define SCLogNotice(...)
Macro used to log NOTICE messages.
Definition: util-debug.h:250
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
DecodeSll2
int DecodeSll2(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Definition: decode-sll2.c:40
PcapPacketVars_::pfv
PcapFileFileVars * pfv
Definition: source-pcap.h:40
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:288
PcapFileSharedVars_::delete_mode
PcapFileDeleteMode delete_mode
Definition: source-pcap-file-helper.h:56
PacketGetFromQueueOrAlloc
Packet * PacketGetFromQueueOrAlloc(void)
Get a packet. We try to get a packet from the packetpool first, but if that is empty we alloc a packe...
Definition: decode.c:297
DecodeEthernet
int DecodeEthernet(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Definition: decode-ethernet.c:42
PcapFileFileVars_::cleanup_requested
bool cleanup_requested
Definition: source-pcap-file-helper.h:92
PcapFileGlobalVars_::read_buffer_size
uint32_t read_buffer_size
Definition: source-pcap-file-helper.h:42
PcapFileSharedVars_::pkts
uint64_t pkts
Definition: source-pcap-file-helper.h:62
suricata_ctl_flags
volatile uint8_t suricata_ctl_flags
Definition: suricata.c:176
PcapFileDeleteMode
PcapFileDeleteMode
Definition: source-pcap-file-helper.h:31