Чтение из 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-пакет.
Конечно, если у кого-то есть лучшее предложение, у меня все уши!
Спасибо!!
Дэвид