From: Eric Leblond Date: Fri, 15 Feb 2013 11:10:25 +0000 (+0100) Subject: pcap: set snaplen to MTU if available. X-Git-Tag: suricata-1.4.1~51 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1aaa828b63f8c4528f3632f52d8576761c9f0dc1;p=thirdparty%2Fsuricata.git pcap: set snaplen to MTU if available. Main objective of this patch is to use a dynamic snaplen to avoid to truncate packet at the currently fixed snaplen. It set snaplen to MTU length if the MTU can be retrieved. If not, it does not set the snaplen which results in using a 65535 snaplen. libpcap is trying to use mmaped capture and setup the ring by using buffer_size as the total memory. It also use "rounded" snaplen as frame size. So if we set snaplen to MTU when available we are optimal regarding the building of the ring. --- diff --git a/src/source-pcap.c b/src/source-pcap.c index 6d05f1939b..cb9dd03a37 100644 --- a/src/source-pcap.c +++ b/src/source-pcap.c @@ -39,6 +39,7 @@ #include "util-device.h" #include "util-optimize.h" #include "util-checksum.h" +#include "util-ioctl.h" #include "tmqh-packetpool.h" extern uint8_t suricata_ctl_flags; @@ -353,6 +354,7 @@ TmEcode ReceivePcapLoop(ThreadVars *tv, void *data, void *slot) TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) { SCEnter(); PcapIfaceConfig *pcapconfig = initdata; + int mtu; if (initdata == NULL) { SCLogError(SC_ERR_INVALID_ARGUMENT, "initdata == NULL"); @@ -399,14 +401,18 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) { SCReturnInt(TM_ECODE_FAILED); } - /* set Snaplen, Promisc, and Timeout. Must be called before pcap_activate */ - int pcap_set_snaplen_r = pcap_set_snaplen(ptv->pcap_handle,LIBPCAP_SNAPLEN); - //printf("ReceivePcapThreadInit: pcap_set_snaplen(%p) returned %" PRId32 "\n", ptv->pcap_handle, pcap_set_snaplen_r); - if (pcap_set_snaplen_r != 0) { - SCLogError(SC_ERR_PCAP_SET_SNAPLEN, "Couldn't set snaplen, error: %s", pcap_geterr(ptv->pcap_handle)); - SCFree(ptv); - pcapconfig->DerefFunc(pcapconfig); - SCReturnInt(TM_ECODE_FAILED); + /* We only set snaplen if we can get the MTU */ + mtu = GetIfaceMTU(pcapconfig->iface); + if (mtu > 0) { + /* set Snaplen, Promisc, and Timeout. Must be called before pcap_activate */ + int pcap_set_snaplen_r = pcap_set_snaplen(ptv->pcap_handle, mtu); + //printf("ReceivePcapThreadInit: pcap_set_snaplen(%p) returned %" PRId32 "\n", ptv->pcap_handle, pcap_set_snaplen_r); + if (pcap_set_snaplen_r != 0) { + SCLogError(SC_ERR_PCAP_SET_SNAPLEN, "Couldn't set snaplen, error: %s", pcap_geterr(ptv->pcap_handle)); + SCFree(ptv); + pcapconfig->DerefFunc(pcapconfig); + SCReturnInt(TM_ECODE_FAILED); + } } int pcap_set_promisc_r = pcap_set_promisc(ptv->pcap_handle,LIBPCAP_PROMISC); diff --git a/suricata.yaml.in b/suricata.yaml.in index 9ce0ebbad3..c352d6305c 100644 --- a/suricata.yaml.in +++ b/suricata.yaml.in @@ -689,7 +689,10 @@ pfring: pcap: - interface: eth0 - #buffer-size: 32768 + # On Linux, pcap will try to use mmaped capture and will use buffer-size + # as total of memory used by the ring. So set this to something bigger + # than 1% of your bandwidth. + #buffer-size: 16777216 #bpf-filter: "tcp and port 25" # Choose checksum verification mode for the interface. At the moment # of the capture, some packets may be with an invalid checksum due to