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 */
63typedef 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 */
72typedef 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 */
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 */
106
108
110
113
114static TmEcode ReceivePcapThreadInit(ThreadVars *, const void *, void **);
115static TmEcode ReceivePcapThreadDeinit(ThreadVars *tv, void *data);
116static void ReceivePcapThreadExitStats(ThreadVars *, void *);
117static TmEcode ReceivePcapLoop(ThreadVars *tv, void *data, void *slot);
118static TmEcode ReceivePcapBreakLoop(ThreadVars *tv, void *data);
119
120static TmEcode DecodePcapThreadInit(ThreadVars *, const void *, void **);
121static TmEcode DecodePcapThreadDeinit(ThreadVars *tv, void *data);
122static TmEcode DecodePcap(ThreadVars *, Packet *, void *);
123
124#ifdef UNITTESTS
125static 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 */
130static 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 */
166static 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 */
187static 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
195static 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
202 ptv->last_stats64.ps_recv);
205 (void)SC_ATOMIC_SET(ptv->livedev->drop, ptv->last_stats64.ps_drop);
208 }
209}
210
211static int PcapOpenInterface(PcapThreadVars *ptv)
212{
213 const char *iface = ptv->livedev->dev;
214
215 if (ptv->pcap_handle) {
216 pcap_close(ptv->pcap_handle);
217 ptv->pcap_handle = NULL;
218 if (ptv->filter.bf_insns) {
219 SCBPFFree(&ptv->filter);
220 }
221 }
222
223 if (LiveGetOffload() == 0) {
224 (void)GetIfaceOffloading(iface, 1, 1);
225 } else {
227 }
228
229 char errbuf[PCAP_ERRBUF_SIZE];
230 ptv->pcap_handle = pcap_create(iface, errbuf);
231 if (ptv->pcap_handle == NULL) {
232 if (strlen(errbuf)) {
233 SCLogError("%s: could not create a new pcap handler, error %s", iface, errbuf);
234 } else {
235 SCLogError("%s: could not create a new pcap handler", iface);
236 }
238 }
239
240 if (ptv->pcap_snaplen > 0) {
241 /* set Snaplen. Must be called before pcap_activate */
242 int pcap_set_snaplen_r = pcap_set_snaplen(ptv->pcap_handle, ptv->pcap_snaplen);
243 if (pcap_set_snaplen_r != 0) {
245 "%s: could not set snaplen, error: %s", iface, pcap_geterr(ptv->pcap_handle));
247 }
248 SCLogInfo("%s: snaplen set to %d", iface, ptv->pcap_snaplen);
249 }
250
251 if (ptv->promisc) {
252 /* set Promisc, and Timeout. Must be called before pcap_activate */
253 int pcap_set_promisc_r = pcap_set_promisc(ptv->pcap_handle, ptv->promisc);
254 if (pcap_set_promisc_r != 0) {
255 SCLogError("%s: could not set promisc mode, error %s", iface,
256 pcap_geterr(ptv->pcap_handle));
258 }
259 }
260
261 int pcap_set_timeout_r = pcap_set_timeout(ptv->pcap_handle, LIBPCAP_COPYWAIT);
262 if (pcap_set_timeout_r != 0) {
263 SCLogError("%s: could not set timeout, error %s", iface, pcap_geterr(ptv->pcap_handle));
265 }
266#ifdef HAVE_PCAP_SET_BUFF
267 if (ptv->pcap_buffer_size > 0) {
268 SCLogInfo("%s: going to use pcap buffer size of %" PRId32, iface, ptv->pcap_buffer_size);
269
270 int pcap_set_buffer_size_r = pcap_set_buffer_size(ptv->pcap_handle, ptv->pcap_buffer_size);
271 if (pcap_set_buffer_size_r != 0) {
272 SCLogError("%s: could not set pcap buffer size, error %s", iface,
273 pcap_geterr(ptv->pcap_handle));
275 }
276 }
277#endif /* HAVE_PCAP_SET_BUFF */
278
279 /* activate the handle */
280 int pcap_activate_r = pcap_activate(ptv->pcap_handle);
281 if (pcap_activate_r != 0) {
282 SCLogError("%s: could not activate the pcap handler, error %s", iface,
283 pcap_geterr(ptv->pcap_handle));
284 pcap_close(ptv->pcap_handle);
285 ptv->pcap_handle = NULL;
287 }
289
290 /* set bpf filter if we have one */
291 if (ptv->bpf_filter) {
292 SCMutexLock(&pcap_bpf_compile_lock);
293
294 if (pcap_compile(ptv->pcap_handle, &ptv->filter, (char *)ptv->bpf_filter, 1, 0) < 0) {
295 SCLogError("%s: bpf compilation error %s", iface, pcap_geterr(ptv->pcap_handle));
296 SCMutexUnlock(&pcap_bpf_compile_lock);
297 return TM_ECODE_FAILED;
298 }
299
300 if (pcap_setfilter(ptv->pcap_handle, &ptv->filter) < 0) {
301 SCLogError("%s: could not set bpf filter %s", iface, pcap_geterr(ptv->pcap_handle));
302 SCMutexUnlock(&pcap_bpf_compile_lock);
303 return TM_ECODE_FAILED;
304 }
305
306 SCMutexUnlock(&pcap_bpf_compile_lock);
307 }
308
309 /* no offloading supported at all */
310 (void)GetIfaceOffloading(iface, 1, 1);
311 return TM_ECODE_OK;
312}
313
314static int PcapTryReopen(PcapThreadVars *ptv)
315{
317
318 if (PcapOpenInterface(ptv) != TM_ECODE_OK)
319 return -1;
320
321 SCLogInfo("%s: interface recovered, state is now \"up\"", ptv->livedev->dev);
323 return 0;
324}
325
326static void PcapCallbackLoop(char *user, struct pcap_pkthdr *h, u_char *pkt)
327{
328 SCEnter();
329
330 PcapThreadVars *ptv = (PcapThreadVars *)user;
332
333 if (unlikely(p == NULL)) {
334 SCReturn;
335 }
336
338 p->ts = SCTIME_FROM_TIMEVAL(&h->ts);
339 SCLogDebug("p->ts.tv_sec %" PRIuMAX "", (uintmax_t)SCTIME_SECS(p->ts));
340 p->datalink = ptv->datalink;
341
342 ptv->pkts++;
343 ptv->bytes += h->caplen;
344 (void) SC_ATOMIC_ADD(ptv->livedev->pkts, 1);
345 p->livedev = ptv->livedev;
346
347 if (unlikely(PacketCopyData(p, pkt, h->caplen))) {
348 TmqhOutputPacketpool(ptv->tv, p);
349 SCReturn;
350 }
351
352 switch (ptv->checksum_mode) {
355 SC_ATOMIC_GET(ptv->livedev->pkts),
356 SC_ATOMIC_GET(ptv->livedev->invalid_checksums))) {
359 }
360 break;
363 break;
364 default:
365 break;
366 }
367
368 if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) {
369 pcap_breakloop(ptv->pcap_handle);
371 }
372
373 /* Trigger one dump of stats every second */
374 SCTime_t current_time = TimeGet();
375 if ((time_t)SCTIME_SECS(current_time) != ptv->last_stats_dump) {
376 PcapDumpCounters(ptv);
377 ptv->last_stats_dump = SCTIME_SECS(current_time);
378 }
379
380 SCReturn;
381}
382
383#ifndef PCAP_ERROR_BREAK
384#define PCAP_ERROR_BREAK -2
385#endif
386
387/**
388 * \brief Main PCAP reading Loop function
389 */
390static TmEcode ReceivePcapLoop(ThreadVars *tv, void *data, void *slot)
391{
392 SCEnter();
393
394 int packet_q_len = 64;
395 PcapThreadVars *ptv = (PcapThreadVars *)data;
396 TmSlot *s = (TmSlot *)slot;
397
398 ptv->slot = s->slot_next;
399 ptv->cb_result = TM_ECODE_OK;
400
401 // Indicate that the thread is actually running its application level code (i.e., it can poll
402 // packets)
404
405 while (1) {
408 }
409
410 /* make sure we have at least one packet in the packet pool, to prevent
411 * us from alloc'ing packets at line rate */
413
414 int r = pcap_dispatch(ptv->pcap_handle, packet_q_len,
415 (pcap_handler)PcapCallbackLoop, (u_char *)ptv);
416 if (unlikely(r == 0 || r == PCAP_ERROR_BREAK || (r > 0 && r < packet_q_len))) {
417 if (r == PCAP_ERROR_BREAK && ptv->cb_result == TM_ECODE_FAILED) {
419 }
420 TmThreadsCaptureHandleTimeout(tv, NULL);
421 } else if (unlikely(r < 0)) {
422 int dbreak = 0;
423 SCLogError("error code %" PRId32 " %s", r, pcap_geterr(ptv->pcap_handle));
424 do {
426 if (suricata_ctl_flags != 0) {
427 dbreak = 1;
428 break;
429 }
430 r = PcapTryReopen(ptv);
431 } while (r < 0);
432 if (dbreak) {
433 break;
434 }
435 } else if (ptv->cb_result == TM_ECODE_FAILED) {
436 SCLogError("Pcap callback PcapCallbackLoop failed");
438 }
439
441 }
442
443 PcapDumpCounters(ptv);
446}
447
448/**
449 * \brief PCAP Break Loop function.
450 */
451static TmEcode ReceivePcapBreakLoop(ThreadVars *tv, void *data)
452{
453 SCEnter();
454 PcapThreadVars *ptv = (PcapThreadVars *)data;
455 if (ptv->pcap_handle == NULL) {
457 }
458 pcap_breakloop(ptv->pcap_handle);
460}
461
462/**
463 * \brief Init function for ReceivePcap.
464 *
465 * This is a setup function for receiving packets
466 * via libpcap. There are two versions of this function
467 * depending on the major version of libpcap used.
468 * For versions prior to 1.x we use open_pcap_live,
469 * for versions 1.x and greater we use pcap_create + pcap_activate.
470 *
471 * \param tv pointer to ThreadVars
472 * \param initdata pointer to the interface passed from the user
473 * \param data pointer gets populated with PcapThreadVars
474 *
475 * \todo Create a general pcap setup function.
476 */
477static TmEcode ReceivePcapThreadInit(ThreadVars *tv, const void *initdata, void **data)
478{
479 SCEnter();
480 PcapIfaceConfig *pcapconfig = (PcapIfaceConfig *)initdata;
481
482 if (initdata == NULL) {
483 SCLogError("initdata == NULL");
485 }
486
487 PcapThreadVars *ptv = SCCalloc(1, sizeof(PcapThreadVars));
488 if (unlikely(ptv == NULL)) {
489 pcapconfig->DerefFunc(pcapconfig);
491 }
492
493 ptv->tv = tv;
494
495 ptv->livedev = LiveGetDevice(pcapconfig->iface);
496 if (ptv->livedev == NULL) {
497 SCLogError("unable to find Live device");
498 ReceivePcapThreadDeinit(tv, ptv);
500 }
501
502 if (LiveGetOffload() == 0) {
503 (void)GetIfaceOffloading((char *)pcapconfig->iface, 1, 1);
504 } else {
506 }
507
508 ptv->checksum_mode = pcapconfig->checksum_mode;
510 SCLogInfo("%s: running in 'auto' checksum mode. Detection of interface "
511 "state will require %llu packets",
513 }
514
515 if (pcapconfig->snaplen == 0) {
516 /* We set snaplen if we can get the MTU */
518 } else {
519 ptv->pcap_snaplen = pcapconfig->snaplen;
520 }
521
522 ptv->promisc = pcapconfig->promisc;
523 ptv->pcap_buffer_size = pcapconfig->buffer_size;
524 ptv->bpf_filter = pcapconfig->bpf_filter;
525
526 if (PcapOpenInterface(ptv) != TM_ECODE_OK) {
527 ReceivePcapThreadDeinit(tv, ptv);
528 pcapconfig->DerefFunc(pcapconfig);
530 }
532
533 ptv->datalink = pcap_datalink(ptv->pcap_handle);
535
536 pcapconfig->DerefFunc(pcapconfig);
537
538 ptv->capture_kernel_packets = StatsRegisterCounter("capture.kernel_packets",
539 ptv->tv);
540 ptv->capture_kernel_drops = StatsRegisterCounter("capture.kernel_drops",
541 ptv->tv);
542 ptv->capture_kernel_ifdrops = StatsRegisterCounter("capture.kernel_ifdrops",
543 ptv->tv);
544
545 *data = (void *)ptv;
547}
548
549/**
550 * \brief This function prints stats to the screen at exit.
551 * \param tv pointer to ThreadVars
552 * \param data pointer that gets cast into PcapThreadVars for ptv
553 */
554static void ReceivePcapThreadExitStats(ThreadVars *tv, void *data)
555{
556 SCEnter();
557 PcapThreadVars *ptv = (PcapThreadVars *)data;
558 struct pcap_stat pcap_s;
559
560 if (pcap_stats(ptv->pcap_handle, &pcap_s) < 0) {
561 SCLogError("%s: failed to get pcap_stats: %s", ptv->livedev->dev,
562 pcap_geterr(ptv->pcap_handle));
563 SCLogInfo("%s: packets %" PRIu64 ", bytes %" PRIu64 "", ptv->livedev->dev, ptv->pkts,
564 ptv->bytes);
565 } else {
566 SCLogInfo("%s: packets %" PRIu64 ", bytes %" PRIu64 "", ptv->livedev->dev, ptv->pkts,
567 ptv->bytes);
568
569 /* these numbers are not entirely accurate as ps_recv contains packets
570 * that are still waiting to be processed at exit. ps_drop only contains
571 * packets dropped by the driver and not any packets dropped by the interface.
572 * Additionally see http://tracker.icir.org/bro/ticket/18
573 *
574 * Note: ps_recv includes dropped packets and should be considered total.
575 * Unless we start to look at ps_ifdrop which isn't supported everywhere.
576 */
577 UpdatePcapStats64(&ptv->last_stats64, &pcap_s);
578 float drop_percent =
579 likely(ptv->last_stats64.ps_recv > 0)
580 ? (((float)ptv->last_stats64.ps_drop) /
581 (float)ptv->last_stats64.ps_recv) *
582 100
583 : 0;
584 SCLogInfo("%s: pcap total:%" PRIu64 " recv:%" PRIu64 " drop:%" PRIu64 " (%02.1f%%)",
585 ptv->livedev->dev, ptv->last_stats64.ps_recv,
587 drop_percent);
588 }
589}
590
591static TmEcode ReceivePcapThreadDeinit(ThreadVars *tv, void *data)
592{
593 SCEnter();
594 PcapThreadVars *ptv = (PcapThreadVars *)data;
595 if (ptv != NULL) {
596 if (ptv->pcap_handle != NULL) {
597 pcap_close(ptv->pcap_handle);
598 }
599 if (ptv->filter.bf_insns) {
600 SCBPFFree(&ptv->filter);
601 }
602 SCFree(ptv);
603 }
605}
606
607/**
608 * \brief This function passes off to link type decoders.
609 *
610 * DecodePcap decodes packets from libpcap and passes
611 * them off to the proper link type decoder.
612 *
613 * \param t pointer to ThreadVars
614 * \param p pointer to the current packet
615 * \param data pointer that gets cast into PcapThreadVars for ptv
616 */
617static TmEcode DecodePcap(ThreadVars *tv, Packet *p, void *data)
618{
619 SCEnter();
621
623
624 /* update counters */
626
627 DecodeLinkLayer(tv, dtv, p->datalink, p, GET_PKT_DATA(p), GET_PKT_LEN(p));
628
630
632}
633
634static TmEcode DecodePcapThreadInit(ThreadVars *tv, const void *initdata, void **data)
635{
636 SCEnter();
637
639 if (dtv == NULL)
641
643
644 *data = (void *)dtv;
645
647}
648
649static TmEcode DecodePcapThreadDeinit(ThreadVars *tv, void *data)
650{
651 if (data != NULL)
654}
655
656void PcapTranslateIPToDevice(char *pcap_dev, size_t len)
657{
658 char errbuf[PCAP_ERRBUF_SIZE];
659 pcap_if_t *alldevsp = NULL;
660
661 struct addrinfo ai_hints;
662 struct addrinfo *ai_list = NULL;
663
664 memset(&ai_hints, 0, sizeof(ai_hints));
665 ai_hints.ai_family = AF_UNSPEC;
666 ai_hints.ai_flags = AI_NUMERICHOST;
667
668 /* try to translate IP */
669 if (getaddrinfo(pcap_dev, NULL, &ai_hints, &ai_list) != 0) {
670 return;
671 }
672
673 if (pcap_findalldevs(&alldevsp, errbuf)) {
674 freeaddrinfo(ai_list);
675 return;
676 }
677
678 for (pcap_if_t *devsp = alldevsp; devsp ; devsp = devsp->next) {
679 for (pcap_addr_t *ip = devsp->addresses; ip ; ip = ip->next) {
680
681 if (ai_list->ai_family != ip->addr->sa_family) {
682 continue;
683 }
684
685 if (ip->addr->sa_family == AF_INET) {
686 if (memcmp(&((struct sockaddr_in*)ai_list->ai_addr)->sin_addr,
687 &((struct sockaddr_in*)ip->addr)->sin_addr,
688 sizeof(struct in_addr)))
689 {
690 continue;
691 }
692 } else if (ip->addr->sa_family == AF_INET6) {
693 if (memcmp(&((struct sockaddr_in6*)ai_list->ai_addr)->sin6_addr,
694 &((struct sockaddr_in6*)ip->addr)->sin6_addr,
695 sizeof(struct in6_addr)))
696 {
697 continue;
698 }
699 } else {
700 continue;
701 }
702
703 freeaddrinfo(ai_list);
704
705 memset(pcap_dev, 0, len);
706 strlcpy(pcap_dev, devsp->name, len);
707
708 pcap_freealldevs(alldevsp);
709 return;
710 }
711 }
712
713 freeaddrinfo(ai_list);
714
715 pcap_freealldevs(alldevsp);
716}
717
718/*
719 * unittests
720 */
721
722#ifdef UNITTESTS
723#include "tests/source-pcap.c"
724/**
725 * \brief Register the Unit tests for pcap source
726 */
727static void SourcePcapRegisterTests(void)
728{
729 SourcePcapRegisterStatsTests();
730}
731#endif /* UNITTESTS */
uint8_t len
uint16_t StatsRegisterCounter(const char *name, struct ThreadVars_ *tv)
Registers a normal, unqualified counter.
Definition counters.c:952
void StatsSetUI64(ThreadVars *tv, uint16_t id, uint64_t x)
Sets a value of type double to the local counter.
Definition counters.c:207
void StatsSyncCountersIfSignalled(ThreadVars *tv)
Definition counters.c:450
ChecksumValidationMode
Definition decode.h:42
@ CHECKSUM_VALIDATION_AUTO
Definition decode.h:45
@ CHECKSUM_VALIDATION_DISABLE
Definition decode.h:43
#define PKT_SET_SRC(p, src_val)
Definition decode.h:1325
#define GET_PKT_DATA(p)
Definition decode.h:209
#define GET_PKT_LEN(p)
Definition decode.h:208
#define PKT_IS_PSEUDOPKT(p)
return 1 if the packet is a pseudo packet
Definition decode.h:1321
@ PKT_SRC_WIRE
Definition decode.h:52
#define PKT_IGNORE_CHECKSUM
Definition decode.h:1282
DecodeThreadVars * dtv
ThreadVars * tv
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:293
void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv)
Definition decode.c:628
void PacketDecodeFinalize(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p)
Finalize decoding of a packet.
Definition decode.c:232
DecodeThreadVars * DecodeThreadVarsAlloc(ThreadVars *tv)
Alloc and setup DecodeThreadVars.
Definition decode.c:804
void DecodeThreadVarsFree(ThreadVars *tv, DecodeThreadVars *dtv)
Definition decode.c:822
int PacketCopyData(Packet *p, const uint8_t *pktdata, uint32_t pktlen)
Copy data to Packet payload and set packet length.
Definition decode.c:377
void DecodeUpdatePacketCounters(ThreadVars *tv, const DecodeThreadVars *dtv, const Packet *p)
Definition decode.c:770
void PcapTranslateIPToDevice(char *pcap_dev, size_t len)
#define PCAP_STATE_UP
Definition source-pcap.c:49
#define PCAP_RECONNECT_TIMEOUT
Definition source-pcap.c:51
#define PCAP_STATE_DOWN
Definition source-pcap.c:48
void TmModuleReceivePcapRegister(void)
Registration Function for ReceivePcap.
struct PcapStats64_ PcapStats64
64bit pcap stats counters.
void TmModuleDecodePcapRegister(void)
Registration Function for DecodePcap.
struct PcapThreadVars_ PcapThreadVars
Structure to hold thread specific variables.
#define PCAP_ERROR_BREAK
#define LIBPCAP_COPYWAIT
Definition source-pcap.h:31
Structure to hold thread specific data for all decode modules.
Definition decode.h:963
SCTime_t ts
Definition decode.h:555
int datalink
Definition decode.h:639
struct LiveDevice_ * livedev
Definition decode.h:618
uint32_t flags
Definition decode.h:544
char iface[PCAP_IFACE_NAME_LENGTH]
Definition source-pcap.h:46
ChecksumValidationMode checksum_mode
Definition source-pcap.h:57
const char * bpf_filter
Definition source-pcap.h:56
void(* DerefFunc)(void *)
Definition source-pcap.h:59
64bit pcap stats counters.
Definition source-pcap.c:63
uint64_t ps_recv
Definition source-pcap.c:64
uint64_t ps_drop
Definition source-pcap.c:65
uint64_t ps_ifdrop
Definition source-pcap.c:66
Structure to hold thread specific variables.
Definition source-pcap.c:73
uint16_t capture_kernel_ifdrops
Definition source-pcap.c:94
PcapStats64 last_stats64
uint16_t capture_kernel_drops
Definition source-pcap.c:93
LiveDevice * livedev
struct bpf_program filter
Definition source-pcap.c:79
ChecksumValidationMode checksum_mode
time_t last_stats_dump
Definition source-pcap.c:83
unsigned char pcap_state
Definition source-pcap.c:77
pcap_t * pcap_handle
Definition source-pcap.c:75
ThreadVars * tv
Definition source-pcap.c:96
const char * bpf_filter
Definition source-pcap.c:81
uint16_t capture_kernel_packets
Definition source-pcap.c:92
Per thread variable structure.
Definition threadvars.h:58
const char * name
Definition tm-modules.h:48
TmEcode(* ThreadDeinit)(ThreadVars *, void *)
Definition tm-modules.h:53
void(* RegisterTests)(void)
Definition tm-modules.h:75
void(* ThreadExitPrintStats)(ThreadVars *, void *)
Definition tm-modules.h:52
TmEcode(* PktAcqBreakLoop)(ThreadVars *, void *)
Definition tm-modules.h:61
uint8_t cap_flags
Definition tm-modules.h:77
TmEcode(* Func)(ThreadVars *, Packet *, void *)
Definition tm-modules.h:56
TmEcode(* PktAcqLoop)(ThreadVars *, void *, void *)
Definition tm-modules.h:58
uint8_t flags
Definition tm-modules.h:80
TmEcode(* ThreadInit)(ThreadVars *, const void *, void **)
Definition tm-modules.h:51
struct TmSlot_ * slot_next
Definition tm-threads.h:62
#define BUG_ON(x)
size_t strlcpy(char *dst, const char *src, size_t siz)
volatile uint8_t suricata_ctl_flags
Definition suricata.c:172
#define SURICATA_STOP
Definition suricata.h:94
#define SCMUTEX_INITIALIZER
#define SCMutex
#define SCMutexUnlock(mut)
#define SCMutexLock(mut)
#define THV_RUNNING
Definition threadvars.h:55
TmModule tmm_modules[TMM_SIZE]
Definition tm-modules.c:29
#define TM_FLAG_RECEIVE_TM
Definition tm-modules.h:32
#define TM_FLAG_DECODE_TM
Definition tm-modules.h:33
@ TMM_RECEIVEPCAP
@ TMM_DECODEPCAP
@ TM_ECODE_FAILED
@ TM_ECODE_OK
void TmThreadsSetFlag(ThreadVars *tv, uint32_t flag)
Set a thread flag.
Definition tm-threads.c:101
#define SleepUsec(usec)
Definition tm-threads.h:44
void PacketPoolWait(void)
void TmqhOutputPacketpool(ThreadVars *t, Packet *p)
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
void SCBPFFree(struct bpf_program *program)
Definition util-bpf.c:56
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.
#define CHECKSUM_SAMPLE_COUNT
#define SCEnter(...)
Definition util-debug.h:277
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCReturnInt(x)
Definition util-debug.h:281
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition util-debug.h:225
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267
#define SCReturn
Definition util-debug.h:279
LiveDevice * LiveGetDevice(const char *name)
Get a pointer to the device at idx.
int LiveGetOffload(void)
Definition util-device.c:87
int GetIfaceMaxPacketSize(LiveDevice *ld)
output max packet size for a link
Definition util-ioctl.c:121
int GetIfaceOffloading(const char *dev, int csum, int other)
output offloading status of the link
Definition util-ioctl.c:670
int DisableIfaceOffloading(LiveDevice *dev, int csum, int other)
Definition util-ioctl.c:683
#define SCFree(p)
Definition util-mem.h:61
#define SCCalloc(nm, sz)
Definition util-mem.h:53
#define likely(expr)
#define unlikely(expr)
#define SC_CAP_NET_RAW
Definition util-privs.h:32
SCTime_t TimeGet(void)
Definition util-time.c:152
#define SCTIME_SECS(t)
Definition util-time.h:57
#define SCTIME_FROM_TIMEVAL(tv)
Definition util-time.h:79