suricata
source-pcap.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2019 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 Victor Julien <victor@inliniac.net>
22  *
23  * Live pcap packet acquisition support
24  */
25 
26 #include "suricata-common.h"
27 #include "suricata.h"
28 #include "decode.h"
29 #include "packet-queue.h"
30 #include "threads.h"
31 #include "threadvars.h"
32 #include "tm-queuehandlers.h"
33 #include "tm-threads.h"
34 #include "source-pcap.h"
35 #include "conf.h"
36 #include "util-debug.h"
37 #include "util-error.h"
38 #include "util-privs.h"
39 #include "util-datalink.h"
40 #include "util-device.h"
41 #include "util-optimize.h"
42 #include "util-checksum.h"
43 #include "util-ioctl.h"
44 #include "util-time.h"
45 #include "tmqh-packetpool.h"
46 
47 #define PCAP_STATE_DOWN 0
48 #define PCAP_STATE_UP 1
49 
50 #define PCAP_RECONNECT_TIMEOUT 500000
51 
52 /**
53  * \brief 64bit pcap stats counters.
54  *
55  * libpcap only supports 32bit counters. They will eventually wrap around.
56  *
57  * Keep track of libpcap counters as 64bit counters to keep on counting even
58  * if libpcap's 32bit counters wrap around.
59  * Requires pcap_stats() to be called before 32bit stats wrap around twice,
60  * which we do.
61  */
62 typedef struct PcapStats64_ {
63  uint64_t ps_recv;
64  uint64_t ps_drop;
65  uint64_t ps_ifdrop;
67 
68 /**
69  * \brief Structure to hold thread specific variables.
70  */
71 typedef struct PcapThreadVars_
72 {
73  /* thread specific handle */
74  pcap_t *pcap_handle;
75  /* handle state */
76  unsigned char pcap_state;
77  /* thread specific bpf */
78  struct bpf_program filter;
79  /* ptr to string from config */
80  const char *bpf_filter;
81 
83 
84  /* data link type for the thread */
85  int datalink;
86 
87  /* counters */
88  uint64_t pkts;
89  uint64_t bytes;
90 
94 
97 
98  /** callback result -- set if one of the thread module failed. */
99  int cb_result;
100 
101  /* pcap buffer size */
104 
106 
108 
111 
112 static TmEcode ReceivePcapThreadInit(ThreadVars *, const void *, void **);
113 static void ReceivePcapThreadExitStats(ThreadVars *, void *);
114 static TmEcode ReceivePcapLoop(ThreadVars *tv, void *data, void *slot);
115 static TmEcode ReceivePcapBreakLoop(ThreadVars *tv, void *data);
116 
117 static TmEcode DecodePcapThreadInit(ThreadVars *, const void *, void **);
118 static TmEcode DecodePcapThreadDeinit(ThreadVars *tv, void *data);
119 static TmEcode DecodePcap(ThreadVars *, Packet *, void *);
120 
121 #ifdef UNITTESTS
122 static void SourcePcapRegisterTests(void);
123 #endif
124 
125 /** protect pcap_compile and pcap_setfilter, as they are not thread safe:
126  * http://seclists.org/tcpdump/2009/q1/62 */
127 static SCMutex pcap_bpf_compile_lock = SCMUTEX_INITIALIZER;
128 
129 /**
130  * \brief Registration Function for ReceivePcap.
131  */
133 {
134  tmm_modules[TMM_RECEIVEPCAP].name = "ReceivePcap";
135  tmm_modules[TMM_RECEIVEPCAP].ThreadInit = ReceivePcapThreadInit;
136  tmm_modules[TMM_RECEIVEPCAP].PktAcqLoop = ReceivePcapLoop;
137  tmm_modules[TMM_RECEIVEPCAP].PktAcqBreakLoop = ReceivePcapBreakLoop;
138  tmm_modules[TMM_RECEIVEPCAP].ThreadExitPrintStats = ReceivePcapThreadExitStats;
141 #ifdef UNITTESTS
142  tmm_modules[TMM_RECEIVEPCAP].RegisterTests = SourcePcapRegisterTests;
143 #endif
144 }
145 
146 /**
147  * \brief Registration Function for DecodePcap.
148  */
150 {
151  tmm_modules[TMM_DECODEPCAP].name = "DecodePcap";
152  tmm_modules[TMM_DECODEPCAP].ThreadInit = DecodePcapThreadInit;
153  tmm_modules[TMM_DECODEPCAP].Func = DecodePcap;
154  tmm_modules[TMM_DECODEPCAP].ThreadDeinit = DecodePcapThreadDeinit;
156 }
157 
158 /**
159  * \brief Update 64 bit |last| value from |current32| value taking one
160  * wrap-around into account.
161  */
162 static inline void UpdatePcapStatsValue64(uint64_t *last, uint32_t current32)
163 {
164  /* uint64_t -> uint32_t is defined behaviour. It slices lower 32bits. */
165  uint32_t last32 = *last;
166 
167  /* Branchless code as wrap-around is defined for unsigned */
168  *last += (uint32_t)(current32 - last32);
169 
170  /* Same calculation as:
171  if (likely(current32 >= last32)) {
172  *last += current32 - last32;
173  } else {
174  *last += (1ull << 32) + current32 - last32;
175  }
176  */
177 }
178 
179 /**
180  * \brief Update 64 bit |last| stat values with values from |current|
181  * 32 bit pcap_stat.
182  */
183 static inline void UpdatePcapStats64(
184  PcapStats64 *last, const struct pcap_stat *current)
185 {
186  UpdatePcapStatsValue64(&last->ps_recv, current->ps_recv);
187  UpdatePcapStatsValue64(&last->ps_drop, current->ps_drop);
188  UpdatePcapStatsValue64(&last->ps_ifdrop, current->ps_ifdrop);
189 }
190 
191 static inline void PcapDumpCounters(PcapThreadVars *ptv)
192 {
193  struct pcap_stat pcap_s;
194  if (likely((pcap_stats(ptv->pcap_handle, &pcap_s) >= 0))) {
195  UpdatePcapStats64(&ptv->last_stats64, &pcap_s);
196 
198  ptv->last_stats64.ps_recv);
199  StatsSetUI64(
200  ptv->tv, ptv->capture_kernel_drops, ptv->last_stats64.ps_drop);
201  (void)SC_ATOMIC_SET(ptv->livedev->drop, ptv->last_stats64.ps_drop);
203  ptv->last_stats64.ps_ifdrop);
204  }
205 }
206 
207 static int PcapTryReopen(PcapThreadVars *ptv)
208 {
210 
211  int pcap_activate_r = pcap_activate(ptv->pcap_handle);
212  if (pcap_activate_r != 0 && pcap_activate_r != PCAP_ERROR_ACTIVATED) {
213  return pcap_activate_r;
214  }
215 
216  /* set bpf filter if we have one */
217  if (ptv->bpf_filter != NULL) {
218  if (pcap_compile(ptv->pcap_handle, &ptv->filter,
219  (char *)ptv->bpf_filter, 1, 0) < 0)
220  {
221  SCLogError("bpf compilation error %s", pcap_geterr(ptv->pcap_handle));
222  return -1;
223  }
224 
225  if (pcap_setfilter(ptv->pcap_handle, &ptv->filter) < 0) {
226  SCLogError("could not set bpf filter %s", pcap_geterr(ptv->pcap_handle));
227  return -1;
228  }
229  }
230 
231  SCLogInfo("Recovering interface listening");
232  ptv->pcap_state = PCAP_STATE_UP;
233  return 0;
234 }
235 
236 static void PcapCallbackLoop(char *user, struct pcap_pkthdr *h, u_char *pkt)
237 {
238  SCEnter();
239 
240  PcapThreadVars *ptv = (PcapThreadVars *)user;
242 
243  if (unlikely(p == NULL)) {
244  SCReturn;
245  }
246 
248  p->ts = SCTIME_FROM_TIMEVAL(&h->ts);
249  SCLogDebug("p->ts.tv_sec %" PRIuMAX "", (uintmax_t)SCTIME_SECS(p->ts));
250  p->datalink = ptv->datalink;
251 
252  ptv->pkts++;
253  ptv->bytes += h->caplen;
254  (void) SC_ATOMIC_ADD(ptv->livedev->pkts, 1);
255  p->livedev = ptv->livedev;
256 
257  if (unlikely(PacketCopyData(p, pkt, h->caplen))) {
258  TmqhOutputPacketpool(ptv->tv, p);
259  SCReturn;
260  }
261 
262  switch (ptv->checksum_mode) {
264  if (ChecksumAutoModeCheck(ptv->pkts,
265  SC_ATOMIC_GET(ptv->livedev->pkts),
266  SC_ATOMIC_GET(ptv->livedev->invalid_checksums))) {
269  }
270  break;
273  break;
274  default:
275  break;
276  }
277 
278  if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) {
279  pcap_breakloop(ptv->pcap_handle);
280  ptv->cb_result = TM_ECODE_FAILED;
281  }
282 
283  /* Trigger one dump of stats every second */
284  SCTime_t current_time = TimeGet();
285  if ((time_t)SCTIME_SECS(current_time) != ptv->last_stats_dump) {
286  PcapDumpCounters(ptv);
287  ptv->last_stats_dump = SCTIME_SECS(current_time);
288  }
289 
290  SCReturn;
291 }
292 
293 #ifndef PCAP_ERROR_BREAK
294 #define PCAP_ERROR_BREAK -2
295 #endif
296 
297 /**
298  * \brief Main PCAP reading Loop function
299  */
300 static TmEcode ReceivePcapLoop(ThreadVars *tv, void *data, void *slot)
301 {
302  SCEnter();
303 
304  int packet_q_len = 64;
305  PcapThreadVars *ptv = (PcapThreadVars *)data;
306  TmSlot *s = (TmSlot *)slot;
307 
308  ptv->slot = s->slot_next;
309  ptv->cb_result = TM_ECODE_OK;
310 
311  // Indicate that the thread is actually running its application level code (i.e., it can poll
312  // packets)
314 
315  while (1) {
318  }
319 
320  /* make sure we have at least one packet in the packet pool, to prevent
321  * us from alloc'ing packets at line rate */
322  PacketPoolWait();
323 
324  int r = pcap_dispatch(ptv->pcap_handle, packet_q_len,
325  (pcap_handler)PcapCallbackLoop, (u_char *)ptv);
326  if (unlikely(r == 0 || r == PCAP_ERROR_BREAK || (r > 0 && r < packet_q_len))) {
327  if (r == PCAP_ERROR_BREAK && ptv->cb_result == TM_ECODE_FAILED) {
329  }
330  TmThreadsCaptureHandleTimeout(tv, NULL);
331  } else if (unlikely(r < 0)) {
332  int dbreak = 0;
333  SCLogError("error code %" PRId32 " %s", r, pcap_geterr(ptv->pcap_handle));
334  do {
335  usleep(PCAP_RECONNECT_TIMEOUT);
336  if (suricata_ctl_flags != 0) {
337  dbreak = 1;
338  break;
339  }
340  r = PcapTryReopen(ptv);
341  } while (r < 0);
342  if (dbreak) {
343  break;
344  }
345  } else if (ptv->cb_result == TM_ECODE_FAILED) {
346  SCLogError("Pcap callback PcapCallbackLoop failed");
348  }
349 
351  }
352 
353  PcapDumpCounters(ptv);
356 }
357 
358 /**
359  * \brief PCAP Break Loop function.
360  */
361 static TmEcode ReceivePcapBreakLoop(ThreadVars *tv, void *data)
362 {
363  SCEnter();
364  PcapThreadVars *ptv = (PcapThreadVars *)data;
365  if (ptv->pcap_handle == NULL) {
367  }
368  pcap_breakloop(ptv->pcap_handle);
370 }
371 
372 /**
373  * \brief Init function for ReceivePcap.
374  *
375  * This is a setup function for receiving packets
376  * via libpcap. There are two versions of this function
377  * depending on the major version of libpcap used.
378  * For versions prior to 1.x we use open_pcap_live,
379  * for versions 1.x and greater we use pcap_create + pcap_activate.
380  *
381  * \param tv pointer to ThreadVars
382  * \param initdata pointer to the interface passed from the user
383  * \param data pointer gets populated with PcapThreadVars
384  *
385  * \todo Create a general pcap setup function.
386  */
387 static TmEcode ReceivePcapThreadInit(ThreadVars *tv, const void *initdata, void **data)
388 {
389  SCEnter();
390  PcapIfaceConfig *pcapconfig = (PcapIfaceConfig *)initdata;
391 
392  if (initdata == NULL) {
393  SCLogError("initdata == NULL");
395  }
396 
397  PcapThreadVars *ptv = SCCalloc(1, sizeof(PcapThreadVars));
398  if (unlikely(ptv == NULL)) {
399  pcapconfig->DerefFunc(pcapconfig);
401  }
402 
403  ptv->tv = tv;
404 
405  ptv->livedev = LiveGetDevice(pcapconfig->iface);
406  if (ptv->livedev == NULL) {
407  SCLogError("unable to find Live device");
408  SCFree(ptv);
410  }
411  SCLogInfo("using interface %s", (char *)pcapconfig->iface);
412 
413  if (LiveGetOffload() == 0) {
414  (void)GetIfaceOffloading((char *)pcapconfig->iface, 1, 1);
415  } else {
416  DisableIfaceOffloading(ptv->livedev, 1, 1);
417  }
418 
419  ptv->checksum_mode = pcapconfig->checksum_mode;
421  SCLogInfo("running in 'auto' checksum mode. Detection of interface "
422  "state will require " xstr(CHECKSUM_SAMPLE_COUNT) " packets");
423  }
424 
425  char errbuf[PCAP_ERRBUF_SIZE];
426  ptv->pcap_handle = pcap_create((char *)pcapconfig->iface, errbuf);
427  if (ptv->pcap_handle == NULL) {
428  if (strlen(errbuf)) {
429  SCLogError("could not create a new "
430  "pcap handler for %s, error %s",
431  (char *)pcapconfig->iface, errbuf);
432  } else {
433  SCLogError("could not create a new "
434  "pcap handler for %s",
435  (char *)pcapconfig->iface);
436  }
437  SCFree(ptv);
438  pcapconfig->DerefFunc(pcapconfig);
440  }
441 
442  if (pcapconfig->snaplen == 0) {
443  /* We set snaplen if we can get the MTU */
444  ptv->pcap_snaplen = GetIfaceMaxPacketSize(pcapconfig->iface);
445  } else {
446  ptv->pcap_snaplen = pcapconfig->snaplen;
447  }
448  if (ptv->pcap_snaplen > 0) {
449  /* set Snaplen. Must be called before pcap_activate */
450  int pcap_set_snaplen_r = pcap_set_snaplen(ptv->pcap_handle, ptv->pcap_snaplen);
451  if (pcap_set_snaplen_r != 0) {
452  SCLogError("could not set snaplen, "
453  "error: %s",
454  pcap_geterr(ptv->pcap_handle));
455  SCFree(ptv);
456  pcapconfig->DerefFunc(pcapconfig);
458  }
459  SCLogInfo("Set snaplen to %d for '%s'", ptv->pcap_snaplen,
460  pcapconfig->iface);
461  }
462 
463  /* set Promisc, and Timeout. Must be called before pcap_activate */
464  int pcap_set_promisc_r = pcap_set_promisc(ptv->pcap_handle, pcapconfig->promisc);
465  if (pcap_set_promisc_r != 0) {
466  SCLogError("could not set promisc mode, "
467  "error %s",
468  pcap_geterr(ptv->pcap_handle));
469  SCFree(ptv);
470  pcapconfig->DerefFunc(pcapconfig);
472  }
473 
474  int pcap_set_timeout_r = pcap_set_timeout(ptv->pcap_handle, LIBPCAP_COPYWAIT);
475  if (pcap_set_timeout_r != 0) {
476  SCLogError("could not set timeout, "
477  "error %s",
478  pcap_geterr(ptv->pcap_handle));
479  SCFree(ptv);
480  pcapconfig->DerefFunc(pcapconfig);
482  }
483 #ifdef HAVE_PCAP_SET_BUFF
484  ptv->pcap_buffer_size = pcapconfig->buffer_size;
485  if (ptv->pcap_buffer_size > 0) {
486  SCLogInfo("going to use pcap buffer size of %" PRId32,
487  ptv->pcap_buffer_size);
488 
489  int pcap_set_buffer_size_r = pcap_set_buffer_size(ptv->pcap_handle,
490  ptv->pcap_buffer_size);
491  if (pcap_set_buffer_size_r != 0) {
492  SCLogError("could not set "
493  "pcap buffer size, error %s",
494  pcap_geterr(ptv->pcap_handle));
495  SCFree(ptv);
496  pcapconfig->DerefFunc(pcapconfig);
498  }
499  }
500 #endif /* HAVE_PCAP_SET_BUFF */
501 
502  /* activate the handle */
503  int pcap_activate_r = pcap_activate(ptv->pcap_handle);
504  if (pcap_activate_r != 0) {
505  SCLogError("could not activate the "
506  "pcap handler, error %s",
507  pcap_geterr(ptv->pcap_handle));
508  SCFree(ptv);
509  pcapconfig->DerefFunc(pcapconfig);
511  }
512  ptv->pcap_state = PCAP_STATE_UP;
513 
514  /* set bpf filter if we have one */
515  if (pcapconfig->bpf_filter) {
516  SCMutexLock(&pcap_bpf_compile_lock);
517 
518  ptv->bpf_filter = pcapconfig->bpf_filter;
519 
520  if (pcap_compile(ptv->pcap_handle, &ptv->filter,
521  (char *)ptv->bpf_filter, 1, 0) < 0)
522  {
523  SCLogError("bpf compilation error %s", pcap_geterr(ptv->pcap_handle));
524 
525  SCMutexUnlock(&pcap_bpf_compile_lock);
526  SCFree(ptv);
527  pcapconfig->DerefFunc(pcapconfig);
528  return TM_ECODE_FAILED;
529  }
530 
531  if (pcap_setfilter(ptv->pcap_handle, &ptv->filter) < 0) {
532  SCLogError("could not set bpf filter %s", pcap_geterr(ptv->pcap_handle));
533 
534  SCMutexUnlock(&pcap_bpf_compile_lock);
535  SCFree(ptv);
536  pcapconfig->DerefFunc(pcapconfig);
537  return TM_ECODE_FAILED;
538  }
539 
540  SCMutexUnlock(&pcap_bpf_compile_lock);
541  }
542 
543  /* no offloading supported at all */
544  (void)GetIfaceOffloading(pcapconfig->iface, 1, 1);
545 
546  ptv->datalink = pcap_datalink(ptv->pcap_handle);
548 
549  pcapconfig->DerefFunc(pcapconfig);
550 
551  ptv->capture_kernel_packets = StatsRegisterCounter("capture.kernel_packets",
552  ptv->tv);
553  ptv->capture_kernel_drops = StatsRegisterCounter("capture.kernel_drops",
554  ptv->tv);
555  ptv->capture_kernel_ifdrops = StatsRegisterCounter("capture.kernel_ifdrops",
556  ptv->tv);
557 
558  *data = (void *)ptv;
560 }
561 
562 /**
563  * \brief This function prints stats to the screen at exit.
564  * \param tv pointer to ThreadVars
565  * \param data pointer that gets cast into PcapThreadVars for ptv
566  */
567 static void ReceivePcapThreadExitStats(ThreadVars *tv, void *data)
568 {
569  SCEnter();
570  PcapThreadVars *ptv = (PcapThreadVars *)data;
571  struct pcap_stat pcap_s;
572 
573  if (pcap_stats(ptv->pcap_handle, &pcap_s) < 0) {
574  SCLogError("(%s) Failed to get pcap_stats: %s", tv->name, pcap_geterr(ptv->pcap_handle));
575  SCLogInfo("(%s) Packets %" PRIu64 ", bytes %" PRIu64 "", tv->name,
576  ptv->pkts, ptv->bytes);
577  } else {
578  SCLogInfo("(%s) Packets %" PRIu64 ", bytes %" PRIu64 "", tv->name,
579  ptv->pkts, ptv->bytes);
580 
581  /* these numbers are not entirely accurate as ps_recv contains packets
582  * that are still waiting to be processed at exit. ps_drop only contains
583  * packets dropped by the driver and not any packets dropped by the interface.
584  * Additionally see http://tracker.icir.org/bro/ticket/18
585  *
586  * Note: ps_recv includes dropped packets and should be considered total.
587  * Unless we start to look at ps_ifdrop which isn't supported everywhere.
588  */
589  UpdatePcapStats64(&ptv->last_stats64, &pcap_s);
590  float drop_percent =
591  likely(ptv->last_stats64.ps_recv > 0)
592  ? (((float)ptv->last_stats64.ps_drop) /
593  (float)ptv->last_stats64.ps_recv) *
594  100
595  : 0;
596  SCLogInfo("(%s) Pcap Total:%" PRIu64 " Recv:%" PRIu64 " Drop:%" PRIu64
597  " (%02.1f%%).",
598  tv->name, ptv->last_stats64.ps_recv,
600  ptv->last_stats64.ps_drop, drop_percent);
601  }
602 }
603 
604 /**
605  * \brief This function passes off to link type decoders.
606  *
607  * DecodePcap decodes packets from libpcap and passes
608  * them off to the proper link type decoder.
609  *
610  * \param t pointer to ThreadVars
611  * \param p pointer to the current packet
612  * \param data pointer that gets cast into PcapThreadVars for ptv
613  */
614 static TmEcode DecodePcap(ThreadVars *tv, Packet *p, void *data)
615 {
616  SCEnter();
618 
620 
621  /* update counters */
623 
624  DecodeLinkLayer(tv, dtv, p->datalink, p, GET_PKT_DATA(p), GET_PKT_LEN(p));
625 
627 
629 }
630 
631 static TmEcode DecodePcapThreadInit(ThreadVars *tv, const void *initdata, void **data)
632 {
633  SCEnter();
634 
636  if (dtv == NULL)
638 
640 
641  *data = (void *)dtv;
642 
644 }
645 
646 static TmEcode DecodePcapThreadDeinit(ThreadVars *tv, void *data)
647 {
648  if (data != NULL)
649  DecodeThreadVarsFree(tv, data);
651 }
652 
653 void PcapTranslateIPToDevice(char *pcap_dev, size_t len)
654 {
655  char errbuf[PCAP_ERRBUF_SIZE];
656  pcap_if_t *alldevsp = NULL;
657 
658  struct addrinfo ai_hints;
659  struct addrinfo *ai_list = NULL;
660 
661  memset(&ai_hints, 0, sizeof(ai_hints));
662  ai_hints.ai_family = AF_UNSPEC;
663  ai_hints.ai_flags = AI_NUMERICHOST;
664 
665  /* try to translate IP */
666  if (getaddrinfo(pcap_dev, NULL, &ai_hints, &ai_list) != 0) {
667  return;
668  }
669 
670  if (pcap_findalldevs(&alldevsp, errbuf)) {
671  freeaddrinfo(ai_list);
672  return;
673  }
674 
675  for (pcap_if_t *devsp = alldevsp; devsp ; devsp = devsp->next) {
676  for (pcap_addr_t *ip = devsp->addresses; ip ; ip = ip->next) {
677 
678  if (ai_list->ai_family != ip->addr->sa_family) {
679  continue;
680  }
681 
682  if (ip->addr->sa_family == AF_INET) {
683  if (memcmp(&((struct sockaddr_in*)ai_list->ai_addr)->sin_addr,
684  &((struct sockaddr_in*)ip->addr)->sin_addr,
685  sizeof(struct in_addr)))
686  {
687  continue;
688  }
689  } else if (ip->addr->sa_family == AF_INET6) {
690  if (memcmp(&((struct sockaddr_in6*)ai_list->ai_addr)->sin6_addr,
691  &((struct sockaddr_in6*)ip->addr)->sin6_addr,
692  sizeof(struct in6_addr)))
693  {
694  continue;
695  }
696  } else {
697  continue;
698  }
699 
700  freeaddrinfo(ai_list);
701 
702  memset(pcap_dev, 0, len);
703  strlcpy(pcap_dev, devsp->name, len);
704 
705  pcap_freealldevs(alldevsp);
706  return;
707  }
708  }
709 
710  freeaddrinfo(ai_list);
711 
712  pcap_freealldevs(alldevsp);
713 }
714 
715 /*
716  * unittests
717  */
718 
719 #ifdef UNITTESTS
720 #include "tests/source-pcap.c"
721 /**
722  * \brief Register the Unit tests for pcap source
723  */
724 static void SourcePcapRegisterTests(void)
725 {
726  SourcePcapRegisterStatsTests();
727 }
728 #endif /* UNITTESTS */
TmModule_::cap_flags
uint8_t cap_flags
Definition: tm-modules.h:73
PcapThreadVars_::capture_kernel_ifdrops
uint16_t capture_kernel_ifdrops
Definition: source-pcap.c:93
PcapThreadVars_::cb_result
int cb_result
Definition: source-pcap.c:99
tm-threads.h
len
uint8_t len
Definition: app-layer-dnp3.h:2
source-pcap.h
PcapThreadVars_::livedev
LiveDevice * livedev
Definition: source-pcap.c:107
ThreadVars_::name
char name[16]
Definition: threadvars.h:64
PcapThreadVars_::pcap_buffer_size
int pcap_buffer_size
Definition: source-pcap.c:102
PcapThreadVars_::filter
struct bpf_program filter
Definition: source-pcap.c:78
PacketCopyData
int PacketCopyData(Packet *p, const uint8_t *pktdata, uint32_t pktlen)
Copy data to Packet payload and set packet length.
Definition: decode.c:292
PKT_IS_PSEUDOPKT
#define PKT_IS_PSEUDOPKT(p)
return 1 if the packet is a pseudo packet
Definition: decode.h:1063
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:387
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
TmThreadsSetFlag
void TmThreadsSetFlag(ThreadVars *tv, uint32_t flag)
Set a thread flag.
Definition: tm-threads.c:99
LiveGetOffload
int LiveGetOffload(void)
Definition: util-device.c:81
PcapIfaceConfig_::promisc
int promisc
Definition: source-pcap.h:54
util-checksum.h
Packet_::flags
uint32_t flags
Definition: decode.h:464
threads.h
PcapIfaceConfig_::bpf_filter
const char * bpf_filter
Definition: source-pcap.h:56
PcapThreadVars_::bpf_filter
const char * bpf_filter
Definition: source-pcap.c:80
LiveDevice_
Definition: util-device.h:49
SC_ATOMIC_ADD
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
Definition: util-atomic.h:333
StatsSetUI64
void StatsSetUI64(ThreadVars *tv, uint16_t id, uint64_t x)
Sets a value of type double to the local counter.
Definition: counters.c:210
THV_RUNNING
#define THV_RUNNING
Definition: threadvars.h:54
CHECKSUM_SAMPLE_COUNT
#define CHECKSUM_SAMPLE_COUNT
Definition: util-checksum.h:35
packet-queue.h
PcapStats64_::ps_drop
uint64_t ps_drop
Definition: source-pcap.c:64
SURICATA_STOP
#define SURICATA_STOP
Definition: suricata.h:89
SCMutexLock
#define SCMutexLock(mut)
Definition: threads-debug.h:117
util-privs.h
StatsSyncCountersIfSignalled
#define StatsSyncCountersIfSignalled(tv)
Definition: counters.h:140
CHECKSUM_VALIDATION_DISABLE
@ CHECKSUM_VALIDATION_DISABLE
Definition: decode.h:45
SCMUTEX_INITIALIZER
#define SCMUTEX_INITIALIZER
Definition: threads-debug.h:121
PacketDecodeFinalize
void PacketDecodeFinalize(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p)
Finalize decoding of a packet.
Definition: decode.c:147
PcapThreadVars_::bytes
uint64_t bytes
Definition: source-pcap.c:89
TmqhOutputPacketpool
void TmqhOutputPacketpool(ThreadVars *t, Packet *p)
Definition: tmqh-packetpool.c:356
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:85
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
tmqh-packetpool.h
TmModule_::PktAcqLoop
TmEcode(* PktAcqLoop)(ThreadVars *, void *, void *)
Definition: tm-modules.h:54
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:84
source-pcap.c
PcapThreadVars_::pkts
uint64_t pkts
Definition: source-pcap.c:88
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
PcapTranslateIPToDevice
void PcapTranslateIPToDevice(char *pcap_dev, size_t len)
Definition: source-pcap.c:653
TmModule_::ThreadDeinit
TmEcode(* ThreadDeinit)(ThreadVars *, void *)
Definition: tm-modules.h:49
Packet_::datalink
int datalink
Definition: decode.h:608
GetIfaceMaxPacketSize
int GetIfaceMaxPacketSize(const char *pcap_dev)
output max packet size for a link
Definition: util-ioctl.c:130
PcapIfaceConfig_::snaplen
int snaplen
Definition: source-pcap.h:52
PKT_SET_SRC
#define PKT_SET_SRC(p, src_val)
Definition: decode.h:1066
DecodeRegisterPerfCounters
void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv)
Definition: decode.c:526
CHECKSUM_VALIDATION_AUTO
@ CHECKSUM_VALIDATION_AUTO
Definition: decode.h:47
LIBPCAP_COPYWAIT
#define LIBPCAP_COPYWAIT
Definition: source-pcap.h:31
decode.h
util-device.h
util-debug.h
PKT_SRC_WIRE
@ PKT_SRC_WIRE
Definition: decode.h:54
util-error.h
TmModule_::PktAcqBreakLoop
TmEcode(* PktAcqBreakLoop)(ThreadVars *, void *)
Definition: tm-modules.h:57
PcapThreadVars_::capture_kernel_packets
uint16_t capture_kernel_packets
Definition: source-pcap.c:91
PcapThreadVars_::slot
TmSlot * slot
Definition: source-pcap.c:96
PcapStats64_::ps_recv
uint64_t ps_recv
Definition: source-pcap.c:63
PCAP_STATE_DOWN
#define PCAP_STATE_DOWN
Definition: source-pcap.c:47
Packet_::ts
SCTime_t ts
Definition: decode.h:472
SCMutexUnlock
#define SCMutexUnlock(mut)
Definition: threads-debug.h:119
LiveGetDevice
LiveDevice * LiveGetDevice(const char *name)
Get a pointer to the device at idx.
Definition: util-device.c:242
PCAP_RECONNECT_TIMEOUT
#define PCAP_RECONNECT_TIMEOUT
Definition: source-pcap.c:50
SCEnter
#define SCEnter(...)
Definition: util-debug.h:271
GET_PKT_DATA
#define GET_PKT_DATA(p)
Definition: decode.h:220
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
PCAP_STATE_UP
#define PCAP_STATE_UP
Definition: source-pcap.c:48
SCTIME_FROM_TIMEVAL
#define SCTIME_FROM_TIMEVAL(tv)
Definition: util-time.h:71
TmModule_::Func
TmEcode(* Func)(ThreadVars *, Packet *, void *)
Definition: tm-modules.h:52
util-time.h
PcapThreadVars
struct PcapThreadVars_ PcapThreadVars
Structure to hold thread specific variables.
PcapIfaceConfig_::buffer_size
int buffer_size
Definition: source-pcap.h:50
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:295
xstr
#define xstr(s)
Definition: suricata-common.h:285
PcapThreadVars_::capture_kernel_drops
uint16_t capture_kernel_drops
Definition: source-pcap.c:92
PacketPoolWait
void PacketPoolWait(void)
Definition: tmqh-packetpool.c:69
SCReturn
#define SCReturn
Definition: util-debug.h:273
Packet_
Definition: decode.h:429
TM_FLAG_DECODE_TM
#define TM_FLAG_DECODE_TM
Definition: tm-modules.h:32
PcapIfaceConfig_::DerefFunc
void(* DerefFunc)(void *)
Definition: source-pcap.h:59
tmm_modules
TmModule tmm_modules[TMM_SIZE]
Definition: tm-modules.c:33
GET_PKT_LEN
#define GET_PKT_LEN(p)
Definition: decode.h:219
TimeGet
SCTime_t TimeGet(void)
Definition: util-time.c:152
conf.h
TmModule_::RegisterTests
void(* RegisterTests)(void)
Definition: tm-modules.h:71
TmSlot_
Definition: tm-threads.h:53
PKT_IGNORE_CHECKSUM
#define PKT_IGNORE_CHECKSUM
Definition: decode.h:1023
SCTime_t
Definition: util-time.h:40
Packet_::livedev
struct LiveDevice_ * livedev
Definition: decode.h:587
TmEcode
TmEcode
Definition: tm-threads-common.h:83
GetIfaceOffloading
int GetIfaceOffloading(const char *dev, int csum, int other)
output offloading status of the link
Definition: util-ioctl.c:675
DisableIfaceOffloading
int DisableIfaceOffloading(LiveDevice *dev, int csum, int other)
Definition: util-ioctl.c:688
TmModule_::name
const char * name
Definition: tm-modules.h:44
PcapIfaceConfig_
Definition: source-pcap.h:45
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:224
PcapThreadVars_::tv
ThreadVars * tv
Definition: source-pcap.c:95
TM_FLAG_RECEIVE_TM
#define TM_FLAG_RECEIVE_TM
Definition: tm-modules.h:31
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:33
tm-queuehandlers.h
DecodeThreadVarsFree
void DecodeThreadVarsFree(ThreadVars *tv, DecodeThreadVars *dtv)
Definition: decode.c:713
ChecksumValidationMode
ChecksumValidationMode
Definition: decode.h:44
suricata-common.h
PcapThreadVars_::last_stats64
PcapStats64 last_stats64
Definition: source-pcap.c:109
PcapThreadVars_::pcap_handle
pcap_t * pcap_handle
Definition: source-pcap.c:74
PcapThreadVars_::pcap_state
unsigned char pcap_state
Definition: source-pcap.c:76
SCTIME_SECS
#define SCTIME_SECS(t)
Definition: util-time.h:57
TmModule_::ThreadInit
TmEcode(* ThreadInit)(ThreadVars *, const void *, void **)
Definition: tm-modules.h:47
PcapStats64_
64bit pcap stats counters.
Definition: source-pcap.c:62
PcapIfaceConfig_::iface
char iface[PCAP_IFACE_NAME_LENGTH]
Definition: source-pcap.h:46
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
util-optimize.h
TmModule_::ThreadExitPrintStats
void(* ThreadExitPrintStats)(ThreadVars *, void *)
Definition: tm-modules.h:48
threadvars.h
TMM_DECODEPCAP
@ TMM_DECODEPCAP
Definition: tm-threads-common.h:40
TmModuleDecodePcapRegister
void TmModuleDecodePcapRegister(void)
Registration Function for DecodePcap.
Definition: source-pcap.c:149
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
SCFree
#define SCFree(p)
Definition: util-mem.h:61
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:665
TmModuleReceivePcapRegister
void TmModuleReceivePcapRegister(void)
Registration Function for ReceivePcap.
Definition: source-pcap.c:132
bpf_program
Definition: source-af-packet.c:80
util-ioctl.h
DecodeThreadVarsAlloc
DecodeThreadVars * DecodeThreadVarsAlloc(ThreadVars *tv)
Alloc and setup DecodeThreadVars.
Definition: decode.c:694
PcapStats64_::ps_ifdrop
uint64_t ps_ifdrop
Definition: source-pcap.c:65
suricata.h
PcapIfaceConfig_::checksum_mode
ChecksumValidationMode checksum_mode
Definition: source-pcap.h:57
PcapThreadVars_::last_stats_dump
time_t last_stats_dump
Definition: source-pcap.c:82
TMM_RECEIVEPCAP
@ TMM_RECEIVEPCAP
Definition: tm-threads-common.h:38
likely
#define likely(expr)
Definition: util-optimize.h:32
TmSlot_::slot_next
struct TmSlot_ * slot_next
Definition: tm-threads.h:62
PcapStats64
struct PcapStats64_ PcapStats64
64bit pcap stats counters.
SC_ATOMIC_GET
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
Definition: util-atomic.h:376
PcapThreadVars_
Structure to hold thread specific variables.
Definition: source-pcap.c:72
PcapThreadVars_::checksum_mode
ChecksumValidationMode checksum_mode
Definition: source-pcap.c:105
StatsRegisterCounter
uint16_t StatsRegisterCounter(const char *name, struct ThreadVars_ *tv)
Registers a normal, unqualified counter.
Definition: counters.c:955
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:275
PcapThreadVars_::datalink
int datalink
Definition: source-pcap.c:85
PCAP_ERROR_BREAK
#define PCAP_ERROR_BREAK
Definition: source-pcap.c:294
SCMutex
#define SCMutex
Definition: threads-debug.h:114
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:208
SC_CAP_NET_RAW
#define SC_CAP_NET_RAW
Definition: util-privs.h:32
TmModule_::flags
uint8_t flags
Definition: tm-modules.h:76
DecodeUpdatePacketCounters
void DecodeUpdatePacketCounters(ThreadVars *tv, const DecodeThreadVars *dtv, const Packet *p)
Definition: decode.c:660
suricata_ctl_flags
volatile uint8_t suricata_ctl_flags
Definition: suricata.c:170
PcapThreadVars_::pcap_snaplen
int pcap_snaplen
Definition: source-pcap.c:103