tcpdump mailing list archives

Re: pcap_next_ex receive isse


From: Christian Gieseler <christiangieseler () yahoo de>
Date: Sat, 24 Oct 2015 23:14:26 +0200

Hi Guy,

thanks for your answers.
>
> On Oct 23, 2015, at 7:04 AM, Christian Gieseler <christiangieseler () 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. Still it is strange that i can see the intervals change according to changed timeout values. However that was just my second try while trying to track down the issue discussed below. what do you suggest then if i drop the set_timeout. Use epoll or poll like i did before?
>
> 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.
That explains the behaviour. I will try to find a way around.

Another thing i have seen from time to time that with with both the code i have posted and with a version epoll + pcap_next_ex (no pcap_set_timeout used) is that the receiver thread eats up all processor time it gets. On my gpio debug pin i see that i run into timeouts with full speed. It happens not everytime but now and then. Since this is not persitent on every execution i am not sure if this is due to immediate_mode.
Have you seen this before? Any idea why it happens even with epoll?
epoll should get a save way around this but is does not. Is the POLLIN event not cleared?

Should i use another libpcap call to capture the frames? I need a way to get a hand on the frames as soon as possible without doing the filtering of all received frames manually in userspace which is the previous solution.
>
Thank you for the hints below.
Best Regards
Christian
> 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


Current thread: