#!c:/perl/bin/perl.exe ########################################################## # Alelyze - traffic analysis of PcAle logs # (c) 2007 www.tarapippo.net # Project page: www.tarapippo.net/sirad/alelyze.html # # released under GNU/GPL license - # please see http://www.gnu.org for more details # version: 0.1 - published: apr07 ########################################################## use GD; $debug = 0; $blk = -1 ; open (ALELOG, "$ARGV[0]") || die "couldn't open the file!"; my(@lines) = ; ##### PROCESS PCALE STYLE LOGS #### # join all log lines into a single block # and remove all status lines that don't contain traffic info foreach $line (@lines) { if ($debug > 1){print $line;} if ($line =~ /STARTED \w{3}-\d\d-\d{4} \d\d:\d\d/) {$line = "";} chomp $line; # delete start - stop entries, as they may complicate things $line =~ s/State SCANNING STOPPED//g; $line =~ s/State SCANNING//g; $line =~ s/State PAUSE SCAN TO LISTEN FOR CALL//g; $line =~ s/State SCANNING//g; if ($debug > 3){print "===PROCESSED: $line \n---------------\n";} if ($line =~ /\[\d\d:\d\d:\d\d\]/) { if ($debug > 1){print "==========================\n";} $blk++ ; } #### identify full "THIS WAS" #### if ($line =~ m/\[TWS\]\[.{15}\]/) { $entry = substr($&,5); $entry =~ s/\s//g; $entry =~ s/\[//; $entry =~ s/\]//; if($thiswaslong[$blk] == 0){ $thiswaslong[$blk]=$entry; if ($debug > 1){print "> This was (full): $thiswaslong[$blk]\n";} push (@heardlong, $thiswaslong[$blk]);} } #### identify full "TO" #### if ($line =~ m/\[TO\s\]\[.{15}\]/) { $entry = substr($&,5); $entry =~ s/\s//g; $entry =~ s/\[//; $entry =~ s/\]//; if($tolong[$blk] == 0){ $tolong[$blk]=$entry; if ($debug > 1){print "> To (full) : $tolong[$blk]\n";} push (@calledlong, $tolong[$blk]); } } #### identify message #### if ($line =~ m/\[AMD\]/) { $entry = $' ; $entry =~ s/\[//; $entry =~ s/\]//; if($message[$blk] == 0){ $message[$blk]=$entry; if ($debug > 1){print "> Message : $message[$blk]\n";} } } #### identify full "THIS IS" #### if ($line =~ m/\[TIS\]\[.{15}\]/) { $entry = substr($&,5); $entry =~ s/\s//g; $entry =~ s/\[//; $entry =~ s/\]//; if($thisislong[$blk] == 0){ $thisislong[$blk]=$entry; if ($debug > 1){print "> This is (full) : $thisislong[$blk]\n";} push (@heardlong, $thisislong[$blk]); } } } close(ALELOG); ###### COMMON SECTION ###### #### compile list of "heard" ID, picking only from the "long" ones %service = (); @heardlong = grep ++$service{$_} < 2, @heardlong; @sheardlong = sort { $a <=> $b } @heardlong; #### compile list of "heard" ID, picking only from the long "TO:" %service = (); @calledlong = grep ++$service{$_} < 2, @calledlong; @scalledlong = sort { $a <=> $b } @calledlong; #### joint list @total = (@sheardlong, @scalledlong); %service = (); @total = grep ++$service{$_} < 2, @total; @stotal = sort { $a <=> $b } @total; $totalid = @stotal; $spacing = 360 / $totalid; ##### plot image # create a new image $hsize = 800; $vsize = $hsize; $vcanvas = $vsize + 100 ; $spoke = int($hsize * 0.85 / 2) ; $hcenter = int($hsize / 2 ); $vcenter = int($vsize / 2 - $spoke * 0.05 ); $im = new GD::Image($hsize,$vcanvas); # allocate some colors $white = $im->colorAllocate(255,255,255); $black = $im->colorAllocate(0,0,0); $red = $im->colorAllocate(255,0,0); $blue = $im->colorAllocate(0,0,255); $green = $im->colorAllocate(0,250,154); $grey = $im->colorAllocate(105,105,105); # make the background transparent and interlaced $im->transparent($white); $im->interlaced('true'); #### start plotting my %elements = (); $pi = 3.14159265358979; ### plot units in circle foreach (@stotal) { # assign a position in degrees to each ID $position = $position + $spacing; $radpos = ($position / 180) * $pi; $elements{$_} = $radpos; $y = int($spoke * sin($radpos) + $hcenter); $x = int($spoke * cos($radpos) + $vcenter); #$im->rectangle($x,$y,$x+5,$y+5,$blue); $im->string(gdSmallFont,$x,$y,$_,$black); if ($debug > 0){print "ID $_ - position $position degrees - $radpos radians - X $x - Y $y \n";} } ### draw connecting lines while ( $k < $blk + 1) { if ($debug > 0){print "===== block $k of $blk =====\n";} # draw calls if (($tolong[$k]) and ($thisislong[$k])){ $radposto = $elements{$tolong[$k]}; $radposfrom = $elements{$thisislong[$k]}; $y0 = int($spoke * sin($radposfrom) + $hcenter); $x0 = int($spoke * cos($radposfrom) + $vcenter) + 10; $y1 = int($spoke * sin($radposto) + $hcenter); $x1 = int($spoke * cos($radposto) + $vcenter) + 10; $im->line($x0,$y0,$x1,$y1,$blue); $im->filledRectangle($x1,$y1,$x1 + 3,$y1 + 3,$blue); if ($debug > 0){print "$thisislong[$k] calling $tolong[$k]\n";} } # draw messages if (($message[$k]) and ($thisislong[$k])){ $radposto = $elements{$tolong[$k]}; $radposfrom = $elements{$thisislong[$k]}; $y0 = int($spoke * sin($radposfrom) + $hcenter); $x0 = int($spoke * cos($radposfrom) + $vcenter) + 10; $y1 = int($spoke * sin($radposto) + $hcenter); $x1 = int($spoke * cos($radposto) + $vcenter) + 10; $im->line($x0,$y0,$x1,$y1,$red); $im->filledRectangle($x1,$y1,$x1 + 3,$y1 + 3,$red); if ($debug > 0){print "$thisislong[$k] message $tolong[$k]\n";} } # draw beacons if (($thiswaslong[$k])){ $radposto = $elements{$thiswaslong[$k]}; $y0 = int($spoke * sin($radposto) + $hcenter); $x0 = int($spoke * cos($radposto) + $vcenter) + 10; $im->rectangle($x0 - 2,$y0 - 2,$x0 + 5,$y0 + 5,$green); if ($debug > 0){print "thiswas $thiswaslong[$k]\n";} } if (($thisislong[$k])){ $radposto = $elements{$thisislong[$k]}; $y0 = int($spoke * sin($radposto) + $hcenter); $x0 = int($spoke * cos($radposto) + $vcenter) + 10; $im->rectangle($x0 - 2,$y0 - 2,$x0 + 5,$y0 + 5,$green); if ($debug > 0){print "thisis $thisislong[$k]\n";} } $k++ ; } # title $im->string(gdLargeFont,20,20,"Analysis of logfile: $ARGV[0]",$black); # draw guide to symbols $im->string(gdSmallFont,20,800,"A called B",$blue); $im->line(110,806,190,806,$blue); $im->filledRectangle(190,804,194,808,$blue); $im->string(gdSmallFont,100,800,"A",$blue); $im->string(gdSmallFont,198,800,"B",$blue); $im->string(gdSmallFont,350,800,"A sent message to B",$red); $im->line(510,806,590,806,$red); $im->filledRectangle(590,804,594,808,$red); $im->string(gdSmallFont,500,800,"A",$red); $im->string(gdSmallFont,598,800,"B",$red); $im->string(gdSmallFont,20,820,"A was heard directly",$green); $im->rectangle(190,823,195,829,$green); $im->string(gdSmallFont,198,820,"A",$green); # make sure we are writing to a binary stream # Open a file for writing open(PICTURE, ">$ARGV[0].jpg") or die("Cannot open file for writing"); # Make sure we are writing to a binary stream binmode PICTURE; # Convert the image to JPG and print it to the file PICTURE print PICTURE $im->jpeg; close PICTURE;