Чтение из IPC::open2 очень медленно

Я читаю дампкап из stdin и хочу передать его в tshark через IPC::open2 и собрать вывод из tshark также через IPC::open2.

это вот так:

dumpcap ->STDIN-> myscript.pl <- IPC: open2 -> tshark

Поэтому я пытаюсь прочитать файл dumpcap, который приходит через STDIN, я читаю заголовок файла с помощью getHeader (в коде), а затем начинаю читать пакет за пакетом и передавать его (также пакет за пакетом) в tshark, который возвращает рассылка пакета к моему сценарию.

Теперь моя проблема на линии:

my $in = <CHLD_IN>;

Для возврата требуется почти полсекунды, даже если tshark возвращает ОЧЕНЬ быстро. Если я уберу строку, она идет ОЧЕНЬ быстро...

Не подходит?

Заранее спасибо!

это код в Perl:

 #!/usr/bin/perl

 use strict;
 use warnings;
 use Expect;
 use IO::Handle;


 use IPC::Open2;
 my $pid = open2(\*CHLD_IN, \*CHLD_OUT, '/usr/local/bin/tshark -c 100 -l -i - ');

 open(OUT,"> cap.txt");

 my $file = shift;
 my $packet_count = 0;
 my $magic_number = "";
 my $version_major = "";
 my $version_minor = "";
 my $thiszone = "";
 my $sigfigs = "";
 my $snaplen = "";
 my $network = "";


 binmode(STDIN);
 binmode(CHLD_OUT);

 STDOUT->autoflush(1);
 CHLD_OUT->autoflush(1);

 my $counter = 1;
 my $gblCounter = 1;

 getHeader();

 while(1){

     my $data;

     read(STDIN, my $data, 16);

     print "<---- reading 16 bytes: packet number. $packet_count\n";
     my $packet = $data;

     my $ts_sec = substr($packet,0,4); $packet = substr($packet,4);           my $ts_sec_bin = $ts_sec;     $ts_sec = reverse $ts_sec; $ts_sec = unPack($ts_sec);
     my $ts_usec = substr($packet,0,4); $packet = substr($packet,4);          my $ts_usec_bin = $ts_usec;   $ts_usec = reverse $ts_usec; $ts_usec = unPack($ts_usec);
     my $incl_len = substr($packet,0,4); $packet = substr($packet,4);         my $incl_len_bin = $incl_len; $incl_len = reverse $incl_len; $incl_len = unPack($incl_len);
     my $orig_len = substr($packet,0,4); $packet = substr($packet,4);         my $orig_len_bin = $orig_len; $orig_len = reverse $orig_len; my $data_len = sumBytes($orig_len);

     my $packet_data;
     my $count=1;

     read(STDIN, my $packet_data, $data_len);
     my $packet_data_bin = $packet_data;
     $packet_data = unPack($packet_data);

     # PRINT PACKET HEADER
     print CHLD_OUT $ts_sec_bin . $ts_usec_bin . $incl_len_bin . $orig_len_bin;
     print OUT "HEADER : " . unPack(reverse($ts_sec_bin) . reverse($ts_usec_bin) . reverse($incl_len_bin) . reverse($orig_len_bin)) . "\n";
     $|++;

     # PRINT PACKET DATA
     print CHLD_OUT $packet_data_bin;
     print OUT "DATA   : " . unPack($packet_data_bin) . "\n";
     $|++;

     my $in = <CHLD_IN>;            <----Here's my problem
     print "IN: $in";

     $packet_count++;

     exit if $packet_count >= 100;
 }

 exit;


 sub getHeader{

     read (STDIN, my $data, 24);

         #my $line = read (FILE, my $data, 40);

         my $header = $data;

         $magic_number = substr($header,0,4); $header = substr($header,4);     $magic_number = reverse $magic_number; $magic_number = unPack($magic_number);
         $version_major = substr($header,0,2); $header = substr($header,2);    $version_major = reverse $version_major; $version_major = unPack($version_major);
         $version_minor = substr($header,0,2); $header = substr($header,2);    $version_minor = reverse $version_minor; $version_minor = unPack($version_minor);
         $thiszone = substr($header,0,4); $header = substr($header,4);         $thiszone = reverse $thiszone; $thiszone = unPack($thiszone);
         $sigfigs = substr($header,0,4); $header = substr($header,4);          $sigfigs = reverse $sigfigs; $sigfigs = unPack($sigfigs);
         $snaplen = substr($header,0,4); $header = substr($header,4);          $snaplen = reverse $snaplen; $snaplen = unPack($snaplen);
         $network = substr($header,0,4); $header = substr($header,4);          $network = reverse $network; $network = unPack($network);

     print OUT reverse($magic_number) . reverse($version_major) . reverse($version_minor) . reverse($thiszone) . reverse($sigfigs) . reverse($snaplen) . reverse($network);
     print CHLD_OUT $data;
     $|++;

 }


 sub unPack{
     my $unpacked = unpack('H*', $_[0]);
     return uc($unpacked);
 }

 sub sumBytes{
     my $sum = 0;
     foreach my $ascval (unpack("C*", $_[0])) {
         $sum += $ascval;
     }
     return $sum;
 }

Вы можете спросить, ПОЧЕМУ я это делаю. Я вставляю в БД результат вскрытия (без моего сценария), но там ПУТЬ слишком много данных (я использую почти 400 Гб / день), и это потому, что я вставляю полное вскрытие...

То, что я хочу сделать, это просто получить некоторые метаданные о пакете из tshark и вставить в базу данных только метаданные и RAW-пакет.

Конечно, если у кого-то есть лучшее предложение, у меня все уши!

Спасибо!!

Дэвид

0 ответов

Другие вопросы по тегам