2013-07-26 114 views
0

我試圖用perl腳本內的tcpdump做捕獲。這個想法是捕獲10000個數據包或10秒,以先到者爲準。我的代碼適用於10000個數據包,但是如果我發送SIGINTSIGTERM到tcpdump以取消它,輸出似乎會損壞,導致腳本的其餘部分(處理tcpdump的原始輸出)出現問題。在不破壞捕獲的情況下查殺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" appears to have been cut short in the middle of a packet.

從我的人閱讀tcpdump的頁面,發送一個SIGTERMSIGINT應該正常工作(我已經嘗試了兩種):

if run with the -c flag, it will capture packets until it is interrupted by a SIGINT or SIGTERM signal or the specified number of packets have been processed.

+1

如果tcpdump的不具有完成這個功能的信號處理程序,我不認爲你可以對此做任何事情。 – Barmar

+0

難道你不能忽略tshark的錯誤嗎? –

+0

@JimGarrison,由於該錯誤,tshark無法處理該文件 – Ryley

回答

0

好了,這個問題原來是一個競爭條件:

kill('SIGTERM',$pid); 

這告訴tcpdump的正常退出,而它做的事情之一,有寫出關於捕獲的統計數據(即多少包)。我注意到,如果我在殺死之後立即發表打印聲明,有時會在統計之前出現,有時會在統計之前出現。因此,解決辦法是等到tcpdump的繼續上處理來自tcpdump的輸出中的一個命令之前完成:

waitpid($pid,0); 
system('tshark -r dumpcapfile ...') 
相關問題