Reputation: 11258
If you use blocking pcap_loop()
or pcap_dispatch()
to handle incoming packet data via a suitable callback fn you may have a requirement to break out of those functions, i.e. get them to return.
Now pcap_breakloop()
is a means to do this, but that doesn't work if you call it from another thread of execution. You can call pcap_breakloop()
from within the callback fn specified in pcap_loop()
/pcap_dispatch()
but this is only an option if you can guarantee a pkt is going to trigger the callback.
How can one break a pcap_loop()
or pcap_dispatch()
in the absence of an incoming packet to trigger the callback fn?
If pcap_loop()
/pcap_dispatch()
is blocked in this use-case scenario, then you're going to want to unblock it from a different thread. But you can't call pcap_breakloop()
from a different thread of execution.
I read the man page and it mentioned something about using signals, but these are non-portable OS specific.
The only work-around I can see to this problem is using pcap_dispatch()
but in unblocking mode (pcap_setnonblock()
). You can then put pcap_dispatch()
in a tight while-loop. This works but I think it would be more elegant to be able to politely ask pcap_loop()
or pcap_dispatch()
to return from another thread?
Upvotes: 4
Views: 2764
Reputation: 109
How can one break a pcap_loop() or pcap_dispatch() in the absence of an incoming packet to trigger the callback fn?
On UN*Xes, catch a signal such as SIGUSR1
, have the signal handler do nothing, and, after calling pcap_breakloop()
, call pthread_kill()
to send that signal to the thread that's doing the pcap_dispatch()
or pcap_loop()
. When you catch the signal, do not specify SA_RESTART
; that way, the signal will interrupt system calls such as the call made by libpcap to read the captured packets. That's UN*X-specific, but it's not specific to particular versions of UN*X.
On Windows, use pcap_getevent()
to get the "event handle for the pcap_t
, and use SetEvent()
on that handle after calling pcap_breakloop()
.
Upvotes: 3