]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
pcap: set snaplen to MTU if available.
authorEric Leblond <eric@regit.org>
Fri, 15 Feb 2013 11:10:25 +0000 (12:10 +0100)
committerVictor Julien <victor@inliniac.net>
Thu, 21 Feb 2013 10:05:36 +0000 (11:05 +0100)
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.

src/source-pcap.c
suricata.yaml.in

index 6d05f1939bc9ba08e2b661cb11fee64096ae5fa2..cb9dd03a37344616c4e59f0d8c5600c9c1af3e4b 100644 (file)
@@ -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);
index 9ce0ebbad3b8a7a885f0129c6c8fd0da4f5efda4..c352d6305cb8473eb5fee0b6bce2bd67a28ac1ff 100644 (file)
@@ -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