|
|
|
@ -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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|