#! /usr/bin/perl
#
#  Purpose:  
#  FlowViewer_Utilities.pm holds utility functions that are called 
#  by FlowViewer, FlowGrapher, and FlowTracker scripts.
#
#  Description:
#  Various conversion and formatting utility functions.
#
#  Input arguments:
#  Name                 Description
#  -----------------------------------------------------------------------
#  None
#
#  Modification history:
#  Author       Date            Vers.   Description
#  -----------------------------------------------------------------------
#  J. Loiacono  07/04/2005      1.0     Original version.
#  J. Loiacono  01/01/2006      2.0     Added y_format for FlowGrapher
#  J. Loiacono  04/15/2006      2.3     Added time_check for testing
#  J. Loiacono  07/04/2006      3.0     Included new formatting and filter subs
#                                       Permits host names (thanks Mark Foster)
#
#$Author$
#$Date$
#$Header$
#
###########################################################################
#
#               BEGIN EXECUTABLE STATEMENTS
#
#
 
use Time::Local;
#use Time::HiRes qw( usleep ualarm gettimeofday tv_interval );

sub format_date {

	my ($sec,$min,$hr,$date,$mnth,$yr) = @_;
	$mnth++; 
	$yr += 1900; 
	if ($date<10) {$date = "0" . $date; } 
	if ($mnth<10) {$mnth = "0" . $mnth; } 
	if ($hr<10) {$hr = "0" . $hr; } 
	if ($min<10) {$min = "0" . $min; } 
	if ($sec<10) {$sec = "0" . $sec; } 
	$formatted_date = $mnth ."\/". $date ."\/". $yr ." ". $hr .":". $min .":". $sec; 
}

sub format_number { 

	my ($number) = @_;
	my $counter;
        $formatted_number = ""; 
        $length_number = length($number); 
        $counter = $length_number; 
        for ($digit=1;$digit<=$length_number;$digit++) { 
                $formatted_number = substr($number,$counter-1,1) . $formatted_number; 
                if (($digit>0) && ($digit%3 == 0)) { $formatted_number = "," . $formatted_number;} 
                $counter = $counter - 1; 
        } 
        if ( substr($formatted_number,0,1) eq ",") { 
                $formatted_number = substr($formatted_number,1,35); } 

	return $formatted_number;
} 

sub date_to_epoch {
 
	my ($in_date,$in_time,$time_zone)  = @_;
	 
	($mon,$day,$yr) = split(/\//,$in_date);
	($hr, $min, $sec) = split(/:/,$in_time);
	$date = $mon."/".$day."/".$yr." ".$hr.":".$min.":".$sec;
 
	if ($time_zone eq "LOCAL") {
		$epoch_date = timelocal($sec,$min,$hr,$day,$mon-1,$yr); }
	else {
		$epoch_date = timegm($sec,$min,$hr,$day,$mon-1,$yr); }
	return $epoch_date;
}

sub epoch_to_date {

	my ($epoch_date,$time_zone)  = @_;
	 
	if ($time_zone eq "LOCAL") {
		($sec,$min,$hr,$date,$mnth,$yr,$day,$yr_date,$DST) = localtime($epoch_date); }
	else {
		($sec,$min,$hr,$date,$mnth,$yr,$day,$yr_date,$DST) = gmtime($epoch_date); }

	$current_yr_date = $yr_date;
	$mnth++;
	$yr += 1900;
	if ($date<10) {$date = "0" . $date; }
	if ($mnth<10) {$mnth = "0" . $mnth; }
	if ($hr<10) {$hr = "0" . $hr; }
	if ($min<10) {$min = "0" . $min; }
	if ($sec<10) {$sec = "0" . $sec; }
	return $mnth ."\/". $date ."\/". $yr ." ". $hr .":". $min .":". $sec;
}

sub flow_date_time {
 
        my ($flow_time,$time_zone) = @_;
 
        $formatted = epoch_to_date($flow_time,$time_zone);
        ($first_half,$second_half) = split(/ /,$formatted);
        ($mnth,$date,$yr) = split(/\//,$first_half);
        ($hr,$min,$sec) = split(/:/,$second_half);
 
        if ((0 < $date) && ($date < 10)) { $date = substr($date,1,1); }
        if ((0 < $hr) && ($hr < 10)) { $hr = substr($hr,1,1); }
 
        if    ($mnth == 1)  { $month = "January"; }
        elsif ($mnth == 2)  { $month = "February"; }
        elsif ($mnth == 3)  { $month = "March"; }
        elsif ($mnth == 4)  { $month = "April"; }
        elsif ($mnth == 5)  { $month = "May"; }
        elsif ($mnth == 6)  { $month = "June"; }
        elsif ($mnth == 7)  { $month = "July"; }
        elsif ($mnth == 8)  { $month = "August"; }
        elsif ($mnth == 9)  { $month = "September"; }
        elsif ($mnth == 10) { $month = "October"; }
        elsif ($mnth == 11) { $month = "November"; }
        elsif ($mnth == 12) { $month = "December"; }
 
        return $month ." ". $date .", ". $yr ." ". $hr .":". $min .":". $sec;
}

sub day_of_week {

	my ($day_number) = @_;
	 
	if    ($day_number == 0) { $day = "Sun"; }
	elsif ($day_number == 1) { $day = "Mon"; }
	elsif ($day_number == 2) { $day = "Tue"; }
	elsif ($day_number == 3) { $day = "Wed"; }
	elsif ($day_number == 4) { $day = "Thr"; }
	elsif ($day_number == 5) { $day = "Fri"; }
	elsif ($day_number == 6) { $day = "Sat"; }

	return $day;
}

sub month_of_year {

	my ($mnth) = @_;
	 
	if    ($mnth == 0)  { $month = "Jan"; }
	elsif ($mnth == 1)  { $month = "Feb"; }
	elsif ($mnth == 2)  { $month = "Mar"; }
	elsif ($mnth == 3)  { $month = "Apr"; }
	elsif ($mnth == 4)  { $month = "May"; }
	elsif ($mnth == 5)  { $month = "Jun"; }
	elsif ($mnth == 6)  { $month = "Jul"; }
	elsif ($mnth == 7)  { $month = "Aug"; }
	elsif ($mnth == 8)  { $month = "Sep"; }
	elsif ($mnth == 9)  { $month = "Oct"; }
	elsif ($mnth == 10) { $month = "Nov"; }
	elsif ($mnth == 11) { $month = "Dec"; }

	return $month;
}

sub full_month {

	my ($mnth) = @_;

        if    ($mnth == "01")  { $month = "January"; }
        elsif ($mnth == "02")  { $month = "February"; }
        elsif ($mnth == "03")  { $month = "March"; }
        elsif ($mnth == "04")  { $month = "April"; }
        elsif ($mnth == "05")  { $month = "May"; }
        elsif ($mnth == "06")  { $month = "June"; }
        elsif ($mnth == "07")  { $month = "July"; }
        elsif ($mnth == "08")  { $month = "August"; }
        elsif ($mnth == "09")  { $month = "September"; }
        elsif ($mnth == "10")  { $month = "October"; }
        elsif ($mnth == "11")  { $month = "November"; }
        elsif ($mnth == "12")  { $month = "December"; }

	return $month;
}

sub convert_month {

	my ($mnth) = @_;
	 
	if    ($mnth eq "Jan") { $month = "01"; }
	elsif ($mnth eq "Feb") { $month = "02"; }
	elsif ($mnth eq "Mar") { $month = "03"; }
	elsif ($mnth eq "Apr") { $month = "04"; }
	elsif ($mnth eq "May") { $month = "05"; }
	elsif ($mnth eq "Jun") { $month = "06"; }
	elsif ($mnth eq "Jul") { $month = "07"; }
	elsif ($mnth eq "Aug") { $month = "08"; }
	elsif ($mnth eq "Sep") { $month = "09"; }
	elsif ($mnth eq "Oct") { $month = "10"; }
	elsif ($mnth eq "Nov") { $month = "11"; }
	elsif ($mnth eq "Dec") { $month = "12"; }

	return $month;
}

sub y_format { 
     
        my $value = shift; 
        my $ret; 
     
        if ($value >= 1000000) {   
                $ret = int ($value / 1000000) . " M"; }  
        else {   
                $ret = $value; } 
        return $ret; 
}

sub time_check {  
      
        my ($tc_event) = @_;  
      
        $tc_current_time = [gettimeofday]; 
        $tc_elapsed_time = tv_interval( $tc_last_time, $tc_current_time ); 
        if ($tc_last_event eq "") { $tc_elapsed_time = 0; } 
        $tc_total_time  += $tc_elapsed_time; 
     
        printf DEBUG "from: %-30s to %-30s  elapsed seconds: %-3.6f  running: %-3.6f\n", $tc_last_event, $tc_event, $tc_elapsed_time, $tc_total_time;  
       
        $tc_last_time = $tc_current_time; 
        $tc_last_event = $tc_event;  
}    

sub print_formatted_parameters {
 
	my $device_name       = $FORM{'device_name'}; 
	my $protocols         = $FORM{'protocols'}; 
	my $source_addresses  = $FORM{'source_address'}; 
	my $source_ports      = $FORM{'source_port'}; 
	my $source_ifs        = $FORM{'source_if'}; 
	my $source_ases       = $FORM{'source_as'}; 
	my $dest_addresses    = $FORM{'dest_address'}; 
	my $dest_ports        = $FORM{'dest_port'}; 
	my $dest_ifs          = $FORM{'dest_if'}; 
	my $dest_ases         = $FORM{'dest_as'}; 
	my $tcp_flags         = $FORM{'tcp_flags'}; 
	my $tos_fields        = $FORM{'tos_fields'}; 
      
	$my_html_file         = "$html_file";

	if ($html_file eq "") {
        	printf "      Device: %-42s        Protocols: %-42s\n", $device_name,$protocols; }
	else {
        	printf HTML "      Device: %-42s        Protocols: %-42s\n", $device_name,$protocols;
	}
 
	# Segment long Source or Destination input lines if neccessary

        $length_sa = length($source_addresses);
        $length_da = length($dest_addresses);
 
        if (($length_sa > 42) || ($length_da > 42)) {
 
                # Segment Source Addresses field for formatted output
 
                $source_addresses_1 = substr($source_addresses,0,42);
                $last_blank_1 = rindex($source_addresses_1," ");
                if ($last_blank_1 > 1) { $source_addresses_1 = substr($source_addresses,0,$last_blank_1); }
                $length_printed = length($source_addresses_1) + 1;
                $length_remaining = $length_sa - $length_printed;
 
                $first_address_2 = $last_blank_1 + 1;
                $source_addresses_2 = substr($source_addresses,$first_address_2,42);
		if ($last_blank_1 < 1) { $source_addresses_2 = ""; }
                if ($length_remaining > 42) {
                        $last_blank_2 = rindex($source_addresses_2," ");
                        $source_addresses_2 = substr($source_addresses,$first_address_2,$last_blank_2);
                }
                $length_printed += (length($source_addresses_2) + 1);
                $length_remaining = $length_sa - $length_printed;
 
                if ($length_remaining > 0) {
                        $first_address_3 = $last_blank_1 + $last_blank_2 + 2;
                        $source_addresses_3 = substr($source_addresses,$first_address_3,42);
                        if ($length_remaining > 42) {
                                $last_blank_3 = rindex($source_addresses_3," ");
                                $source_addresses_3 = substr($source_addresses,$first_address_3,$last_blank_3);
                        }
                }
                $length_printed += (length($source_addresses_3) + 1);
                $length_remaining = $length_sa - $length_printed;
 
                if ($length_remaining > 0) {
                        $first_address_4 = $last_blank_1 + $last_blank_2 + $last_blank_3 + 3;
                        $source_addresses_4 = substr($source_addresses,$first_address_4,42);
                        if ($length_remaining > 42) {
                                $last_blank_4 = rindex($source_addresses_4," ");
                                $source_addresses_4 = substr($source_addresses,$first_address_4,$last_blank_4);
                        }
                }
                $length_printed += (length($source_addresses_4) + 1);
                $length_remaining = $length_sa - $length_printed;
 
                if ($length_remaining > 0) {
                        $first_address_5 = $last_blank_1 + $last_blank_2 + $last_blank_3 + $last_blank_4 + 4;
                        $source_addresses_5 = substr($source_addresses,$first_address_5,42);
                }
 
                # Segment Destination Addresses field for formatted output
 
                $dest_addresses_1 = substr($dest_addresses,0,42);
                $last_blank_1 = rindex($dest_addresses_1," ");
                if ($last_blank_1 > 1) { $dest_addresses_1 = substr($dest_addresses,0,$last_blank_1); }
                $length_printed = length($dest_addresses_1) + 1;
                $length_remaining = $length_da - $length_printed;
 
                $first_address_2 = $last_blank_1 + 1;
                $dest_addresses_2 = substr($dest_addresses,$first_address_2,42);
		if ($last_blank_1 < 1) { $dest_addresses_2 = ""; }
                if ($length_remaining > 42) {
                        $last_blank_2 = rindex($dest_addresses_2," ");
                        $dest_addresses_2 = substr($dest_addresses,$first_address_2,$last_blank_2);
                }
                $length_printed += (length($dest_addresses_2) + 1);
                $length_remaining = $length_da - $length_printed;
 
                if ($length_remaining > 0) {
                        $first_address_3 = $last_blank_1 + $last_blank_2 + 2;
                        $dest_addresses_3 = substr($dest_addresses,$first_address_3,42);
                        if ($length_remaining > 42) {
                                $last_blank_3 = rindex($dest_addresses_3," ");
                                $dest_addresses_3 = substr($dest_addresses,$first_address_3,$last_blank_3);
                        }
                }
                $length_printed += (length($dest_addresses_3) + 1);
                $length_remaining = $length_da - $length_printed;
 
                if ($length_remaining > 0) {
                        $first_address_4 = $last_blank_1 + $last_blank_2 + $last_blank_3 + 3;
                        $dest_addresses_4 = substr($dest_addresses,$first_address_4,42);
                        if ($length_remaining > 42) {
                                $last_blank_4 = rindex($dest_addresses_4," ");
                                $dest_addresses_4 = substr($dest_addresses,$first_address_4,$last_blank_4);
                        }
                }
                $length_printed += (length($dest_addresses_4) + 1);
                $length_remaining = $length_da - $length_printed;
 
                if ($length_remaining > 0) {
                        $first_address_5 = $last_blank_1 + $last_blank_2 + $last_blank_3 + $last_blank_4 + 4;
                        $dest_addresses_5 = substr($dest_addresses,$first_address_5,42);
                }
 
                # Output the formatted source and destination address fields
 
		if ($html_file eq "") {
                	printf "      Source: %-42s      Destination: %-42s\n", $source_addresses_1, $dest_addresses_1;
                	printf "              %-42s                   %-42s\n", $source_addresses_2, $dest_addresses_2; }
		else {
                	printf HTML "      Source: %-42s      Destination: %-42s\n", $source_addresses_1, $dest_addresses_1;
                	printf HTML "              %-42s                   %-42s\n", $source_addresses_2, $dest_addresses_2;
		}
 
                if (($source_addresses_3 ne "") || ($dest_addresses_3 ne "")) {
			if ($html_file eq "") {
                        	printf "              %-42s                   %-42s\n", $source_addresses_3, $dest_addresses_3; }
			else {
                        	printf HTML "              %-42s                   %-42s\n", $source_addresses_3, $dest_addresses_3;
			}
                }
 
                if (($source_addresses_4 ne "") || ($dest_addresses_4 ne "")) {
			if ($html_file eq "") {
                        	printf "              %-42s                   %-42s\n", $source_addresses_4, $dest_addresses_4; }
			else {
                        	printf HTML "              %-42s                   %-42s\n", $source_addresses_4, $dest_addresses_4;
			}
                }
 
                if (($source_addresses_5 ne "") || ($dest_addresses_5 ne "")) {
			if ($html_file eq "") {
                        	printf "              %-42s                   %-42s\n", $source_addresses_5, $dest_addresses_5; }
			else {
                        	printf HTML "              %-42s                   %-42s\n", $source_addresses_5, $dest_addresses_5;
			}
                } }
        else {
		if ($html_file eq "") {
                	printf "      Source: %-42s      Destination: %-42s\n", $source_addresses, $dest_addresses; }
		else {
                	printf HTML "      Source: %-42s      Destination: %-42s\n", $source_addresses, $dest_addresses;
		}
        }
 
	# Segment long Source Port or Destination Port input lines if neccessary

        $length_sp = length($source_ports);
        $length_dp = length($dest_ports);
 
        if (($length_sp > 42) || ($length_dp > 42)) {

                $source_ports_1 = substr($source_ports,0,42);
                $last_blank_1 = rindex($source_ports_1," ");
                if ($last_blank_1 > 1) { $source_ports_1 = substr($source_ports,0,$last_blank_1); }
                $length_printed = length($source_ports_1) + 1;
                $length_remaining = $length_sp - $length_printed;
 
                $first_port_2 = $last_blank_1 + 1;
                $source_ports_2 = substr($source_ports,$first_port_2,42);
                if ($length_remaining > 42) {
                        $last_blank_2 = rindex($source_ports_2," ");
                        $source_ports_2 = substr($source_ports,$first_port_2,$last_blank_2);
                }
 
                $dest_ports_1 = substr($dest_ports,0,42);
                $last_blank_1 = rindex($dest_ports_1," ");
                if ($last_blank_1 > 1) { $dest_ports_1 = substr($dest_ports,0,$last_blank_1); }
                $length_printed = length($dest_ports_1) + 1;
                $length_remaining = $length_dp - $length_printed;
 
                $first_port_2 = $last_blank_1 + 1;
                $dest_ports_2 = substr($dest_ports,$first_port_2,42);
                if ($length_remaining > 42) {
                        $last_blank_2 = rindex($dest_ports_2," ");
                        $dest_ports_2 = substr($dest_ports,$first_port_2,$last_blank_2);
                }
 
		if ($html_file eq "") {
                	printf " Source Port: %-42s Destination Port: %-42s\n", $source_ports_1, $dest_ports_1;
                	printf "              %-42s                   %-42s\n", $source_ports_2, $dest_ports_2; } 
		else {
                	printf HTML " Source Port: %-42s Destination Port: %-42s\n", $source_ports_1, $dest_ports_1;
                	printf HTML "              %-42s                   %-42s\n", $source_ports_2, $dest_ports_2;
		} }
        else {
		if ($html_file eq "") {
        		printf " Source Port: %-42s Destination Port: %-42s\n", $source_ports, $dest_ports; }
		else {
        		printf HTML " Source Port: %-42s Destination Port: %-42s\n", $source_ports, $dest_ports;
		}
	}

	# Segment long Source I/F or Destination I/F input lines if neccessary

        $length_sif = length($source_ifs);
        $length_dif = length($dest_ifs);
 
        if (($length_sif> 42) || ($length_dif> 42)) {

                $source_ifs_1 = substr($source_ifs,0,42);
                $last_blank_1 = rindex($source_ifs_1," ");
                if ($last_blank_1 > 1) { $source_ifs_1 = substr($source_ifs,0,$last_blank_1); }
                $length_printed = length($source_ifs_1) + 1;
                $length_remaining = $length_sif - $length_printed;
 
                $first_if_2 = $last_blank_1 + 1;
                $source_ifs_2 = substr($source_ifs,$first_if_2,42);
                if ($length_remaining > 42) {
                        $last_blank_2 = rindex($source_ifs_2," ");
                        $source_ifs_2 = substr($source_ifs,$first_if_2,$last_blank_2);
                }
 
                $dest_ifs_1 = substr($dest_ifs,0,42);
                $last_blank_1 = rindex($dest_ifs_1," ");
                if ($last_blank_1 > 1) { $dest_ifs_1 = substr($dest_ifs,0,$last_blank_1); }
                $length_printed = length($dest_ifs_1) + 1;
                $length_remaining = $length_dif - $length_printed;
 
                $first_if_2 = $last_blank_1 + 1;
                $dest_ifs_2 = substr($dest_ifs,$first_if_2,42);
                if ($length_remaining > 42) {
                        $last_blank_2 = rindex($dest_ifs_2," ");
                        $dest_ifs_2 = substr($dest_ifs,$first_if_2,$last_blank_2);
                }
 
		if ($html_file eq "") {
                	printf "  Source I/F: %-42s  Destination I/F: %-42s\n", $source_ifs_1, $dest_ifs_1;
                	printf "              %-42s                   %-42s\n", $source_ifs_2, $dest_ifs_2; }
		else {
                	printf HTML "  Source I/F: %-42s  Destination I/F: %-42s\n", $source_ifs_1, $dest_ifs_1;
                	printf HTML "              %-42s                   %-42s\n", $source_ifs_2, $dest_ifs_2;
		} }
        else {
		if ($html_file eq "") {
        		printf "  Source I/F: %-42s  Destination I/F: %-42s\n", $source_ifs, $dest_ifs; }
		else {
        		printf HTML "  Source I/F: %-42s  Destination I/F: %-42s\n", $source_ifs, $dest_ifs;
		}
	}

	# Segment long Source AS or Destination AS input lines if neccessary

        $length_sas = length($source_ases);
        $length_das = length($dest_ases);
 
        if (($length_sas> 42) || ($length_das> 42)) {

                $source_ases_1 = substr($source_ases,0,42);
                $last_blank_1 = rindex($source_ases_1," ");
                if ($last_blank_1 > 1) { $source_ases_1 = substr($source_ases,0,$last_blank_1); }
                $length_printed = length($source_ases_1) + 1;
                $length_remaining = $length_sas - $length_printed;
 
                $first_as_2 = $last_blank_1 + 1;
                $source_ases_2 = substr($source_ases,$first_as_2,42);
                if ($length_remaining > 42) {
                        $last_blank_2 = rindex($source_ases_2," ");
                        $source_ases_2 = substr($source_ases,$first_as_2,$last_blank_2);
                }
 
                $dest_ases_1 = substr($dest_ases,0,42);
                $last_blank_1 = rindex($dest_ases_1," ");
                if ($last_blank_1 > 1) { $dest_ases_1 = substr($dest_ases,0,$last_blank_1); }
                $length_printed = length($dest_ases_1) + 1;
                $length_remaining = $length_das - $length_printed;
 
                $first_as_2 = $last_blank_1 + 1;
                $dest_ases_2 = substr($dest_ases,$first_as_2,42);
                if ($length_remaining > 42) {
                        $last_blank_2 = rindex($dest_ases_2," ");
                        $dest_ases_2 = substr($dest_ases,$first_as_2,$last_blank_2);
                }
 
		if ($html_file eq "") {
                	printf "   Source AS: %-42s   Destination AS: %-42s\n", $source_ases_1, $dest_ases_1;
                	printf "              %-42s                   %-42s\n", $source_ases_2, $dest_ases_2; } 
		else {
                	printf HTML "   Source AS: %-42s   Destination AS: %-42s\n", $source_ases_1, $dest_ases_1;
                	printf HTML "              %-42s                   %-42s\n", $source_ases_2, $dest_ases_2;
		} }
        else {
		if ($html_file eq "") {
        		printf "   Source AS: %-42s   Destination AS: %-42s\n", $source_ases, $dest_ases; }
		else {
        		printf HTML "   Source AS: %-42s   Destination AS: %-42s\n", $source_ases, $dest_ases;
		}
	}

	# Segment long TOS Fields or TCP Flags input lines if neccessary

        $length_tos = length($tos_fields);
        $length_tcp = length($tcp_flags);
 
        if (($length_tos> 42) || ($length_tcp> 42)) {

                $tos_fields_1 = substr($tos_fields,0,42);
                $last_blank_1 = rindex($tos_fields_1," ");
                if ($last_blank_1 > 1) { $tos_fields_1 = substr($tos_fields,0,$last_blank_1); }
                $length_printed = length($tos_fields_1) + 1;
                $length_remaining = $length_tos - $length_printed;
 
                $first_tos_2 = $last_blank_1 + 1;
                $tos_fields_2 = substr($tos_fields,$first_tos_2,42);
                if ($length_remaining > 42) {
                        $last_blank_2 = rindex($tos_fields_2," ");
                        $tos_fields_2 = substr($tos_fields,$first_tos_2,$last_blank_2);
                }
 
                $tcp_flags_1 = substr($tcp_flags,0,42);
                $last_blank_1 = rindex($tcp_flags_1," ");
                if ($last_blank_1 > 1) { $tcp_flags_1 = substr($tcp_flags,0,$last_blank_1); }
                $length_printed = length($tcp_flags_1) + 1;
                $length_remaining = $length_tcp - $length_printed;
 
                $first_tcp_2 = $last_blank_1 + 1;
                $tcp_flags_2 = substr($tcp_flags,$first_tcp_2,42);
                if ($length_remaining > 42) {
                        $last_blank_2 = rindex($tcp_flags_2," ");
                        $tcp_flags_2 = substr($tcp_flags,$first_tcp_2,$last_blank_2);
                }
 
		if ($html_file eq "") {
                	printf "   TOS Field: %-42s         TCP Flag: %-42s\n", $tos_fields_1, $tcp_flags_1;
                	printf "              %-42s                   %-42s\n", $tos_fields_2, $tcp_flags_2; }
		else {
                	printf HTML "   TOS Field: %-42s         TCP Flag: %-42s\n", $tos_fields_1, $tcp_flags_1;
                	printf HTML "              %-42s                   %-42s\n", $tos_fields_2, $tcp_flags_2;
		} }
        else {
		if ($html_file eq "") {
        		printf "   TOS Field: %-42s         TCP Flag: %-42s\n", $tos_fields, $tcp_flags; }
		else {
        		printf HTML "   TOS Field: %-42s         TCP Flag: %-42s\n", $tos_fields, $tcp_flags;
		}
	}
}

sub create_filter_file {

	# General parameters for generating Filter Files
	
	my $device_name       = $FORM{'device_name'};
	my $flow_select       = $FORM{'flow_select'};
	my $start_date        = $FORM{'start_date'};
	my $start_time        = $FORM{'start_time'};
	my $end_date          = $FORM{'end_date'};
	my $end_time          = $FORM{'end_time'};
	my $source_addresses  = $FORM{'source_address'};
	my $source_ports      = $FORM{'source_port'};
	my $source_ifs        = $FORM{'source_if'};
	my $source_ases       = $FORM{'source_as'};
	my $dest_addresses    = $FORM{'dest_address'};
	my $dest_ports        = $FORM{'dest_port'};
	my $dest_ifs          = $FORM{'dest_if'};
	my $dest_ases         = $FORM{'dest_as'};
	my $protocols         = $FORM{'protocols'};
	my $tcp_flags         = $FORM{'tcp_flags'};
	my $tos_fields        = $FORM{'tos_fields'};
	
	$new_filter_file      = "$filter_file";
	
	if ($start_date ne "") {
		$epoch_start = date_to_epoch($start_date,$start_time,"LOCAL"); 
		$flows_start = &flow_date_time($epoch_start,"LOCAL");
	}
	
	if ($end_date ne "") {
		$epoch_end   = date_to_epoch($end_date,$end_time,"LOCAL"); 
		$flows_end   = &flow_date_time($epoch_end,"LOCAL");
	}
	
	# Create the filter to match the input specifications
	
	open (FILTER,">$new_filter_file") || die "cannot open Filter file for write: $new_filter_file";
	
	# Set up source address filtering, if any
	 
	if ($source_addresses ne "") {
	 
	        print FILTER "filter-primitive source_address\n";
	        print FILTER "  type ip-address-prefix\n";
	 
	        $source_addresses =~ s/\s+//g;
	
	        for ($i=0;$i<10;$i++) {
	 
	                ($source_address) = split(/,/,$source_addresses);
	                $start_char = length($source_address) + 1;
	                $source_addresses = substr($source_addresses,$start_char,210);
	 
	                if ($source_address =~ m/^\s*-*\d+/) {
		                $_ = $source_address;
		                $num_dots = tr/\.//;
		                if ($num_dots != 3) { &print_error("Not full address: $source_address Try: n.n.n.n/m"); last; }
		 
		                ($a,$b,$c,$d)    = split(/\./,$source_address);
		 
				($source_ip,$source_prefix) = split(/\//,$source_address);
		                if (($source_prefix eq "") && ($d eq "0")) {
		                        &print_error("Missing or improper IP address prefix.  Use (e.g.) : 192.168.10.0/24."); last; }
		                if ((($source_prefix > 0) && ($source_prefix < 1)) || ($source_prefix > 32)) {
		                        &print_error("Improper network mask (1 <= mask <= 32)."); last; }
		 
		                if ($a > 255 || $a eq "") { &print_error("Improper network: $address Try: n.n.n.n/m"); last; }
		                if ($b > 255 || $b eq "") { &print_error("Improper network: $address Try: n.n.n.n/m"); last; }
		                if ($c > 255 || $c eq "") { &print_error("Improper network: $address Try: n.n.n.n/m"); last; }
		                if ($d > 255 || $d eq "") { &print_error("Improper network: $address Try: n.n.n.n/m"); last; }
			}
	 
	                if (substr($source_address,0,1) eq "-") {
	                        $source_address = substr($source_address,1);
				print FILTER "  deny $source_address\n";
	                        $exclude = 1; }
	                else {
	                        print FILTER "  permit $source_address\n";
	                }
	 
	                if ($source_addresses eq "") { last; }
	        }
	 
	        if ($exclude) {
	                $exclude = 0;
	                print FILTER "  default permit\n"; }
	        else {
	                print FILTER "  default deny\n";
	        }
	 
	        $save_file .= "_" . $source_address;
	}
	 
	# Set up source interface filtering, if any
	 
	if ($source_ifs ne "") {
	 
	        print FILTER "filter-primitive source_if\n";
	        print FILTER "  type ifindex\n";
	 
	        $source_ifs =~ s/\s+//g;
	
	        for ($i=0;$i<10;$i++) {
	 
	                ($source_if) = split(/,/,$source_ifs);
	                $start_char = length($source_if) + 1;
	                $source_ifs = substr($source_ifs,$start_char,60);
	 
	                if (length($source_if) > 4) { &print_error("Improper interface index: $source_if Try: nnn"); last; }
	 
	                if (substr($source_if,0,1) eq "-") {
	                        $source_if = substr($source_if,1,3);
	                        print FILTER "  deny $source_if\n";
	                        $exclude = 1; }
	                else {
	                        print FILTER "  permit $source_if\n";
	                }
	 
	                if ($source_ifs eq "") { last; }
	        }
	 
	        if ($exclude) {
	                $exclude = 0;
	                print FILTER "  default permit\n"; }
	        else {
	                print FILTER "  default deny\n";
	        }
	 
	        $save_file .= "_" . $source_if;
	}
	 
	# Set up source port filtering, if any
	 
	if ($source_ports ne "") {
	 
	        print FILTER "filter-primitive source_port\n";
	        print FILTER "  type ip-port\n";
	 
	        $source_ports =~ s/\s+//g;
	
	        for ($i=0;$i<10;$i++) {
	 
	                ($source_port) = split(/,/,$source_ports);
	                $start_char = length($source_port) + 1;
	                $source_ports = substr($source_ports,$start_char,80);
	 
	                if (($source_port < -65536) || ($source_port > 65536)) { &print_error("Port out of range -65536 < port < 65536"); last; }
	 
	                if (substr($source_port,0,1) eq "-") {
	                        $source_port = substr($source_port,1,6);
	                        print FILTER "  deny $source_port\n";
	                        $exclude = 1; }
	                else {
	                        print FILTER "  permit $source_port\n";
	                }
	 
	                if ($source_ports eq "") { last; }
	        }
	 
	        if ($exclude) {
	                $exclude = 0;
	                print FILTER "  default permit\n"; }
	        else {
	                print FILTER "  default deny\n";
	        }
	 
	        $save_file .= "_" . $source_port;
	}
	 
	# Set up source AS filtering, if any
	 
	if ($source_ases ne "") {
	 
	        print FILTER "filter-primitive source_as\n";
	        print FILTER "  type as\n";
	 
	        $source_ases =~ s/\s+//g;
	
	        for ($i=0;$i<10;$i++) {
	 
	                ($source_as) = split(/,/,$source_ases);
	                $start_char = length($source_as) + 1;
	                $source_ases = substr($source_ases,$start_char,80);
	 
	                if (($source_as < -65536) || ($source_as > 65536)) { &print_error("AS out of range -65536 < AS < 65536"); last; }
	 
	                if (substr($source_as,0,1) eq "-") {
	                        $source_as = substr($source_as,1,6);
	                        print FILTER "  deny $source_as\n";
	                        $exclude = 1; }
	                else {
	                        print FILTER "  permit $source_as\n";
	                }
	 
	                if ($source_ases eq "") { last; }
	        }
	 
	        if ($exclude) {
	                $exclude = 0;
	                print FILTER "  default permit\n"; }
	        else {
	                print FILTER "  default deny\n";
	        }
	 
	        $save_file .= "_" . $source_as;
	}
	 
	# Set up destination address filtering, if any
	 
	if ($dest_addresses ne "") {
	
		($dest_ip,$dest_prefix)     = split(/\//,$dest_address);
	 
	        print FILTER "filter-primitive dest_address\n";
	        print FILTER "  type ip-address-prefix\n";
	 
	        $dest_addresses =~ s/\s+//g;
	
	        for ($i=0;$i<10;$i++) {
	 
	                ($dest_address) = split(/,/,$dest_addresses);
	                $start_char = length($dest_address) + 1;
	                $dest_addresses = substr($dest_addresses,$start_char,210);
	 
	                if ($dest_address =~ m/^\s*-*\d+/) {
		                $_ = $dest_address;
		                $num_dots = tr/\.//;
		                if ($num_dots != 3) { &print_error("Not full address: $dest_address Try: n.n.n.n/m"); last; }
		 
		                ($a,$b,$c,$d)    = split(/\./,$dest_address);
		 
		                if (($dest_prefix eq "") && ($d eq "0")) {
		                        &print_error("Missing or improper IP address prefix.  Use (e.g.) : 192.168.10.0/24"); last; }
		                if ((($dest_prefix > 0) && ($dest_prefix < 8)) || ($dest_prefix > 32)) { &print_error("Improper network mask (8 <= mask <= 32)"); last; }
		 
		                if ($a > 255 || $a eq "") { &print_error("Improper network: $address Try: n.n.n.n/m"); last; }
		                if ($b > 255 || $b eq "") { &print_error("Improper network: $address Try: n.n.n.n/m"); last; }
		                if ($c > 255 || $c eq "") { &print_error("Improper network: $address Try: n.n.n.n/m"); last; }
		                if ($d > 255 || $d eq "") { &print_error("Improper network: $address Try: n.n.n.n/m"); last; }
			}
	 
	                if (substr($dest_address,0,1) eq "-") {
	                        $dest_address = substr($dest_address,1);
	                        print FILTER "  deny $dest_address\n";
	                        $exclude = 1; }
	                else {
	                        print FILTER "  permit $dest_address\n";
	                }
	 
	                if ($dest_addresses eq "") { last; }
	        }
	 
	        if ($exclude) {
	                $exclude = 0;
	                print FILTER "  default permit\n"; }
	        else {
	                print FILTER "  default deny\n";
	        }
	 
	        $save_file .= "_" . $dest_address;
	}
	 
	# Set up destination interface filtering, if any
	 
	if ($dest_ifs ne "") {
	 
	        print FILTER "filter-primitive dest_if\n";
	        print FILTER "  type ifindex\n";
	 
	        $dest_ifs =~ s/\s+//g;
	
	        for ($i=0;$i<10;$i++) {
	 
	                ($dest_if) = split(/,/,$dest_ifs);
	                $start_char = length($dest_if) + 1;
	                $dest_ifs = substr($dest_ifs,$start_char,60);
	 
	                if (length($dest_if) > 4) { &print_error("Improper interface index: $dest_if Try: nnn"); last; }
	 
	                if (substr($dest_if,0,1) eq "-") {
	                        $dest_if = substr($dest_if,1,3);
	                        print FILTER "  deny $dest_if\n";
	                        $exclude = 1; }
	                else {
	                        print FILTER "  permit $dest_if\n";
	                }
	 
	                if ($dest_ifs eq "") { last; }
	        }
	 
	        if ($exclude) {
	                $exclude = 0;
	                print FILTER "  default permit\n"; }
	        else {
	                print FILTER "  default deny\n";
	        }
	 
	        $save_file .= "_" . $dest_if;
	}
	 
	# Set up destination port filtering, if any
	 
	if ($dest_ports ne "") {
	 
	        print FILTER "filter-primitive dest_port\n";
	        print FILTER "  type ip-port\n";
	 
	        $dest_ports =~ s/\s+//g;
	
	        for ($i=0;$i<10;$i++) {
	 
	                ($dest_port) = split(/,/,$dest_ports);
	                $start_char = length($dest_port) + 1;
	                $dest_ports = substr($dest_ports,$start_char,80);
	 
	                if (($dest_port < -65536) || ($dest_port > 65536)) { &print_error("Port out of range -65536 < port < 65536"); last; }
	 
	                if (substr($dest_port,0,1) eq "-") {
	                        $dest_port = substr($dest_port,1,6);
	                        print FILTER "  deny $dest_port\n";
	                        $exclude = 1; }
	                else {
	                        print FILTER "  permit $dest_port\n";
	                }
	 
	                if ($dest_ports eq "") { last; }
	        }
	 
	        if ($exclude) {
	                $exclude = 0;
	                print FILTER "  default permit\n"; }
	        else {
	                print FILTER "  default deny\n";
	        }
	 
	        $save_file .= "_" . $dest_port;
	}
	 
	# Set up destination AS filtering, if any
	 
	if ($dest_ases ne "") {
	 
	        print FILTER "filter-primitive dest_as\n";
	        print FILTER "  type as\n";
	 
	        $dest_ases =~ s/\s+//g;
	
	        for ($i=0;$i<10;$i++) {
	 
	                ($dest_as) = split(/,/,$dest_ases);
	                $start_char = length($dest_as) + 1;
	                $dest_ases = substr($dest_ases,$start_char,80);
	 
	                if (($dest_as < -65536) || ($dest_as > 65536)) { &print_error("AS out of range -65536 < AS < 65536"); last; }
	 
	                if (substr($dest_as,0,1) eq "-") {
	                        $dest_as = substr($dest_as,1,6);
	                        print FILTER "  deny $dest_as\n";
	                        $exclude = 1; }
	                else {
	                        print FILTER "  permit $dest_as\n";
	                }
	 
	                if ($dest_ases eq "") { last; }
	        }
	 
	        if ($exclude) {
	                $exclude = 0;
	                print FILTER "  default permit\n"; }
	        else {
	                print FILTER "  default deny\n";
	        }
	 
	        $save_file .= "_" . $dest_as;
	}
	
	# Set up Protocol filtering, if any
	
	if ($protocols ne "") {
	 
	        print FILTER "filter-primitive protocol\n";
	        print FILTER "  type ip-protocol\n";
	 
	        $protocols =~ s/\s+//g;
	
	        for ($i=0;$i<10;$i++) {
	 
	                ($protocol) = split(/,/,$protocols);
	                $start_char = length($protocol) + 1;
	                $protocols = substr($protocols,$start_char,60);
	 
	                if (($protocol < -255) || ($protocol > 255)) { &print_error("Protocol out of range 1 < Protocol < 255"); last; }
	 
	                if (substr($protocol,0,1) eq "-") {
	                        $protocol = substr($protocol,1,3);
	                        print FILTER "  deny $protocol\n";
	                        $exclude = 1; }
	                else {
	                        print FILTER "  permit $protocol\n";
	                }
	 
	                if ($protocols eq "") { last; }
	        }
	 
	        if ($exclude) {
	                $exclude = 0;
	                print FILTER "  default permit\n"; }
	        else {
	                print FILTER "  default deny\n";
	        }
	 
	        $save_file .= "_" . $protocol;
	}
	
	# Set up TCP Flag filtering, if any
	
	if ($tcp_flags ne "") {
	 
	        print FILTER "filter-primitive tcp_flag\n";
	        print FILTER "  type ip-tcp-flags\n";
	 
	        $tcp_flags =~ s/\s+//g;
	
	        for ($i=0;$i<10;$i++) {
	 
	                ($tcp_flag) = split(/,/,$tcp_flags);
	                $start_char = length($tcp_flag) + 1;
	                $tcp_flags = substr($tcp_flags,$start_char,120);
	 
			($tcp_flag,$tcp_mask) = split(/\//,$tcp_flag);
	
	                if (substr($tcp_flag,0,1) eq "-") {
	                        $tcp_flag = substr($tcp_flag,1,4);
				if ($tcp_mask ne "") { print FILTER "  mask $tcp_mask\n"; }
	                        print FILTER "  deny $tcp_flag\n";
				$exclude = 1; }
	                else {
				if ($tcp_mask ne "") { print FILTER "  mask $tcp_mask\n"; }
	                        print FILTER "  permit $tcp_flag\n";
	                }
	 
	                if ($tcp_flags eq "") { last; }
	        }
	
	        if ($exclude) {
	                $exclude = 0;
	                print FILTER "  default permit\n"; }
	        else {
	                print FILTER "  default deny\n";
	        }
	 
	        $save_file .= "_" . $tcp_flag;
	}
	
	# Set up TOS Field filtering, if any
	
	if ($tos_fields ne "") {
	 
	        print FILTER "filter-primitive tos_field\n";
	        print FILTER "  type ip-tos\n";
	 
	        $tos_fields =~ s/\s+//g;
	
	        for ($i=0;$i<10;$i++) {
	 
	                ($tos_field) = split(/,/,$tos_fields);
	                $start_char = length($tos_field) + 1;
	                $tos_fields = substr($tos_fields,$start_char,120);
	 
			($tos_field,$tos_mask) = split(/\//,$tos_field);
	
	                if (substr($tos_field,0,1) eq "-") {
	                        $tos_field = substr($tos_field,1,4);
				if ($tos_mask ne "") { print FILTER "  mask $tos_mask\n"; }
	                        print FILTER "  deny $tos_field\n";
				$exclude = 1; }
	                else {
				if ($tos_mask ne "") { print FILTER "  mask $tos_mask\n"; }
	                        print FILTER "  permit $tos_field\n";
	                }
	 
	                if ($tos_fields eq "") { last; }
	        }
	 
	        if ($exclude) {
	                $exclude = 0;
	                print FILTER "  default permit\n"; }
	        else {
	                print FILTER "  default deny\n";
	        }
	 
	        $save_file .= "_" . $tos_field;
	}
	
	# Write out the flow files filter
	
	print FILTER "filter-primitive start_flows\n";
	print FILTER "  type time-date\n";
	print FILTER "  permit ge $flows_start\n";
	print FILTER "  default deny\n";
	print FILTER "filter-primitive end_flows\n";
	print FILTER "  type time-date\n";
	print FILTER "  permit lt $flows_end\n";
	print FILTER "  default deny\n";
	print FILTER " \n";
	print FILTER "filter-definition Flow_Filter\n";
	if ($source_address ne "") {
	        print FILTER "  match ip-source-address source_address\n";
	}
	if ($source_if ne "") {
	        print FILTER "  match input-interface source_if\n";
	}
	if ($source_port ne "") {
	        print FILTER "  match ip-source-port source_port\n";
	}
	if ($source_as ne "") {
	        print FILTER "  match source-as source_as\n";
	}
	if ($dest_address ne "") {
	        print FILTER "  match ip-destination-address dest_address\n";
	}
	if ($dest_if ne "") {
	        print FILTER "  match output-interface dest_if\n";
	}
	if ($dest_port ne "") {
	        print FILTER "  match ip-destination-port dest_port\n";
	}
	if ($dest_as ne "") {
	        print FILTER "  match destination-as dest_as\n";
	}
	if ($protocol ne "") {
	        print FILTER "  match ip-protocol protocol\n";
	}
	if ($tcp_flag ne "") {
	        print FILTER "  match ip-tcp-flags tcp_flag\n";
	}
	if ($tos_field ne "") {
	        print FILTER "  match ip-tos tos_field\n";
	}
	
	if ($flow_select == 1) {
		print FILTER "  match end-time start_flows\n";
		print FILTER "  match start-time end_flows\n";
		$flow_select_manner = "Any part of flow in Time Period";
	}
	if ($flow_select == 2) {
		print FILTER "  match end-time start_flows\n";
		print FILTER "  match end-time end_flows\n";
		$flow_select_manner = "Flow end-time in Time Period";
	}
	if ($flow_select == 3) {
		print FILTER "  match start-time start_flows\n";
		print FILTER "  match start-time end_flows\n";
		$flow_select_manner = "Flow start-time in Time Period";
	}
	if ($flow_select == 4) {
		print FILTER "  match start-time start_flows\n";
		print FILTER "  match end-time end_flows\n";
		$flow_select_manner = "Flow entirely in Time Period";
	}
	
	close (FILTER);
}

return 1;
