杀死tcpdump而不破坏捕获

时间:2013-07-26 22:28:33

标签: perl tcpdump

我正在尝试使用perl脚本中的tcpdump进行捕获。这个想法是捕获10000个数据包或10秒,以先到者为准。我的代码适用于10000个数据包,但是如果我向tcpdump发送SIGINTSIGTERM来取消它,输出似乎会损坏,导致脚本的其余部分出现问题(处理tcpdump的原始输出。

相关的perl代码:

    defined(my $pid = fork()) or die "Cannot fork: $!";
    if($pid){
        #parent
        my ($kid,$wait_time) = (0,0);
        do{
            sleep 1;
            $wait_time++;
            $kid = waitpid(-1, WNOHANG);
        }until ($kid > 0 || $wait_time > $MAX_TIME_SEC);

        #kill the child
        if ($kid <= 0){
            kill('SIGTERM',$pid);
        } 
    }else{
        #child runs tcpdump to get raw data and write it to a temporary file
        exec('tcpdump','-ieth1','-s0','-c'.$MAX_PACKETS,'-w'.$dmp_name);
    }

接下来发生的事情是由tcpdump生成的转储文件被送入tshark,这会产生此错误:

  

tshark:“TheDumpFileFromAbove”似乎在中间缩短了   一包。

根据我在tcpdump手册页中的内容,发送SIGTERMSIGINT应该正常工作(我已经尝试过):

  

如果使用-c标志运行,它将捕获数据包,直到它为止   被SIGINT或SIGTERM信号或指定数量的信号中断   数据包已被处理。

1 个答案:

答案 0 :(得分:0)

好的,所以问题结果是竞争条件:

kill('SIGTERM',$pid);

告诉tcpdump正常退出,其中的一件事就是写出有关捕获的统计信息(即有多少数据包)。我注意到,如果我在杀戮之后立即发出一个印刷声明,有时它会在统计数据之前出现,有时候会出现。所以解决方案是等到tcpdump完成后继续执行下一个处理tcpdump输出的命令:

waitpid($pid,0);
system('tshark -r dumpcapfile ...')