Search code examples
multithreadingperlforktcpdump

Perl script to capture tcpdump traces on Linux


Hi I have written a script, which was working fine previously with 'snoop' commands. This script forks child in the script to start tcpdump. When i have to stop the dump I kill the child but when i look at the pcap generated in wireshark, it shows the error "The capture file appears to have been cut short in the middle of a packet". My commands are

my $snoopAPP = &startService("tcpdump -w /tmp/app.pcap -i bond0>/dev/null 2>&1" , '');
kill 9, -$snoopAPP;waitpid $snoopAPP, 0;

sub startService(){
    #runs a program in background and returns PID which can be used later to kill the process
    #arguments are 1, path , 2nd the name of the file
    my $processPath = $_[0];chomp($processPath);
    if ($_[1] ne ''){$processPath = $processPath . " >$path/$_[1].log";}
    print "\nStarting ... \n-- $processPath\n";
    my $pid = fork();
    die "unable to fork $processPath: $!" unless defined($pid);
    if (!$pid) {  # child
        setpgrp(0, 0);
      exec("$processPath");
      die "\nunable to exec: $!\n";
      exit;
    }
    print " ---- PID: $pid\n";
    return $pid;
}

Another post suggests to wait for tcpdump to exit, which I am doing already, but still it results in the same error message.


Solution

  • Try

    kill 15, -$snoopAPP
    

    Signal 9, SIGKILL, is an immediate terminate, and doesn't give the application the opportunity to finish up, so, well, the capture file stands a good chance of being cut short in the middle of a packet.

    Signal 15, SIGTERM, can be caught by an application, so it can clean up before terminating. Tcpdump catches it and finishes writing out buffered output.