diff --git a/src/decode.h b/src/decode.h index dc6621e746..a678cee599 100644 --- a/src/decode.h +++ b/src/decode.h @@ -30,6 +30,7 @@ #include "source-nfq.h" #endif /* NFQ */ +#include "source-pcap.h" #include "action-globals.h" #include "decode-ethernet.h" @@ -223,6 +224,9 @@ typedef struct _Packet NFQPacketVars nfq_v; #endif /* NFQ */ + /* libpcap vars */ + PcapPacketVars pcap_v; + /* storage */ u_int8_t pkt[65536]; u_int16_t pktlen; diff --git a/src/source-pcap.c b/src/source-pcap.c index 4702a94792..0af550af26 100644 --- a/src/source-pcap.c +++ b/src/source-pcap.c @@ -25,12 +25,17 @@ #include "source-pcap.h" typedef struct PcapGlobalVars_ { - pcap_t *pcap_handle; void (*Decoder)(ThreadVars *, Packet *, u_int8_t *, u_int16_t, PacketQueue *); } PcapGlobalVars; typedef struct PcapThreadVars_ { + /* thread specific handle */ + pcap_t *pcap_handle; + + /* data link type for the thread */ + int datalink; + /* counters */ u_int32_t pkts; u_int64_t bytes; @@ -39,7 +44,7 @@ typedef struct PcapThreadVars_ ThreadVars *tv; } PcapThreadVars; -static PcapGlobalVars pcap_g = { NULL, NULL, }; +static PcapGlobalVars pcap_g = { NULL, }; int ReceivePcap(ThreadVars *, Packet *, void *, PacketQueue *); int ReceivePcapThreadInit(ThreadVars *, void *, void **); @@ -80,10 +85,10 @@ void PcapCallback(char *user, struct pcap_pkthdr *h, u_char *pkt) { Packet *p = tv->tmqh_in(tv); p->ts.tv_sec = h->ts.tv_sec; p->ts.tv_usec = h->ts.tv_usec; - ptv->pkts++; ptv->bytes += h->caplen; + p->pcap_v.datalink = ptv->datalink; p->pktlen = h->caplen; memcpy(p->pkt, pkt, p->pktlen); //printf("PcapCallback: p->pktlen: %u (pkt %02x, p->pkt %02x)\n", p->pktlen, *pkt, *p->pkt); @@ -96,9 +101,9 @@ int ReceivePcap(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) { PcapThreadVars *ptv = (PcapThreadVars *)data; //printf("ReceivePcap: tv %p\n", tv); - int r = pcap_dispatch(pcap_g.pcap_handle, 1, (pcap_handler)PcapCallback, (u_char *)ptv); + int r = pcap_dispatch(ptv->pcap_handle, 1, (pcap_handler)PcapCallback, (u_char *)ptv); if (r <= 0) { - //printf("ReceivePcap: error %s\n", pcap_geterr(pcap_g.pcap_handle)); + //printf("ReceivePcap: error %s\n", pcap_geterr(ptv->pcap_handle)); } return 0; @@ -123,59 +128,43 @@ int ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) { /* XXX create a general pcap setup function */ char errbuf[PCAP_ERRBUF_SIZE]; - pcap_g.pcap_handle = pcap_create((char *)initdata, errbuf); - if (pcap_g.pcap_handle == NULL) { - printf("error %s\n", pcap_geterr(pcap_g.pcap_handle)); + ptv->pcap_handle = pcap_create((char *)initdata, errbuf); + if (ptv->pcap_handle == NULL) { + printf("error %s\n", pcap_geterr(ptv->pcap_handle)); exit(1); } /* set Snaplen, Promisc, and Timeout. Must be called before pcap_activate */ - int pcap_set_snaplen_r = pcap_set_snaplen(pcap_g.pcap_handle,LIBPCAP_SNAPLEN); - //printf("ReceivePcapThreadInit: pcap_set_snaplen(%p) returned %d\n", pcap_g.pcap_handle, pcap_set_snaplen_r); + int pcap_set_snaplen_r = pcap_set_snaplen(ptv->pcap_handle,LIBPCAP_SNAPLEN); + //printf("ReceivePcapThreadInit: pcap_set_snaplen(%p) returned %d\n", ptv->pcap_handle, pcap_set_snaplen_r); if (pcap_set_snaplen_r != 0) { - printf("ReceivePcapThreadInit: error is %s\n", pcap_geterr(pcap_g.pcap_handle)); + printf("ReceivePcapThreadInit: error is %s\n", pcap_geterr(ptv->pcap_handle)); exit(1); } - int pcap_set_promisc_r = pcap_set_promisc(pcap_g.pcap_handle,LIBPCAP_PROMISC); - //printf("ReceivePcapThreadInit: pcap_set_promisc(%p) returned %d\n", pcap_g.pcap_handle, pcap_set_promisc_r); + int pcap_set_promisc_r = pcap_set_promisc(ptv->pcap_handle,LIBPCAP_PROMISC); + //printf("ReceivePcapThreadInit: pcap_set_promisc(%p) returned %d\n", ptv->pcap_handle, pcap_set_promisc_r); if (pcap_set_promisc_r != 0) { - printf("ReceivePcapThreadInit: error is %s\n", pcap_geterr(pcap_g.pcap_handle)); + printf("ReceivePcapThreadInit: error is %s\n", pcap_geterr(ptv->pcap_handle)); exit(1); } - int pcap_set_timeout_r = pcap_set_timeout(pcap_g.pcap_handle,LIBPCAP_COPYWAIT); - //printf("ReceivePcapThreadInit: pcap_set_timeout(%p) returned %d\n", pcap_g.pcap_handle, pcap_set_timeout_r); + int pcap_set_timeout_r = pcap_set_timeout(ptv->pcap_handle,LIBPCAP_COPYWAIT); + //printf("ReceivePcapThreadInit: pcap_set_timeout(%p) returned %d\n", ptv->pcap_handle, pcap_set_timeout_r); if (pcap_set_timeout_r != 0) { - printf("ReceivePcapThreadInit: error is %s\n", pcap_geterr(pcap_g.pcap_handle)); + printf("ReceivePcapThreadInit: error is %s\n", pcap_geterr(ptv->pcap_handle)); exit(1); } /* activate the handle */ - int pcap_activate_r = pcap_activate(pcap_g.pcap_handle); - //printf("ReceivePcapThreadInit: pcap_activate(%p) returned %d\n", pcap_g.pcap_handle, pcap_activate_r); + int pcap_activate_r = pcap_activate(ptv->pcap_handle); + //printf("ReceivePcapThreadInit: pcap_activate(%p) returned %d\n", ptv->pcap_handle, pcap_activate_r); if (pcap_activate_r != 0) { - printf("ReceivePcapThreadInit: error is %s\n", pcap_geterr(pcap_g.pcap_handle)); + printf("ReceivePcapThreadInit: error is %s\n", pcap_geterr(ptv->pcap_handle)); exit(1); } - int datalink = pcap_datalink(pcap_g.pcap_handle); - //printf("TmModuleReceivePcapFileRegister: datalink %d\n", datalink); - switch(datalink) { - case LINKTYPE_LINUX_SLL: - pcap_g.Decoder = DecodeSll; - break; - case LINKTYPE_ETHERNET: - pcap_g.Decoder = DecodeEthernet; - break; - case LINKTYPE_PPP: - pcap_g.Decoder = DecodePPP; - break; - default: - printf("Error: datalink type %d not yet supported in module PcapFile.\n", datalink); - break; - } - + ptv->datalink = pcap_datalink(ptv->pcap_handle); *data = (void *)ptv; return 0; @@ -198,29 +187,14 @@ int ReceivePcapThreadInit(ThreadVars *tv, void *initdata, void **data) { printf("ReceivePcapThreadInit: using interface %s\n", (char *)initdata); char errbuf[PCAP_ERRBUF_SIZE] = ""; - pcap_g.pcap_handle = pcap_open_live((char *)initdata, LIBPCAP_SNAPLEN, + ptv->pcap_handle = pcap_open_live((char *)initdata, LIBPCAP_SNAPLEN, LIBPCAP_PROMISC, LIBPCAP_COPYWAIT, errbuf); - if (pcap_g.pcap_handle == NULL) { + if (ptv->pcap_handle == NULL) { printf("error %s\n", errbuf); exit(1); } - int datalink = pcap_datalink(pcap_g.pcap_handle); - printf("TmModuleReceivePcapFileRegister: datalink %d\n", datalink); - switch(datalink) { - case LINKTYPE_LINUX_SLL: - pcap_g.Decoder = DecodeSll; - break; - case LINKTYPE_ETHERNET: - pcap_g.Decoder = DecodeEthernet; - break; - case LINKTYPE_PPP: - pcap_g.Decoder = DecodePPP; - break; - default: - printf("Error: datalink type %d not yet supported in module PcapFile.\n", datalink); - break; - } + ptv->datalink = pcap_datalink(ptv->pcap_handle); *data = (void *)ptv; return 0; @@ -240,7 +214,20 @@ int ReceivePcapThreadDeinit(ThreadVars *tv, void *data) { int DecodePcap(ThreadVars *t, Packet *p, void *data, PacketQueue *pq) { /* call the decoder */ - pcap_g.Decoder(t,p,p->pkt,p->pktlen,pq); + switch(p->pcap_v.datalink) { + case LINKTYPE_LINUX_SLL: + DecodeSll(t,p,p->pkt,p->pktlen,pq); + break; + case LINKTYPE_ETHERNET: + DecodeEthernet(t,p,p->pkt,p->pktlen,pq); + break; + case LINKTYPE_PPP: + DecodePPP(t,p,p->pkt,p->pktlen,pq); + break; + default: + printf("Error: datalink type %d not yet supported in module PcapFile.\n", p->pcap_v.datalink); + break; + } return 0; } diff --git a/src/source-pcap.h b/src/source-pcap.h index e12cb67666..cddf4c880d 100644 --- a/src/source-pcap.h +++ b/src/source-pcap.h @@ -11,5 +11,10 @@ void TmModuleDecodePcapRegister (void); #define LIBPCAP_COPYWAIT 500 #define LIBPCAP_PROMISC 1 +typedef struct _PcapPacketVars +{ + int datalink; /* datalink from libpcap */ +} PcapPacketVars; + #endif /* __SOURCE_PCAP_H__ */