diff --git a/src/source-pcap-file.c b/src/source-pcap-file.c index 75a762386f..e3d065e781 100644 --- a/src/source-pcap-file.c +++ b/src/source-pcap-file.c @@ -10,7 +10,7 @@ #include #else #include -#endif +#endif /* LIBPCAP_VERSION_MAJOR */ #include "suricata-common.h" #include "suricata.h" @@ -23,11 +23,14 @@ #include "source-pcap-file.h" #include "util-time.h" #include "util-debug.h" +#include "conf.h" + typedef struct PcapFileGlobalVars_ { pcap_t *pcap_handle; void (*Decoder)(ThreadVars *, DecodeThreadVars *, Packet *, u_int8_t *, u_int16_t, PacketQueue *); int datalink; + struct bpf_program filter; } PcapFileGlobalVars; typedef struct PcapFileThreadVars_ @@ -114,6 +117,9 @@ TmEcode ReceivePcapFile(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) } TmEcode ReceivePcapFileThreadInit(ThreadVars *tv, void *initdata, void **data) { + + char *tmpbpfstring; + if (initdata == NULL) { printf("ReceivePcapFileThreadInit error: initdata == NULL\n"); return TM_ECODE_FAILED; @@ -132,6 +138,22 @@ TmEcode ReceivePcapFileThreadInit(ThreadVars *tv, void *initdata, void **data) { exit(1); } + if (ConfGet("bpf-filter", &tmpbpfstring) != 1) { + SCLogInfo("could not get bpf or none specified"); + } else { + SCLogInfo("using bpf-filter %s", tmpbpfstring); + + if(pcap_compile(pcap_g.pcap_handle,&pcap_g.filter,tmpbpfstring,1,0) < 0) { + SCLogError(SC_ERR_BPF,"bpf compilation error %s",pcap_geterr(pcap_g.pcap_handle)); + exit(1); + } + + if(pcap_setfilter(pcap_g.pcap_handle,&pcap_g.filter) < 0) { + SCLogError(SC_ERR_BPF,"could not set bpf filter %s",pcap_geterr(pcap_g.pcap_handle)); + exit(1); + } + } + pcap_g.datalink = pcap_datalink(pcap_g.pcap_handle); printf("TmModuleReceivePcapFileRegister: datalink %" PRId32 "\n", pcap_g.datalink); switch(pcap_g.datalink) { diff --git a/src/source-pcap.c b/src/source-pcap.c index 693ca0248c..f125d2554d 100644 --- a/src/source-pcap.c +++ b/src/source-pcap.c @@ -16,6 +16,7 @@ #include "tm-modules.h" #include "tm-threads.h" #include "source-pcap.h" +#include "conf.h" #include "util-debug.h" /** @@ -26,6 +27,9 @@ typedef struct PcapThreadVars_ /* thread specific handle */ pcap_t *pcap_handle; + /* thread specific bpf */ + struct bpf_program filter; + /* data link type for the thread */ int datalink; @@ -159,6 +163,9 @@ TmEcode ReceivePcap(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) { */ #if LIBPCAP_VERSION_MAJOR == 1 TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) { + + char *tmpbpfstring; + if (initdata == NULL) { printf("ReceivePcapThreadInit error: initdata == NULL\n"); return TM_ECODE_FAILED; @@ -212,6 +219,23 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) { exit(1); } + /* set bpf filter if we have one */ + if (ConfGet("bpf-filter", &tmpbpfstring) != 1) { + SCLogInfo("could not get bpf or none specified"); + } else { + SCLogInfo("using bpf-filter %s", tmpbpfstring); + + if(pcap_compile(ptv->pcap_handle,&ptv->filter,tmpbpfstring,1,0) < 0) { + SCLogError(SC_ERR_BPF,"bpf compilation error %s",pcap_geterr(ptv->pcap_handle)); + exit(1); + } + + if(pcap_setfilter(ptv->pcap_handle,&ptv->filter) < 0) { + SCLogError(SC_ERR_BPF,"could not set bpf filter %s",pcap_geterr(ptv->pcap_handle)); + exit(1); + } + } + ptv->datalink = pcap_datalink(ptv->pcap_handle); *data = (void *)ptv; @@ -219,6 +243,9 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) { } #else /* implied LIBPCAP_VERSION_MAJOR == 0 */ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) { + + char *tmpbpfstring; + if (initdata == NULL) { printf("ReceivePcapThreadInit error: initdata == NULL\n"); return TM_ECODE_FAILED; @@ -242,6 +269,24 @@ TmEcode ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) { exit(1); } + /* set bpf filter if we have one */ + if (ConfGet("bpf-filter", &tmpbpfstring) != 1) { + SCLogInfo("could not get bpf or none specified"); + } else { + SCLogInfo("using bpf-filter %s", tmpbpfstring); + + if(pcap_compile(ptv->pcap_handle,&ptv->filter,tmpbpfstring,1,0) < 0) { + SCLogError(SC_ERR_BPF,"bpf compilation error %s",pcap_geterr(ptv->pcap_handle)); + exit(1); + } + + if(pcap_setfilter(ptv->pcap_handle,&ptv->filter) < 0) { + SCLogError(SC_ERR_BPF,"could not set bpf filter %s",pcap_geterr(ptv->pcap_handle)); + exit(1); + } + } + + ptv->datalink = pcap_datalink(ptv->pcap_handle); *data = (void *)ptv; diff --git a/src/suricata.c b/src/suricata.c index bdf5d4b8ae..892b2835e2 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -304,6 +304,9 @@ void usage(const char *progname) printf("\t--fatal-unittests : enable fatal failure on unittest error\n"); #endif /* UNITTESTS */ printf("\t--init-errors-fatal : enable fatal failure on signature init error\n"); + printf("\t--dump-config : show the running configuration\n"); + printf("\t--pfring-int : run in pfring mode\n"); + printf("\t--pfring-clusterid : pfring cluster id to use for flow pinning\n"); printf("\n"); printf("\nTo run the engine with default configuration on " "interface eth0 with signature file \"signatures.rules\", run the " @@ -320,6 +323,9 @@ int main(int argc, char **argv) char *sig_file = NULL; char *nfq_id = NULL; char *conf_filename = NULL; + char *bpf_filter = NULL; + uint32_t bpf_len = 0; + int tmpindex = 0; #ifdef UNITTESTS char *regex_arg = NULL; #endif @@ -500,6 +506,30 @@ int main(int argc, char **argv) } } + /* attempt to parse remaining args as bpf filter */ + tmpindex = optind; + while(argv[tmpindex] != NULL) { + bpf_len+=strlen(argv[tmpindex]) + 1; + tmpindex++; + } + bpf_filter= malloc(bpf_len); + + tmpindex = optind; + while(argv[tmpindex] != NULL) { + strlcat(bpf_filter, argv[tmpindex],bpf_len); + if(argv[tmpindex + 1] != NULL) { + strlcat(bpf_filter," ", bpf_len); + } + tmpindex++; + } + + if(strlen(bpf_filter) > 0) { + if (ConfSet("bpf-filter", bpf_filter, 0) != 1) { + fprintf(stderr, "ERROR: Failed to set bpf filter.\n"); + exit(EXIT_FAILURE); + } + } + SCLogInfo("This is %s version %s", PROG_NAME, PROG_VER); UtilCpuPrintSummary(); diff --git a/src/util-error.c b/src/util-error.c index 2b88d35601..8dc97bf89f 100644 --- a/src/util-error.c +++ b/src/util-error.c @@ -86,7 +86,7 @@ const char * SCErrorToString(SCError err) CASE_CODE (SC_WARN_IPFW_SETSOCKOPT); CASE_CODE (SC_WARN_IPFW_UNBIND); CASE_CODE (SC_ERR_MULTIPLE_RUN_MODE); - + CASE_CODE (SC_ERR_BPF); default: return "UNKNOWN_ERROR"; } diff --git a/src/util-error.h b/src/util-error.h index 33aaf59932..c995b3e941 100644 --- a/src/util-error.h +++ b/src/util-error.h @@ -106,7 +106,8 @@ typedef enum { SC_REPUTATION_INVALID_TYPE, SC_ERR_UNKNOWN_PROTOCOL, SC_ERR_UNKNOWN_RUN_MODE, - SC_ERR_MULTIPLE_RUN_MODE + SC_ERR_MULTIPLE_RUN_MODE, + SC_ERR_BPF, } SCError; const char *SCErrorToString(SCError);