tcpdump mailing list archives

pcap_next_ex receive isse


From: "Christian Gieseler" <christiangieseler () yahoo de>
Date: Fri, 23 Oct 2015 16:04:59 +0200

Hi all,
I have a receive thread in my program which shall capture frames according
to a filter. The Host is sending frames with the same multicast destination
mac as I want to receive them with the filter.
Filtering in general works fine. It looks as if I only receive the frames I
want. But somehow pcap_next_ex also reacts when I send out frames matching
the filter. It returns with a timeout even if the timeout was not reached.
I have set the handle properties to capture only incoming frames with
pcap_setdirection. And that works from reception perspective. But I run into
timeouts with pcap_next_ex far more often then configured and it looks this
happens exactly when I send the frames out. If I change the filter to have a
slight mismatch with the frames I send out eg 01:15:4e:00:00:22 intead of
01:15:4e:00:00:02 see the regular timeouts configured in pcap_set_timeout.
Is something missing in my configuration or is that a bug?

I am running on linux, arm, pcap version is 1.5.3
This is my receiver thread. Frames are send out in the main thread with
sendto on a raw socket.

void *
Mrp62439rcvTestThread (void *arg)
{
//Libpcap vars
pcap_t *gmrpPHandle;            /* packet capture handle */
static int gmrpPReadFd = -1;

  struct bpf_program l2fltr;    /* compiled filter program (expression) */
  bpf_u_int32 mask = 0;         /* subnet mask */
  bpf_u_int32 net = 0;          /* ip */
  char cpuIf[] = EPI_CPU_ETH_INTF;      /* capture device name */
  char errbuf[PCAP_ERRBUF_SIZE];
  int ret=0;
  char filter_exp[] = "ether dst (01:15:4e:00:00:01 || 01:15:4e:00:00:02)";
/* filter expression */
 
  int len;
  int length = 0;
  const u_char *pcap_packet;
  struct pcap_pkthdr *pkt_header;
  const unsigned char *pkt_data;

        /* open capture device */
        gmrpPHandle = pcap_create (cpuIf, errbuf);

        if (gmrpPHandle == NULL)
        {
                fprintf(stderr,"Couldn't open device %s: %s\n", cpuIf,
errbuf);
                MRP62439_ASSERT (0);
        }

        if (pcap_set_immediate_mode (gmrpPHandle, 1) ==
PCAP_ERROR_ACTIVATED)
        {
                fprintf(stderr,"%s Capture handle already activated\n",
cpuIf);
                MRP62439_ASSERT (0);
        }

        if (pcap_set_timeout (gmrpPHandle, 40) == PCAP_ERROR_ACTIVATED)
        {
                fprintf(stderr,"%s Capture handle already activated\n",
cpuIf);
                MRP62439_ASSERT (0);
        }

        if (pcap_activate (gmrpPHandle) < 0)
        {
                fprintf(stderr,"%s Capture handle activatation failed\n",
cpuIf);
                MRP62439_ASSERT (0);
        }

        if (pcap_datalink (gmrpPHandle) != DLT_EN10MB)
        {
                fprintf(stderr,"%s is not an Ethernet\n",cpuIf);
                MRP62439_ASSERT (0);
        }

        /* compile the filter expression */
        if (pcap_compile (gmrpPHandle, &l2fltr, filter_exp, 0,
PCAP_NETMASK_UNKNOWN) < 0)
        {
                fprintf(stderr,"Couldn't parse filter %s: %s\n",
filter_exp,pcap_geterr (gmrpPHandle));
                MRP62439_ASSERT (0);
        }

        /* apply the compiled filter */
        if (pcap_setfilter (gmrpPHandle, &l2fltr) < 0)
        {
                fprintf(stderr,"Couldn't install filter %s: %s\n",
filter_exp,pcap_geterr (gmrpPHandle));
                MRP62439_ASSERT (0);
    }

        if (pcap_setdirection (gmrpPHandle, PCAP_D_IN) < 0)
        {
                fprintf(stderr,"Failed to set direction for capture\n");
                MRP62439_ASSERT (0);
        }

        gmrpPReadFd = pcap_fileno(gmrpPHandle);

        if (gmrpPReadFd < 0)
        {
                fprintf(stderr,"Failed to get fd for capture handle : %s
\n",pcap_geterr (gmrpPHandle));
                MRP62439_ASSERT (0);
        }

        while (!mrp62439_instance->stopMrpThreads)
        {
                        ret = pcap_next_ex (gmrpPHandle, &pkt_header,
&pkt_data);
                        if (ret < 0 )
                        {
                                //We had an Error
                                continue;
                        }
                        
                        if (ret == 0)
                        {
                                //We had a timeout
                                continue;
                        }
                        else
                        {
                                memcpy (buffer, pkt_data, pkt_header->len);
                                ProcessPaket (buffer, pkt_header->len);
                        }
        }
        pthread_exit (NULL);
        return NULL;
}


Thanks for reading and any hint

Best Regards
Christian


_______________________________________________
tcpdump-workers mailing list
tcpdump-workers () lists tcpdump org
https://lists.sandelman.ca/mailman/listinfo/tcpdump-workers


Current thread: