Calea perl trafr

From MikroTik Wiki
Revision as of 10:07, 1 March 2010 by Kostil (talk | contribs)
Jump to: navigation, search

System independent trafr script

This small article describe the script wrote on perl which help you to get packets encapsulated by calea and captured by tcpdump or wireshark. You could upgrade it to catch traffic without tcpdump or wireshark.

#!/usr/bin/perl -w

#
#  TZSP headers remover
#
#  You need this modules:
#  Data-HexDump		0.02
#  Net-Pcap		0.16
#  Net-Pcap-Reassemble	0.04
#  NetPacket		0.41.1
#  
# usage: trafr -r filename.pcap [ -d ] [ -c count ]

use strict;
use Net::Pcap qw ( :datalink :functions );
use NetPacket::Ethernet;
use NetPacket::IP;
use NetPacket::UDP;
use Data::HexDump;
use Getopt::Std;

our($opt_d, $opt_r, $opt_c);
my ($err,$dumpOUT,$errdumpOUT,$count,$pcap,$dumper,$errdumper);

getopt('rc');
getopts('d');

my $dumpIN = $opt_r or die "No input file!\nUse -r\n";	# input pcap file
my $debug = $opt_d;					# do you need debug?
print "test: ".$debug."\n" if ($debug);
if (!$opt_c) { $count = -1}
else { $count = $opt_c}					# how many packets to process? (for debug)
my $counter = 1;
my $observedIP = '10.16.18.14';				# ip that you looking for
#my $errdumpOUT = 'errpackets.pcap';			# file for errors packets (for debug)

# --- Output file name
if ($dumpIN !~ m/^(\S+)\.pcap$/i){ $dumpOUT = $dumpIN.'.ok.pcap'}
else { $dumpOUT = $1.'.ok.pcap'}

# --- Errors packets file name
if ($debug){
   if ($dumpIN !~ m/^(\S+)\.pcap$/i){ $errdumpOUT = $dumpIN.'.err.pcap'}
   else { $errdumpOUT = $1.'.err.pcap'}
}

# --- Open input file
$pcap = Net::Pcap::pcap_open_offline($dumpIN, \$err)
   or die $err;

# --- Open output file
$dumper = Net::Pcap::pcap_dump_open($pcap, $dumpOUT);

# --- Open file for errors packets
# --- (for debug)
$errdumper = Net::Pcap::pcap_dump_open($pcap,$errdumpOUT) if ($debug);

# --- Process
Net::Pcap::pcap_loop($pcap, $count, \&headoff_tzsp, "user data");

# --- Close all open files
Net::Pcap::close($pcap);
Net::Pcap::pcap_dump_close($dumper);
Net::Pcap::pcap_dump_close($errdumper) if ($debug);

# --- Delete error file if it empty
if ($debug) {
   if ( -e $errdumpOUT and -s $errdumpOUT == 24){
	system("rm $errdumpOUT") == 0
	or die "rm -f ".$errdumpOUT." failed: $?";
   }
}

# --- TZSP head remove function
sub headoff_tzsp {

   print STDOUT "\n=============================================================================\n" if ($debug);
   my($user_data, $header, $packet) = @_;
    
   # --- Decapsulate packet
   my $ether = NetPacket::Ethernet->decode($packet);
   my $ip = NetPacket::IP->decode($ether->{data});
   my $udp = NetPacket::UDP->decode($ip->{data});

   # --- For debug
#    print STDOUT $counter," ",
#        $ip->{'src_ip'}, ":", $udp->{'src_port'}, " -> ",
#        $ip->{'dest_ip'}, ":", $udp->{'dest_port'}, 
#	" length: ", $udp->{'len'}, " chksum: ",$udp->{'cksum'},
#	" fragment: ",$ip->{'foffset'},"\n" if ($debug);
#    print STDOUT HexDump $udp->{data} if($debug);
    
   # --- Cut TZSP bytes
   my $tzspheader = substr $udp->{data}, 0, 5;
   my $tzspdata = substr $udp->{data}, 5;
#    print STDOUT HexDump $tzspheader if($debug);
   
   # --- Check is the header is TZSP
   if (unpack ('H*',$tzspheader) ne '0100000101'){
	print STDERR $counter," Maybe wrong tzsp header? -> ",unpack ('H*',$tzspheader),"\n" if ($debug);
	Net::Pcap::pcap_dump($errdumper, $header, $packet) if ($debug);
	$counter++;
	return;
   }
#    print STDOUT HexDump $tzspdata if($debug);
   
   # --- Process included packet
   my $ethertzsp = NetPacket::Ethernet->decode($tzspdata);
   my $iptzsp = NetPacket::IP->decode($ethertzsp->{data});
	
   # --- If it's the right ip
   if ($iptzsp->{'src_ip'} eq $observedIP or $iptzsp->{'dest_ip'} eq $observedIP){
#	Net::Pcap::pcap_dump($dumper, $header, $packet) if ($debug);
	# --- If yes, add it to output file
	Net::Pcap::pcap_dump($dumper, $header, $tzspdata);
   }
   else {
	print STDERR $counter," Maybe wrong include packet? ",$iptzsp->{'src_ip'}," -> ",$iptzsp->{'dest_ip'},"\n";
   }
   $counter++;
}

--kostil 08:07, 1 March 2010 (UTC)