suricata
source-pcap-file-helper.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2026 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 QA_SIMULATION
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 
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  struct stat sb;
275  int fd = fileno(pcap_file(pfv->pcap_handle));
276  if (fd >= 0 && fstat(fd, &sb) == 0 && !S_ISREG(sb.st_mode)) {
277  SCLogInfo("%s: skipping setvbuf, underlying fd is not a regular file", pfv->filename);
278  } else {
279  errno = 0;
280  if (setvbuf(pcap_file(pfv->pcap_handle), pfv->buffer, _IOFBF,
281  pcap_g.read_buffer_size) != 0) {
282  SCLogWarning("Failed to setvbuf on PCAP file handle: %s", strerror(errno));
283  }
284  }
285  }
286 #endif
287 
288  if (pfv->shared != NULL && pfv->shared->bpf_string != NULL) {
289  SCLogInfo("using bpf-filter \"%s\"", pfv->shared->bpf_string);
290 
291  if (pcap_compile(pfv->pcap_handle, &pfv->filter, pfv->shared->bpf_string, 1, 0) < 0) {
292  SCLogError("bpf compilation error %s for %s", pcap_geterr(pfv->pcap_handle),
293  pfv->filename);
295  }
296 
297  if (pcap_setfilter(pfv->pcap_handle, &pfv->filter) < 0) {
298  SCLogError("could not set bpf filter %s for %s", pcap_geterr(pfv->pcap_handle),
299  pfv->filename);
300  pcap_freecode(&pfv->filter);
302  }
303  pcap_freecode(&pfv->filter);
304  }
305 
306  SC_ATOMIC_INIT(pfv->alerts_count);
307  SC_ATOMIC_SET(pfv->alerts_count, 0);
308 
309  SC_ATOMIC_INIT(pfv->ref_cnt);
310  SC_ATOMIC_SET(pfv->ref_cnt, 0);
311 
312  pfv->cleanup_requested = false;
313 
314  pfv->datalink = pcap_datalink(pfv->pcap_handle);
315  SCLogDebug("datalink %" PRId32 "", pfv->datalink);
317 
318  if (!PeekFirstPacketTimestamp(pfv))
320 
321  DecoderFunc UnusedFnPtr;
322  TmEcode validated = ValidateLinkType(pfv->datalink, &UnusedFnPtr);
323  SCReturnInt(validated);
324 }
325 
326 TmEcode ValidateLinkType(int datalink, DecoderFunc *DecoderFn)
327 {
328  switch (datalink) {
329  case LINKTYPE_LINUX_SLL2:
330  *DecoderFn = DecodeSll2;
331  break;
332  case LINKTYPE_LINUX_SLL:
333  *DecoderFn = DecodeSll;
334  break;
335  case LINKTYPE_ETHERNET:
336  *DecoderFn = DecodeEthernet;
337  break;
338  case LINKTYPE_PPP:
339  *DecoderFn = DecodePPP;
340  break;
341  case LINKTYPE_IPV4:
342  case LINKTYPE_IPV6:
343  case LINKTYPE_RAW:
344  case LINKTYPE_RAW2:
346  *DecoderFn = DecodeRaw;
347  break;
348  case LINKTYPE_NULL:
349  *DecoderFn = DecodeNull;
350  break;
351  case LINKTYPE_CISCO_HDLC:
352  *DecoderFn = DecodeCHDLC;
353  break;
354 
355  default:
356  SCLogError(
357  "datalink type %" PRId32 " not (yet) supported in module PcapFile.", datalink);
359  }
360 
362 }
363 
365 {
366  if (pfv == NULL || pfv->shared == NULL) {
367  return false;
368  }
369 
371  return false;
372  }
373 
375  return true;
376  }
377 
378  /* PCAP_FILE_DELETE_NON_ALERTS mode */
379  uint64_t file_alerts = SC_ATOMIC_GET(pfv->alerts_count);
380 
381  if (file_alerts != 0) {
382  SCLogDebug("Skipping deletion of %s due to %" PRIu64 " alert(s) generated.", pfv->filename,
383  file_alerts);
384  return false;
385  }
386 
387  SCLogDebug("pcap-file: will delete %s (no alerts counted)", pfv->filename);
388 
389  return true;
390 }
391 
393 {
394  if (pfv != NULL) {
395  /* decrease ref count as packet is done */
396  uint32_t prev = SC_ATOMIC_SUB(pfv->ref_cnt, 1);
397  SCLogDebug("pcap-file: packet done pfv=%p filename=%s ref_cnt was=%u now=%u", (void *)pfv,
398  pfv->filename, prev, prev - 1);
399  if (prev == 1) {
400  if (pfv->cleanup_requested) {
402  }
403  }
404  }
405 }
406 
407 void PcapFileAddAlertCount(PcapFileFileVars *pfv, uint16_t alert_count)
408 {
409  if (pfv != NULL && alert_count > 0) {
410  SC_ATOMIC_ADD(pfv->alerts_count, alert_count);
411  }
412 }
413 
414 static void PcapCaptureOnPacketWithAlerts(const Packet *p)
415 {
416  PcapFileFileVars *pfv = p->pcap_v.pfv;
417  if (pfv == NULL) {
418  pfv = PcapFileGetCurrentPfv();
419  }
420  if (pfv != NULL) {
421  /* alerts.cnt is uint16_t; count alerts for delete-on-non-alerts logic */
423  }
424 }
425 
426 static void PcapCaptureOnPseudoPacketCreated(Packet *p)
427 {
428  /* For pseudo packets created by generic layers, associate with current pfv
429  * and ensure refcount held so deletion defers. */
430  if (p->pcap_v.pfv == NULL) {
432  if (pfv != NULL) {
433  p->pcap_v.pfv = pfv;
435  SC_ATOMIC_ADD(pfv->ref_cnt, 1);
436  }
437  }
438 }
439 
441 {
442  CaptureHooksSet(PcapCaptureOnPacketWithAlerts, PcapCaptureOnPseudoPacketCreated);
443 }
444 
446 {
448  const char *delete_when_done_str = NULL;
449 
450  if (SCConfGetNonNull("pcap-file.delete-when-done", &delete_when_done_str) == 1) {
451  if (strcmp(delete_when_done_str, "non-alerts") == 0) {
452  delete_mode = PCAP_FILE_DELETE_NON_ALERTS;
453  } else {
454  int delete_always = 0;
455  if (SCConfGetBool("pcap-file.delete-when-done", &delete_always) == 1) {
456  if (delete_always == 1) {
457  delete_mode = PCAP_FILE_DELETE_ALWAYS;
458  }
459  }
460  }
461  }
462 
463  return delete_mode;
464 }
465 
466 #ifdef UNITTESTS
467 #include "util-unittest-helper.h"
468 /**
469  * \test Tests that the PcapFileShouldDeletePcapFile function correctly applies the
470  * delete mode configuration.
471  */
472 static int SourcePcapFileHelperTest01(void)
473 {
474  PcapFileSharedVars shared;
475  memset(&shared, 0, sizeof(shared));
477 
478  PcapFileFileVars pfv;
479  memset(&pfv, 0, sizeof(pfv));
480  pfv.shared = &shared;
481  pfv.filename = SCStrdup("test.pcap");
482  SC_ATOMIC_INIT(pfv.alerts_count);
483  SC_ATOMIC_SET(pfv.alerts_count, 0);
484 
485  /* Test case 1: Always delete mode */
486  int result1 = PcapFileShouldDeletePcapFile(&pfv);
487  FAIL_IF_NOT(result1);
488 
489  /* Test case 2: Non-alerts mode with no alerts */
491  int result2 = PcapFileShouldDeletePcapFile(&pfv);
492  FAIL_IF_NOT(result2);
493 
494  /* Test case 3: Non-alerts mode with alerts */
495  SC_ATOMIC_ADD(pfv.alerts_count, 1);
496  int result3 = PcapFileShouldDeletePcapFile(&pfv);
497  FAIL_IF(result3);
498 
499  /* Test case 4: Always delete mode with alerts */
501  int result4 = PcapFileShouldDeletePcapFile(&pfv);
502  FAIL_IF_NOT(result4);
503 
504  /* Test case 5: No delete mode */
506  int result5 = PcapFileShouldDeletePcapFile(&pfv);
507  FAIL_IF(result5);
508 
509  SCFree(pfv.filename);
510 
511  PASS;
512 }
513 
514 /**
515  * \test Test PcapFileFinalizePacket function with reference counting
516  */
517 static int SourcePcapFileHelperTest02(void)
518 {
519  PcapFileFileVars pfv;
520  memset(&pfv, 0, sizeof(pfv));
521  SC_ATOMIC_INIT(pfv.alerts_count);
522  SC_ATOMIC_SET(pfv.alerts_count, 0);
523  SC_ATOMIC_INIT(pfv.ref_cnt);
524  SC_ATOMIC_SET(pfv.ref_cnt, 0);
525  pfv.cleanup_requested = false;
526 
527  /* Test adding alerts with reference counting */
528  SC_ATOMIC_ADD(pfv.ref_cnt, 1); /* simulate packet in flight */
529  PcapFileAddAlertCount(&pfv, 5);
531  uint64_t count = SC_ATOMIC_GET(pfv.alerts_count);
532  FAIL_IF_NOT(count == 5);
533  FAIL_IF_NOT(SC_ATOMIC_GET(pfv.ref_cnt) == 0); /* should be decremented */
534 
535  /* Test adding more alerts */
536  SC_ATOMIC_ADD(pfv.ref_cnt, 1);
537  PcapFileAddAlertCount(&pfv, 3);
539  count = SC_ATOMIC_GET(pfv.alerts_count);
540  FAIL_IF_NOT(count == 8);
541 
542  /* Test with zero alerts (should not increment count) */
543  SC_ATOMIC_ADD(pfv.ref_cnt, 1);
545  count = SC_ATOMIC_GET(pfv.alerts_count);
546  FAIL_IF_NOT(count == 8);
547 
548  /* Test with NULL pfv (should not crash) */
550 
551  PASS;
552 }
553 
554 /* Mock for configuration testing */
555 static int SetupYamlConf(const char *conf_string)
556 {
558  SCConfInit();
559 
560  return SCConfYamlLoadString(conf_string, strlen(conf_string));
561 }
562 
563 static void CleanupYamlConf(void)
564 {
565  SCConfDeInit();
567 }
568 
569 /**
570  * \test Test PcapFileParseDeleteMode with all configuration combinations
571  */
572 static int SourcePcapFileHelperTest03(void)
573 {
574  /* Test 1: No configuration (should default to NONE) */
576  SCConfInit();
577 
580 
581  SCConfDeInit();
583 
584  /* Test 2: "false" configuration */
585  const char *conf_false = "%YAML 1.1\n"
586  "---\n"
587  "pcap-file:\n"
588  " delete-when-done: false\n";
589 
590  SetupYamlConf(conf_false);
591  result = PcapFileParseDeleteMode();
593  CleanupYamlConf();
594 
595  /* Test 3: "true" configuration */
596  const char *conf_true = "%YAML 1.1\n"
597  "---\n"
598  "pcap-file:\n"
599  " delete-when-done: true\n";
600 
601  SetupYamlConf(conf_true);
602  result = PcapFileParseDeleteMode();
604  CleanupYamlConf();
605 
606  /* Test 4: "non-alerts" configuration */
607  const char *conf_non_alerts = "%YAML 1.1\n"
608  "---\n"
609  "pcap-file:\n"
610  " delete-when-done: \"non-alerts\"\n";
611 
612  SetupYamlConf(conf_non_alerts);
613  result = PcapFileParseDeleteMode();
615  CleanupYamlConf();
616 
617  /* Test 5: Invalid configuration (should default to NONE) */
618  const char *conf_invalid = "%YAML 1.1\n"
619  "---\n"
620  "pcap-file:\n"
621  " delete-when-done: \"invalid-value\"\n";
622 
623  SetupYamlConf(conf_invalid);
624  result = PcapFileParseDeleteMode();
626  CleanupYamlConf();
627 
628  PASS;
629 }
630 
631 /**
632  * \test pfv is NULL.
633  */
634 static int SourcePcapFileHelperTest04(void)
635 {
636  int rc = PcapFileShouldDeletePcapFile(NULL);
637  FAIL_IF(rc);
638  PASS;
639 }
640 
641 /**
642  * \test pfv->shared is NULL.
643  */
644 static int SourcePcapFileHelperTest05(void)
645 {
646  PcapFileFileVars pfv;
647  memset(&pfv, 0, sizeof(pfv));
648 
649  int rc = PcapFileShouldDeletePcapFile(&pfv);
650  FAIL_IF(rc);
651  PASS;
652 }
653 
654 /**
655  * \test Test cleanup with reference counting and deferred deletion
656  */
657 static int SourcePcapFileHelperTest06(void)
658 {
659  PcapFileFileVars pfv;
660  memset(&pfv, 0, sizeof(pfv));
661  SC_ATOMIC_INIT(pfv.alerts_count);
662  SC_ATOMIC_SET(pfv.alerts_count, 0);
663  SC_ATOMIC_INIT(pfv.ref_cnt);
664  SC_ATOMIC_SET(pfv.ref_cnt, 2); /* simulate 2 packets in flight */
665  pfv.cleanup_requested = false;
666 
667  /* Simulate first packet completion - should not cleanup yet */
668  SC_ATOMIC_SUB(pfv.ref_cnt, 1);
669  FAIL_IF_NOT(SC_ATOMIC_GET(pfv.ref_cnt) == 1);
670 
671  /* Request cleanup while packets are still in flight */
672  pfv.cleanup_requested = true;
673 
674  /* Simulate second packet completion - should trigger cleanup */
675  if (SC_ATOMIC_SUB(pfv.ref_cnt, 1) == 1) {
676  FAIL_IF_NOT(pfv.cleanup_requested); /* cleanup should have been requested */
677  /* In real code, CleanupPcapFileFileVars would be called here */
678  }
679 
680  PASS;
681 }
682 
683 /**
684  * \test Test edge cases and error conditions
685  */
686 static int SourcePcapFileHelperTest07(void)
687 {
688  /* Test 1: PcapFileShouldDeletePcapFile with very high alert count */
689  PcapFileSharedVars shared;
690  memset(&shared, 0, sizeof(shared));
692 
693  PcapFileFileVars pfv;
694  memset(&pfv, 0, sizeof(pfv));
695  pfv.shared = &shared;
696  pfv.filename = SCStrdup("test.pcap");
697  SC_ATOMIC_INIT(pfv.alerts_count);
698  SC_ATOMIC_SET(pfv.alerts_count, UINT64_MAX); /* max value */
699 
700  int result = PcapFileShouldDeletePcapFile(&pfv);
701  FAIL_IF(result); /* should not delete with max alerts */
702 
703  /* Test 2: PcapFileFinalizePacket with max alert count */
704  SC_ATOMIC_INIT(pfv.ref_cnt);
705  SC_ATOMIC_ADD(pfv.ref_cnt, 1);
706  PcapFileAddAlertCount(&pfv, UINT16_MAX); /* max uint16_t */
708  /* Should not overflow or crash */
709 
710  SCFree(pfv.filename);
711  PASS;
712 }
713 
714 /**
715  * \test Test command-line --pcap-file-delete override behavior
716  */
717 static int SourcePcapFileHelperTest08(void)
718 {
719  /* Test 1: Command line overrides YAML "false" */
720  const char *conf_false = "%YAML 1.1\n"
721  "---\n"
722  "pcap-file:\n"
723  " delete-when-done: false\n";
724 
725  SetupYamlConf(conf_false);
726 
727  /* Simulate --pcap-file-delete command line option */
728  int set_result = SCConfSetFinal("pcap-file.delete-when-done", "true");
729  FAIL_IF_NOT(set_result == 1);
730 
732  FAIL_IF_NOT(result == PCAP_FILE_DELETE_ALWAYS); /* Should override YAML false */
733  CleanupYamlConf();
734 
735  /* Test 2: Command line overrides YAML "non-alerts" */
736  const char *conf_non_alerts = "%YAML 1.1\n"
737  "---\n"
738  "pcap-file:\n"
739  " delete-when-done: \"non-alerts\"\n";
740 
741  SetupYamlConf(conf_non_alerts);
742 
743  /* Simulate --pcap-file-delete command line option */
744  set_result = SCConfSetFinal("pcap-file.delete-when-done", "true");
745  FAIL_IF_NOT(set_result == 1);
746 
747  result = PcapFileParseDeleteMode();
748  FAIL_IF_NOT(result == PCAP_FILE_DELETE_ALWAYS); /* Should override YAML "non-alerts" */
749  CleanupYamlConf();
750 
751  /* Test 3: Command line overrides no YAML config */
753  SCConfInit();
754 
755  /* Simulate --pcap-file-delete command line option with no YAML config */
756  set_result = SCConfSetFinal("pcap-file.delete-when-done", "true");
757  FAIL_IF_NOT(set_result == 1);
758 
759  result = PcapFileParseDeleteMode();
760  FAIL_IF_NOT(result == PCAP_FILE_DELETE_ALWAYS); /* Should set to always delete */
761 
762  SCConfDeInit();
764 
765  PASS;
766 }
767 
768 /**
769  * \test Test that cleanup defers while packets are in flight and that a file
770  * with alerts is not deleted in NON_ALERTS mode.
771  */
772 static int SourcePcapFileHelperTest09(void)
773 {
774  PcapFileSharedVars *shared = SCCalloc(1, sizeof(*shared));
775  FAIL_IF_NULL(shared);
777 
778  PcapFileFileVars *pfv = SCCalloc(1, sizeof(*pfv));
779  FAIL_IF_NULL(pfv);
780  pfv->shared = shared;
781  pfv->filename = SCStrdup("unit_del_test.pcap");
782  FAIL_IF_NULL(pfv->filename);
783 
784  SC_ATOMIC_INIT(pfv->alerts_count);
785  SC_ATOMIC_SET(pfv->alerts_count, 0);
786  SC_ATOMIC_INIT(pfv->ref_cnt);
787  SC_ATOMIC_SET(pfv->ref_cnt, 2); /* two packets in flight */
788  pfv->cleanup_requested = false;
789 
790  /* Request cleanup while packets still in flight: should defer. */
793  FAIL_IF_NULL(pfv->filename); /* not freed yet */
794 
795  /* First packet completes and generates an alert. */
796  PcapFileAddAlertCount(pfv, 1);
798  FAIL_IF_NOT(SC_ATOMIC_GET(pfv->alerts_count) == 1);
799 
800  /* Second (last) packet completes: triggers final cleanup. */
802 
803  /* pfv memory is freed at this point; only free shared. */
804  SCFree(shared);
805 
806  PASS;
807 }
808 
809 /**
810  * \test Cover unlink-on-ALWAYS branch (ref_cnt == 0) and deferred deletion when ref_cnt > 0
811  */
812 static int SourcePcapFileHelperTest10(void)
813 {
814  /* Create a temporary file that we expect to be deleted. */
815  const char *tmpname = "suri_ut_delete_always.pcap";
816  const uint8_t dummy[] = { 0x00 };
817  int rc = TestHelperBufferToFile(tmpname, dummy, sizeof(dummy));
818  FAIL_IF_NOT(rc >= 0);
819 
820  /* Case 1: delete ALWAYS with no packets in flight -> file unlinked immediately */
821  PcapFileSharedVars *shared1 = SCCalloc(1, sizeof(*shared1));
822  FAIL_IF_NULL(shared1);
824 
825  PcapFileFileVars *pfv1 = SCCalloc(1, sizeof(*pfv1));
826  FAIL_IF_NULL(pfv1);
827  pfv1->shared = shared1;
828  pfv1->filename = SCStrdup(tmpname);
829  FAIL_IF_NULL(pfv1->filename);
830 
831  SC_ATOMIC_INIT(pfv1->alerts_count);
832  SC_ATOMIC_SET(pfv1->alerts_count, 0);
833  SC_ATOMIC_INIT(pfv1->ref_cnt);
834  SC_ATOMIC_SET(pfv1->ref_cnt, 0);
835 
836  /* Provide a closable handle to cover close path. */
837  pfv1->pcap_handle = pcap_open_dead(DLT_EN10MB, 65535);
838  FAIL_IF_NULL(pfv1->pcap_handle);
839 
841 
842  /* File should be gone. */
843  FILE *f = fopen(tmpname, "rb");
844  FAIL_IF_NOT_NULL(f);
845  if (f != NULL)
846  fclose(f);
847 
848  /* Case 2: delete ALWAYS but ref_cnt > 0 -> defer until finalize. */
849  /* Recreate the file. */
850  rc = TestHelperBufferToFile(tmpname, dummy, sizeof(dummy));
851  FAIL_IF_NOT(rc >= 0);
852 
853  PcapFileSharedVars *shared2 = SCCalloc(1, sizeof(*shared2));
854  FAIL_IF_NULL(shared2);
856 
857  PcapFileFileVars *pfv2 = SCCalloc(1, sizeof(*pfv2));
858  FAIL_IF_NULL(pfv2);
859  pfv2->shared = shared2;
860  pfv2->filename = SCStrdup(tmpname);
861  FAIL_IF_NULL(pfv2->filename);
862 
863  SC_ATOMIC_INIT(pfv2->alerts_count);
864  SC_ATOMIC_SET(pfv2->alerts_count, 0);
865  SC_ATOMIC_INIT(pfv2->ref_cnt);
866  SC_ATOMIC_SET(pfv2->ref_cnt, 1);
867  pfv2->pcap_handle = pcap_open_dead(DLT_EN10MB, 65535);
868  FAIL_IF_NULL(pfv2->pcap_handle);
869 
871 
872  /* Still exists now because deletion should be deferred. */
873  f = fopen(tmpname, "rb");
874  FAIL_IF_NULL(f);
875  if (f != NULL)
876  fclose(f);
877 
878  /* Finalize the last packet which should trigger final cleanup & unlink. */
880 
881  /* Now the file should be gone. */
882  f = fopen(tmpname, "rb");
883  FAIL_IF_NOT_NULL(f);
884  if (f != NULL)
885  fclose(f);
886 
887  SCFree(shared1);
888  SCFree(shared2);
889 
890  PASS;
891 }
892 
893 /**
894  * \test Test PcapFileReleasePseudoPacket refcount decrement without cleanup
895  */
896 static int SourcePcapFileHelperTest11(void)
897 {
898  /* Setup pfv with ref_cnt=2 so release does not trigger cleanup */
899  PcapFileFileVars pfv;
900  memset(&pfv, 0, sizeof(pfv));
901  SC_ATOMIC_INIT(pfv.ref_cnt);
902  SC_ATOMIC_SET(pfv.ref_cnt, 2);
903  pfv.cleanup_requested = false;
904 
905  /* Allocate a packet from the pool to allow safe release */
907  FAIL_IF_NULL(p);
908  p->pcap_v.pfv = &pfv;
909 
910  /* Call release and ensure ref count decremented by 1 */
912  FAIL_IF_NOT(SC_ATOMIC_GET(pfv.ref_cnt) == 1);
913 
914  PASS;
915 }
916 
917 /**
918  * \test Test adding alert count and that cleanup after refcnt reaches zero
919  * does not delete when alerts exist in NON_ALERTS mode.
920  */
921 static int SourcePcapFileHelperTest12(void)
922 {
923  PcapFileSharedVars shared;
924  memset(&shared, 0, sizeof(shared));
926 
927  PcapFileFileVars *pfv = SCCalloc(1, sizeof(*pfv));
928  FAIL_IF_NULL(pfv);
929  pfv->shared = &shared;
930  pfv->filename = SCStrdup("ut_non_alerts.pcap");
931  FAIL_IF_NULL(pfv->filename);
932 
933  SC_ATOMIC_INIT(pfv->alerts_count);
934  SC_ATOMIC_SET(pfv->alerts_count, 0);
935  SC_ATOMIC_INIT(pfv->ref_cnt);
936  SC_ATOMIC_SET(pfv->ref_cnt, 1);
937  pfv->cleanup_requested = true;
938 
939  /* Simulate pseudo alert */
940  PcapFileAddAlertCount(pfv, 2);
941  FAIL_IF_NOT(SC_ATOMIC_GET(pfv->alerts_count) == 2);
942 
943  /* Simulate last ref release triggering cleanup; file shouldn't be deleted
944  * due to alerts > 0. We cannot check unlink here; rely on return value. */
945  if (SC_ATOMIC_SUB(pfv->ref_cnt, 1) == 1) {
947  }
948  /* Success if no crash. */
949  PASS;
950 }
951 
952 /**
953  * \test Test global current pfv pointer lifecycle
954  */
955 static int SourcePcapFileHelperTest13(void)
956 {
957  PcapFileFileVars *pfv = SCCalloc(1, sizeof(*pfv));
958  FAIL_IF_NULL(pfv);
959  pfv->filename = SCStrdup("ut_global_clear.pcap");
960  FAIL_IF_NULL(pfv->filename);
961 
964 
965  /* Cleanup should clear global reference when pointing to this pfv */
967  /* Global accessor must be NULL after cleanup. */
969  PASS;
970 }
971 
972 /**
973  * \test Exercise unlink failure branch in CleanupPcapFileFileVars
974  */
975 static int SourcePcapFileHelperTest14(void)
976 {
977  PcapFileSharedVars shared;
978  memset(&shared, 0, sizeof(shared));
980 
981  PcapFileFileVars *pfv = SCCalloc(1, sizeof(*pfv));
982  FAIL_IF_NULL(pfv);
983  pfv->shared = &shared;
984  pfv->filename = SCStrdup("does-not-exist-ut.pcap");
985  FAIL_IF_NULL(pfv->filename);
986 
987  SC_ATOMIC_INIT(pfv->ref_cnt);
988  SC_ATOMIC_SET(pfv->ref_cnt, 0);
989 
990  /* Attempt cleanup; unlink should fail but must not crash */
992  PASS;
993 }
994 
995 /**
996  * \test Cover alerts hook fallback using current PFV
997  */
998 static int SourcePcapFileHelperTest15(void)
999 {
1001 
1002  PcapFileFileVars *pfv = SCCalloc(1, sizeof(*pfv));
1003  FAIL_IF_NULL(pfv);
1004  SC_ATOMIC_INIT(pfv->alerts_count);
1005  SC_ATOMIC_SET(pfv->alerts_count, 0);
1006 
1007  /* Set current PFV to exercise fallback path */
1008  PcapFileSetCurrentPfv(pfv);
1009 
1011  FAIL_IF_NULL(p);
1012  p->alerts.cnt = 3; /* simulate 3 alerts */
1013  p->pcap_v.pfv = NULL; /* force fallback */
1014 
1015  /* Call hook: it should update pfv->alerts_count */
1017  FAIL_IF_NOT(SC_ATOMIC_GET(pfv->alerts_count) == 3);
1018 
1019  /* Cleanup */
1022  PASS;
1023 }
1024 
1025 /**
1026  * \brief Register unit tests for pcap file helper
1027  */
1029 {
1030  UtRegisterTest("SourcePcapFileHelperTest01", SourcePcapFileHelperTest01);
1031  UtRegisterTest("SourcePcapFileHelperTest02", SourcePcapFileHelperTest02);
1032  UtRegisterTest("SourcePcapFileHelperTest03", SourcePcapFileHelperTest03);
1033  UtRegisterTest("SourcePcapFileHelperTest04", SourcePcapFileHelperTest04);
1034  UtRegisterTest("SourcePcapFileHelperTest05", SourcePcapFileHelperTest05);
1035  UtRegisterTest("SourcePcapFileHelperTest06", SourcePcapFileHelperTest06);
1036  UtRegisterTest("SourcePcapFileHelperTest07", SourcePcapFileHelperTest07);
1037  UtRegisterTest("SourcePcapFileHelperTest08", SourcePcapFileHelperTest08);
1038  UtRegisterTest("SourcePcapFileHelperTest09", SourcePcapFileHelperTest09);
1039  UtRegisterTest("SourcePcapFileHelperTest10", SourcePcapFileHelperTest10);
1040  UtRegisterTest("SourcePcapFileHelperTest11", SourcePcapFileHelperTest11);
1041  UtRegisterTest("SourcePcapFileHelperTest12", SourcePcapFileHelperTest12);
1042  UtRegisterTest("SourcePcapFileHelperTest13", SourcePcapFileHelperTest13);
1043  UtRegisterTest("SourcePcapFileHelperTest14", SourcePcapFileHelperTest14);
1044  UtRegisterTest("SourcePcapFileHelperTest15", SourcePcapFileHelperTest15);
1045 }
1046 #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:536
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:282
StatsSyncCountersIfSignalled
void StatsSyncCountersIfSignalled(StatsThreadContext *stats)
Definition: counters.c:482
PcapFileFinalizePacket
void PcapFileFinalizePacket(PcapFileFileVars *pfv)
Definition: source-pcap-file-helper.c:392
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:383
ValidateLinkType
TmEcode ValidateLinkType(int datalink, DecoderFunc *DecoderFn)
Definition: source-pcap-file-helper.c:326
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:288
TM_ECODE_DONE
@ TM_ECODE_DONE
Definition: tm-threads-common.h:83
Packet_::flags
uint32_t flags
Definition: decode.h:561
PcapFileShouldDeletePcapFile
bool PcapFileShouldDeletePcapFile(PcapFileFileVars *pfv)
Definition: source-pcap-file-helper.c:364
threads.h
PcapFileAddAlertCount
void PcapFileAddAlertCount(PcapFileFileVars *pfv, uint16_t alert_count)
Definition: source-pcap-file-helper.c:407
SC_ATOMIC_ADD
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
Definition: util-atomic.h:332
DecoderFunc
int(* DecoderFunc)(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Definition: decode.h:1224
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:524
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
p
Packet * p
Definition: fuzz_iprep.c:21
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:636
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:1028
Packet_::datalink
int datalink
Definition: decode.h:651
PKT_SET_SRC
#define PKT_SET_SRC(p, src_val)
Definition: decode.h:1365
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:569
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:601
SCEnter
#define SCEnter(...)
Definition: util-debug.h:284
SCConfGetNonNull
int SCConfGetNonNull(const char *name, const char **vptr)
Retrieve the non-null value of a configuration node.
Definition: conf.c:381
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:440
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:515
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:1326
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:741
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:321
TmThreadsInitThreadsTimestamp
void TmThreadsInitThreadsTimestamp(const SCTime_t ts)
Definition: tm-threads.c:2320
PcapFileSharedVars_::bpf_string
char * bpf_string
Definition: source-pcap-file-helper.h:50
Packet_::ReleasePacket
void(* ReleasePacket)(struct Packet_ *)
Definition: decode.h:605
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:760
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:261
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:751
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:445
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:299
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