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