#! /usr/bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# perf720 src/bos/usr/sbin/perf/tools/ipfilter/ipfilter 1.3 
#  
# Licensed Materials - Property of IBM 
#  
# COPYRIGHT International Business Machines Corp. 1999,2001 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# @(#)17	1.3  src/bos/usr/sbin/perf/tools/ipfilter/ipfilter, cmdperft, perf720 12/14/01 11:46:00
# 
# Origin: 27
#  ipfilter [-f [untxca]] [-s [untxca]] [-n [-d <#ofmsecs>]] <ipreport_output_file>
#  
#
#
#
#
####################
#  Sort options and place in variables to be passed to awk scripts
####################

nopt=0;
ddelta=0;
nerror=0;

# check for parameters


while getopts f:s:nd: c
do case $c in
    f) ffopt=$OPTARG;;
    s) sopt=$OPTARG;;
    n) nopt=1;;
    d) ddelta=$OPTARG;;
    \?) print "ipfilter [-f [untxca]] [-s [untxca]] [-n [-d <number of milliseconds>]] <ipreport_output_file>"
print " -f - include only the following headers in ipfilter.all"
print " -s - create individual ipfilter reports for each header"
print " "
print " Header Types:"
print " c icmp"
print " n nfs"
print " t tcp"
print " u udp"
print " x ipx"
print " a atm"
print " "
print " -n - create an nfs.rpt "
print " -d <number of milliseconds> - only report Call/Reply pairs when "
print "    time elapsed is greater than given milliseconds"
exit 1;;
    esac
done



#############
# Shift $* variable so it points to the ipreport file
#############

shift OPTIND-1

############
# Error checking: is the file legit
############



if [ $# = 0 ]; then
    print "Error: No input file specified";
    exit 1;
fi

if [ ! -r $* ]; then
    print "Error: \"$*\" is not readable";
    exit 1;
fi

##################
# Error checking: check if input number is legit
###################

if [ $nopt = 1 ]; then
   if [[ $ddelta != +([0-9]) ]]; then
	print "Error: non-number input for -d option";
	exit 1;
    fi

##############
# If generating nfs.rpts, 
# Grep to cut down input for nfs.rpt
# Execute awk script
##############

 egrep "Packet Number|CALL|REPLY|bytes|Accepted|Program" $* > __ip.out;

awk '

BEGIN   {i=0;}

  
    {

################
# Check to see if delta is a number
################
	  
	

        if ($1 ~ /Packet/) {
                tmpnum = $3;
        }

        if ($0 ~ /bytes/) {
                split($0, alltime, " ");
                split(alltime[10], mintime, ":");
                tmptime = mintime[3];
		size = alltime[3];
        }

        if ($1 ~ /RPC/) {
		if( $0 ~ /XID/) {
		    split($0, xidsplit, "XID=");
		    xid = xidsplit[2];
		    xidnum[xid] = xid;

		    if ($0 ~ /CALL/) {
                        callpkt[xid] = tmpnum;
                        calltime[xid] = tmptime;
			callsize[xid] = size;
		    }

		    if ($0 ~ /REPLY/) {
                        replypkt[xid] = tmpnum;
                        replytime[xid] = tmptime;
			replysize[xid] = size;
		    }
		}

		if ($0 ~ /Accepted Reply Stat/) {
			split($0, statline," ");
			status[xid] = statline[5];
		}
		
		if($0 ~ /Program/) {
		    split($0, reqline,"[\(]|[\)]");
		    request[xid] = reqline[4];
		}
	}
    }

END {

       for (i in xidnum) {
        if ((replypkt[i] > 0) && (callpkt[i] > 0)) {

##################
# we found a call/reply pair
# adjust for possible overflow to next minute
##################

            if (replytime[i] < calltime[i]) {
               replytime[i] =  60.0 + replytime[i];
            }

            elaptime = 1000.0 * (replytime[i] - calltime[i]);

        } else {
               elaptime = 0.0;
        }

#################
# generate nfs.rpt according to if elaptime option is being used
#################

		if(elaptime >= delta || status[i] == NULL)
		    {
		      printf("%14s %9s %8s %7d %16.6f %5d %7d %16.6f %5s %12.3f\n",
			    xidnum[i], request[i], status[i], callpkt[i], calltime[i], 
			    callsize[i], replypkt[i], replytime[i], replysize[i], elaptime);
		    }
	}
        
}' __ip.out delta=$ddelta > __ip.out.1 

##################
# Sort report with kshell script, faster
##################

echo "                              NFS REPORT\n\n" > nfs.rpt
if [ $ddelta = 0 ];  then  
  print -n "                 Elasped Milliseconds Cut Off= " >> nfs.rpt; 
  print $ddelta >> nfs.rpt;
fi
print "\n\n"

echo "                                  --------CALL------------------- ------REPLY-------------------         " >> nfs.rpt
    
echo "Transaction ID Request   Status   Packet   Send Time (secs) Size  Packet  Send Time (secs) Size  Elapsed msec" >> nfs.rpt
echo "-------------- --------- -------- -------- ---------------- ----- ------- ---------------- ----- ------------" >> nfs.rpt;

sort __ip.out.1 >> nfs.rpt;

rm __ip.out;
rm __ip.out.1;
fi


########################
# awk for ipfilter.*
########################

awk 'BEGIN{

uflag = 0;
nflag = 0;
tflag = 0;
xflag = 0;
cflag = 0;
aflag = 0;
rflag = 1;

suflag = 0;
snflag = 0;
stflag = 0;
sxflag = 0;
scflag = 0;
saflag = 0;
scount = 0;


 sum = "ipfilter.all"

sfile[1] = "ipfilter.udp";
sfile[2] = "ipfilter.nfs";
sfile[3] = "ipfilter.tcp";
sfile[4] = "ipfilter.ipx";
sfile[5] = "ipfilter.icmp";
sfile[6] = "ipfilter.atm";

label[1] = "UDP";
label[2] = "NFS";
label[3] = "TCP";
label[4] = "IPX";
label[5] = "ICMP"
label[6] = "ATM";

 packet=0
 Time=0
 source=0
 destination=0
 Length=0
 source_p=0
 dest_p=0
 pout[2]=0
 pout[3]=0
 pout[1]=0
 pout[5]=0
 pout[4]=0
 pout[6]=0
 pout[7]=0
 pout[8]=0
 pout[9]=0
 netwrk=""
 seq=""
 ack_no=""
 printf("                                Operation Headers: ") > sum;

 }
/Packet Number/        {
    if( packet == 0)
      {  
       if ( sopt ~/u/) {
          sout[1] = 1;
	
        }
        if( sopt ~ /n/) {
	 sout[2] = 2;
	
        }
        if( sopt ~ /t/) {
          sout[3] = 3;
	
          }
        if (sopt ~ /x/) {
	  sout[4] = 4;
	
	}
        if (sopt ~ /c/) {
	  sout[5] = 5;

        }
        if (sopt ~ /a/) {
          sout[6] = 6;

        }
        if ( fopt ~/u/) {
          uflag = 1;
          rflag = 0;
        }
        if( fopt ~ /n/) {
          nflag = 1;
          rflag = 0;
        }
        if( fopt ~ /t/) {
          tflag = 1;
          rflag = 0;
          }
        if (fopt ~ /x/) {
          xflag = 1;
          rflag = 0;
        }
        if (fopt ~ /c/) {
          cflag = 1;
        rflag = 0;
        }
        if (fopt ~ /a/) {
          aflag = 1;
          rflag = 0;
        }
if(rflag == 1) {
 printf(" ICMP IPX NFS TCP UDP ATM  \n") > sum;
}
else {
 if(cflag ==1)
   printf(" ICMP") > sum;
 if(xflag == 1)
   printf(" IPX") > sum;
 if(nflag == 1)
   printf(" NFS") > sum;
 if(tflag == 1)
   printf(" TCP") > sum;
 if (uflag == 1)
   printf(" UDP") > sum;
 if(aflag ==1)
   printf(" ATM") > sum;
}
    printf("\n") > sum;
 printf("                                                                                                Ports\n") > sum;
 printf("                                                                                     ------------------------------------\n") > sum;
 printf(" pkt.      Time            Source            Dest.   Length Seq #      Ack #       Source     Destination Net_Interface Operation\n") > sum;

 printf("-----------------------------------------------------------------------------------------------------------------------------------\n") > sum;

for (j in sout) {
printf("                                Operation Headers: %s\n", label[j]) > sfile[j];


 printf("                                                                                                Ports\n") > sfile[j];
 printf("                                                                                     ------------------------------------\n") > sfile[j];
 printf(" pkt.      Time           Source            Dest.   Length Seq #      Ack #       Source     Destination Net_Interface Operation\n") > sfile[j];

 printf("-----------------------------------------------------------------------------------------------------------------------------------\n") > sfile[j];

}

      }

      
                if (packet != 0 ) {
		 if(rflag || (uflag && pout[1]) || (nflag && pout[2]) || (tflag && pout[3]) || (xflag && pout[4]) || (cflag && pout[5]) || (aflag && pout[6]))
                   {
                    printf("%4s ",packet) > sum;
                    printf("%.15s ",Time) > sum;
                    printf("%15s ",source) > sum;
                    printf("%15s ",destination) > sum;
                    printf("%5s ",Length) > sum;
                    printf("%9s ",seq) > sum;
                    printf("%9s ",ack_no) > sum;
                    printf("%12s ",source_p) > sum;
                    printf("%12s ",dest_p) > sum;
                    printf("%13s ",netwrk) > sum;
                    if ( pout[3] == 1 )
                            printf("TCP ") > sum;
                    if ( pout[7] == 1 )
                            printf("ACK ") > sum;
                    if ( pout[8] == 1 )
                            printf("PUSH ") > sum;
                    if ( pout[1] == 1 )
                            printf("UDP ") > sum;
                    if ( pout[2] == 1 )
                            printf("NFS ") > sum;
                    if ( pout[5] == 1 )
                            printf("ICMP ") > sum;
                    if ( pout[4] == 1 )
                            printf("IPX ") > sum;
                    if ( pout[9] == 1 )
                            printf("ARP ") > sum;
		    if ( pout[6] == 1 )
                            printf("ATM ") > sum;
                    printf("\n") > sum;
                    }
		    for (j in sout) {
		      if(sout[j] && pout[j])
		       {
		      
		         printf("%4s ",packet) > sfile[j];
                    printf("%.15s ",Time) > sfile[j];
                    printf("%15s ",source) > sfile[j];
                    printf("%15s ",destination) > sfile[j];
                    printf("%5s ",Length) > sfile[j];
                    printf("%9s ",seq) > sfile[j];
                    printf("%9s ",ack_no) > sfile[j];
                    printf("%12s ",source_p) > sfile[j];
                    printf("%12s ",dest_p) > sfile[j];
                    printf("%13s ",netwrk) > sfile[j];
                    if ( pout[3] == 1 )
                            printf("TCP ") > sfile[j];
                    if ( pout[7] == 1 )
                            printf("ACK ") > sfile[j];
                    if ( pout[8] == 1 )
                            printf("PUSH ") > sfile[j];
                    if ( pout[1] == 1 )
                            printf("UDP ") > sfile[j];
                    if ( pout[2] == 1 )
                            printf("NFS ") > sfile[j];
                    if ( pout[5] == 1 )
                            printf("ICMP ") > sfile[j];
                    if ( pout[4] == 1 )
                            printf("IPX ") > sfile[j];
                    if ( pout[9] == 1 )
                            printf("ARP ") > sfile[j];
                    if ( pout[6] == 1 )
                            printf("ATM ") > sfile[j];
                    printf("\n") > sfile[j];
                     }
		    }
                   }
                source=0
                destination=0
                Length=0
                source_p=0
                dest_p=0
                pout[2]=0
                pout[3]=0
                pout[1]=0
                pout[5]=0
                pout[4]=0
                pout[6]=0
                pout[7]=0
                pout[8]=0
                pout[9]=0
                netwrk=""
                seq=""
                ack_no=""
                packet=$3i
                }
/TRACING DROPPED/  {

                if (packet != 0 ) {
                  if(rflag || (uflag && pout[1]) || (nflag && pout[2]) || (tflag && pout[3]) || (xflag && pout[4]) || (cflag && pout[5]) || (aflag && pout[6]))
                   {
                    printf("%4s ",packet) > sum;
                    printf("%.15s ",Time) > sum;
                    printf("%15s ",source) > sum;
                    printf("%15s ",destination) > sum;
                    printf("%5s ",Length) > sum;
                    printf("%9s ",seq) > sum;
                    printf("%9s ",ack_no) > sum;
                    printf("%12s ",source_p) > sum;
                    printf("%12s ",dest_p) > sum;
                    printf("%13s ",netwrk) > sum;
                    if ( pout[3] == 1 )
                            printf("TCP ") > sum;
                    if ( pout[7] == 1 )
                            printf("ACK ") > sum;
                    if ( pout[8] == 1 )
                            printf("PUSH ") > sum;
                    if ( pout[1] == 1 )
                            printf("UDP ") > sum;
                    if ( pout[2] == 1 )
                            printf("NFS ") > sum;
                    if ( pout[5] == 1 )
                            printf("ICMP ") > sum;
                    if ( pout[4] == 1 )
                            printf("IPX ") > sum;
                    if ( pout[9] == 1 )
                            printf("ARP ") > sum;
                    if ( pout[6] == 1 )
                            printf("ATM ") > sum;
                    printf("\n") > sum;
                    }
                  for (j in sout) {
		      if(sout[j] && pout[j])
		       {
		         printf("%4s ",packet) > sfile[j];
                    printf("%.15s ",Time) > sfile[j];
                    printf("%15s ",source) > sfile[j];
                    printf("%15s ",destination) > sfile[j];
                    printf("%5s ",Length) > sfile[j];
                    printf("%9s ",seq) > sfile[j];
                    printf("%9s ",ack_no) > sfile[j];
                    printf("%12s ",source_p) > sfile[j];
                    printf("%12s ",dest_p) > sfile[j];
                    printf("%13s ",netwrk) > sfile[j];
                    if ( pout[3] == 1 )
                            printf("TCP ") > sfile[j];
                    if ( pout[7] == 1 )
                            printf("ACK ") > sfile[j];
                    if ( pout[8] == 1 )
                            printf("PUSH ") > sfile[j];
                    if ( pout[1] == 1 )
                            printf("UDP ") > sfile[j];
                    if ( pout[2] == 1 )
                            printf("NFS ") > sfile[j];
                    if ( pout[5] == 1 )
                            printf("ICMP ") > sfile[j];
                    if ( pout[4] == 1 )
                            printf("IPX ") > sfile[j];
                    if ( pout[9] == 1 )
                            printf("ARP ") > sfile[j];
                    if ( pout[6] == 1 )
                            printf("ATM ") > sfile[j];
                    printf("\n") > sfile[j];
                     }
		  }  
                 }
                source=0
                destination=0
                Length=0
                source_p=0
                dest_p=0
                pout[2]=0
                pout[3]=0
                pout[1]=0
                pout[5]=0
                pout[4]=0
                pout[6]=0
                pout[7]=0
                pout[8]=0
                pout[9]=0
                netwrk=""
                seq=""
                ack_no=""
                packet=0
                print( $0 )
                }
/interface/     {
                if ( $1 == "ETH:" )
                        {
                        Time= $10;
                        netwrk=$8
                        Length=$3
                        }
                if ( $1 == "TOK:" )
                        {
                        Time= $10;
                        netwrk=$8
                        Length=$3
                        }
                if ( $1 == "FDDI:" )
                        {
                        Time= $10;
                        netwrk=$8
                        Length=$3
                        }
                if ( $1 == "====(" )
                        {
                        Time= $9;
                        netwrk=$7
                        Length=$3
                        }
               if ( $1 == "ATM:" )
                {
                   Time= $10;
                   netwrk=$8
                   Length=$3
                }

                }
/th_seq/        {
                seq=substr($2,8);
                ack_no=substr($3,8);
                }
/SRC/           {source=$5}
/DST/           {destination=$5}
/ip_len/        { Length=substr($5,8,5)}
/port/          {
                source_p=substr($3,6,12)
                dest_p=substr($5,6,12)
                }
/UDP:/           {pout[1] = 1;}
/NFS:/           {pout[2] = 1;}
/TCP:/           {pout[3] = 1;}
/IPX:/           {pout[4] = 1;}
/ICMP:/          {pout[5] = 1;}
/ATM:/           {pout[6] = 1;}
/ARP:/           {
                pout[9] = 1;
                if ( $2 == "source" )
                        {
                        getline
                        source=$3
                        }
                if ( $2 == "target" )
                        {
                        getline
                        destination=$3
                        }
                }
/ACK/           {pout[7] =1;}
/PUSH/          {pout[8] = 1;}
END{

       if(rflag || (uflag && pout[1]) || (nflag && pout[2]) || (tflag && pout[3]) || (xflag && pout[4]) || (cflag && pout[5] ) || (aflag && pout[6]) )
                   {
                    printf("%4s ",packet) > sum;
                    printf("%.15s ",Time) > sum;
                    printf("%15s ",source) > sum;
                    printf("%15s ",destination) > sum;
                    printf("%5s ",Length) > sum;
                    printf("%9s ",seq) > sum;
                    printf("%9s ",ack_no) > sum;
                    printf("%12s ",source_p) > sum;
                    printf("%12s ",dest_p) > sum;
                    printf("%13s ",netwrk) > sum;
                    if ( pout[3] == 1 )
                            printf( "TCP ") > sum;
                    if ( pout[7] == 1 )
                            printf( "ACK ") > sum;
                    if ( pout[8] == 1 )
                            printf( "PUSH ") > sum;
                    if ( pout[1] == 1 )
                            printf( "UDP ") > sum;
                    if ( pout[2] == 1 )
                            printf( "NFS ") > sum;
                    if ( pout[5] == 1 )
                            printf( "ICMP ") > sum;
                    if ( pout[4] == 1 )
                            printf( "IPX ") > sum;
                    if ( pout[9] == 1 )
                            printf( "ARP ") > sum;
                    if ( pout[6] == 1 )
                            printf( "ATM ") > sum;
                    printf( "\n") > sum;
                  }
                  for (j in sout) {
		      if(sout[j] && pout[j])
		       {
		         printf("%4s ",packet) > sfile[j];
                    printf("%.15s ",Time) > sfile[j];
                    printf("%15s ",source) > sfile[j];
                    printf("%15s ",destination) > sfile[j];
                    printf("%5s ",Length) > sfile[j];
                    printf("%9s ",seq) > sfile[j];
                    printf("%9s ",ack_no) > sfile[j];
                    printf("%12s ",source_p) > sfile[j];
                    printf("%12s ",dest_p) > sfile[j];
                    printf("%13s ",netwrk) > sfile[j];
                    if ( pout[3] == 1 )
                            printf("TCP ") > sfile[j];
                    if ( pout[7] == 1 )
                            printf("ACK ") > sfile[j];
                    if ( pout[8] == 1 )
                            printf("PUSH ") > sfile[j];
                    if ( pout[1] == 1 )
                            printf("UDP ") > sfile[j];
                    if ( pout[2] == 1 )
                            printf("NFS ") > sfile[j];
                    if ( pout[5] == 1 )
                            printf("ICMP ") > sfile[j];
                    if ( pout[4] == 1 )
                            printf("IPX ") > sfile[j];
                    if ( pout[9] == 1 )
                            printf("ARP ") > sfile[j];
                    if ( pout[6] == 1 )
                            printf("ATM ") > sfile[j];
                    printf("\n") > sfile[j];
                     }
		    }

}' fopt=$ffopt sopt=$sopt nopt=$nopt delta=$ddelta $*