
# this program is written by Borisov Sergey
use Net::RawIP; 
require 'getopts.pl';

Getopts('i:d:l:');
die "Usage $0 -i <IP of FreeBSD server> -d <eth device of local> -l <ip of local mashine>;"
unless ($opt_i &&  $opt_d && $opt_l);

@flags = qw/FRAGOFF SOURCE DEST SEQ ACKSEQ U A P R S F WINDOW/;
@flags_icmp = qw/TOS IPLEN ID FRAGOFF IPCHECK SOURCE DEST LEN UDPCHECK DATA/;
$filter_icmp = "ip proto \\udp";
$filter_tcp = "src host $opt_i and ip proto \\tcp";
$psize = 1500;
$device = $opt_d;
$open_p=139;
$closed_p=44321;
$sport=30001;
$local=$opt_l;
$opt_n=7;
$timeout = 1000;
$ttl=255;
$id = 40001;
$seq=10000;
$ack_seq=11001;
@t1=();
@t2=();
@t3=();
@t4=();
@t5=();
@t6=();
@t7=();
@tu=();

if(fork()){
	$b = new Net::RawIP({tcp=>{}});
	my $pcap = $b->pcapinit($device,$filter_tcp,$psize,$timeout);
	if (fork()) {loop $pcap,7,\&tcp_get,\@b;}
	$c = new Net::RawIP({udp=>{}});	
	my $icmp_cap = $c->pcapinit($device,$filter_icmp,$psize,$timeout);
	$offset_icmp=linkoffset($icmp_cap);
	loop $pcap,1,\&icmp_get,\@c;
          }
	  else {
$a = new Net::RawIP;

#test1
print "test 1\n";
$a->set({ ip => {
		 saddr => $local,
                	 daddr => $opt_i,
		 id => $id,
		 frag_off => "0", 
		 ttl => $ttl
		 },
 	  tcp=> {
		 dest => $open_p,
 	         source => $sport,
 	         syn => 1,
		 ack => 0,
		 fin => 0,
		 urg => 0,
		 psh => 0,
		 rst => 0,
		 seq => $seq
		
		}
 	});				
$a->send;
$sport=$sport+1;
$id = "10000" + $sport;

#test2
print "test2 \n";
$a->set({ ip => {
		 saddr => $local,
                  	 daddr => $opt_i,
		 id => $id,
		 frag_off => "0", 
		 ttl => $ttl
 		 },
 	  tcp=> {
		 dest => $open_p,
 	             source => $sport,
 	             syn => 0,
		 ack => 0,
		 fin => 0,
		 urg => 0,
		 psh => 0,
		rst => 0, 
		seq => $seq
		
		}
 	});			
$a->send;
$sport=$sport+1;
$id = "10000" + $sport;
#test3
print "test 3\n"; 
$a->set({ ip => {
		 saddr => $local,
                  	 daddr => $opt_i,
		 id => $id,
		 frag_off => "0", 
		 ttl => $ttl
 		 },
 	  tcp=> {
		 dest => $open_p,
 	             source => $sport,
 	             syn => 1,
		 ack => 0,
		 fin => 1,
		 urg => 1,
		 rst => 0,
		 psh => 1,
		seq => $seq
		
		}
 	});			
$a->send;
$sport=$sport+1;
$id = "10000" + $sport;
#test4
print "test 4\n";
$a->set({ ip => {
		 saddr => $local,
                  	 daddr => $opt_i,
		 id => $id,
		 frag_off => "0", 
		 ttl => $ttl
 		 },
 	  tcp=> {
		 dest => $open_p,
 	             source => $sport,
 	             syn => 0,
		 ack => 1,
		 fin => 0,
		 urg => 0,
		 rst => 0,
		 psh => 0,
		seq => $seq
		
		}
 	});				
$a->send;
$sport=$sport+1;
$id = "10000" + $sport;
#test5
print"test 5\n";
$a->set({ ip => {
		 saddr => $local,
                  	 daddr => $opt_i,
		 id => $id,
		 frag_off => "0", 
		 ttl => $ttl
 		 },
 	  tcp=> {
		 dest => $closed_p,
 	             source => $sport,
 	             syn => 1,
		 ack => 0,
		 fin => 0,
		 urg => 0,
		 rst => 0,
		 psh => 0,
		seq => $seq
		
		}
 	});				
$a->send;
$sport=$sport+1;
$id = "10000" + $sport;
#test6
print"test 6\n";
$a->set({ ip => {
		 saddr => $local,
                  	 daddr => $opt_i,
		 id => $id,
		 frag_off => "0", 
		 ttl => $ttl
 		 },
 	  tcp=> {
		 dest => $closed_p,
 	             source => $sport,
 	             syn => 0,
		 ack => 1,
		 fin => 0,
		 urg => 0,
		 rst => 0,
		 psh => 0,
		seq => $seq
		
		}
 	});				
$a->send;
$sport=$sport+1;
$id = "10000" + $sport;
#test7
print "test 7\n";
$a->set({ ip => {
		 saddr => $local,
                  	 daddr => $opt_i,
		 id => $id,
		 frag_off => "0", 
		 ttl => $ttl
 		 },
 	  tcp=> {
		 dest => $closed_p,
 	             source => $sport,
 	             syn => 0,
		 ack => 1,
		 fin => 0,
		 urg => 0,
		 rst => 0,
		 psh => 0,
		seq => $seq
		
		}
 	});			
$a->send;

$sport=$sport+1;
$id = "10000" + $sport;
#test8
$a= new Net::RawIP({upd=>{}});
print "test $sport\n";
$a->set({ ip => {
		 saddr => $local,
                 daddr => $opt_i,
		 id => $id
 		 },
 	  udp=> {
		 dest => 44322,
 	         source => $sport,
		 data => 'qwertyuiop'
		}
 	});			
$a->send(5,3);
}

sub icmp_get {
$c->bset(substr( $_[2],$offset_icmp));
my @fl1 = $c->get({
			ip=>[qw(tos tot_len id frag_off check)],
			udp=>[qw(source dest len check data)]
   		       });
print "PU -> ";
map { print "$flags_icmp[$_] = ",$fl1[$_],"  " } (0..9);
print "\n";
}

sub tcp_get {
$b->bset(substr( $_[2],14));
my @fl = $b->get({
			ip=>[qw(frag_off)],
			tcp=>[qw(source dest seq ack_seq urg ack psh rst syn fin window)]
   		       });
if ( $fl[2] == 30001)
	{
	if ($fl[0]) {$t1[0]=1;} else {$t1[0]=0;}
	$t1[1]=$fl[11];
	if (($fl[4]>=10000)&&($fl[4]<=10001)) 
		{if (($fl[4] - 10000)==1) {$t1[2]="S++";} else {$t1[2]="S";}} 
		else {$t1[2]=$fl[4];};
	$myflags="";
	map { ($myflags.=$flags[$_])  if $fl[$_] } (5..10);
	$t1[3]=$myflags;
	print "T1:",$t1[0],":",$t1[1],":",$t1[2],":",$t1[3]," \n";
	}

if ( $fl[2] == 30002)
	{
	if ($fl[0]) {$t1[0]=1;} else {$t2[0]=0;}
	$t2[1]=$fl[11];
	if (($fl[4]>=10000)&&($fl[4]<=10001)) 
		{if (($fl[4] - 10000)==1) {$t2[2]="S++";} else {$t2[2]="S";}} 
		else {$t2[2]=$fl[4];};
	$myflags="";
	map { ($myflags.=$flags[$_])  if $fl[$_] } (5..10);
	$t2[3]=$myflags;
	print "T2:",$t2[0],":",$t2[1],":",$t2[2],":",$t2[3]," \n";
	}

if ( $fl[2] == 30003)
	{
	if ($fl[0]) {$t3[0]=1;} else {$t3[0]=0;}
	$t3[1]=$fl[11];
	if (($fl[4]>=10000)&&($fl[4]<=10001)) 
		{if (($fl[4] - 10000)==1) {$t3[2]="S++";} else {$t3[2]="S";}} 
		else {$t3[2]=$fl[4];};
	$myflags="";
	map { ($myflags.=$flags[$_])  if $fl[$_] } (5..10);
	$t3[3]=$myflags;
	print "T3:",$t3[0],":",$t3[1],":",$t3[2],":",$t3[3]," \n";
	}

if ( $fl[2] == 30004)
	{
	if ($fl[0]) {$t4[0]=1;} else {$t4[0]=0;}
	$t4[1]=$fl[11];
	if (($fl[4]>=10000)&&($fl[4]<=10001)) 
		{if (($fl[4] - 10000)==1) {$t4[2]="S++";} else {$t4[2]="S";}} 
		else {$t4[2]=$fl[4];};
	$myflags="";
	map { ($myflags.=$flags[$_])  if $fl[$_] } (5..10);
	$t4[3]=$myflags;
	print "T4:",$t4[0],":",$t4[1],":",$t4[2],":",$t4[3]," \n";
	}

if ( $fl[2] == 30005)
	{
	if ($fl[0]) {$t5[0]=1;} else {$t5[0]=0;}
	$t5[1]=$fl[11];
	if (($fl[4]>=10000)&&($fl[4]<=10001)) 
		{if (($fl[4] - 10000)==1) {$t5[2]="S++";} else {$t5[2]="S";}} 
		else {$t5[2]=$fl[4];};
	$myflags="";
	map { ($myflags.=$flags[$_])  if $fl[$_] } (5..10);
	$t5[3]=$myflags;
	print "T5:",$t5[0],":",$t5[1],":",$t5[2],":",$t5[3]," \n";
	}

if ( $fl[2] == 30006)
	{
	if ($fl[0]) {$t6[0]=1;} else {$t6[0]=0;}
	$t6[1]=$fl[11];
	if (($fl[4]>=10000)&&($fl[4]<=10001)) 
		{if (($fl[4] - 10000)==1) {$t6[2]="S++";} else {$t6[2]="S";}} 
		else {$t6[2]=$fl[4];};
	$myflags="";
	map { ($myflags.=$flags[$_])  if $fl[$_] } (5..10);
	$t6[3]=$myflags;
	print "T6:",$t6[0],":",$t6[1],":",$t6[2],":",$t6[3]," \n";
	}

if ( $fl[2] == 30007)
	{
	if ($fl[0]) {$t7[0]=1;} else {$t7[0]=0;}
	$t7[1]=$fl[11];
	if (($fl[4]>=10000)&&($fl[4]<=10001)) 
		{if (($fl[4] - 10000)==1) {$t7[2]="S++";} else {$t7[2]="S";}} 
		else {$t7[2]=$fl[4];};
	$myflags="";
	map { ($myflags.=$flags[$_])  if $fl[$_] } (5..10);
	$t7[3]=$myflags;
	print "T7:",$t7[0],":",$t7[1],":",$t7[2],":",$t7[3]," \n";
	}
}
