Hi all
My application is a monitoring application that monitors the incoming udp packet when ever required. When ever a particular source ip and port and dest ip and port is provided the filter will be framed based them. For eg,
char filterExpr[1024];
filterExpr = "udp and src host 192.168.16.100 and dst host 55.55.55.55 and src port 3248 and dst port 1234";
putenv("PCAP_SNAPLEN=1600");
putenv("PCAP_FRAMES=2048");
putenv("PCAP_TO_MS=200");
putenv("PCAP_PROMISC=-1");
putenv("PCAP_PROTO=ip");
pCapture = pcap_opn_live(..);
if(!pCapture)
{
return -1;
}
if(pcap_lookupnet(..)<0)
{
return -1;
}
if(pcap_compile(pCapture, &fcode, filterExpr, 0, netmask) < 0)
{
pcap_close(pCapture);
return -1;
}
if(pcap_setfilter(pCapture, &fcode))
{
pcap_close(pCapture);
return -1;
}
........
on timeout pcap_dispatch will be called to process the packets.
when the traffic is selected for unmonitoring pcap_close will be called and the capture pointer will be reset.
if(pCapture)
{
pcap_close(pCapture);
pCapture = 0;
}
The above example works very well for udp traffic.
For vlan traffic when the same filter expression is changed to include vlan
filterExpr = "vlan 87 and udp and src host 192.168.16.100 and dst host 55.55.55.55 and src port 3248 and dst port 1234";
the pcap_dispatch works only for the very first time the traffic is selected for monitoring (ie., the very first time this filter is used.) the subsesquent times the pcap_dispactch hangs ie., after calling pcap_close once and then setting the filter again.
Any input would be of great help!
The libpcap version used is libpcap1.1.1.
Thanks in advance!
---------- Post updated at 06:15 PM ---------- Previous update was at 04:57 PM ----------
This is the sample program with which the above scenario can be simulated.
The below program first does the pcap_next for the given filter then after doing pcap_close and then does a pcap_loop.
This program works for filter "udp" and for "vlan and udp" it is only the first call for pcap_next works(ie, the hdr length gets printed) the subsequent call for pcap_loop does not work and it hangs in there..
#include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/if_ether.h>
/* just print a count every time we have a packet... */
void my_callback(u_char *useless,const struct pcap_pkthdr* pkthdr,const u_char*
packet)
{
static int count = 1;
fprintf(stdout,"%d, ",count);
fflush(stdout);
count++;
}
int main(int argc,char **argv)
{
int i;
char *dev;
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t* descr;
const u_char *packet;
struct pcap_pkthdr hdr; /* pcap.h */
struct ether_header *eptr; /* net/ethernet.h */
struct bpf_program fp; /* hold compiled program */
bpf_u_int32 maskp; /* subnet mask */
bpf_u_int32 netp; /* ip */
if(argc != 2){ fprintf(stdout,"Usage: %s \"filter program\"\n"
,argv[0]);return 0;}
/* grab a device to peak into... */
dev = pcap_lookupdev(errbuf);
if(dev == NULL)
{ fprintf(stderr,"%s\n",errbuf); exit(1); }
dev = "eth1";
/* ask pcap for the network address and mask of the device */
pcap_lookupnet(dev,&netp,&maskp,errbuf);
/* open device for reading this time lets set it in promiscuous
* mode so we can monitor traffic to another machine */
descr = pcap_open_live(dev,BUFSIZ,1,-1,errbuf);
if(descr == NULL)
{ printf("pcap_open_live(): %s\n",errbuf); exit(1); }
/* Lets try and compile the program.. non-optimized */
if(pcap_compile(descr,&fp,argv[1],0,netp) == -1)
{ fprintf(stderr,"Error calling pcap_compile\n"); exit(1); }
/* set the compiled program as the filter */
if(pcap_setfilter(descr,&fp) == -1)
{ fprintf(stderr,"Error setting filter\n"); exit(1); }
pcap_next(descr, &hdr);
fprintf(stdout, "pkt length: %d\n", hdr.len);
pcap_close(descr);
pcap_freecode(&fp);
descr = NULL;
/* grab a device to peak into... */
dev = pcap_lookupdev(errbuf);
if(dev == NULL)
{ fprintf(stderr,"%s\n",errbuf); exit(1); }
dev = "eth1";
/* ask pcap for the network address and mask of the device */
pcap_lookupnet(dev,&netp,&maskp,errbuf);
/* open device for reading this time lets set it in promiscuous
* mode so we can monitor traffic to another machine */
descr = pcap_open_live(dev,BUFSIZ,1,-1,errbuf);
if(descr == NULL)
{ printf("pcap_open_live(): %s\n",errbuf); exit(1); }
/* Lets try and compile the program.. non-optimized */
if(pcap_compile(descr,&fp,argv[1],0,netp) == -1)
{ fprintf(stderr,"Error calling pcap_compile\n"); exit(1); }
/* set the compiled program as the filter */
if(pcap_setfilter(descr,&fp) == -1)
{ fprintf(stderr,"Error setting filter\n"); exit(1); }
/* ... and loop */
pcap_loop(descr,-1,my_callback,NULL);
return 0;
}