From 9ce1399db876331ae4660f3d06db015f9b81ee87 Mon Sep 17 00:00:00 2001 From: William Metcalf Date: Wed, 26 May 2010 23:52:28 -0500 Subject: [PATCH] Add option for setting pcap buffer size if it is available --- configure.in | 11 +++++++++++ src/source-pcap.c | 22 ++++++++++++++++++++++ src/suricata.c | 15 +++++++++++++++ src/util-error.c | 2 ++ src/util-error.h | 2 ++ 5 files changed, 52 insertions(+) diff --git a/configure.in b/configure.in index 0e6d0b673a..9ec00a5b44 100644 --- a/configure.in +++ b/configure.in @@ -612,6 +612,17 @@ AC_CHECK_HEADER(pcap.h,,[AC_ERROR(pcap.h not found ...)]) fi LIBS="${TMPLIBS}" +#Appears as if pcap_set_buffer_size is linux only? + LIBPCAPSBUFF="" +#To prevent duping the lib link we reset LIBS after this check. Setting action-if-found to NULL doesn't seem to work +#see: http://blog.flameeyes.eu/2008/04/29/i-consider-ac_check_lib-harmful + TMPLIBS="${LIBS}" + AC_CHECK_LIB(pcap, pcap_set_buffer_size,, LPCAPSBUFF="no") + if test "$LPCAPSBUFF" != "no"; then + CFLAGS="${CFLAGS} -DHAVE_PCAP_SET_BUFF" + fi + LIBS="${TMPLIBS}" + # enable the running of unit tests AC_ARG_ENABLE(unittests, [ --enable-unittests Enable compilation of the unit tests], diff --git a/src/source-pcap.c b/src/source-pcap.c index 6fc3e0b704..643078db80 100644 --- a/src/source-pcap.c +++ b/src/source-pcap.c @@ -71,6 +71,9 @@ typedef struct PcapThreadVars_ uint64_t bytes; uint32_t errs; + /* pcap buffer size */ + int pcap_buffer_size; + ThreadVars *tv; Packet *in_p; @@ -297,6 +300,25 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) { SCFree(ptv); SCReturnInt(TM_ECODE_FAILED); } +#ifdef HAVE_PCAP_SET_BUFF + char *tmppcapbuffsize; + /* set pcap buffer size if specified and supported. Must be done prior to activating the handle */ + if (ConfGet("pcap.buffer-size", &tmppcapbuffsize) == 1){ + if (atoi(tmppcapbuffsize) >= 0 && atoi(tmppcapbuffsize) <= INT_MAX) { + ptv->pcap_buffer_size = (int)atoi(tmppcapbuffsize); + SCLogInfo("Going to use pcap buffer size of %" PRId32 "", ptv->pcap_buffer_size); + + int pcap_set_buffer_size_r = pcap_set_buffer_size(ptv->pcap_handle,ptv->pcap_buffer_size); + //printf("ReceivePcapThreadInit: pcap_set_timeout(%p) returned %" PRId32 "\n", ptv->pcap_handle, pcap_set_buffer_size_r); + if (pcap_set_buffer_size_r != 0) { + SCLogError(SC_ERR_PCAP_SET_BUFF_SIZE, "Problems setting pcap buffer size, error %s", pcap_geterr(ptv->pcap_handle)); + SCFree(ptv); + SCReturnInt(TM_ECODE_FAILED); + } + + } + } +#endif /* HAVE_PCAP_SET_BUFF */ /* activate the handle */ int pcap_activate_r = pcap_activate(ptv->pcap_handle); diff --git a/src/suricata.c b/src/suricata.c index cf08f9024b..e35d335ee2 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -300,6 +300,9 @@ void usage(const char *progname) printf("\t--pidfile : write pid to this file (only for daemon mode)\n"); printf("\t--init-errors-fatal : enable fatal failure on signature init error\n"); printf("\t--dump-config : show the running configuration\n"); +#ifdef HAVE_PCAP_SET_BUFF + printf("\t--pcap-buffer-size : size of the pcap buffer value from 0 - %i\n",INT_MAX); +#endif /* HAVE_SET_PCAP_BUFF */ #ifdef HAVE_PFRING printf("\t--pfring-int : run in pfring mode\n"); printf("\t--pfring-cluster-id : pfring cluster id \n"); @@ -367,6 +370,7 @@ int main(int argc, char **argv) {"pfring-int", required_argument, 0, 0}, {"pfring-cluster-id", required_argument, 0, 0}, {"pfring-cluster-type", required_argument, 0, 0}, + {"pcap-buffer-size", required_argument, 0, 0}, {"unittest-filter", required_argument, 0, 'U'}, {"list-unittests", 0, &list_unittests, 1}, {"pidfile", required_argument, 0, 0}, @@ -473,6 +477,17 @@ int main(int argc, char **argv) run_mode = MODE_ERF_FILE; erf_file = optarg; } + else if(strcmp((long_opts[option_index]).name, "pcap-buffer-size") == 0) { +#ifdef HAVE_PCAP_SET_BUFF + if (ConfSet("pcap.buffer-size", optarg, 0) != 1) { + fprintf(stderr, "ERROR: Failed to set pcap-buffer-size.\n"); + exit(EXIT_FAILURE); + } +#else + SCLogError(SC_ERR_NO_PCAP_SET_BUFFER_SIZE, "The version of libpcap you have" + " doesn't support setting buffer size."); +#endif /* HAVE_PCAP_SET_BUFF */ + } break; case 'c': conf_filename = optarg; diff --git a/src/util-error.c b/src/util-error.c index ae0ab2dd33..bc451a5285 100644 --- a/src/util-error.c +++ b/src/util-error.c @@ -58,6 +58,8 @@ const char * SCErrorToString(SCError err) CASE_CODE (SC_ERR_PCAP_OPEN_LIVE); CASE_CODE (SC_ERR_PCAP_OPEN_OFFLINE); CASE_CODE (SC_ERR_PCAP_ACTIVATE_HANDLE); + CASE_CODE (SC_ERR_PCAP_SET_BUFF_SIZE); + CASE_CODE (SC_ERR_NO_PCAP_SET_BUFFER_SIZE); CASE_CODE (SC_ERR_NO_PF_RING); CASE_CODE (SC_ERR_PF_RING_RECV); CASE_CODE (SC_ERR_PF_RING_GET_CLUSTERID_FAILED); diff --git a/src/util-error.h b/src/util-error.h index 6201165618..cb332a9397 100644 --- a/src/util-error.h +++ b/src/util-error.h @@ -55,6 +55,8 @@ typedef enum { SC_ERR_PCAP_OPEN_LIVE, SC_ERR_PCAP_OPEN_OFFLINE, SC_ERR_PCAP_ACTIVATE_HANDLE, + SC_ERR_PCAP_SET_BUFF_SIZE, + SC_ERR_NO_PCAP_SET_BUFFER_SIZE, SC_ERR_NO_PF_RING, SC_ERR_PF_RING_RECV, SC_ERR_PF_RING_GET_CLUSTERID_FAILED,