Commit 74182d47 authored by Olav Kvittem's avatar Olav Kvittem

Bugs in field names and values for flows.

parent 05a946c8
......@@ -18,7 +18,7 @@ use NetPacket::IP qw(:strip :protos);;
use NetPacket::UDP;
use NetPacket::TCP;
use Net::IPv6Addr;
use NetPacket::IPv6 qw(ipv6_strip);
#use NetPacket::IPv6 qw(ipv6_strip);
#use Net::RTP;
use Net::RTP::Packet;
use Time::HiRes qw/ sleep time tv_interval gettimeofday/;
......@@ -130,7 +130,7 @@ my %pcr_stats = ();
my %pts_stats = ();
my %mpeg_stats = ();
my %jitter_stats = ();
#PTS stuff
#my $real_time = time();
my $late_video_packets = 0;
......@@ -175,14 +175,14 @@ if ($opt_dump){
open DUMP, ">$opt_dump";
}
if ($opt_test){
if($opt_mpeg || $opt_rtp || $opt_tcp_t){
&unit_test;
}
else {
print "You need to choose a test. (mpeg, tcp or rtp) \n";
}
}
if ($opt_test){
if($opt_mpeg || $opt_rtp || $opt_tcp_t){
&unit_test;
}
else {
print "You need to choose a test. (mpeg, tcp or rtp) \n";
}
}
if ($opt_pcap || ($opt_tcp && !$opt_rtmp)){ # listen in parallell
alarm($opt_last) if $opt_last;
......@@ -191,7 +191,7 @@ if ($opt_pcap || ($opt_tcp && !$opt_rtmp)){ # listen in parallell
eat_pcap_streams(@streams);
&display_stats() if !$opt_xml;
} else { # listen serially
my $stream_count;
my $stream_count;
#my $ln = @streams;
foreach $id (@streams) {
alarm($opt_last) if $opt_last;
......@@ -209,7 +209,7 @@ if ($opt_pcap || ($opt_tcp && !$opt_rtmp)){ # listen in parallell
}
last if ! $uninterrupted;
}
}
&list_flows if $opt_list;
&display_stats() if $opt_sum;
......@@ -219,355 +219,355 @@ if ($opt_pcap || ($opt_tcp && !$opt_rtmp)){ # listen in parallell
exit(0);
#
sub unit_test {
my $test_data = shift;
#streams = "rtp_158.38.130.110_6711_1.pcap";
if ($opt_mpeg){
@streams = "testing/pcap/testdata_mpeg.pcap";
@filter = qw "video audio";
}
@streams = "testing/pcap/testdata_rtp.pcap" if $opt_rtp;
@streams = "testing/pcap/testdata_tcp.pcap" if $opt_tcp_t;
$opt_xml = "tmp_testdata.xml";
$opt_q = 1;
$opt_v = 1;
#print $streams[0], "\n";
my $test_data = shift;
#streams = "rtp_158.38.130.110_6711_1.pcap";
if ($opt_mpeg){
@streams = "testing/pcap/testdata_mpeg.pcap";
@filter = qw "video audio";
}
@streams = "testing/pcap/testdata_rtp.pcap" if $opt_rtp;
@streams = "testing/pcap/testdata_tcp.pcap" if $opt_tcp_t;
$opt_xml = "tmp_testdata.xml";
$opt_q = 1;
$opt_v = 1;
#print $streams[0], "\n";
}
sub unit_test_2{
#my ($orgnial_test) = &feed_data("file",rtp_file.xml);
my $test_data;
$test_data = "testing/xml/testdata_mpeg.xml" if $opt_mpeg;
$test_data = "testing/xml/testdata_rtp.xml" if $opt_rtp;
#$test_data = "udp_testdata" if $opt_net;
$test_data = "testing/xml/testdata_tcp.xml" if $opt_tcp;
my ($orginal_test) = &xml_parser($test_data);
my ($new_test) = &xml_parser("tmp_testdata.xml");
print Dumper($orginal_test), "\n", Dumper($new_test)if $opt_debug;
my $ignore_pattern = "jitter"; #PCR jitter is based on delta local time.
my $ignore_pattern2 = "dwell";
my $ignore_pattern3 ="delay_factor";
my $ignore_pattern4 ="gap";
print "Checking values ....\n";
for my $k1(keys %$orginal_test){
if ($orginal_test->{ $k1} != $new_test->{ $k1} and $orginal_test->{ $k1} !~ m/HASH/) {
print "different value @ $k1, value: $orginal_test->{$k1}, differs from value: $new_test->{$k1}\n";
}
else {
printf "%2s %2s\n", "OK @ ", "$k1 ";
}
for my $k2 ( keys %{$orginal_test->{ $k1}} ) {
if ( ($orginal_test->{ $k1}{$k2} != $new_test->{ $k1}{$k2}) and ($k2 !~ m/$ignore_pattern/) and ($k2 !~ m/$ignore_pattern2/) and ($k2 !~ m/$ignore_pattern3/) and ($k2 !~ m/$ignore_pattern4/)){
print "different value @ $k1-> $k2, value: $orginal_test->{$k1}{$k2} differs from, value: $new_test->{$k1}{$k2}\n";
}
}
#my ($orgnial_test) = &feed_data("file",rtp_file.xml);
my $test_data;
$test_data = "testing/xml/testdata_mpeg.xml" if $opt_mpeg;
$test_data = "testing/xml/testdata_rtp.xml" if $opt_rtp;
#$test_data = "udp_testdata" if $opt_net;
$test_data = "testing/xml/testdata_tcp.xml" if $opt_tcp;
my ($orginal_test) = &xml_parser($test_data);
my ($new_test) = &xml_parser("tmp_testdata.xml");
print Dumper($orginal_test), "\n", Dumper($new_test)if $opt_debug;
my $ignore_pattern = "jitter"; #PCR jitter is based on delta local time.
my $ignore_pattern2 = "dwell";
my $ignore_pattern3 ="delay_factor";
my $ignore_pattern4 ="gap";
print "Checking values ....\n";
for my $k1(keys %$orginal_test){
if ($orginal_test->{ $k1} != $new_test->{ $k1} and $orginal_test->{ $k1} !~ m/HASH/) {
print "different value @ $k1, value: $orginal_test->{$k1}, differs from value: $new_test->{$k1}\n";
}
print "Test complete \n";
else {
printf "%2s %2s\n", "OK @ ", "$k1 ";
}
for my $k2 ( keys %{$orginal_test->{ $k1}} ) {
if ( ($orginal_test->{ $k1}{$k2} != $new_test->{ $k1}{$k2}) and ($k2 !~ m/$ignore_pattern/) and ($k2 !~ m/$ignore_pattern2/) and ($k2 !~ m/$ignore_pattern3/) and ($k2 !~ m/$ignore_pattern4/)){
print "different value @ $k1-> $k2, value: $orginal_test->{$k1}{$k2} differs from, value: $new_test->{$k1}{$k2}\n";
}
}
}
print "Test complete \n";
}
sub xml_parser {
my $file = shift;
my $parser = new XML::DOM::Parser;
my $doc = $parser->parsefile ($file);
my $root = $doc->getFirstChild();
my $nodelist = $root->getChildNodes();
my $node = $nodelist->item(1);
my $dup;
my $flow_childs = $node->getChildNodes();
my @test_array = ();
my %test_hash = ();
foreach my $child ($node->getChildNodes()) {
if ($child->getNodeType == ELEMENT_NODE) {
if ($child->getChildNodes()){
my @children = $child->getChildNodes();
my $l = @children;
if ($l > 1){
#print "=== " ,$child->getNodeName(), " === \n";
if (exists $test_hash{$child->getNodeName()}){
$dup +=1;
}
foreach my $grandchild ($child->getChildNodes()){
if ($grandchild->getNodeType == ELEMENT_NODE){
#print $grandchild->getNodeName(), "\n";
eval {
$test_hash{$child->getNodeName().$dup}{$grandchild->getNodeName()}= $grandchild->getFirstChild()->getData();
};
if ($@){
};
}
}
my $file = shift;
my $parser = new XML::DOM::Parser;
my $doc = $parser->parsefile ($file);
my $root = $doc->getFirstChild();
my $nodelist = $root->getChildNodes();
my $node = $nodelist->item(1);
my $dup;
my $flow_childs = $node->getChildNodes();
my @test_array = ();
my %test_hash = ();
foreach my $child ($node->getChildNodes()) {
if ($child->getNodeType == ELEMENT_NODE) {
if ($child->getChildNodes()){
my @children = $child->getChildNodes();
my $l = @children;
if ($l > 1){
#print "=== " ,$child->getNodeName(), " === \n";
if (exists $test_hash{$child->getNodeName()}){
$dup +=1;
}
foreach my $grandchild ($child->getChildNodes()){
if ($grandchild->getNodeType == ELEMENT_NODE){
#print $grandchild->getNodeName(), "\n";
eval {
$test_hash{$child->getNodeName().$dup}{$grandchild->getNodeName()}= $grandchild->getFirstChild()->getData();
};
if ($@){
};
}
else {
$test_hash{'flow'}{$child->getNodeName()} = $child->getFirstChild()->getData();
}
}
else {
$test_hash{'flow'}{$child->getNodeName()} = $child->getFirstChild()->getData();
}
}
}
}
return (\%test_hash)
}
}
}
return (\%test_hash)
}
sub http_stream_client {
my $f = shift;
my $playlist = get("$f");
my @list_items = split(/\n/,$playlist);
my @streams;
my $duration;
my $regex = "http://";
my $p_chunk;
while(1){
foreach my $item (@list_items){
my @tmp_streams= get("$item");
if ($item=~ /$regex/g){
foreach my $stream (@tmp_streams){
if ($stream =~ /EXT-X-TARGETDURATION/){
my @temp = split(/:/,$stream);
$duration = $temp[1];
}
if($stream !~ /#/g){
push(@streams,$stream);
my $l = @streams;
my $current_chunk = $streams[$l-1];
if ($current_chunk ne $p_chunk){
my $data = get("$current_chunk");
$p_chunk = $current_chunk;
sleep(9);
}
}
}
my $f = shift;
my $playlist = get("$f");
my @list_items = split(/\n/,$playlist);
my @streams;
my $duration;
my $regex = "http://";
my $p_chunk;
while(1){
foreach my $item (@list_items){
my @tmp_streams= get("$item");
if ($item=~ /$regex/g){
foreach my $stream (@tmp_streams){
if ($stream =~ /EXT-X-TARGETDURATION/){
my @temp = split(/:/,$stream);
$duration = $temp[1];
}
if($stream !~ /#/g){
push(@streams,$stream);
my $l = @streams;
my $current_chunk = $streams[$l-1];
if ($current_chunk ne $p_chunk){
my $data = get("$current_chunk");
$p_chunk = $current_chunk;
sleep(9);
}
}
}
}
}
}
}
sub get_stream {
my $uri = shift;
my $data = get("$uri");
my $uri = shift;
my $data = get("$uri");
}
##TCP impl. -PMM
sub handle_threads {
$tcp_stop = 1;
$thr->join();
$tcp_stop = 1;
$thr->join();
}
sub end_xml{
my $filename;
my $twig = XML::Twig->new(pretty_print => 'indented');
my ($date,$time) = &get_date_time();
$filename = $opt_xml;
$filename = $date."_".$time.".xml" if $opt_xml eq "date_time";
open (MYFILE, '>'.$filename);
my $final_xml = $doc->toString();
$twig->parse($final_xml);
$twig->flush(\*MYFILE);
#print "</qstream> \n" if $opt_xml eq "-";
$doc->dispose;
close (MYFILE);
$xml_printed = 1;
&unit_test_2($filename) if $opt_test;
my $filename;
my $twig = XML::Twig->new(pretty_print => 'indented');
my ($date,$time) = &get_date_time();
$filename = $opt_xml;
$filename = $date."_".$time.".xml" if $opt_xml eq "date_time";
open (MYFILE, '>'.$filename);
my $final_xml = $doc->toString();
$twig->parse($final_xml);
$twig->flush(\*MYFILE);
#print "</qstream> \n" if $opt_xml eq "-";
$doc->dispose;
close (MYFILE);
$xml_printed = 1;
&unit_test_2($filename) if $opt_test;
}
sub tcp_packet_stats {
my $f = shift;
my $ip = shift;
my ($tcp_obj) = shift;
my $len,$ip_hlen = 0;
#ipv6.pm uses different variables.
if($opt_ipv6){
$len = plen;
my $f = shift;
my $ip = shift;
my ($tcp_obj) = shift;
my $len,$ip_hlen = 0;
#ipv6.pm uses different variables.
if($opt_ipv6){
$len = plen;
}
else {
$len = len;
$ip_hlen = 20;
}
#my $ip = NetPacket::IP->decode(eth_strip($pkt));
#my $tcp_obj = NetPacket::TCP->decode(ip_strip(eth_strip($pkt)));
#my $f = $ip->{src_ip}.":".$tcp_obj->{src_port} if !$offline;
my $seq_num = $tcp_obj->{seqnum};
my $options = $tcp_obj->{options}; #12 bytes
#print "$tcp_obj->{src_port} \n";
if (!exists $tcp_packet_stats{$f}){
&init_stats($f);
$tcp_packet_stats{$f} = &share( {} );
$seq_stats{$f} = &share( {} );
$seq_stats_n{$f} = &share( {} );
$tcp_packet_stats{$f}{'pkt_late'} = 0;
$tcp_packet_stats{$f}{'pkt_retrans'} =0;
$tcp_packet_stats{$f}{'pkt_dup'} = 0;
}
++$tcp_packet_stats{$f}{'num_packets'};
&tcp_jitter_stats($f,$options);
#Bandwidth messurements
$tcp_packet_stats{$f}{'num_bytes'} += $ip->{$len}; #counts the bytes
#Check for duplicated,out-of-order, late and lost packets.
$seq_stats{$f}{'seq_diff'} = $seq_num - $seq_stats{$f}{'p_seq_num'} - $seq_stats{$f}{'p_packet_len'};
if ($seq_stats_n{$f}{'seq_num_p'} == $seq_num && $seq_stats{$f}{'p_seq_num'} != 0) {
++$tcp_packet_stats{$f}{'pkt_dup'};
}
if ($seq_stats{$f}{'seq_diff'} != 0 && $seq_stats{$f}{'p_seq_num'} != 0){
if ($seq_stats{$f}{'seq_diff'} < 0){
++$tcp_packet_stats{$f}{'pkt_late'};
if ($seq_stats_n{$f}{'seq_num_n'} == $seq_num){
++$tcp_packet_stats{$f}{'pkt_retrans'};
}
}
else {
$len = len;
$ip_hlen = 20;
}
#my $ip = NetPacket::IP->decode(eth_strip($pkt));
#my $tcp_obj = NetPacket::TCP->decode(ip_strip(eth_strip($pkt)));
#my $f = $ip->{src_ip}.":".$tcp_obj->{src_port} if !$offline;
my $seq_num = $tcp_obj->{seqnum};
my $options = $tcp_obj->{options}; #12 bytes
#print "$tcp_obj->{src_port} \n";
if (!exists $tcp_packet_stats{$f}){
&init_stats($f);
$tcp_packet_stats{$f} = &share( {} );
$seq_stats{$f} = &share( {} );
$seq_stats_n{$f} = &share( {} );
$tcp_packet_stats{$f}{'pkt_late'} = 0;
$tcp_packet_stats{$f}{'pkt_retrans'} =0;
$tcp_packet_stats{$f}{'pkt_dup'} = 0;
++$tcp_packet_stats{$f}{'pkt_lost'};
}
++$tcp_packet_stats{$f}{'num_packets'};
&tcp_jitter_stats($f,$options);
#Bandwidth messurements
$tcp_packet_stats{$f}{'num_bytes'} += $ip->{$len}; #counts the bytes
#Check for duplicated,out-of-order, late and lost packets.
$seq_stats{$f}{'seq_diff'} = $seq_num - $seq_stats{$f}{'p_seq_num'} - $seq_stats{$f}{'p_packet_len'};
if ($seq_stats_n{$f}{'seq_num_p'} == $seq_num && $seq_stats{$f}{'p_seq_num'} != 0) {
++$tcp_packet_stats{$f}{'pkt_dup'};
}
if ($seq_stats{$f}{'seq_diff'} != 0 && $seq_stats{$f}{'p_seq_num'} != 0){
if ($seq_stats{$f}{'seq_diff'} < 0){
++$tcp_packet_stats{$f}{'pkt_late'};
if ($seq_stats_n{$f}{'seq_num_n'} == $seq_num){
++$tcp_packet_stats{$f}{'pkt_retrans'};
}
}
else {
++$tcp_packet_stats{$f}{'pkt_lost'};
}
}
if($seq_stats{$f}{'p_seq_num'} < $seq_num){
$seq_stats{$f}{'n_seq_num'} = ($seq_num+$ip->{$len} -($ip_hlen)-($tcp_obj->{hlen}*4))
}
$seq_stats{$f}{'p_seq_num'} = $seq_num;
$seq_stats{$f}{'p_packet_len'} = $ip->{$len}-($ip_hlen)-($tcp_obj->{hlen}*4);
$seq_stats_n{$f}{'seq_num_p'} = $seq_num;
$seq_stats_n{$f}{'seq_num_n'} = $seq_stats{$f}{'n_seq_num'};
}
if($seq_stats{$f}{'p_seq_num'} < $seq_num){
$seq_stats{$f}{'n_seq_num'} = ($seq_num+$ip->{$len} -($ip_hlen)-($tcp_obj->{hlen}*4))
}
$seq_stats{$f}{'p_seq_num'} = $seq_num;
$seq_stats{$f}{'p_packet_len'} = $ip->{$len}-($ip_hlen)-($tcp_obj->{hlen}*4);
$seq_stats_n{$f}{'seq_num_p'} = $seq_num;
$seq_stats_n{$f}{'seq_num_n'} = $seq_stats{$f}{'n_seq_num'};
}
sub tcp_jitter_stats {
my $f = shift;
my $options = shift;
my $tcp_time_stamp_echo = unpack("N",substr($options,8,4));#from our client
my $tcp_time_stamp_delta = $tcp_time_stamp - $seq_stats{$f}{'p_tcp_time_stamp'};
my $tcp_time_stamp_echo_delta = $tcp_time_stamp_echo - $seq_stats{$f}{'p_tcp_time_stamp_echo'};
$seq_stats{$f}{'p_tcp_time_stamp'} = $tcp_time_stamp;
$seq_stats{$f}{'p_tcp_time_stamp_echo'} = $tcp_time_stamp_echo;
my $real_time_delta = time() - $seq_stats{$f}{'real_last_time'};
$seq_stats{$f}{'real_last_time'} = time();
#After AV streams starts
#$first_av_packet = &get_stream_start() if $opt_rtmp;
#$first_av_packet = $tcp_packet_stats{'num_packets'} if !$opt_rtmp and $opt_tcp;
if ($tcp_packet_stats{$f}{'num_packets'} > 1){
#gaps
$tcp_packet_stats{$f}{'gap_sum'} += $real_time_delta;
$tcp_packet_stats{$f}{'gap_square'} +=$real_time_delta**2;
if ($tcp_packet_stats{$f}{'gap_max'} < $real_time_delta){
$tcp_packet_stats{$f}{'gap_max'} = (10**3)*$real_time_delta;
}
if ($tcp_packet_stats{$f}{'gap_min'} > $real_time_delta){
$tcp_packet_stats{$f}{'gap_min'} = (10**3)*$real_time_delta;
}
my $jitter = abs($tcp_time_stamp_delta - $real_time_delta*10**3);
if($jitter > $tcp_packet_stats{$f}{'jitter_max'} ){
$tcp_packet_stats{$f}{'jitter_max'} = $jitter;
}
if($jitter < $tcp_packet_stats{$f}{'jitter_min'} ){
$tcp_packet_stats{$f}{'jitter_min'} = $jitter;
}
$tcp_packet_stats{$f}{'jitter_sum'} += $jitter;
$tcp_packet_stats{$f}{'jitter_square'} += $jitter**2;
}
else {
$tcp_packet_stats{$f}{'jitter_min'} = 2**31;
$tcp_packet_stats{$f}{'jitter_max'} = 0;
$tcp_packet_stats{$f}{'gap_max'} = 0;
$tcp_packet_stats{$f}{'gap_min'} = 2*31;
}
my $f = shift;
my $options = shift;
my $tcp_time_stamp_echo = unpack("N",substr($options,8,4));#from our client
my $tcp_time_stamp_delta = $tcp_time_stamp - $seq_stats{$f}{'p_tcp_time_stamp'};
my $tcp_time_stamp_echo_delta = $tcp_time_stamp_echo - $seq_stats{$f}{'p_tcp_time_stamp_echo'};
$seq_stats{$f}{'p_tcp_time_stamp'} = $tcp_time_stamp;
$seq_stats{$f}{'p_tcp_time_stamp_echo'} = $tcp_time_stamp_echo;
my $real_time_delta = time() - $seq_stats{$f}{'real_last_time'};
$seq_stats{$f}{'real_last_time'} = time();
#After AV streams starts
#$first_av_packet = &get_stream_start() if $opt_rtmp;
#$first_av_packet = $tcp_packet_stats{'num_packets'} if !$opt_rtmp and $opt_tcp;
if ($tcp_packet_stats{$f}{'num_packets'} > 1){
#gaps
$tcp_packet_stats{$f}{'gap_sum'} += $real_time_delta;
$tcp_packet_stats{$f}{'gap_square'} +=$real_time_delta**2;
if ($tcp_packet_stats{$f}{'gap_max'} < $real_time_delta){
$tcp_packet_stats{$f}{'gap_max'} = (10**3)*$real_time_delta;
}
if ($tcp_packet_stats{$f}{'gap_min'} > $real_time_delta){
$tcp_packet_stats{$f}{'gap_min'} = (10**3)*$real_time_delta;
}
my $jitter = abs($tcp_time_stamp_delta - $real_time_delta*10**3);
if($jitter > $tcp_packet_stats{$f}{'jitter_max'} ){
$tcp_packet_stats{$f}{'jitter_max'} = $jitter;
}
if($jitter < $tcp_packet_stats{$f}{'jitter_min'} ){
$tcp_packet_stats{$f}{'jitter_min'} = $jitter;
}
$tcp_packet_stats{$f}{'jitter_sum'} += $jitter;
$tcp_packet_stats{$f}{'jitter_square'} += $jitter**2;
}
else {
$tcp_packet_stats{$f}{'jitter_min'} = 2**31;
$tcp_packet_stats{$f}{'jitter_max'} = 0;
$tcp_packet_stats{$f}{'gap_max'} = 0;
$tcp_packet_stats{$f}{'gap_min'} = 2*31;
}
}
sub check_period {
my $f = shift;
if((($opt_last)+$start_time) < time() || (($opt_period)+$start_time) < time()){
$tcp_stop=1;
my $span = time() - $start_time;
&do_math($f,$span);
}
my $f = shift;
if((($opt_last)+$start_time) < time() || (($opt_period)+$start_time) < time()){
$tcp_stop=1;
my $span = time() - $start_time;
&do_math($f,$span);
}
}
sub eat_tcp {
my $ip;
my $port;
if (!$opt_rtmp) {
$uri = shift;
$port = shift;
if ($ip !~ /^\d+\.\d+\.\d+\.\d+$/){
($ip,$port) = prepare_ip($uri);
}
my $f = $ip.":".$port;
if (! exists($tstart{$f})){
$tstart{$f} = [gettimeofday];
$first_us{$f}=$prev1s_us{$f}=$prevt100ms_us{$f}=$us;
if (! exists($setuptime{$f}) ){
if ( $pinterval){
$setuptime{$f}=0;
} else {
$setuptime{$f}=tv_interval ( $tjoined{$f}, $tstart{$f}) * 10**3;
}
printf "setup $f : %.3f\n", $setuptime{$f} if $opt_debug;
}
my $ip;
my $port;
if (!$opt_rtmp) {
$uri = shift;
$port = shift;
if ($ip !~ /^\d+\.\d+\.\d+\.\d+$/){
($ip,$port) = prepare_ip($uri);
}
my $f = $ip.":".$port;
if (! exists($tstart{$f})){
$tstart{$f} = [gettimeofday];
$first_us{$f}=$prev1s_us{$f}=$prevt100ms_us{$f}=$us;
if (! exists($setuptime{$f}) ){
if ( $pinterval){
$setuptime{$f}=0;
} else {
$setuptime{$f}=tv_interval ( $tjoined{$f}, $tstart{$f}) * 10**3;
}
printf "setup $f : %.3f\n", $setuptime{$f} if $opt_debug;
}
}
$ip = $rtmp_addr if $opt_rtmp;
$port = 1935 unless $port;
my ($net, $netmask, $filter_t, $err, $dev);
#my $time_out_ms = ($opt_last*10**3) || ($opt_period*10**3) if !$opt_last;
my $time_out_ms = 2000;
my $filter_str = "( (src $ip and port $port ) )";
$dev = Net::Pcap::lookupdev(\$err); # find a device
my $r = Net::Pcap::lookupnet( $dev, \$net, \$netmask, \$err);
my $pcap = Net::Pcap::open_live($dev, 1514, 1, $time_out_ms, \$err) || die "You need to run this as sudo $err";
$r=Net::Pcap::compile($pcap, \$filter_t, $filter_str, 0,$netmask);
$r=Net::Pcap::setfilter($pcap, $filter_t);
while (my $pkt=Net::Pcap::next($pcap,\%hdr)) { # get all packets
my $ip_obj = NetPacket::IP->decode(eth_strip($pkt));
my $tcp_obj = NetPacket::TCP->decode(ip_strip(eth_strip($pkt)));
if($tcp_obj->{src_port} == $port && $ip_obj->{src_ip} eq $ip ){
my $f = $ip_obj->{src_ip}.":".$tcp_obj->{src_port};
check_period($f) if $opt_last;
last if $tcp_stop==1;
&tcp_packet_stats($pkt);
}
}
$ip = $rtmp_addr if $opt_rtmp;
$port = 1935 unless $port;
my ($net, $netmask, $filter_t, $err, $dev);
#my $time_out_ms = ($opt_last*10**3) || ($opt_period*10**3) if !$opt_last;
my $time_out_ms = 2000;
my $filter_str = "( (src $ip and port $port ) )";
$dev = Net::Pcap::lookupdev(\$err); # find a device
my $r = Net::Pcap::lookupnet( $dev, \$net, \$netmask, \$err);
my $pcap = Net::Pcap::open_live($dev, 1514, 1, $time_out_ms, \$err) || die "You need to run this as sudo $err";
$r=Net::Pcap::compile($pcap, \$filter_t, $filter_str, 0,$netmask);
$r=Net::Pcap::setfilter($pcap, $filter_t);
while (my $pkt=Net::Pcap::next($pcap,\%hdr)) { # get all packets
my $ip_obj = NetPacket::IP->decode(eth_strip($pkt));
my $tcp_obj = NetPacket::TCP->decode(ip_strip(eth_strip($pkt)));
if($tcp_obj->{src_port} == $port && $ip_obj->{src_ip} eq $ip ){
my $f = $ip_obj->{src_ip}.":".$tcp_obj->{src_port};
check_period($f) if $opt_last;
last if $tcp_stop==1;
&tcp_packet_stats($pkt);
}
}
}
##RTMP impl. -PMM
sub rtmp_eat_stream {
($rtmp,$period,$last,$reconnect,$debug,$swfurl,$pageurl,$flash_version) = @_;
($address, $app, $play) = rtmp_prepare_url($rtmp);
$rtmp_addr = $address;
$port = 1935 unless $opt_port;
my $f = $address.":".$port;
while(!$endstream){
$start_time = time();
if (! exists($tstart{$f})){
$tstart{$f} = [gettimeofday];
$first_us{$f}=$prev1s_us{$f}=$prevt100ms_us{$f}=$us;
if (! exists($setuptime{$f}) ){
if ( $pinterval){
$setuptime{$f}=0;
} else {
$setuptime{$f}=tv_interval ( $tjoined{$f}, $tstart{$f}) * 10**3;
}
printf "setup $f : %.3f\n", $setuptime{$f} if $opt_debug;
($rtmp,$period,$last,$reconnect,$debug,$swfurl,$pageurl,$flash_version) = @_;
($address, $app, $play) = rtmp_prepare_url($rtmp);
$rtmp_addr = $address;
$port = 1935 unless $opt_port;
my $f = $address.":".$port;
while(!$endstream){
$start_time = time();
if (! exists($tstart{$f})){
$tstart{$f} = [gettimeofday];
$first_us{$f}=$prev1s_us{$f}=$prevt100ms_us{$f}=$us;
if (! exists($setuptime{$f}) ){
if ( $pinterval){
$setuptime{$f}=0;
} else {
$setuptime{$f}=tv_interval ( $tjoined{$f}, $tstart{$f}) * 10**3;
}
}
$thr = threads->new(\&eat_tcp) if $opt_tcp and !$reconnect;
rtmp_connect($address, '1935', $app , $swfurl, $pageurl,$flash_version) if $opt_rtmp;
rtmp_play($play, '-1.0', '-1.0', $period, $last,$debug) if $opt_rtmp;
&display_stats() if ($opt_period != $opt_last) and !$endstream;
my $pkt_stat = $thr->join if $opt_tcp;
last if $endstream;
printf "setup $f : %.3f\n", $setuptime{$f} if $opt_debug;
}
}
$thr = threads->new(\&eat_tcp) if $opt_tcp and !$reconnect;
rtmp_connect($address, '1935', $app , $swfurl, $pageurl,$flash_version) if $opt_rtmp;
rtmp_play($play, '-1.0', '-1.0', $period, $last,$debug) if $opt_rtmp;
&display_stats() if ($opt_period != $opt_last) and !$endstream;
my $pkt_stat = $thr->join if $opt_tcp;
last if $endstream;
}
}
sub rtmp_prepare_url{
my $uri = shift;
# return 0 if $uri != m/^(rtmp)://;
$uri =~ s/^(rtmp)://;
$uri =~ s#//##;
@string = split(/\//, $uri);
my $length = $#string;
my $host = $string[0];
my $app = '';
if ($host !~ /^\d+\.\d+\.\d+\.\d+$/){ # hostname
my $padr=gethostbyname($host) || die "Gethostbyname - $host - $padr : $!";
$address=Socket::inet_ntoa($padr);
my $uri = shift;
# return 0 if $uri != m/^(rtmp)://;
$uri =~ s/^(rtmp)://;
$uri =~ s#//##;
@string = split(/\//, $uri);
my $length = $#string;
my $host = $string[0];
my $app = '';
if ($host !~ /^\d+\.\d+\.\d+\.\d+$/){ # hostname
my $padr=gethostbyname($host) || die "Gethostbyname - $host - $padr : $!";
$address=Socket::inet_ntoa($padr);
}
for (my $i = 1; $i < $length;$i++){
$app .= $string[$i];
if ($i > 1 ){$app .="/";}
}
my $play = $string[$length];
return ($address,$app,$play)
for (my $i = 1; $i < $length;$i++){
$app .= $string[$i];
if ($i > 1 ){$app .="/";}
}
my $play = $string[$length];
return ($address,$app,$play)
}
#------------------------------------------------------------------------------
......@@ -730,7 +730,7 @@ sub eat_stream {
my $tx0;
if (($fid, $seq, $src, $dst, $tx, $rx, $size)=
/ID=(\d+)\s+SEQ=(\d+)\s+SRC=([\d.:]+)\s+DST=([\d.:]+)\s+Tx=([\d.,]+)\s+Rx=([\d.,]+)\s+SIZE=(\d+)/){
/ID=(\d+)\s+SEQ=(\d+)\s+SRC=([\d.:]+)\s+DST=([\d.:]+)\s+Tx=([\d.,]+)\s+Rx=([\d.,]+)\s+SIZE=(\d+)/){
$flow_key="$src->$dst";
$flow_pkts{$flow_key}++;
......@@ -769,8 +769,8 @@ sub eat_stream {
# my $select=IO::Select->new(Net::Pcap::fileno($pcap));
until ( ! $uninterrupted || $endstream || ($opt_packets && $n_packets > $opt_packets)
|| ! (my $pkt=Net::Pcap::next($pcap, \%hdr) ) ) {
#$file_flag =1;
$offline =1;
#$file_flag =1;
$offline =1;
eat_pcap($f, $pcap, $pkt);
$n_packets++;
}
......@@ -796,11 +796,11 @@ sub eat_pcap_streams{ # open groups and listen on pcap
die "Could not connect to port $port : $!";
foreach $id (@streams){ # listen to all groups
if ($opt_ipv6){
$address = Net::IPv6Addr::ipv6_parse($id);
$port = $opt_p;
$address = Net::IPv6Addr::ipv6_parse($id);
$port = $opt_p;
}
else {
($address, $port, $multicast) = prepare_ip($id);
($address, $port, $multicast) = prepare_ip($id);
}
$filter .= " or " if $filter =~ /\(\s+\(/;
if ($multicast){
......@@ -838,11 +838,11 @@ sub eat_pcap_streams{ # open groups and listen on pcap
}
sub set_network_info{
my ($f,$src_ip,$dst_ip,$src_port,$dst_port) = @_;
$network_info{$f}{'src_ip'} = $src_ip;
$network_info{$f}{'dst_ip'} = $dst_ip;
$network_info{$f}{'src_port'} = $src_port;
$network_info{$f}{'dst_port'} = $dst_port;
my ($f,$src_ip,$src_port,$dst_ip,$dst_port) = @_;
$network_info{$f}{'src_ip'} = $src_ip;
$network_info{$f}{'dst_ip'} = $dst_ip;
$network_info{$f}{'src_port'} = $src_port;
$network_info{$f}{'dst_port'} = $dst_port;
}
sub eat_pcap { # process pcap packets
my ($f, $pcap, $pkt)=@_;