pcap_dispatch hangs on vlan filter

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