listening using Pcap with timeout

心不动则不痛 提交于 2019-12-04 17:53:33
lemonsqueeze

You should call pcap_breakloop() when you want stop listening. So one way would be to:

  • setup an alarm to trigger in N seconds,
  • install a signal handler for SIGALRM signal,
  • call pcap_breakloop() inside the handler to make pcap_loop() return.

code:

void alarm_handler(int sig)
{
    pcap_breakloop(handle);
}

int main()
{
    ...

    alarm(N);
    signal(SIGALRM, alarm_handler);

    /* now we can set our callback function */
    pcap_loop(handle, num_packets, got_packet, NULL);

    /* cleanup */
    pcap_freecode(&fp);
    pcap_close(handle);
}

Note: As for using libpcap's read timeout to do this, it won't and can't work, man pcap explicitly warns against it:

The read timeout cannot be used to cause calls that read packets to return within a limited period of time [...] This means that the read timeout should NOT be used, for example, in an interactive application to allow the packet capture loop to poll for user input periodically, as there's no guarantee that a call reading packets will return after the timeout expires even if no packets have arrived.

If you look at this page from the tcpdump website, you can see the follwing:

Opening the device for sniffing

The task of creating a sniffing session is really quite simple. For this, we use pcap_open_live(). The prototype of this function (from the pcap man page) is as follows:

pcap_t *pcap_open_live(char *device, int snaplen, int promisc, int to_ms,
                       char *ebuf)

The first argument is the device that we specified in the previous section. snaplen is an integer which defines the maximum number of bytes to be captured by pcap. promisc, when set to true, brings the interface into promiscuous mode (however, even if it is set to false, it is possible under specific cases for the interface to be in promiscuous mode, anyway). to_ms is the read time out in milliseconds (a value of 0 means no time out; on at least some platforms, this means that you may wait until a sufficient number of packets arrive before seeing any packets, so you should use a non-zero timeout). Lastly, ebuf is a string we can store any error messages within (as we did above with errbuf). The function returns our session handler.

If this does not work, let us know.

I have been studying and testing these code fragments for a while. Somewhere, I noticed the observation that when you exit pcap_loop, although you may have seen packets, the exit conditions suggest that you have seen none. I assume from this that all the processing of the packet must occur in the scope of the callback function. So if I want to reset quickly and be ready for another packet, I will need to spawn another process to work on each packet.

Old post but I was researching and came across this.

From the man page for pcap_loop() it specifically says, "It does not return when live read timeouts occur; instead, it attempts to read more packets."

But the man pages for pcap_dispatch() and pcap_next() both indicate they return on timeout.

You can use pcap_next() function and set timeout with pcap_set_timeout, for libpcap 1.8.1 you need immediate mode, see https://github.com/the-tcpdump-group/libpcap/issues/572.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!