1

I am trying to make a program, that will parse pcap file until the timer expires. I use alarm function for that, found here, which really stops the pcap_loop, but definitely not after given time.

Important parts of code:

pcap_t *handle;

void end_loop(int signum)
{
   pcap_breakloop(handle);
}

int main(...){
...
handle = pcap_open_live(argv[2], BUFSIZ, 1, 100, errbuf);
....
signal(SIGALRM, end_loop);
alarm(5);
pcap_loop(handle, num_packets, got_packet, NULL);
pcap_close(handle);
send_syslog_message(hostname, list_of_parsed_packets));
return 0;
}

I have tried running the program many times and it always stops, but as the title says, the time it takes is just random. Am I doing something wrong?

Ab Majeed
  • 106
  • 4
Erik
  • 303
  • 1
  • 3
  • 12

1 Answers1

1

man pcap_breakloop says:

The flag is checked in loops reading packets from the OS - a signal by itself will not necessarily terminate those loops - as well as in loops processing a set of packets returned by the OS. Note that if you are catching signals on UNIX systems that support restarting system calls after a signal, and calling pcap_breakloop() in the signal handler, you must specify, when catching those signals, that system calls should NOT be restarted by that signal. Otherwise, if the signal interrupted a call reading packets in a live capture, when your signal handler returns after calling pcap_breakloop(), the call will be restarted, and the loop will not terminate until more packets arrive and the call completes.

This is probably what you observes. The alarm signal is received in due time, but you fail to specify that system calls should NOT be restarted by that signal. As a consequence, pcap_loop() is not returning immediately.

See How to know if a Linux system call is restartable or not?

YSC
  • 38,212
  • 9
  • 96
  • 149
  • It seems that this is the problem. However this is the first time I am using signals and I am not sure if I am able to make it work. My only idea, after reading this, is to set global flag in `end_loop` and in `got_packet` call `pcap_breakloop` if flag is set. – Erik Nov 15 '18 at 09:58