On Oct 23, 2015, at 7:04 AM, Christian Gieseler <christiangiese...@yahoo.de> 
wrote:

> 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.

In immediate mode, there *is* no timeout - that's the whole point of immediate 
mode.

The problem here is that:

        currently, libpcap doesn't tell the kernel to discard packets not going 
in the direction specified by pcap_setdirection() rather than handing them to 
libpcap;

        libpcap handles this by filtering out those packets itself;

        this means that the internal "loop through available packets" routines 
in libpcap for Linux may not find any available packets to show to the user, 
because they've been filtered out, so it returns 0, which looks like a timeout.

This might be fixable, but it'll take some work.

By the way:

>       /* 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);
>       }

Given that you haven't yet called pcap_activate(), that "shouldn't happen", so 
you might just want to do

        status = pcap_set_immediate_mode (gmrpPHandle, 1);
        if (status < 0) {
                if (status == PCAP_ERROR)
                        fprintf(stderr, "%s Setting immediate mode failed: 
%s\n", cpuIf, pcap_geterr(gmrpPHandle));
                else
                        fprintf(stderr,"%s Setting immediate mode failed: 
%s\n", cpuIf, pcap_statustostr(status));
                MRP62439_ASSERT (0);
        }

to catch all errors and report something.

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

You can just get rid of that, as there's no timeout in immediate mode - packets 
are delivered as soon as they arrive, the capture mechanism doesn't buffer up 
packets to deliver in batches, with a timeout to keep it from buffering them 
indefinitely.

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

You probably want to do

        status = pcap_activate (gmrpPHandle);
        if (status < 0) {
                if (status == PCAP_ERROR)
                        fprintf(stderr, "%s Capture handle activation failed: 
%s\n", cpuIf, pcap_geterr(gmrpPHandle));
                else
                        fprintf(stderr,"%s Capture handle activation failed: 
%s\n", cpuIf, pcap_statustostr(status));
                MRP62439_ASSERT (0);
        }

to report the precise problem.
_______________________________________________
tcpdump-workers mailing list
tcpdump-workers@lists.tcpdump.org
https://lists.sandelman.ca/mailman/listinfo/tcpdump-workers

Reply via email to