diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 24c6f6f5f1..f28aa66c74 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -3715,6 +3715,9 @@ module GLOBAL; ## Number of bytes per packet to capture from live interfaces. const snaplen = 8192 &redef; +## Number of bytes for libpcap buffer. +const bufsize = 128 &redef; + ## Seed for hashes computed internally for probabilistic data structures. Using ## the same value here will make the hashes compatible between independent Bro ## instances. If left unset, Bro will use a temporary local seed. diff --git a/src/Net.h b/src/Net.h index d19bd9083c..e57c4a8c7f 100644 --- a/src/Net.h +++ b/src/Net.h @@ -73,6 +73,9 @@ extern bool using_communication; // Snaplen passed to libpcap. extern int snaplen; +// Buffer size passed to libpcap. +extern int bufsize; + extern const Packet* current_pkt; extern int current_dispatched; extern double current_timestamp; diff --git a/src/iosource/PktSrc.cc b/src/iosource/PktSrc.cc index f44aae77c5..125a72c052 100644 --- a/src/iosource/PktSrc.cc +++ b/src/iosource/PktSrc.cc @@ -71,6 +71,11 @@ int PktSrc::SnapLen() const return snaplen; // That's a global. Change? } +int PktSrc::BufSize() const + { + return bufsize; // That's a global too. Change? + } + bool PktSrc::IsLive() const { return props.is_live; diff --git a/src/iosource/PktSrc.h b/src/iosource/PktSrc.h index bf4c811dca..d6ff03f5b5 100644 --- a/src/iosource/PktSrc.h +++ b/src/iosource/PktSrc.h @@ -100,6 +100,11 @@ public: */ int SnapLen() const; + /** + * Returns the buffer size for this source. + */ + int BufSize() const; + /** * In pseudo-realtime mode, returns the logical timestamp of the * current packet. Undefined if not running pseudo-realtime mode. diff --git a/src/iosource/pcap/Source.cc b/src/iosource/pcap/Source.cc index 2af21bf9b4..9c5ba2819a 100644 --- a/src/iosource/pcap/Source.cc +++ b/src/iosource/pcap/Source.cc @@ -89,11 +89,53 @@ void PcapSource::OpenLive() // broken on FreeBSD: even when select() indicates that we can read // something, we may get nothing if the store buffer hasn't filled up // yet.) - pd = pcap_open_live(props.path.c_str(), SnapLen(), 1, 1, tmp_errbuf); + pd = pcap_create(props.path.c_str(), errbuf); if ( ! pd ) { - Error(tmp_errbuf); + safe_snprintf(errbuf, sizeof(errbuf), + "pcap_create: %s", pcap_geterr(pd)); + Error(errbuf); + return; + } + + if ( pcap_set_snaplen(pd, SnapLen()) ) + { + safe_snprintf(errbuf, sizeof(errbuf), + "pcap_set_snaplen: %s", pcap_geterr(pd)); + Error(errbuf); + return; + } + + if ( pcap_set_promisc(pd, 1) ) + { + safe_snprintf(errbuf, sizeof(errbuf), + "pcap_set_promisc: %s", pcap_geterr(pd)); + Error(errbuf); + return; + } + + if ( pcap_set_timeout(pd, 1) ) + { + safe_snprintf(errbuf, sizeof(errbuf), + "pcap_set_timeout: %s", pcap_geterr(pd)); + Error(errbuf); + return; + } + + if ( pcap_set_buffer_size(pd, BufSize()) ) + { + safe_snprintf(errbuf, sizeof(errbuf), + "pcap_set_buffer_size: %s", pcap_geterr(pd)); + Error(errbuf); + return; + } + + if ( pcap_activate(pd) ) + { + safe_snprintf(errbuf, sizeof(errbuf), + "pcap_activate: %s", pcap_geterr(pd)); + Error(errbuf); return; } diff --git a/src/main.cc b/src/main.cc index 64acb408ea..347d01137e 100644 --- a/src/main.cc +++ b/src/main.cc @@ -122,6 +122,7 @@ vector params; set requested_plugins; char* proc_status_file = 0; int snaplen = 0; // this gets set from the scripting-layer's value +int bufsize = 0; OpaqueType* md5_type = 0; OpaqueType* sha1_type = 0; @@ -990,6 +991,7 @@ int main(int argc, char** argv) } snaplen = internal_val("snaplen")->AsCount(); + bufsize = internal_val("bufsize")->AsCount() * 1024 * 1024; // Size in Mbytes if ( dns_type != DNS_PRIME ) net_init(interfaces, read_files, writefile, do_watchdog);