# -sam k (commport5@lucidx.com)

use POSIX qw(strftime);
use pdump::Sniff;

sub check_tcp {
 my ($nite,$headers,$df,$trgt,@nda,@ndb,$totl,@ints,$vers,$ihl,$tos,$tot,$id,$frg,$ttl,$pro,$chc,$saddr,$daddr,$sport,$dport,$seq,$aseq,$dof,$res1,$res2,$urg,$ack,$psh,$rst,$syn,$fin,$win,$chk,$data,$len,$mtu,$iid,$type,$code,$gateway,$unu,@tmrp) = (0);
 my ($call,$packet_all,$alla,$cll,$nite,$time,$untm,$protocol,$pro,$proto,$amt) = @_;
 my ($vers,$ihl,$tos,$tot,$id,$frg,$ttl,$pro,$chc,$saddr,$daddr,$sport,$dport,$seq,$aseq,$dof,$res1,$res2,$urg,$ack,$psh,$rst,$syn,$fin,$win,$chk,$data) =
 $packet_all->get({ip=>['version','ihl','tos','tot_len','id','frag_off','ttl','protocol','check','saddr','daddr'],tcp=>[
 'source','dest','seq','ack_seq','doff','res1','res2','urg','ack','psh','rst','syn','fin','window','check','data']});
 if ($strg) {
  @torn = ($strg,$vers,$ihl,$tos,$tot,$id,$frg,$ttl,$pro,$chc,$saddr,$daddr,$sport,$dport,$seq,$aseq,$dof,$res1,$res2,$urg,$ack,$psh,$rst,$syn,$fin,$win,$chk,$data);
 }
 if ($urg) {
  $headers .= "U";
  $fphd .= "U";
 }
 if ($ack) {
  $fphd .= "A";
 }
 if ($psh) {
  $headers .= "P";
  $fphd .= "P";
 }
 if ($rst) {
  $headers .= "R";
  $fphd .= "R";
 }
 if ($syn) {
  $headers .= "S";
  $fphd .= "S";
 }
 if ($fin) {
  $headers .= "F";
  $fphd .= "F";
 }
 unless ($headers) {
  $headers = ".";
 }
 $seq =~ s/^-//;
 if ($frg == 16384) {
  $df = " (DF)";
 }
 if ($dmth) {
  $flags = unpack("B8", substr($ctcp, $tcpo+20+13, 1));
  substr($flags, 6, 1) == '1' || substr($flags, 7, 1) == '1';
  %pd = &getpckt($tcpo);
  if ($nons) {
   $sname = $pd{'saddr'};
   $dname = $pd{'daddr'};
   $stest = $sname;
   $dtest = $dname;
  }
  else {
   $sname = $pd{'shost'};
   $dname = $pd{'dhost'};
   $stest = $pd{'saddr'};
   $dtest = $pd{'daddr'};
  }
 }
 else {
  if ($nons) {
   $sname = &ip2dot($saddr);
   $dname = &ip2dot($daddr);
   $stest = $sname;
   $dtest = $dname;
  }
  else {
   $sname = &ip2name($saddr);
   $dname = &ip2name($daddr);
   $stest = &ip2dot($saddr);
   $dtest = &ip2dot($daddr);
  }
 }
 unless ($nosv) {
  @sserv = &port2serv($sport, $proto);
  @dserv = &port2serv($dport, $proto);
 }
 if ($sserv[0]) {
  $stype = $sserv[0];
 }
 else {
  $stype = $sport;
 }
 if ($dserv[0]) {
  $dtype = $dserv[0];
 }
 else {
  $dtype = $dport;
 }
 if ($pgnr) {
  unless ($pnrc) {
   if ($sport =~ /$prgx/ or $dport =~ /$prgx/ or $stype =~ /$prgx/ or $dtype =~ /$prgx/) {
    $nite++;
   }
  }
  else {
   if ($sport =~ /$prgx/i or $dport =~ /$prgx/i or $stype =~ /$prgx/i or $dtype =~ /$prgx/i) {
    $nite++;
   }
  }
 }
 if ($ignr) {
  unless ($gnrc) {
   if ($sname =~ /$regx/ or $dname =~ /$regx/ or $stest =~ /$regx/ or $dtest =~ /$regx/) {
    $nite++;
   }
  }
  else {
   if ($sname =~ /$regx/i or $dname =~ /$regx/i or $stest =~ /$regx/i or $dtest =~ /$regx/i) {
    $nite++;
   }
  }
 }
 if ($nofl and !$fl) {
  $dname =~ s/^([^\.]+)\..*?$/$1/;
  $sname =~ s/^([^\.]+)\..*?$/$1/;
 }
 unless ($nite) {
  $top++;
  if ($osdt) {
   @opts = $packet_tcp->optget(ip => {});
   foreach $ctn (@prnt) {
    @sel = split(/\n/, $ctn);
    foreach $ect (@sel) {
     if ($ect =~ /^T\d+/) {
      $ect =~ s/^T\d+\(//;
      $ect =~ s/\)$//;
      %info = split(/(?:\%|=)/, $ect);
      if ($info{'DF'} eq "Y" and $frg == 16384 or $info{'DF'} eq "N" and $frg == 0) {
       @wins = split(/\|/, $info{'W'});
       foreach $ws (@wins) {
        $wrs = hex($ws);
        if ($wrs == $win) {
         $info{'Flags'} =~ s/A//;
         if ($info{'Flags'} eq $fphd) {
          @trth = grep { /^[^#]/ } split(/\n/, $ctn);
          $trth[0] =~ s/\s*#.*?$//;
          unless ($done{$dtest} eq $trth[0]) {
           print "$dtest\t$stest\t$trth[0]\n";
          }
          $done{$dtest} = $trth[0];
         }
        }
       }
      }
     }
    }
   }
  }
  elsif ($spfp) {
   unless ($done{$stest}) {
    unless ($stest eq $ip) {
     foreach $trgt (@sffp) {
      @ints = split(/:/, $trgt);
      if (hex($ints[0]) eq $win) {
#      if ($ints[1] eq $ttl) {
       if ($ints[2] == 0 and $frg != 16384 or $ints[2] == 1 and $frg == 16384) {
        print "$stest\t$sport\t$ints[3]\n";
        $done{$stest} = 1;
        last;
       }
      }
     }
    }
   }
  }
  elsif ($ngrp) {
   if ($data) {
    if ($ack) {
     $hdrs = "A" . $headers;
    }
    else {
     $hdrs = $headers;
    }
    unless ($ngrx) {
     if ($ngrc) {
      if ($ngra) {
       unless ($ansi) {
        if ($strn) {
         &format(@torn);
        }
        else {
         print "\nT $stest:$sport -> $dtest:$dport [$hdrs]\n$data..\n";
        }
       }
       else {
        if ($strn) {
         &format(@torn);
        }
        else {
         print "\nT $stest:$sport -> $dtest:$dport [$hdrs]\n$data..\n";
        }
       }
      }
      else {
       if ($data =~ /$ngrr/i) {
        unless ($ansi) {
         if ($strn) {
          &format(@torn);
         }
         else {
          print "\nT $stest:$sport -> $dtest:$dport [$hdrs]\n$data..\n";
         }
        }
        else {
         if ($strn) {
          &format(@torn);
         }
         else {
          print "\nT $stest:$sport -> $dtest:$dport [$hdrs]\n$data..\n";
         }
        }
       }
       else {
        unless ($strn) {
         print "#";
        }
       }
      }
     }
     else {
      if ($ngra) {
       unless ($ansi) {
        if ($strn) {
         &format(@torn);
        }
        else {
         print "\nT $stest:$sport -> $dtset:$dport [$hdrs]\n$data..\n";
        }
       }
       else {
        if ($strn) {
         &format(@torn);
        }
        else {
         print "\nT $stest:$sport -> $dtset:$dport [$hdrs]\n$data..\n";
        }
       }
      }
      else {
       if ($data =~ /$ngrr/) {
        unless ($ansi) {
         if ($strn) {
          &format(@torn);
         }
         else {
          print "\nT $stest:$sport -> $dtest:$dport [$hdrs]\n$data..\n";
         }
        }
        else {
         if ($strn) {
          &format(@torn);
         }
         else {
          print "\nT $stest:$sport -> $dtest:$dport [$hdrs]\n$data..\n";
         }
        }
       }
       else {
        unless ($strn) {
         print "#";
        }
       }
      }
     }    
    }
    else {
     if ($ngrc) {
      if ($ngra) {
       unless ($ansi) {
        if ($strn) {
         &format(@torn);
        }
        else {
         print "\nT $stest:$sport -> $dtest:$dport [$hdrs]\n$data..\n";
        }
       }
       else {
        if ($strn) {
         &format(@torn);
        }
        else {
         print "\nT $stest:$sport -> $dtest:$dport [$hdrs]\n$data..\n";
        }
       }
      }
      else {
       if ($data !~ /$ngrr/i) {
        unless ($ansi) {
         if ($strn) {
          &format(@torn);
         }
         else {
          print "\nT $stest:$sport -> $dtest:$dport [$hdrs]\n$data..\n";
         }
        }
        else {
         if ($strn) {
          &format(@torn);
         }
         else {
          print "\nT $stest:$sport -> $dtest:$dport [$hdrs]\n$data..\n";
         }
        }
       }
       else {
        unless ($strn) {
         print "#";
        }
       }
      }
     }
     else {
      if ($ngra) {
       unless ($ansi) {
        if ($strn) {
         &format(@torn);
        }
        else {
         print "\nT $stest:$sport -> $dtest:$dport [$hdrs]\n$data..\n";
        }
       }
       else {
        if ($strn) {
         &format(@torn);
        }
        else {
         print "\nT $stest:$sport -> $dtest:$dport [$hdrs]\n$data..\n";
        }
       }
      }
      else {
       if ($data !~ /$ngrr/) {
        unless ($ansi) {
         if ($strn) {
          &format(@torn);
         }
         else {
          print "\nT $stest:$sport -> $dtest:$dport [$hdrs]\n$data..\n";
         }
        }
        else {
         if ($strn) {
          &format(@torn);
         }
         else {
          print "\nT $stest:$sport -> $dtest:$dport [$hdrs]\n$data..\n";
         }
        }
       }
       else {
        unless ($strn) {
         print "#";
        }
       }
      }
     }
    }
   }
  }
  elsif ($strn) {
   $tm = strftime "%H:%M:%S", localtime;
   $tm .= ".$time";
   if ($df) {
    $dff = 1;
   }
   else {
    $dff = 0;
   }
   %string = (
        "saddr", $stest,
        "daddr", $dtest,
        "source", $sname,
        "dest", $dname,
        "shost", $sname,
        "dhost", $dname,
        "sserv", $stype,
        "dserv", $dtype,
        "version", $vers,
        "ihl", $ihl,
        "tos", $tos,
        "totlen", $tot,
        "id", $id,
        "fragoff", $frg,
        "ttl", $ttl,
        "protocol", $pro,
        "proto", $prt,
        "check1", $chc,
        "rawsaddr", $saddr,
        "rawdaddr", $daddr,
        "sport", $sport,
        "dport", $dport,
        "sequence", $seq,
        "seq", $seq,
        "ackseq", $aseq,
        "doff", $dof,
        "res1", $res1,
        "res2", $res2,
        "urg", $urg,
        "ack", $ack,
        "psh", $psh,
        "rst", $rst,
        "syn", $syn,
        "fin", $fin,
        "winsize", $win,
        "hexwin", sprintf("%x", $win),
        "df", $dff,
        "check2", $chk,
        "data", $data,
        "time", $tm,
        "headers", $headers,
   );
   if ($string{"data"} =~ /^\n*$/) {
    $string{"data"} = "";
   }
   $str = $strg;
   $string{"seq"} =~ s/^-//;
   $string{"sequence"} =~ s/^-//;
   $string{"ackseq"} =~ s/^-//;
   $strg =~ s/\\t/\t/g;
   $strg =~ s/\\n/\n/g;
   $strg =~ s/\$([A-Za-z0-9]+)/$string{$1}/g;
   unless ($str =~ /^[\s\\]*\$data[\s\\]*$/ and $data =~ /^\s*$/) {
    print "$strg\n";
   }
  }
  else {
   if ($tstm != 1 and $tstm != 2) {
    print strftime "%H:%M:%S", localtime;
    print ".$time ";
   }
   if ($tstm == 2) {
    print "$untm.$time ";
   }
   print "$sname.$stype > $dname.$dtype: $headers $seq";
#   if ($urg) {
#    print "$prg ";
#   }
   if ($ack) {
    $aseq =~ s/^-//;
    print " ack $aseq"
   }
   if (defined($win)) {
    print " win $win";
   }
   print $df;
   if ($tos != 0) {
    print " [tos 0x";
#    $nts = sprintf("%x", unpack("C", $tos));
    $nts = $tos;
    $nts =~ s/(.{2})/sprintf("%x",ord($1))/eg;
    print "$nts]";
   }
   print " ($proto";
   if ($verb) {
    print " ttl $ttl, id $id";
   }
   print ")";
   if ($hex and !$hexa) {
    if ($data) {
     print "\n";
     ($ndata = $data) =~ s/(.{1})/sprintf("%x", unpack("C", $1))/eg;
     $ndata =~ s/(\w{32})/\t\t\t $1\n/g;
     if (($tmpr) = $ndata =~ /\n(\w+)$/) {
      $ndata =~ s/\n$r$/\n\t\t\t $r\n/;
     }
     $ndata =~ s/(\w{4})/$1 /g;
     print $ndata;
    }
   }
   print "\n";
  }
  if ($amt and $top == $amt) {
   die "$amt packets recieved by filter\n";
  }
 }
}

1;
