#!/usr/bin/perl


#NOTE 
# :set tabstop=4  (in vi[m])
# to bring this bad boy into focus


# DEMARC 2000-2001, DEMARC Organization
#
#
# 1. REDISTRIBUTION
#
# Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer. You may not sell DEMARC,
# nor sell any of the functionality it provides without first obtaining a
# commercial license or receiving direct written authorization from DENARC
# Organization.
#
#
# 2. FREE FOR NON-COMMERCIAL USE
#
# No part of DEMARC may be used  by any commercial entity without
# having first obtained a commercial license from DEMARC Organization unless
# exempt by meeting one of the following conditions:
#
# a. Your company's primary business is as an ISP (Internet Service Provider)
#    and has a customer base of fewer than 1000 users.
#
# b. Your company has fewer than 25 employees and is not an ISP.
#
# c. You have extenuating circumstances and have received written authorization
#    from DEMARC Organization to use this software free of charge.
#
# A free evaluation period of 60 days is granted for any commercial entity who does
# not meet the conditions above but wishes to first try out the product.
#
#
# 3. TRADEMARKS AND NOTICES
#
# The software, graphics and documentation which make up DEMARC are Copyright
# 2000-2001 DEMARC Organization. You agree to respect these rights and leave all
# notices and product references intact.
#
#
# 4. LIMITATION OF LIABILITY AND DISCLAIMER OF WARRANTY
#
# THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
# DEMARC ORGANIZATION PROVIDE THIS PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND,
# EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE
# QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
# DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
#
# DEMARC Organization reserves the right to modify this license at any time.
#
# Any questions or comments regarding this license or the official evaluation of
# individual circumstances may be directed to license@demarc.org
#
#

BEGIN{
	# CHANGE this to reflect where you have your StaticServices.pm module
	# which SHOULD be the same as where this script resides
	push (@INC,"/usr/share/demarc/cgi");
};

use StaticServices; #Make SURE your cgi-bin directory is in your INC array above
use DEMARC_config; #Make SURE your cgi-bin directory is in your INC array above
use DBI;
use DBD::mysql;
use CGI;
use CGI::Cookie;
use strict;
use Digest::MD5  qw(md5_hex);

# MIME::Base64 needed for decoding basic auth


use vars qw (	$db @substitutions $header_printed $debug_level 
					$current_row_color $program_name $program_version 
					%FORM $cgi $current_page $recent_alert @messages 
					@remote_services @local_services @special_services
					$logged_in_as $downed_hosts_array_ref $use_cache 
					$minimum_monitoring_table %cookies $total_count
					$is_admin $is_f1_admin $is_f2_admin $is_f3_admin
					%global_sid_hash $cache_disabled $show_mini_view			
					%conf
);

## Get the config vars in hash form:
%conf = DEMARC_config::get_config_hash();

my $use_Apache_DBI_with_mod_perl = $conf{'use_Apache_DBI_with_mod_perl'};

if ($use_Apache_DBI_with_mod_perl && $ENV{'MOD_PERL'}){
	eval{
    	require Apache::DBI;
    	Apache::DBI->import();
	};
# Don't worry  about error handling... we just evaled it 
# so it won't throw an error if it doesn't exist... but it's really optional
}

###############################################
# Database Authentication Variables
my $db_user 				= $conf{'db_user'};
my $db_password				= $conf{'db_passwd'};
my $db_host					= $conf{'db_host'};
my $db_name					= $conf{'db_name'};
###############################################

###############################################
# General config variables 
# (leave them alone if you followed default install instructions)
my $v_graphics_path  = "/dm_images";
my $this_program     = "demarc";
my $v_base_path      = $conf{'v_base_path'};
my $base_path        = "/usr/share/demarc/cgi";
my $template_subdir  = "/templates";
my $home_url         = "$v_base_path/$this_program";
##############################################

##############################################
# Paths to binaries
my $whois_command				= $conf{'whois_command'};
my $traceroute_command  		= $conf{'traceroute_command'};
my $nslookup_command  			= $conf{'nslookup_command'};
my $ping_command  				= $conf{'ping_command'};
my $monitor_sid					= $conf{'monitor_sid'};
my $detect_basic_auth			= $conf{'detect_basic_auth'};
my $default_limit 				= $conf{'default_limit'};
my $allow_anonymous_access 		= $conf{'allow_anonymous_access'};


#ONLY IF YOU ARE HAVING PROBLEMS LOGGING IN FOR THE FIRST TIME... DO NOT NOT NOT LEAVE THIS ON!
my $anonymous_user_is_admin		= $conf{'anonymous_user_is_admin'};

my $allow_user_to_change_email 	= $conf{'allow_user_to_change_email'};
my $validate_ip					= $conf{'validate_ip'};
my $session_timeout_minutes		= $conf{'session_timeout_minutes'};
###############################################


# if you enable the following bypass flag, please understand that 
# unless you own and trust ALL machines on your network, you must
# assume that someone can and WILL compromise DEMARC by sniffing
# the admin passwords!
my $bypass_admin_lockout_on_no_ssl		= $conf{'bypass_admin_lockout_on_no_ssl'};

my $allowed_cache_minutes				= $conf{'allowed_cache_minutes'};
my $allowed_long_cache_minutes			= $conf{'allowed_long_cache_minutes'};




###############################################################
# Alert Priority levels are set as follows:
#
# 1 - HIGH ALERT 		- action should be taken on this alert
# 2 - WARNING ALERT	- action may need further action
# 3 - -\
# 4 -   \_LOW LEVEL ALERTS - can be categorized as you see fit
# 5 -   /
# 6 - _/
#
# THESE SHOULD NOT BE CHANGED!!! You've been warned...
my $priority_levels						= "123456";
my $alert_priority_levels				= "12";
my $high_alert_level					= 1;
my $mid_alert_level						= 1;
my $default_priority_level				= "2";
###############################################################

#general colors
my $head_color					= "#003366";
my $title_color					= "#244A75";
my $desc_color					= "#001E4B";

#mini view colors
my $miniborder_color			= "#CB9400";
my $minigap_color				= "#426286";
my $minititle_color				= "#003F92";
my $minidesc_color				= "#021439";


##DEPRICATED:
my $system_type							= "bsd"; #options: bsd|linux
##


################
# Reset values for MOD_PERL (such a blessing, and SUCH a curse!)
$recent_alert 				= ();
$current_page 				= ();
@substitutions				= ();
$header_printed				= ();
%FORM						= ();
%cookies					= ();
$cgi						= ();
@messages					= ();
$total_count				= ();
$is_admin					= (); 
$is_f1_admin				= ();
$is_f2_admin				= ();
$is_f3_admin				= ();
$minimum_monitoring_table 	= ();
$downed_hosts_array_ref		= ();
%global_sid_hash			= ();
$cache_disabled				= ();
$show_mini_view				= 1;

$use_cache					= $conf{'use_cache'};

@remote_services		= qw(
									Ping
									HTTP
									SSH
									SMTP
									FTP
									HTTPS
									Telnet
									POP3
									DNS
									IMAP4
									NNTP
									TCP
									TCP1
									TCP2
									TCP3
									TCP4
);
@local_services			= qw(
									load
									disks
);
@special_services		= qw(
									Logs
									Proc
);






##############################################################
# No need to change below here
##############################################################

$program_name 		= "DEMARC";
$program_version	= "1.05-RC-1";

my $ctime 				= time();

####################
# Get FORM vars

$cgi = new CGI;
#The following isn't supported in the older versions of CGI.pm
#%FORM = $cgi->Vars;
# So lets do it a different way:
my @names = $cgi->param;
foreach (@names){
	$FORM{$_} =$cgi->param($_);
}




####################
# Check for cookies:
%cookies = fetch CGI::Cookie;

# See if we should show the mini_view
$show_mini_view = () if ($cookies{'nmv'} && ($cookies{'nmv'}->value eq "yes"));

###### File Paths (relative to $base_path and $template subdir)
my $main_template			= "$base_path$template_subdir/main.html";
my $main_template_nmv		= "$base_path$template_subdir/main_nmv.html";
my $search_form				= "$base_path$template_subdir/search_form.html";
my $new_service_form		= "$base_path$template_subdir/new_service_form.html";
my $monitor_ids_form		= "$base_path$template_subdir/monitor_ids_form.html";
my $monitor_md5_form		= "$base_path$template_subdir/monitor_md5_form.html";
my $monitor_service_form	= "$base_path$template_subdir/monitor_service_form.html";
my $monitor_proc_form		= "$base_path$template_subdir/monitor_proc_form.html";
my $monitor_logs_form		= "$base_path$template_subdir/monitor_logs_form.html";
my $age_data_form			= "$base_path$template_subdir/age_data_form.html";
#my $general_config_form	= "$base_path$template_subdir/general_config_form.html";
my $configure_md5_form		= "$base_path$template_subdir/configure_md5_form.html";
my $admin_user_config_form	= "$base_path$template_subdir/admin_user_config.html";
my $ul_user_config_form		= "$base_path$template_subdir/ul_user_config.html";
my $ul_email_config_form	= "$base_path$template_subdir/ul_user_config_email.html";
my $whois_select_form		= "$base_path$template_subdir/whois.html";


my $footer_string	= "$program_name - Version $program_version";


###################
# Authentication:
my $ttime = time();

if ($FORM{'username'} && $FORM{'password'}){
	$logged_in_as = &login($FORM{'username'},$FORM{'password'});
	if (!$logged_in_as){
			&push_message("<FONT COLOR=red><B>Login Failure.</B></FONT>");
         &print_login_screen;
         &safe_exit;
   }
	# if we're still here then login was a success	
}
elsif (($cookies{'s_key'}) && ($cookies{'s_key'}->value)){
	$logged_in_as = &check_login($cookies{'s_key'}->value);
	if (!$logged_in_as){
		   &print_login_screen;
   		&safe_exit;
	}
	# if we're still here then validation was a success	
}
else{
	&print_login_screen;
	&safe_exit;
}

#####################################
### Check if we are using HTTPS and check for user
if (!$ENV{'HTTPS'} && !$bypass_admin_lockout_on_no_ssl){
		&push_message("<FONT COLOR=red>You are <B>NOT</B> using HTTPS, all administrative functions have been locked out</FONT>");
		$is_admin = 0;
}

push (@substitutions,"\\[USER\\],-,$logged_in_as");

#####################################
###  Get shared monitoring info:
($downed_hosts_array_ref,$minimum_monitoring_table) = &get_minimum_monitoring_table;
#####################################

# Check if we are supposed to temporarily disable caching:
if ($FORM{'no_cache'}){
	$use_cache = 0 ;
	$cache_disabled = 1;
}

# Check if we are supposed to disable mini_view:
if ($FORM{'no_mini_view'}){
	&set_no_mini_view_cookie();
	$show_mini_view = ();
}
if ($FORM{'show_mini_view'}){
	&set_show_mini_view_cookie();
	$show_mini_view = 1;
}

#############################################
# Control Section
#############################################

if ($FORM{'td'} eq "view_payload"){
	($FORM{'sid'}=~/^\d+$/) || &error("No SID passed");
	($FORM{'cid'}=~/^\d+$/) || &error("No CID passed");
	&view_payload($FORM{'sid'},$FORM{'cid'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "search"){
	$current_page = "search";
	&print_search;
	&safe_exit;
}
elsif ($FORM{'td'} eq "about"){
	$current_page = "about";
	&print_about;
	&safe_exit;
}
elsif ($FORM{'td'} eq "logout"){
	$current_page = "logout";
	&logout;
	&print_login_screen;
	&safe_exit;
}
elsif ($FORM{'td'} eq "show_events"){
	$current_page = "show_events";
	my $table = &print_events(	
						offset_type		=> $FORM{'offset_type'},
						offset_number	=> $FORM{'offset_number'},
						sid				=> $FORM{'sid'},
						cid				=> $FORM{'cid'},
						tcp				=> $FORM{'tcp'},
						udp				=> $FORM{'udp'},
						icmp				=> $FORM{'icmp'},
						other				=> $FORM{'other'},
						signature		=> $FORM{'signature'},
						signature2		=> $FORM{'signature2'},
						signature3		=> $FORM{'signature3'},
						signature_is	=> $FORM{'signature_is'},
						start				=> $FORM{'start'},
						limit				=> $FORM{'limit'},
						src_ip			=> $FORM{'src_ip'},
						dst_ip			=> $FORM{'dst_ip'},
						hr_s				=> $FORM{'hr_s'},
						min_s				=> $FORM{'min_s'},
						day_s				=> $FORM{'day_s'},
						mon_s				=> $FORM{'mon_s'},
						yr_s				=> $FORM{'yr_s'},
						hr_f				=> $FORM{'hr_f'},
						min_f				=> $FORM{'min_f'},
						day_f				=> $FORM{'day_f'},
						mon_f				=> $FORM{'mon_f'},
						yr_f				=> $FORM{'yr_f'},
						search_type		=> $FORM{'search_type'},
						graph			=> $FORM{'graph'},
				);
	push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
	&print_main_with_key($main_template);
	&safe_exit;
}
elsif ($FORM{'td'} eq "delete"){
(&is_admin("f1")) || (&error("Only an administrator can delete records."));
   $current_page = "main";
	if (!($FORM{'delete_type'}=~/^limit$|^all$/)){ 
		&error("You must specify whether you would like to delete the entire query or simply the events on the page you were viewing.");
	}
		&log_event(	username => "$logged_in_as",
						action 	=> "Deleted events (starting)",
						target	=> '',
					 );
my $delete_array_ref = &print_events(
                  offset_type    => $FORM{'offset_type'},
                  offset_number  => $FORM{'offset_number'},
                  sid            => $FORM{'sid'},
                  cid            => $FORM{'cid'},
                  tcp            => $FORM{'tcp'},
                  udp            => $FORM{'udp'},
                  icmp           => $FORM{'icmp'},
                  other          => $FORM{'other'},
                  signature      => $FORM{'signature'},
				  signature2	 => $FORM{'signature2'},
				  signature3	 => $FORM{'signature3'},
				  signature_is	 => $FORM{'signature_is'},
                  start          => $FORM{'start'},
                  limit          => $FORM{'limit'},
                  src_ip         => $FORM{'src_ip'},
                  dst_ip         => $FORM{'dst_ip'},
                  hr_s           => $FORM{'hr_s'},
                  min_s          => $FORM{'min_s'},
                  day_s          => $FORM{'day_s'},
                  mon_s          => $FORM{'mon_s'},
                  yr_s           => $FORM{'yr_s'},
                  hr_f           => $FORM{'hr_f'},
                  min_f          => $FORM{'min_f'},
                  day_f          => $FORM{'day_f'},
                  mon_f          => $FORM{'mon_f'},
                  yr_f           => $FORM{'yr_f'},
                  search_type    => $FORM{'search_type'},
						delete_type		=> $FORM{'delete_type'},
            );
	&delete_events($delete_array_ref);
	my $events_deleted = (@$delete_array_ref);
	&push_message("<FONT COLOR=red><B>Successfully Deleted $events_deleted Event(s).</B></FONT>");
	&print_stats;
		&log_event(	username => "$logged_in_as",
						action 	=> "deleted $events_deleted events (completed)",
						target	=> '',
					 );
	&safe_exit;
}
elsif ($FORM{'td'} eq "unique_events_since"){
	($FORM{'offset_type'}=~/^day$|^hour$/) || ($FORM{'offset_type'} = '');
	($FORM{'offset_number'}=~/^\d+$/) || ($FORM{'offset_number'} = '');
	my $table = &unique_events_since($FORM{'offset_type'},$FORM{'offset_number'});
	push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
	&print_main_with_key($main_template);
	&safe_exit;
}
elsif ($FORM{'td'} eq "mini_me"){
	$current_page = "mini_me";
	&print_mini_me;
	&safe_exit;
}
elsif ($FORM{'td'} eq "view_monitoring_page"){
	$current_page = "monitor";
	&print_monitor_page;
	&safe_exit;
}
elsif ($FORM{'td'} eq "edit_monitored_service"){
   	$current_page = "monitor";
	(&is_admin("f2")) || &error("You must be an administrator to perform this function");
	&print_edit_monitored_service($FORM{'host_name'},$FORM{'service'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "do_edit_monitored_service"){
	(&is_admin("f2")) || &error("You must be an administrator to perform this function");
	$current_page = "monitor";
	if ($FORM{'todo'} eq "Delete"){
		&delete_monitored_service($FORM{'old_host_name'},$FORM{'service'});
		$current_page = "monitor";
		&print_monitor_page;
		&log_event(	username => "$logged_in_as",
			action 	=> "deleted service monitoring event",
			target	=> "$FORM{'old_host_name'} - $FORM{'service'}",
		);
		&safe_exit;
	}
	&edit_monitored_service($FORM{'host_name'},$FORM{'service'});
	&log_event(	username => "$logged_in_as",
					action 	=> "edited service monitoring event",
					target	=> "$FORM{'host_name'} - $FORM{'service'}",
				 );
	&view_monitored_host(	host_name => $FORM{'host_name'},
							service => $FORM{'service'},
								);
   &safe_exit;
}
elsif ($FORM{'td'} eq "arin_whois"){
	($FORM{'ip'}) || &error("No IP address specified for query.");
	&query_arin($FORM{'ip'},$FORM{'whois_server'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "traceroute"){
	($FORM{'ip'}) || &error("No IP address specified for traceroute.");
	&traceroute($FORM{'ip'},$FORM{'timeout'},$FORM{'no_name_resolution'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "ping"){
	($FORM{'ip'}) || &error("No IP address specified for ping.");
	&ping($FORM{'ip'},$FORM{'count'},$FORM{'no_name_resolution'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "nslookup"){
	($FORM{'ip'}) || &error("No IP address specified for nslookup.");
	&nslookup($FORM{'ip'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "config"){
	$current_page = "config";
	(&is_anonymous) && &error("There are no options here for Anonymous users.");
	if (&is_any_admin){
		&print_config;
	}
	else{
		&print_config_user_level;
	}
	&safe_exit;
}
elsif ($FORM{'td'} eq "md5_config_select"){
	$current_page = "config";
	(&is_admin("f3")) || &error("You must be an administrator to perform this function");
	&print_md5_select_menu;
	&safe_exit;
}
elsif ($FORM{'td'} eq "update_md5_rules"){
	$current_page = "config";
	(&is_admin("f3")) || &error("You must be an administrator to perform this function");
	&print_md5_config($FORM{'sid'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "do_update_md5_rules"){
	(&is_admin("f3")) || &error("You must be an administrator to perform this function");
	&update_md5_rules($FORM{'sid'},$FORM{'md5_rules'});
	&print_md5_config($FORM{'sid'});
	&log_event(	username => "$logged_in_as",
					action 	=> "updated md5 rules",
					target	=> "",
				 );
	&safe_exit;
}
elsif ($FORM{'td'} eq "config_sid_menu"){
	(&is_admin("f1")) || &error("You must be an administrator to perform this function");
	$current_page = "config";
	&print_config_sid_menu();
	&safe_exit;
}
elsif ($FORM{'td'} eq "delete_sid"){
	(&is_admin("f1")) || &error("You must be an administrator to perform this function");
	$current_page = "config";
	&delete_sid($FORM{'sid'});
	&print_config_sid_menu();
	&safe_exit;
}
elsif ($FORM{'td'} eq "resync_sid"){
	(&is_admin("f1")) || &error("You must be an administrator to perform this function");
	$current_page = "config";
	&resync_sid($FORM{'sid'});
	&print_config_sid_menu();
	&safe_exit;
}
elsif ($FORM{'td'} eq "config_sid"){
	(&is_admin("f1")) || &error("You must be an administrator to perform this function");
	$current_page = "config";
	&print_config_rules($FORM{'sid'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "find_sig_in_rules"){
    (&is_admin("f1")) || &error("You must be an administrator to perform this function");
    $current_page = "config";
	&find_sig_in_rules($FORM{'signature'});
    &safe_exit;
}

elsif ($FORM{'td'} eq "view_monitored_service_history_detail"){
	$current_page = "monitor";
	&print_monitor_event_detail($FORM{'eid'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "config_ids_monitor"){
	$current_page = "config";
	&print_monitor_ids_form();
	&safe_exit;
}
elsif ($FORM{'td'} eq "add_host_monitoring_event"){
	$current_page = "config";
	&add_host_monitoring_event;
	&print_monitor_service_form();
	&safe_exit;
}
elsif ($FORM{'td'} eq "add_ids_monitoring_event"){
	$current_page = "config";
	&add_ids_monitoring_event;
	&print_monitor_ids_form();
	&safe_exit;
}
elsif ($FORM{'td'} eq "alter_monitor_alert_rule"){
	$current_page = "config";
	&update_monitor_alert_rule;
	&print_monitor_service_form();
	&safe_exit;
}
elsif ($FORM{'td'} eq "alter_ids_alert_rule"){
	$current_page = "config";
	&update_ids_alert_rule;
	&print_monitor_ids_form();
	&safe_exit;
}
elsif ($FORM{'td'} eq "config_md5_monitor"){
	$current_page = "config";
	&print_monitor_md5_form();
	&safe_exit;
}
elsif ($FORM{'td'} eq "add_md5_monitoring_event"){
	$current_page = "config";
	&add_md5_monitoring_event;
	&print_monitor_md5_form();
	&safe_exit;
}
elsif ($FORM{'td'} eq "alter_md5_alert_rule"){
	$current_page = "config";
	&update_md5_alert_rule;
	&print_monitor_md5_form();
	&safe_exit;
}
elsif ($FORM{'td'} eq "config_service_monitor"){
	$current_page = "config";
	&print_monitor_service_form();
	&safe_exit;
}
elsif ($FORM{'td'} eq "config_rules"){
	(&is_admin("f1")) || &error("You must be an administrator to perform this function");
	$current_page = "config";
	&config_rules($FORM{'sid'},$FORM{'rules_type'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "do_config_rules"){
	(&is_admin("f1")) || &error("You must be an administrator to perform this function");
	$current_page = "config";
	&do_config_rules($FORM{'sid'},$FORM{'rules_type'},$FORM{'rules_text'},$FORM{'new_ruleset_name'},$FORM{'action'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "add_monitoring_event"){
	$current_page = "config";
	(&is_admin("f2")) || &error("You must be an administrator to perform this function");
	&print_add_monitoring_event_page;
	&safe_exit;
}
elsif ($FORM{'td'} eq "do_add_monitoring_event"){
	$current_page = "config";
	(&is_admin("f2")) || &error("You must be an administrator to perform this function");
	&do_add_monitoring_event;
	&print_add_monitoring_event_page;
	&safe_exit;
}
elsif ($FORM{'td'} eq "print_add_special_monitoring_event"){
	$current_page = "config";
	(&is_admin("f2")) || &error("You must be an administrator to perform this function");
	&print_add_special_monitoring_event;
	&safe_exit;
}
elsif ($FORM{'td'} eq "do_update_proc_monitor_rules"){
	$current_page = "config";
	(&is_admin("f2")) || &error("You must be an administrator to perform this function");
	my $current_conf = &update_special_monitor_proc($FORM{'sid'},$FORM{'host_name'},$FORM{'proc_rules'});
	#take out DB "safe_slashes" for display in textbox
	&unsafe_slash(\$current_conf);
	&push_message("<FONT COLOR=red>Process Monitoring Rules Updated</FONT>");
	&print_special_monitor_proc($FORM{'sid'},$FORM{'host_name'},$current_conf);
	&safe_exit;
}
elsif ($FORM{'td'} eq "do_update_log_monitor_rules"){
	$current_page = "config";
	(&is_admin("f2")) || &error("You must be an administrator to perform this function");
	my $current_conf = &update_special_monitor_logs($FORM{'sid'},$FORM{'host_name'},$FORM{'log_rules'});
	#take out DB "safe_slashes" for display in textbox
	&unsafe_slash(\$current_conf);
	&push_message("<FONT COLOR=red>Log Monitoring Rules Updated</FONT>");
	&print_special_monitor_logs($FORM{'sid'},$FORM{'host_name'},$current_conf);
	&safe_exit;
}
elsif ($FORM{'td'} eq "view_monitored_host"){
	$current_page = "monitor";
	&view_monitored_host(	host_name => $FORM{'host_name'},
							service => $FORM{'service'},
								);
	&safe_exit;
}
elsif ($FORM{'td'} eq "view_md5_page"){
	$current_page = "md5";
	&view_md5_page($FORM{'minimal'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "view_md5_details_page"){
	$current_page = "md5";
	&view_md5_page('',$FORM{'sid'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "confirm_all_md5_changes"){
	$current_page = "md5";
	(&is_admin("f3")) || &error("You must be an administrator to perform this function");
	&confirm_all_md5_changes;
	&view_md5_page($FORM{'minimal'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "confirm_selective_md5_changes"){
	$current_page = "md5";
	(&is_admin("f3")) || &error("You must be an administrator to perform this function");
	&confirm_selective_md5_changes($FORM{'sid'});
	&view_md5_page($FORM{'minimal'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "age_data"){
	$current_page = "config";
	(&is_admin("f1")) || (&is_admin("f2")) || &error("You must be an administrator to perform this function");
	&print_age_data_form;
	&safe_exit;
}
elsif ($FORM{'td'} eq "do_age_data"){
	$current_page = "config";
	#CHECK FOR ADMIN IN FUNCTION
	&age_data(	services => $FORM{'age_ago_services'},
					ids		=> $FORM{'age_ago_ids'}
				);
	&print_age_data_form;
	&safe_exit;
}
elsif ($FORM{'td'} eq "view_log_entries"){
	$current_page = "config";
	(&is_admin()) || &error("You must be the Super User to perform this function");
	&print_log($FORM{'tail'});
	&safe_exit;
}
elsif ($FORM{'td'} eq "user_config"){
	$current_page = "config";
	&print_user_config_form;
	&safe_exit;
}
elsif ($FORM{'td'} eq "user_level_config"){
	$current_page = "config";
	&print_user_level_config_form;
	&safe_exit;
}
elsif ($FORM{'td'} eq "ul_change_email"){
	$current_page = "config";
	&ul_change_email($FORM{'new_email'});
	&print_user_level_config_form;
	&safe_exit;
}
elsif ($FORM{'td'} eq "ul_change_password"){
	$current_page = "config";
	&ul_change_password($FORM{'old_pw'},$FORM{'new_pw'},$FORM{'new_pw_confirm'});
	&print_user_level_config_form;
	&safe_exit;
}
elsif ($FORM{'td'} eq "add_user"){
	$current_page = "config";
	(&is_admin) || &error("You must be the Super User to perform this function");
	&do_add_user($FORM{'new_username'},$FORM{'new_password'},$FORM{'new_email'},$FORM{'ip_restrict'},$FORM{'su'},$FORM{'nids_admin'},$FORM{'service_admin'},$FORM{'md5_admin'});
	&print_user_config_form;
	&safe_exit;
}
elsif ($FORM{'td'} eq "modify_user"){
	$current_page = "config";
	&do_modify_user($FORM{'current_user'},$FORM{'action'},$FORM{'new_value'});
	&print_user_config_form;
	&safe_exit;
}
else{
	$current_page = "main";
	&print_stats;
#&debug("Page loadtime :" . (time() - $ttime));
	&safe_exit;
}



#############################################
# Functions
#############################################

sub connect_to_db{
if (!$db || !$db->ping){

 $db_user         ||  &error("No database user specified.","BLANK");
 $db_password     ||  &error("No database password specified.","BLANK");
 $db_host         ||  &error("No database host specified.","BLANK");
 $db_name         ||  &error("No database specified.","BLANK");

 $db = DBI->connect("dbi:mysql:host=$db_host;database=$db_name", $db_user , $db_password) || &error("Connection Problem! ". $DBI::errstr , "BLANK");

}
return $db;
}


####################
sub error{
my ($error_string,$plain_page) = @_;

if ($plain_page){
	&print_header;
	print "<HTML><BODY BGCOLOR=black TEXT=red><CENTER><H2>$error_string</H2></CENTER></BODY></HTML>";
	&safe_exit;
}

push (@substitutions,"\\[MAIN_TABLE\\],-,<CENTER><FONT COLOR=red><B>$error_string</B></FONT></CENTER>");
&print_main_with_key($main_template);
&safe_exit;
}
####################
sub debug{
my ($d_string,$d_level) = @_;

return if ($debug_level && $d_level && ($debug_level > $d_level));

&print_header;
print $d_string . "<BR>";
}
####################
sub print_header{

return if ($header_printed);
$header_printed = 1;
print "Content-type: text/html\n\n";
}
###################
sub safe_exit{

if (!$ENV{'MOD_PERL'} && $db){
    $db->disconnect;
}

exit;
}
###################
sub print_events{
my (%args) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
my $proto;
my @where_array;
my @special_where_array;
my @proto_array;
my $where;
my $limit;
my $row_count;
my $search_type;
my $return_count;
my $start;

&safe_slash(\$args{'signature'});
&safe_slash(\$args{'signature2'});
&safe_slash(\$args{'signature3'});
&safe_slash(\$args{'signature_is'});
($args{'sid'}=~/^\d+$/) 
	|| ($args{'sid'} = ());
($args{'cid'}=~/^\d+$/) 
	|| ($args{'cid'} = ());
($args{'start_record'}=~/^\d+$/) 
	|| ($args{'start_record'} = ());
($args{'limit'}=~/^\d+$/) 
	|| ($args{'limit'} = ());
($args{'start'}=~/^\d+$/) 
	|| ($args{'start'} = ());
($args{'limit'}=~/^\d+$/) 
	|| ($args{'limit'} = ());

#Time restrictions:
#db-defaults to 0's for bad input, 
#but at least make sure its all numbers:
($args{'hr_s'}=~/^\d+$/) 
	|| ($args{'hr_s'} = "0");
($args{'min_s'}=~/^\d+$/) 
	|| ($args{'min_s'} = "0");
($args{'day_s'}=~/^\d+$/) 
	|| ($args{'day_s'} = "0");
($args{'mon_s'}=~/^\d+$/) 
	|| ($args{'mon_s'} = "0");
($args{'yr_s'}=~/^\d+$/) 
	|| ($args{'yr_s'} = "0");
($args{'hr_f'}=~/^\d+$/) 
	|| ($args{'hr_f'} = "0");
($args{'min_f'}=~/^\d+$/) 
	|| ($args{'min_f'} = "0");
($args{'day_f'}=~/^\d+$/) 
	|| ($args{'day_f'} = "0");
($args{'mon_f'}=~/^\d+$/) 
	|| ($args{'mon_f'} = "0");
($args{'yr_f'}=~/^\d+$/) 
	|| ($args{'yr_f'} = "0");
($args{'graph'}=~/^\d+$/) 
	|| ($args{'graph'} = "0");


# IP focusing
($args{'src_ip'}=~/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) 
	|| ($args{'src_ip'} = ());
($args{'dst_ip'}=~/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) 
	|| ($args{'dst_ip'} = ());

# Table stuff:
($args{'cellpadding'}=~/^\d+$/) 
	|| ($args{'cellpadding'} = "0");
($args{'cellspacing'}=~/^\d+$/) 
	|| ($args{'cellspacing'} = "1");
($args{'table_width'}=~/^\d+\%{0,1}$/) 
	|| ($args{'table_width'} = "100%");
($args{'first_color'}) 
	|| ($args{'first_color'} = "#000000");
($args{'second_color'}) 
	|| ($args{'second_color'} = "#000000");
($args{'head_color'}) 
	|| ($args{'head_color'} = $head_color);
($args{'border_color'}) 
	|| ($args{'border_color'} = "#000000");

&safe_slash(\$args{'order_by'});

($args{'offset_type'}=~/^day$|^hour$/) || ($FORM{'offset_type'} = '');
($args{'offset_number'}=~/^\d+$/) || ($FORM{'offset_number'} = '');
	

if ($args{'signature'}){
	push (@where_array,"(sig_name LIKE '%$args{'signature'}%')");
}
if ($args{'signature2'}){
	push (@where_array,"(sig_name LIKE '%$args{'signature2'}%')");
}
if ($args{'signature3'}){
	push (@where_array,"(sig_name LIKE '%$args{'signature3'}%')");
}
if ($args{'signature_is'}){
	push (@where_array,"(sig_name =  '$args{'signature_is'}')");
}
if ($args{'sid'}){
	push (@where_array,"(event.sid = '$args{'sid'}')");
}
if ($args{'cid'}){
	push (@where_array,"(event.cid = '$args{'cid'}')");
}

# Limit it to past x days/hours
if (!$args{'graph'}){
	my $time_limited; #make sure specific time query overrides "past x days" type of restrictions

	# The right time period:
	if ($args{'yr_s'} ||$args{'mon_s'} || $args{'day_s'} || $args{'hr_s'} || $args{'min_s'}){
		push (@where_array,"(timestamp >= '$args{'yr_s'}-$args{'mon_s'}-$args{'day_s'} $args{'hr_s'}:$args{'min_s'}:00')");
		$time_limited = 1;
	}
	if ($args{'yr_f'} ||$args{'mon_f'} || $args{'day_f'} || $args{'hr_f'} || $args{'min_f'}){
		push (@where_array,"(timestamp <= '$args{'yr_f'}-$args{'mon_f'}-$args{'day_f'} $args{'hr_f'}:$args{'min_f'}:00')");
		$time_limited = 1;
	}
	if (!$time_limited){
		if (($args{'offset_type'}) && ($args{'offset_number'})){
			push (@special_where_array,"(timestamp >= date_add(now(),interval -$args{'offset_number'} $args{'offset_type'}))");
		}
	}
}
else{
	push (@special_where_array,"(timestamp >= date_add(now(),interval -$args{'graph'} day))");
	
	# Make message of what we're graphing:
	my $graph_message;
	$graph_message .= " for Sensor \"$args{'sid'}\" " if ($args{'sid'});
	$graph_message .= " where the signature matches \"$args{'signature_is'}\" " if ($args{'signature_is'});
	$graph_message .= " where the signature contains \"$args{'signature'}\" " if ($args{'signature'});
	$graph_message .= " where the signature contains \"$args{'signature2'}\" " if ($args{'signature2'});
	$graph_message .= " where the signature contains \"$args{'signature3'}\" " if ($args{'signature3'});

	&push_message("<B>Events $graph_message<B>");
my $time_period = ($args{'graph'} > 1)
				? " $args{'graph'} days "
				: " 24 hours ";
&push_message("<B>Graphed over the past $time_period</B>");
}

#Make sure we get the protocol we want
# Deal with protocols in a special (OR) manner

#Optimization: check to see if we wan't all proto's:
if (!($args{'tcp'} && $args{'udp'} && $args{'icmp'})){
	if ($args{'tcp'}){
		push (@proto_array,"(tcp_dport IS NOT NULL)");
	}
	if ($args{'udp'}){
		push (@proto_array,"(udp_dport IS NOT NULL)");
	}
	if ($args{'icmp'}){
		push (@proto_array,"(icmp_type IS NOT NULL)");
	}
	if ($args{'other'}){
		push (@proto_array,"((icmp_type IS NULL) AND (udp_dport IS NULL) AND (tcp_dport IS NULL))");
	}
}
if (@proto_array){
	my $temp_string = "( ";
	foreach (@proto_array){
		$temp_string .= " $_ OR";
	}
	$temp_string =~s/OR$/\) /;#Take off last OR and end with )
	push (@special_where_array,$temp_string);
}



#Only get certain ips src/dst if requested
if ($args{'src_ip'}){
	push (@where_array,"(ip_src = '" . &convert_dotted_ip($args{'src_ip'}) . "')");
}
if ($args{'dst_ip'}){
	push (@where_array,"(ip_dst = '" . &convert_dotted_ip($args{'dst_ip'}) . "')");
}
	
# Limit the results if applicable:
if (!$args{'delete_type'} || $args{'delete_type'} eq "limit"){
	if (($args{'start'}=~/^\d+$/) && ($args{'limit'})){
		$limit = " LIMIT $args{'start'},$args{'limit'} ";
	}
	elsif ($args{'limit'}){
		$limit = " LIMIT $args{'limit'} ";
	}
}

#Figure out if we're doing an OR/AND search

$search_type = ($args{'search_type'} eq "ANY")? "OR" : "AND";

#Put together where clause:
if (@where_array){
#	$where = " WHERE 1=1 ";
	$where = " WHERE ";
	foreach (@where_array){
		#$where .= " AND $_ ";
		$where .= " $_ $search_type";
	}
	# Take off the last boolean connector:
	$where=~s/$search_type$//;
}

# now add the special ones that HAVE to be ANDs

if (@special_where_array){
		$where .= (@where_array)?" AND ( " : " WHERE (";
	foreach (@special_where_array){
		$where .= " $_ AND";
	}
	# take off the last boolean connector, and add closing ):
	$where=~s/AND$/) /;
}

if ($current_page ne "main"){
# Get total returned rows count first:
$sql_query = "SELECT count(*) as COUNT \
					FROM event \
                  LEFT JOIN iphdr   ON  ((event.cid = iphdr.cid) AND (event.sid = iphdr.sid)) \
                  LEFT JOIN tcphdr  ON ((event.cid = tcphdr.cid) AND (event.sid = tcphdr.sid)) \
                  LEFT JOIN udphdr  ON ((event.cid = udphdr.cid) AND (event.sid = udphdr.sid)) \
						LEFT JOIN signature  ON (event.signature = signature.sig_id)  \
                  LEFT JOIN icmphdr ON ((event.cid = icmphdr.cid) AND (event.sid = icmphdr.sid)) $where";
$db_ptr = &run_query($sql_query);
$hash_ref = $db_ptr->fetchrow_hashref;
$return_count = $$hash_ref{'COUNT'};
push (@substitutions,"<TOTAL_ROWS_RETURNED>,-,Total rows returned: $return_count") if ($current_page ne "main");
}

if ($args{'graph'}){
	if ($args{'graph'} == 1){
		#hourly graph:
			$sql_query = 'SELECT count(*) AS COUNT,DATE_FORMAT( timestamp,"%Y%m%d%H") AS DAILY ,DATE_FORMAT( NOW(), "%Y%m%d") AS TODAY, DATE_FORMAT( (DATE_ADD(NOW(), INTERVAL -1 DAY)), "%Y%m%d") AS YESTERDAY, DATE_FORMAT( NOW(), "%Y%m%d%H") AS THIS_HOUR, timestamp ';
	}
	else{
		#daily graph
			#$sql_query = 'SELECT count(*) AS COUNT,DATE_FORMAT( timestamp,"%Y%m%d") AS DAILY ';
			$sql_query = 'SELECT count(*) AS COUNT,TO_DAYS(timestamp) AS DAILY,TO_DAYS(now()) AS TODAY,timestamp ';
	}
}
elsif (!$args{'delete_type'}){
$sql_query = "SELECT \
					event.*,iphdr.ip_src,iphdr.ip_dst,tcphdr.tcp_sport,\
					tcphdr.tcp_dport,udphdr.udp_sport,udphdr.udp_dport,\
					sensor.hostname,sig_name ";
# Add "feelers" for accurate protocol IDing
$sql_query .= ", udphdr.sid AS UDP, icmphdr.sid AS ICMP, tcphdr.sid AS TCP ";
}
else{
	#then we just want to get the sid and cid s:
	$sql_query = " SELECT event.sid,event.cid ";
}
$sql_query .= " FROM event \
						LEFT JOIN iphdr 	ON  ((event.cid = iphdr.cid) AND (event.sid = iphdr.sid)) \
						LEFT JOIN tcphdr 	ON ((event.cid = tcphdr.cid) AND (event.sid = tcphdr.sid)) \
						LEFT JOIN udphdr 	ON ((event.cid = udphdr.cid) AND (event.sid = udphdr.sid)) \
						LEFT JOIN icmphdr ON ((event.cid = icmphdr.cid) AND (event.sid = icmphdr.sid)) \
						LEFT JOIN sensor  ON (event.sid = sensor.sid)  \
						LEFT JOIN signature  ON (event.signature = signature.sig_id)  \
					$where ";

if (!$args{'graph'}){
	$sql_query .= " ORDER BY timestamp DESC $limit";
}
else{
	$sql_query .= " GROUP BY DAILY ORDER BY DAILY ";
#	&debug("GRAPH IT");
#&debug($sql_query);
	&graph_data($args{'graph'},$sql_query);
	&safe_exit;
}

$db_ptr = &run_query($sql_query);

if ($args{'delete_type'}){
	#then we just have return the list to be deleted:
	my @delete_array;
	while ($hash_ref = $db_ptr->fetchrow_hashref){
		push (@delete_array,"$$hash_ref{'sid'},$$hash_ref{'cid'}");
	}
	return \@delete_array;
}


$table .= "<TABLE width=\"$args{'table_width'}\" border=0 cellspacing=\"$args{'cellspacing'}\" cellpadding=\"2\">";

	if ($current_page eq "show_events"){
  		$table .= "<TR BGCOLOR=$head_color><TD BACKGROUND=\"$v_graphics_path/bg_title.gif\" COLSPAN=6 align=center><B>Event List</B></TD></TR>\n";
 	} 
 	else
    	{
			#$table .= "<TR BGCOLOR=$head_color><TD BACKGROUND=\"$v_graphics_path/bg_title.gif\" COLSPAN=6 align=center><B>Last 6 Events</B></TD></TR>\n";
			$table .= "<TR BGCOLOR=$head_color><TD BACKGROUND=\"$v_graphics_path/bg_title.gif\" COLSPAN=6 align=center><B>$args{'title'}</B></TD></TR>\n";
	}
$table .= "<TR BGCOLOR=$title_color><TD align=center><b>Signature</b></TD><TD align=center><b>Type</b></TD><TD align=center><b>Source</b></TD><TD align=center><b>Destination</b></TD><TD align=center><b>Sensor</b></TD><TD align=center><b>Time/Date</b></TD></TR>\n";

while ($hash_ref = $db_ptr->fetchrow_hashref){
	$row_count++;
	$table .= "<TR bgcolor=\"$desc_color\">";
	$table .= "<TD width=90%>&nbsp;";
	if ($$hash_ref{'sig_name'}=~/portscan.{1,11}from/i){
			$$hash_ref{'sig_name'}=~s/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/<A HREF=\"$home_url?td=arin_whois&ip=$1\">$1<\/A>/g;
			$table .= "$$hash_ref{'sig_name'}";
	}
	else{
			$table .= "<A HREF=\"$home_url?td=view_payload&sid=$$hash_ref{'sid'}&cid=$$hash_ref{'cid'}\">";
			$table .= "$$hash_ref{'sig_name'}";
			$table .= "</A>";
	}
	$table .= "&nbsp;</TD>";

# TCP/UDP/ICMP
   if ($$hash_ref{'TCP'}){
      $proto = "TCP";
   }
   elsif ($$hash_ref{'UDP'}){
      $proto = "UDP";
   }
   elsif ($$hash_ref{'ICMP'}){
      $proto = "ICMP";
   }
   elsif ($$hash_ref{'sig_name'}=~/portscan/i){
      $proto = "Scan";
   }
   else{
      $proto = "???";
   }

	$table .= "<TD>&nbsp;<B>$proto</B>&nbsp;</TD>";
   
# Source IP/port:
   $table .= "<TD nowrap>&nbsp;";

	if ($$hash_ref{'ip_src'}){
		my $src_ip = &convert_long_ip($$hash_ref{'ip_src'});
		$table .= "<A HREF=\"$home_url?td=show_events&src_ip=$src_ip&limit=$default_limit\">$src_ip</A>";
	}
	else{
		$table .= "NA";
	}
	if ($$hash_ref{'tcp_sport'}){
			$table .= ":$$hash_ref{'tcp_sport'}";
	}
	elsif ($$hash_ref{'udp_sport'}){
			$table .= ":$$hash_ref{'udp_sport'}";
	}
	else{
			$table .= ":na";
	}

	$table .= "&nbsp;</TD><TD nowrap>&nbsp;";

# Dest IP/port:
	
   if ($$hash_ref{'ip_dst'}){
      my $dst_ip = &convert_long_ip($$hash_ref{'ip_dst'});
      $table .= "<A HREF=\"$home_url?td=show_events&limit=$default_limit&dst_ip=$dst_ip\">$dst_ip</A>";
   }
   else{
      $table .= "NA";
   }
   if ($$hash_ref{'tcp_dport'}){
         $table .= ":$$hash_ref{'tcp_dport'}";
   }
   elsif ($$hash_ref{'udp_dport'}){
         $table .= ":$$hash_ref{'udp_dport'}";
   }
   else{
         $table .= ":na";
   }
   $table .= "&nbsp;</TD>";
# Sensor / host
   $table .= "<TD align=center>&nbsp;$$hash_ref{'hostname'}&nbsp;</TD>";
# Time / Date
	#strip seconds off to save space:
	$$hash_ref{'timestamp'}=~s/:\d\d$//;
	#strip year off to save space (not needed!):
	$$hash_ref{'timestamp'}=~s/^\d\d\d\d\-//;
	$$hash_ref{'timestamp'}=~s/(\d\d\-\d\d) (\d\d:\d\d)/$2 $1/;
   $table .= "<TD NOWRAP>&nbsp;$$hash_ref{'timestamp'}&nbsp;</TD>\n";
	$table .= "</TR>\n";
}
$table .= "<TR bgcolor=\"$desc_color\"><TD align=center colspan=6><B>No records returned</B></TD></TR>\n"
	if (!$row_count);

# Start the form:
$table .= << "EOF";
<TR><TD align=center colspan=6 bgcolor="$desc_color">
<TABLE cellpadding=0 cellspacing=0 border=0 WIDTH=\"100%\">
<TR><TD ALIGN=center>
<TABLE cellpadding=2 cellspacing=0 border=0 BGCOLOR=\"#000000\">
EOF

$table .= "<FORM ACTION=\"$home_url\" METHOD=get>";
$table .= "<TR bgcolor=\"$desc_color\"><TD valign=top nowrap>";
$table .= "<B>Events in the past:</B>"; 
$table .= "<SELECT NAME=offset_number style=\"font-size:8pt;\">";
$table .= "<OPTION SELECTED>$args{'offset_number'}</OPTION>" if ($args{'offset_number'});
$table .= << "EOF";
<OPTION>1</OPTION>
<OPTION>2</OPTION>
<OPTION>3</OPTION>
<OPTION>4</OPTION>
<OPTION>5</OPTION>
<OPTION>6</OPTION>
<OPTION>7</OPTION>
<OPTION>8</OPTION>
<OPTION>9</OPTION>
<OPTION>10</OPTION>
<OPTION>11</OPTION>
<OPTION>12</OPTION>
<OPTION>13</OPTION>
<OPTION>14</OPTION>
<OPTION>15</OPTION>
<OPTION>16</OPTION>
<OPTION>17</OPTION>
<OPTION>18</OPTION>
<OPTION>19</OPTION>
<OPTION>20</OPTION>
<OPTION>21</OPTION>
<OPTION>22</OPTION>
<OPTION>23</OPTION>
<OPTION>24</OPTION>
</SELECT>
<SELECT NAME=offset_type style="font-size:8pt;">
EOF
if ($args{'offset_type'}=~/hour/){
   $table .= "<OPTION value=day>Days</OPTION>";
   $table .= "<OPTION value=hour selected>Hours</OPTION>";
}
elsif ($args{'offset_type'}=~/day/){
   $table .= "<OPTION value=day selected>Days</OPTION>";
   $table .= "<OPTION value=hour>Hours</OPTION>";
}
$table .= << "EOF";
</SELECT>
 </TD>
<TD valign=top>
<B>#</B><FONT SIZE="3"><B>/</B></FONT><B>Page:</B>
<SELECT NAME=limit style="font-size:8pt;">
EOF
$table .= "<OPTION selected>$args{'limit'}</OPTION>" if ($args{'limit'} && ($args{'limit'} > 10));
$table .= << "EOF";
<OPTION>600</OPTION>
<OPTION>300</OPTION>
<OPTION>200</OPTION>
<OPTION>100</OPTION>
<OPTION>60</OPTION>
<OPTION>50</OPTION>
<OPTION>40</OPTION>
<OPTION>30</OPTION>
<OPTION>20</OPTION>
<OPTION>10</OPTION>
</SELECT>
 </TD>
EOF
$table .= "<TD valign=top align=center>TCP:<INPUT TYPE=checkbox NAME=tcp " ;
$table .=  ($args{'tcp'})? " checked></TD>":"></TD>";
$table .= "<TD valign=top align=center>UDP:<INPUT TYPE=checkbox NAME=udp " ;
$table .=  ($args{'udp'})? " checked></TD>":"></TD>";
$table .= "<TD valign=top align=center>ICMP:<INPUT TYPE=checkbox NAME=icmp " ;
$table .= ($args{'icmp'})? " checked></TD>":"></TD>";
$table .= "<TD valign=top align=center>OTHER:<INPUT TYPE=checkbox NAME=other " ;
$table .= ($args{'other'})? " checked></TD>":"></TD>";
$table .= "<TD><INPUT TYPE=Submit Value=\"Go\" style=\"font-size:8pt\">";
$table .= "</TD>";
$table .= "</FORM>";
$table .= "</TR>\n";
$table .= "</TABLE>";
#$table .= "</TABLE></TD></TR>\n"; 

#</TABLE>
$table .= "</TD><TD ALIGN=right>";

if ($current_page eq "main"){
	$table .= "<A HREF=\"$home_url?offset_number=1&td=show_events&offset_type=day&limit=60\"><B>More...</B></A> &nbsp; &nbsp;";
}
else{
	$table .= "&nbsp;";
}

$table .= << "EOF";
</TD></TR>
</TABLE>
</TD></TR>
<TR HEIGHT=2 BGCOLOR="$head_color"><TD COLSPAN=6><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>
</TABLE>
EOF


if ($args{'limit'} && ($current_page ne "main")){
	# First get the args to pass:
	my $get_string;
	foreach (keys %args){
		if ($_ eq "signature"){
			$get_string .= "&signature=" . &linkify($args{'signature'});
		}
		elsif ($args{$_} && ($_ !~/^start$|color|table_width|^cell/)){
			$get_string .= "&$_=$args{$_}";
		}
	}

	$table .= "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH=\"100%\"><TR>";
	#$table .= "<TD WIDTH=50% ALIGN=left>";
	$table .= "<TD WIDTH=50%>";
	if ($args{'start'}){
		$start = $args{'start'};
		($args{'limit'}) ? ($start-=$args{'limit'}): ($start-=30);
		$start = "0" if ($start<0);  
		$table .= "&nbsp;<A HREF=\"$home_url?td=show_events&start=$start$get_string\">";
		$table .= "<B>&lt; BACK</B></A>"
	}
	$table .= "&nbsp;</TD>";
$table .= "<TD ALIGN=center NOWRAP>Records " ;
$table .= ($args{'start'})? $args{'start'} : "0" ;
$table .= " to " ;
$table .=  (($args{'start'} + $args{'limit'}) <= $return_count) ? ($args{'start'} + $args{'limit'}) : $return_count ;
$table .= " of $return_count</TD>";
	$table .= "<TD WIDTH=50% ALIGN=right>&nbsp;";
	if (($start + $args{'limit'}) < $return_count){
		$start = $args{'start'};
		$start += $args{'limit'};
		$table .= "<A HREF=\"$home_url?td=show_events&start=$start$get_string\">";
		$table .= "<B>NEXT &gt;</B></A>&nbsp;";
	}
	$table .= "</TD>";
	$table .= "</TR>\n</TABLE>\n";
}

if ((&is_admin("f1")) && ($current_page ne "main")){
	$table .= &get_delete_table(\%args);
}
return $table;
push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
##############
sub print_stats{
my $table;

$table .= "$minimum_monitoring_table";
$table .= "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 BGCOLOR=\"#000000\" WIDTH=\"100%\"><TR><TD>";

#takes ~7 seconds w/25k events
#=head
$table .= &print_events_opt(
						start_record		=> 0,
						limit					=> 6,
						title					=> "Last 6 Events",
						cellspacing			=> 1,
						cellpadding			=> 2,
						tcp					=> 1,
						udp					=> 1,
						icmp					=> 1,
						other					=> 1,
						head_color			=> $head_color,
			);
#=cut
$table .= "</TD></TR></TABLE>\n";
$table .= "<BR>";
$table .= &unique_events_since("day",-1,11);#takes~1 sec w/25k events

push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
##############
sub run_query{
my ($sql_query) = @_;
&connect_to_db();
my $t = time();

#my ($t1,$t2);
my $prepared = $db->prepare($sql_query);
if (!$prepared){
        #Then there's an error with the syntax of the query:
#        &error("Database Error: Please try again");
        &error("Syntax Error in SQL Query:<BR><B>$sql_query</B><P>".$db->errstr);
}
my $dbquery = $prepared->execute();
if (my $error_string = $prepared->errstr){
        &error("$error_string : $sql_query");
#        &error("Database Error: Please try again");
}
my $g = time();
#print STDERR ("SQL: " . ($g-$t) . "\n$sql_query\n". ($g-$t) ."\n") if (($g-$t) > 4);
return $prepared;
}
#######################
sub view_payload{
my ($sid,$cid) = @_;

my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
my $decoded;
my $decoded_ascii_string;
my $table2;
my $payload_table;
my $reference_link;

$sql_query = "SELECT hostname,data_payload,timestamp,sig_name,ref_id \
	      FROM \
			data,event \
			LEFT JOIN signature ON (event.signature = signature.sig_id) \
			LEFT JOIN sig_reference ON (event.signature = sig_reference.sig_id) \
			LEFT JOIN sensor ON (event.sid = sensor.sid) \
	      WHERE 	\
			data.sid ='$sid' AND \
			data.cid ='$cid' AND \
			data.sid = event.sid AND \
			data.cid = event.cid ";

$db_ptr = &run_query($sql_query);
if ($hash_ref = $db_ptr->fetchrow_hashref){

	if ($$hash_ref{'ref_id'}=~/^\d+$/){
		$reference_link = &get_reference_link($$hash_ref{'ref_id'});
	}
	
	$decoded = &decode_hex($$hash_ref{'data_payload'});
	$decoded_ascii_string = &decode_hex($$hash_ref{'data_payload'},"RETURN_STRING");

	# Sub out TEXTAREA HTML tags for safety while displaying
	$decoded_ascii_string=~s/<(\/{0,1})TEXTAREA>/<$1TA>/g;
	$decoded=~s/<(\/{0,1})TEXTAREA>/<$1TA>/g;

	$payload_table = "<BR>\n<TABLE CELLPADDING=2 CELLSPACING=1 BORDER=0 ALIGN=CENTER>\n";
	$payload_table .= "<TR BGCOLOR=\"$head_color\"><TD BACKGROUND=\"$v_graphics_path/bg_title.gif\" align=center><B>Event Payload</B></TD></TR>\n";
	$payload_table .= "<TR BGCOLOR=\"$title_color\">";
	$payload_table .= "<TD align=center><B>Payload with Hex</B></TD>";
	$payload_table .= "</TR>\n";
	$payload_table .= "<TR BGCOLOR=\"$desc_color\">";
	$payload_table .= "<TD align=center><FORM ACTION=\"javascript:void(0);\">";
	$payload_table .= "<TEXTAREA rows=8 cols=70>$decoded</TEXTAREA>";
	$payload_table .= "</TD></TR>\n";
	$payload_table .= "<TR BGCOLOR=\"$title_color\"><TD align=center><B>Alt-255 Decoded Payload</B></TD></TR>\n";
	$payload_table .= "<TR BGCOLOR=\"$desc_color\"><TD align=center><FORM ACTION=\"javascript:void(0);\">";
	$payload_table .= "<TEXTAREA rows=6 cols=70 WRAP=virtual>$decoded_ascii_string</TEXTAREA>";
	$payload_table .= "</TD></TR>\n";
	$payload_table .= "<TR HEIGHT=2><TD BGCOLOR=\"$head_color\" COLSPAN=5><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>\n"; 
	$payload_table .= "</TABLE>\n<BR>\n";
if (($detect_basic_auth) && ($decoded_ascii_string=~/Authorization: Basic (\S+)/)){
	my $basic_auth = $1;
	eval{
		require MIME::Base64;
		MIME::Base64->import();
		my $cracked = MIME::Base64::decode($basic_auth);
		&push_message("<FONT COLOR=red>Basic Authentication in payload : $cracked</FONT>");
	};
}

}
else{
	#still have to get the timestamp and signature:
	$sql_query = "SELECT timestamp,signature,sig_name,hostname \
					  FROM event \
         			LEFT JOIN signature ON (event.signature = signature.sig_id) \
						LEFT JOIN sensor ON (event.sid = sensor.sid) \
					  WHERE \
						event.sid = '$sid' AND \
						cid = '$cid'";
	$db_ptr = &run_query($sql_query);
	($hash_ref = $db_ptr->fetchrow_hashref) || &error("No such event exists");
}

#Get general header table:
	$table .= &get_general_header_table($sid,$cid,$$hash_ref{'timestamp'},$$hash_ref{'sig_name'},$reference_link,$$hash_ref{'hostname'});
#Get IP header table:
	$table .= &get_ip_header_table($sid,$cid);
#Get TCP header table:
	$table .= &get_tcp_header_table($sid,$cid);
#Get ICMP header table:
	$table .= &get_icmp_header_table($sid,$cid);
#Get UDP header table:
	$table .= &get_udp_header_table($sid,$cid);
#Insert Payload table created earlier:
	$table .= $payload_table;



push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);



}
#########################
sub decode_hex{
my ($hex_stuff,$return_ascii) = @_;
my @buf1;
my @buf2;
my $ascii;
my $j;
my $hex_ascii_sep       = "   ";
my $sep1                = " ";
my $char_spacer         = " ";


# Decode hex crap and split into hex/ascii arrays
foreach ($hex_stuff =~ /[0-9a-fA-F]{2}/g) {

        push (@buf1,  $_);
        #push (@buf2,  chr(hex($_)));
        push (@buf2,  &validate_char(chr(hex($_))));

}

return join('',@buf2) if $return_ascii;

##############
# Combine two arrays into readable format:

for ($j=0;$j<=(@buf1);$j++){
        if (($j > 2) && ((($j+1) % 16) == 1)){
                #print out asci stuff
                for (1..16){
                        $ascii .= $hex_ascii_sep if ($_==1);
                      #  $ascii .= $sep1 if ($_==9);
                        #$ascii .= &validate_char(shift @buf2);
                        $ascii .= (shift @buf2);
                }
                $ascii .= "\n";
        }
        elsif (($j > 2) && ((($j+1) % 8) == 1)){
                $ascii .= $sep1;
        }
        else{
                $ascii .= $char_spacer if ($j != 0);
        }

        $ascii .= $buf1[$j];
}

if (@buf2){ #check for left over stuff
            #(ie didnt end on 16th hex out needed to dump the ascii)

        my $left_over = ($j % 16);
        for (0..(16-($j % 16))){
                $ascii .= " " x 3;
        }
		# Take off the last space
		$ascii=~s/ $//;
        if ($j<8){
                $ascii .= $sep1;
        }
        $ascii .= $hex_ascii_sep;

        for (my $r=0;$r<(@buf2);$r++){
                #$ascii .= &validate_char($buf2[$r]);
                $ascii .= $buf2[$r];
        }
}
return ($ascii);
}

###################
sub validate_char{
my ($c)         = @_;
my $c2          ;
my $oob_spacer  = ".";

my $char_num = (ord $c);
if ((($char_num>=32) && ($char_num <=127)) || ($char_num == 10)){
		#allow standard characters, and newlines
        $c2 = $c;
}
elsif ($char_num == 13){
		# ahhh, we don't need to return anything for M$ curser returns ... when will they learn, a nl is enuf?!
		$c2 = '';
}
else{
        $c2 = $oob_spacer;
}

return $c2;
}
################
sub get_ip_header_table{
my ($sid,$cid) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
my @table_header_columns_1 = ('IP Src','Src Port','Src Service','IP Dst','Dst Port','Dst Service');
my @table_header_columns_2 = ('Ver','Hlen','TOS','Length','ID', 'Flags','Offset','Chksum','TTL');
my @table_fields_2 = ('ip_ver','ip_hlen','ip_tos','ip_len','ip_id'
			,'ip_flags','ip_off','ip_csum','ip_ttl');
my $services_hash_ref = StaticServices::get_services_hash_ref();
my $proto;
my $sport;
my $dport;

$sql_query = "SELECT  \
      iphdr.sid, iphdr.cid, iphdr.ip_src, iphdr.ip_dst,\
      iphdr.ip_ver, iphdr.ip_hlen, iphdr.ip_tos, \
      iphdr.ip_len, iphdr.ip_id, iphdr.ip_flags, \
      iphdr.ip_off, iphdr.ip_ttl, iphdr.ip_proto, iphdr.ip_csum, \
		tcphdr.tcp_sport, tcphdr.tcp_dport, \
		udphdr.udp_sport, udphdr.udp_dport \
         FROM iphdr \
				LEFT JOIN tcphdr ON ((iphdr.cid = tcphdr.cid) AND (iphdr.sid = tcphdr.sid)) \
         	LEFT JOIN udphdr ON ((iphdr.cid = udphdr.cid) AND (iphdr.sid = udphdr.sid)) \
         WHERE \
      iphdr.sid = '$sid' AND \
      iphdr.cid = '$cid'";

$db_ptr = &run_query($sql_query);
($hash_ref = $db_ptr->fetchrow_hashref) || &error("No such payload exists");

$table = "<BR>\n<TABLE CELLSPACING=1 CELLPADDING=2 BORDER=0 WIDTH=\"100%\">";
#First row - IP and port stuff:
$table .= "<TR bgcolor=\"$head_color\"><TD background=\"$v_graphics_path/bg_title.gif\" align=center COLSPAN=6><B>Port Information</B></TD></TR>\n";
$table .= "<TR BGCOLOR=\"$title_color\">";
foreach (@table_header_columns_1){
	$table .= "<TD align=center><B>$_</B></TD>";
}
$table .= "</TR>\n";

$table .= "<TR BGCOLOR=\"$desc_color\">";
my $ip_s = &convert_long_ip($$hash_ref{'ip_src'});
$table .= "<TD align=center>";
$table .= "<A HREF=\"$home_url?td=show_events&limit=$default_limit&src_ip=$ip_s\">$ip_s</A>";
$table .= "<BR><A HREF=\"$home_url?td=arin_whois&ip=$ip_s\">Whois</A>";
$table .= " / ";
$table .= " <A HREF=\"$home_url?td=traceroute&ip=$ip_s\">Trace</A>";
$table .= " / ";
$table .= " <A HREF=\"$home_url?td=ping&ip=$ip_s\">Ping</A>";
$table .= " / ";
$table .= " <A HREF=\"$home_url?td=nslookup&ip=$ip_s\">NSlookup</A>";
$table .= "</TD>";
#$table .= "<TD align=center>$$hash_ref{'tcp_sport'}</TD>";
if ($$hash_ref{'tcp_sport'}){
	$table .= "<TD align=center>$$hash_ref{'tcp_sport'}</TD>";
	$proto = "tcp";
	$sport = $$hash_ref{'tcp_sport'};
}
elsif($$hash_ref{'udp_sport'}){
   $table .= "<TD align=center>$$hash_ref{'udp_sport'}</TD>";
	$proto = "udp";
	$sport = $$hash_ref{'udp_sport'};
}
else{
		$table .= "<TD align=center><FONT SIZE=\"-2\">[NA]</FONT></TD>";
		$proto = "NA";
		$sport = "NA";
}
$table .= ($$services_hash_ref{$proto."_".$sport}) ? "<TD align=center>$$services_hash_ref{$proto.'_'.$sport}</TD>": "<TD align=center><FONT SIZE=\"-2\">[NA]</FONT></TD>";

my $ip_d = &convert_long_ip($$hash_ref{'ip_dst'});
$table .= "<TD align=center>";
$table .= "<A HREF=\"$home_url?td=show_events&limit=$default_limit&dst_ip=$ip_d\">$ip_d</A>";
$table .= "<BR><A HREF=\"$home_url?td=arin_whois&ip=$ip_d\">Whois</A>";
$table .= " / ";
$table .= " <A HREF=\"$home_url?td=traceroute&ip=$ip_d\">Trace</A>";
$table .= " / ";
$table .= " <A HREF=\"$home_url?td=ping&ip=$ip_d\">Ping</A>";
$table .= " / ";
$table .= " <A HREF=\"$home_url?td=nslookup&ip=$ip_d\">NSlookup</A>";
$table .= "</TD>";
if ($$hash_ref{'tcp_dport'}){
	$table .= "<TD align=center>$$hash_ref{'tcp_dport'}</TD>";
	$proto = "tcp";
	$dport = $$hash_ref{'tcp_dport'};
}
elsif($$hash_ref{'udp_sport'}){
   $table .= "<TD align=center>$$hash_ref{'udp_dport'}</TD>";
	$proto = "udp";
	$dport = $$hash_ref{'udp_dport'};
}
else{
		$table .= "<TD align=center><FONT SIZE=\"-2\">[NA]</FONT></TD>";
		$proto = "NA";
		$dport = "NA";
}
$table .= ($$services_hash_ref{$proto."_".$dport}) ? "<TD align=center>$$services_hash_ref{$proto.'_'.$dport}</TD>": "<TD align=center><FONT SIZE=\"-2\">[NA]</FONT></TD>";
$table .= "</TR>\n";
$table .= "<TR HEIGHT=2><TD BGCOLOR=\"$head_color\" COLSPAN=6><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE>\n<BR>\n";

# Second Row (ip):
$table .= "<TABLE CELLSPACING=1 CELLPADDING=2 BORDER=0 WIDTH=100%>";
#IP Information
$table .= "<TR bgcolor=\"$head_color\"><TD background=\"$v_graphics_path/bg_title.gif\" align=center COLSPAN=9><B>IP Information</B></TD></TR>\n";
$table .= "<TR BGCOLOR=\"$title_color\">";
# Verticle Header row
foreach (@table_header_columns_2){
	$table .= "<TD align=center><B>$_</B></TD>";
}
$table .= "</TR><TR BGCOLOR=\"$desc_color\">\n";
foreach (@table_fields_2){
	#($table .= "<TD>$$hash_ref{$_}</TD>") ?($$hash_ref{$_}):($table .= "<TD>BBB</TD>");
	if ($$hash_ref{$_}){
		$table .= "<TD align=center>$$hash_ref{$_}</TD>";
	}
	else{
		$table .= "<TD align=center><FONT SIZE=\"-2\">[NA]</FONT></TD>";
	}
}
$table .= "</TR>\n";
$table .= "<TR HEIGHT=2><TD BGCOLOR=\"$head_color\" COLSPAN=9><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE>\n<BR>\n";

return $table;
}
################
sub get_icmp_header_table{
my ($sid,$cid) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
my @table_header_columns = ('Type','Code','Checksum','ID','Sequence');
my @table_fields 			 = ('icmp_type','icmp_code','icmp_csum','icmp_id','icmp_seq');

$sql_query = "SELECT  \
				icmp_type,icmp_code,icmp_csum,icmp_id,icmp_seq 
         FROM icmphdr \
         WHERE \
      		sid = '$sid' AND \
      		cid = '$cid'";

$db_ptr = &run_query($sql_query);
($hash_ref = $db_ptr->fetchrow_hashref) || return; #Simply return, no errors

$table .= "<TABLE CELLSPACING=1 CELLPADDING=2 BORDER=0 WIDTH=\"100%\">";
#ICMP Information
# Verticle Header row
$table .= "<TR bgcolor=\"$head_color\"><TD background=\"$v_graphics_path/bg_title.gif\" align=center COLSPAN=5><B>ICMP Information</B></TD></TR>\n";
$table .= "<TR BGCOLOR=\"$title_color\">";
foreach (@table_header_columns){
	$table .= "<TD align=center><B>$_</B></TD>";
}
$table .= "</TR>\n";
$table .= "<TR BGCOLOR=\"$desc_color\">";
foreach (@table_fields){
	if ($$hash_ref{$_}){
		$table .= "<TD align=center>$$hash_ref{$_}</TD>";
	}
	else{
		$table .= "<TD align=center><FONT SIZE=\"-2\">[NA]</FONT></TD>";
	}
}
$table .= "</TR>\n";
$table .= "<TR HEIGHT=2><TD BGCOLOR=\"$head_color\" COLSPAN=5><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE>";

return $table;
}
################
sub get_udp_header_table{
my ($sid,$cid) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
my @table_header_columns = ('Src Port','Dst Port','Length','Checksum');
my @table_fields 			 = ('udp_sport','udp_dport','udp_len','udp_csum');

$sql_query = "SELECT  \
				udp_sport,udp_dport,udp_len,udp_csum \
         FROM udphdr \
         WHERE \
      		sid = '$sid' AND \
      		cid = '$cid'";

$db_ptr = &run_query($sql_query);
($hash_ref = $db_ptr->fetchrow_hashref) || return; #Simply return, no errors

$table .= "<TABLE CELLPADDING=2 CELLSPACING=1 BORDER=0 WIDTH=100%>";
# Verticle Header row
$table .= "<TR bgcolor=\"$head_color\"><TD background=\"$v_graphics_path/bg_title.gif\" colspan=4 align=center><B>UDP Information</B></TD></TR>";
$table .="<TR BGCOLOR=\"$title_color\">";
foreach (@table_header_columns){
	$table .= "<TD align=center width=\"25%\"><B>$_</B></TD>";
}
$table .= "</TR>\n";
$table .= "<TR BGCOLOR=\"$desc_color\">";
foreach (@table_fields){
	if ($$hash_ref{$_}){
		$table .= "<TD align=center>$$hash_ref{$_}</TD>";
	}
	else{
		$table .= "<TD align=center><FONT SIZE=\"-2\">[NA]</FONT></TD>";
	}
}
$table .= "</TR>\n";
$table .= "<TR HEIGHT=2><TD BGCOLOR=\"$head_color\" COLSPAN=4><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE>";

return $table;
}
################
sub get_tcp_header_table{
my ($sid,$cid) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
my @table_header_columns = ('Seq','Ack', 'Urp','Res',   'Win','Flags','Offset','Chksum');
my @table_fields = ('tcp_seq','tcp_ack','tcp_urp','tcp_res','tcp_win','tcp_flags','tcp_off','tcp_csum');

$sql_query = "SELECT  \
            	tcp_seq,tcp_ack,tcp_urp,tcp_res,tcp_win,tcp_flags,tcp_off,tcp_csum \
         	  FROM tcphdr \
         	  WHERE \
            	sid = '$sid' AND \
            	cid = '$cid'";

$db_ptr = &run_query($sql_query);
($hash_ref = $db_ptr->fetchrow_hashref) || return; #Simply return, no errors

#Third Row (tcp):
$table .= "<TABLE CELLSPACING=1 CElLPADDING=2 BORDER=0 WIDTH=\"100%\">";
#TCP Information
$table .= "<TR bgcolor=\"$head_color\"><TD background=\"$v_graphics_path/bg_title.gif\" align=center COLSPAN=8><B>TCP Information</B></TD></TR>\n";
$table .= "<TR BGCOLOR=\"$title_color\">";
# Verticle Header row
foreach (@table_header_columns){
	$table .= "<TD align=center><B>$_</B></TD>";
}
$table .= "</TR>\n<TR BGCOLOR=\"$desc_color\">\n";
foreach (@table_fields){
	if ($$hash_ref{$_}){
		$table .= "<TD align=center>$$hash_ref{$_}</TD>";
	}
	else{
		$table .= "<TD align=center><FONT SIZE=\"-2\">[NA]</FONT></TD>";
	}
}
$table .= "</TR>\n";
$table .= "<TR HEIGHT=2><TD BGCOLOR=\"$head_color\" colspan=8><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>\n";
$table .= "</TABLE>\n";

return $table;
}
#####################
sub convert_long_ip{
my ($long) = @_;
my $t1;
my $new_ip;

for (my $i=3;$i>=0;$i--){
        $t1 = sprintf ("%d",($long / (256 ** $i)));
        $new_ip .= $t1.".";
        $long = $long - ($t1 * (256 ** $i))
}
$new_ip =~s/\.$//;

return $new_ip;
}
####################
sub convert_dotted_ip{
my ($ip) = @_;

my @IP = split(/\./,$ip);

my $long_ip =(
  		   ($IP[0]*(256**3))
  		 + ($IP[1]*(256**2))
  		 + ($IP[2]*(256**1))
  		 + ($IP[3])
  		  );
return $long_ip;
}
####################
sub get_general_header_table{
my ($sid,$cid,$timestamp,$signature,$reference_link,$hostname) = @_;
my @table_header_columns = ('SID','CID','TimeStamp');
my $table;


$table  = "<TABLE CELLSPACING=1 CELLPADDING=2 BORDER=0 WIDTH=\"100%\">";

# Signature row first:
$table .= "<TR bgcolor=\"$head_color\"><TD background=\"$v_graphics_path/bg_title.gif\" align=center COLSPAN=4><B>Basic Information</B></TD></TR>\n";
$table .= "<TR BGCOLOR=\"$title_color\">";
$table .= "<TD align=center WIDTH=\"50%\"><B>Signature</B></TD>";
foreach (@table_header_columns){
	$table .= "<TD align=center nowrap><B>$_</B></TD>";
}
$table .= "</TR>\n";
$table .= "<TR BGCOLOR=\"$desc_color\">";
$table .= "<TD align=center>&nbsp;$signature &nbsp;$reference_link";

if (&is_admin("f1")){
	my $signature_link = $signature;
	$signature_link=~s/ /%20/g;
	$table .= " &nbsp;-&nbsp; <A HREF=\"$home_url?td=find_sig_in_rules&signature=$signature_link\">Find in Rules</A>";
}

$table .= "</TD>";
$table .= "<TD align=center width=100>&nbsp;$sid&nbsp;-&nbsp($hostname)</TD>";
$table .= "<TD align=center width=100>&nbsp;$cid&nbsp;</TD>";
$table .= "<TD align=center nowrap>&nbsp;$timestamp&nbsp;</TD>";
$table .= "</TR>\n";
$table .= "<TR HEIGHT=2><TD BGCOLOR=\"$head_color\" COLSPAN=4><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE>\n";

return $table;
}
###########

##################
sub print_main_with_key{
my ($file_to_print,$to_string) = @_;
my $message;
my $extra_head;

if (@messages){
	foreach (@messages){
		$message .= "<CENTER>$_</CENTER><BR>";
	}
}
push (@substitutions,"\\[MESSAGE\\],-,$message");

my $menu_bar = &get_menu_bar;
   push (@substitutions,"\\[MENU_BAR\\],-,$menu_bar");

if ($current_page eq "main"){
	$extra_head = ($current_page=~/^main$|^monitor$/)? "<META HTTP-EQUIV=\"REFRESH\" CONTENT=\"180; URL=$home_url\">" : " ";
}
else{
	$extra_head = ($current_page=~/^main$|^monitor$/)? "<META HTTP-EQUIV=\"REFRESH\" CONTENT=\"180;\">" : " ";
}
   push (@substitutions,"<EXTRA_HEAD>,-,$extra_head");

my $unique = &get_unique_events_count;
   push (@substitutions,"\\[UNIQUE_EVENTS_COUNT\\],-,$unique");
my $total = &get_total_events_count;
   push (@substitutions,"\\[TOTAL_EVENTS_COUNT\\],-,$total");

my $table;
if ($show_mini_view){
	$table = &get_proto_stats_table;
}
else{
	$file_to_print = $main_template_nmv;
	my $request_uri = $ENV{'REQUEST_URI'};
	$request_uri=~s/no_mini_view=\d//g;
	$request_uri .= ($request_uri=~/\?/) ? "&show_mini_view=1" : "?show_mini_view=1";
	$table .= "<A HREF=\"$request_uri\"><IMG SRC=\"$v_graphics_path/ln_minimize1.gif\" alt=\"Maximize Quick Stats\" width=13 height=13 border=0></A>";
}
   	push (@substitutions,"<_STATS_>,-,$table");
return &print_with_key($file_to_print,$to_string);
}
##################
sub print_mini_me{
my $table;

my $stats_table = &get_proto_stats_table;
my $bgcolor;
my $linkcolor;

$bgcolor = "#080E19";
#$linkcolor = "#CCCCFF";
$linkcolor = "#FF9900";

my $body_focus = ($recent_alert) ? " onload=\"window.focus();\" " : " startBlink(); ";
$table =<< "EOF";
<HTML>
<HEAD>
<TITLE>Quick Stats Miniview</TITLE>
<style type="text/css">
<!--
td { font-family: Arial, Helvetica, sans-serif; font-size: 8pt; font-weight: normal }
A:link    {  font-family: Arial, Helvetica, sans-serif; font-size: 8pt; text-decoration: none; color: $linkcolor }
A:visited {  font-family: Arial, Helvetica, sans-serif; font-size: 8pt; text-decoration: none; color: $linkcolor}
A:hover   {  font-family: Arial, Helvetica, sans-serif; font-size: 8pt; text-decoration: underline; color: yellow}
form { margin-bottom: 0}
-->
</style>
<META HTTP-EQUIV="REFRESH" CONTENT="180;">
<script LANGUAGE="JavaScript1.1">
<!--//Begin
function close_me(){
 	if (window.big_poppa != null){
		window.big_poppa.location.reload();
		window.big_poppa.focus();
	} else {
		notorious=window.open('$home_url','big_poppa');
		notorious.focus();
	}
		window.close();
}

// End -->
</script>
</HEAD>
<body bgcolor=$bgcolor text=white link=$linkcolor vlink=$linkcolor alink=red marginwidth=0 marginheight=0 topmargin=0 leftmargin=0 rightmargin=0 border=0 $body_focus>
EOF
$table .= "<center>";
$table .= "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH=145><TR><TD>";
$table .= $stats_table;
$table .= "</TD></TR>\n</TABLE>\n";
$table .= "</center>";
$table .= "</BODY></HTML>";
&print_header;
print $table;

}
######################
sub print_with_key{
my ($file_to_print,$to_string,$about_to_print) = @_;
my $sub;
my @arrayed;


if (!$to_string){
    &print_header;
}

my $linkcolor;
#$linkcolor = "#CCCCFF";
$linkcolor = "#FF9900";

push (@substitutions,"\\[LINKCOLOR\\],-,$linkcolor");

   my $ltime=&format_localtime();
   push (@substitutions,"\\[DATESTAMP\\],-,$ltime");
   push (@substitutions,"\\[PROGRAM_NAME\\],-,$program_name");
   push (@substitutions,"\\[PROGRAM_VERSION\\],-,$program_version");
   push (@substitutions,"\\[HOME_URL\\],-,$v_base_path/$this_program");
   push (@substitutions,"\\[G_P\\],-,$v_graphics_path");
   push (@substitutions,"\\[FOOTER\\],-,<A HREF=\"$home_url?td=about\">$footer_string</A>");

if (!$about_to_print){
   open (KEYED, "$file_to_print") || die "Can't Open $file_to_print: $!\n";
	#load the file into one string
	   while (<KEYED>){
	        $about_to_print .= $_;
	   }
	   close KEYED;
}

#do one pass through the file for each variable that needs to be sub-ed
 foreach $sub(@substitutions){
                @arrayed=split(/,-,/,$sub);
                $about_to_print=~s/$arrayed[0]/$arrayed[1]/g;
        }
=head
#DEBUG FOR SCREENSHOTS
$about_to_print=~s/\d{1,3}\.\d{1,3}(\.\d{1,3}\.\d{1,3})/192.168$1/g;
#BAD ASS REGEX FOLLOWS:
$about_to_print=~s/A HREF\s*=\s*\"[\s\S]+?\"/a href=\'javascript:alert(\"Mockup version... links do not work!\");\'/g;
=cut

if (!$to_string){
       print $about_to_print;
}
else{
    return $about_to_print;
}
}
###########################
sub print_about{

my $about_text = << 'EOF';

<table width="80%" border="0" cellspacing="0" cellpadding="6" align="center">
  <tr> 
    <td colspan="2">
      <p align=center><b>DEMARC &copy;2000-2001, DEMARC Organization</b></p>
      
<ol>
<p>
<li><b>REDISTRIBUTION</b><br>
        <br>

Redistributions of source code must retain the above copyright notice, this 
list of conditions and the following disclaimer. You may not sell DEMARC, 
nor sell any of the functionality it provides without first obtaining a  
commercial license or receiving direct written authorization from DENARC 
Organization.
<br>

</p>
<p><li><b>FREE FOR NON-COMMERCIAL USE</b><br>
          <br>
No part of DEMARC may be used by any commercial entity without 
having first obtained a commercial license from DEMARC Organization unless 
exempt by meeting one of the following conditions:
<br>
<p>
            <b>a.</b>
 Your company's primary business is as an ISP (Internet Service Provider) 
and has a customer base of fewer than 1000 users.<br> 
</p>
<p>
            <b>b.</b>
 Your company has fewer than 25 employees and is not an ISP. <br>
</p>
<p>
            <b>c.</b>
 You have extenuating circumstances and have received written authorization 
   from DEMARC Organization to use this software free of charge. <br>
</p>
        <b>A free evaluation period of 60 days is granted 
          for any commercial entity who does not meet the requirements above but 
          wishes to first try out the product.</b><br>
</p>
<p><li><b>TRADEMARKS AND NOTICES</b><br>
        <br>
        The software, graphics and documentation which make up DEMARC are Copyright 
        &copy; 2000-2001 DEMARC Organization You agree to respect these rights and leave 
        all notices and product references intact. <br>
</p>
<p><li><b>LIMITATION OF LIABILITY AND DISCLAIMER OF WARRANTY</b><br>
			<br>
     THERE IS NO WARRANTY FOR THE PROGRAM, TO THE 
          EXTENT PERMITTED BY APPLICABLE LAW. DEMARC ORGANIZATION PROVIDE THIS PROGRAM 
          &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, 
          BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
          FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE 
          OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU 
          ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 
</p>
<p>    
DEMARC Organization reserves the right to modify this license at any time.<br> 
</ol>
</p>
<p align=center>Any questions or comments regarding this license or the official evaluation of individual circumstances may be directed to <a href="mailto:license@demarc.org">license@demarc.org</a>
</p>
<br>
 </td>
</tr>
  <tr align="center"> 
    <td><a href="http://demarc.org/" target="_blank"><b>http://demarc.org/</b></a></td>
  </tr>
</TABLE>
EOF


push (@substitutions,"\\[MAIN_TABLE\\],-,$about_text");
&print_main_with_key($main_template);
}
###########################
sub get_proto_stats_table{
my $sql_query;
my $db_ptr;
my $hash_ref;
my $db_ptr_2;
my $hash_ref_2;
my $table;
my $table2;
my $total_count;
my $icmp_count;
my $tcp_count;
my $udp_count;
my $other_count;
my $icmp_percent;
my $tcp_percent;
my $udp_percent;
my $other_percent;
my $max_width = 42;
my $title_color = $minititle_color;
#my $inner_color = "#000033";
my $inner_color = $minidesc_color;
my $newest_proto = "Other";
my $alert_bg = "#FFFFFF";
my $alert_link;
my $mini_me_target;
my $cached_expire_seconds;


$mini_me_target = " TARGET=big_poppa " if ($current_page eq "mini_me");

# Total:
$total_count = &count_total_records;
($total_count) || ($total_count = "0");#Pretty view if 0 records

# TCP:
$sql_query = "SELECT count(*) as count FROM tcphdr";
$db_ptr = &run_query($sql_query);
$tcp_count = ($hash_ref = $db_ptr->fetchrow_hashref)? $$hash_ref{'count'} : 0;

# UDP:
$sql_query = "SELECT count(*) as count FROM udphdr";
$db_ptr = &run_query($sql_query);
$udp_count = ($hash_ref = $db_ptr->fetchrow_hashref)? $$hash_ref{'count'} : 0;

# ICMP:
$sql_query = "SELECT count(*) as count FROM icmphdr";
$db_ptr = &run_query($sql_query);
$icmp_count = ($hash_ref = $db_ptr->fetchrow_hashref)? $$hash_ref{'count'} : 0;

$other_count = $total_count - ($icmp_count + $tcp_count + $udp_count);

$tcp_percent =  ($total_count) 
			? &round(($tcp_count/$total_count)*100)
			: 0 ;
$udp_percent =  ($total_count)
			? &round(($udp_count/$total_count)*100)
			: 0;
$icmp_percent =  ($total_count)
			? &round(($icmp_count/$total_count)*100)
			: 0;
$other_percent =  ($total_count)
			? &round(($other_count/$total_count)*100)
			:0;

#Now make the table:
$table2 .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=1  WIDTH=\"100%\">\n<TR><TD BGCOLOR=\"$miniborder_color\">";
$table2 .= "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 BGCOLOR=\"$minigap_color\" WIDTH=\"100%\">\n<TR><TD BGCOLOR=\"$minigap_color\">";
$table2 .= "<TABLE BORDER=0 CELLSPACING=2 CELLPADDING=1 WIDTH=\"100%\" BGCOLOR=\"$minigap_color\">\n";

$table2 .= "<TR bgcolor=\"$minidesc_color\"><TD COLSPAN=2 ALIGN=center>";
my $ltime = &format_localtime();


$table2 .= "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH=\"100%\">\n";
$table2 .= "<TR BGCOLOR=\"$minititle_color\"><TD><A HREF=\"$home_url?td=mini_me\" target=\"MiniMe\" onClick=\"load_mini_me();return false;\"><img src=\"$v_graphics_path/ln_popup.gif\" alt=\"Launch Miniview Window\" width=13 height=13 border=0></A></TD>";
$table2 .= "<TD align=center><B>Quick Stats</B></TD>";

my $request_uri = $ENV{'REQUEST_URI'};
$request_uri=~s/show_mini_view=\d//g;
$request_uri .= ($request_uri=~/\?/) ? "&no_mini_view=1" : "?no_mini_view=1";
$table2 .= "<TD align=right><A HREF=\"$request_uri\"><IMG SRC=\"$v_graphics_path/ln_minimize0.gif\" alt=\"Minimize Quick Stats\" width=13 height=13 border=0></A></TD>";

$table2 .= "</TR>\n</TABLE>\n";
$table2 .= "<TR bgcolor=\"$minidesc_color\"><TD colspan=2 align=center>$ltime</TD></TR>\n";

#Get info on last event
# First add needed priority clause:
#my $priority_where = " (signature.sig_name RLIKE 'P-[$alert_priority_levels]-.*') ";

my $priority_where = " ((signature.sig_name LIKE 'P-1-%')  OR (signature.sig_name LIKE 'P-2-%')) ";


if ($alert_priority_levels=~/$default_priority_level/){
	$priority_where = "( $priority_where OR (signature.sig_name NOT LIKE 'P-%')) ";
}


						#(TO_DAYS(NOW()) - TO_DAYS(MAX(timestamp))) AS DAYS_SINCE, \

$sql_query = "	SELECT \
						max(timestamp) AS LAST, \
						(TIME_TO_SEC(NOW()) - TIME_TO_SEC(MAX(timestamp))) AS SEC_DIFF \
					FROM event,signature \ 
					WHERE signature.sig_id = event.signature AND $priority_where \
					LIMIT 1";


$db_ptr = &run_query($sql_query);
$hash_ref = $db_ptr->fetchrow_hashref;

$sql_query = "  SELECT \
                        event.sid,event.cid,sig_name, \
                        signature.sig_name \
                    FROM \
                        event\
                        LEFT JOIN signature ON (event.signature = signature.sig_id) \
                    WHERE\
                        timestamp = '$$hash_ref{'LAST'}' AND $priority_where \
                    LIMIT 1"; #LIMIT is just in case there were two at the same timestamp



$db_ptr_2 = &run_query($sql_query);
$hash_ref_2 = $db_ptr_2->fetchrow_hashref;


my $alert_link .= "$home_url?td=view_payload&sid=$$hash_ref_2{'sid'}&cid=$$hash_ref_2{'cid'}"; 

$table2 .= "<TR><TD COLSPAN=2 ALIGN=center BGCOLOR=$title_color>";
$table2 .= "<B>Last NIDS Alert</B></TD></TR>\n";

$table2 .= "<TR><TD align=center colspan=2 bgcolor=\"RECENT_COLOR\" onMouseOver=\"this.style.cursor='hand';window.status='View Latest Alert';this.style.backgroundColor='red';return true\" onMouseOut=\"this.style.cursor='auto';this.style.backgroundColor='RECENT_COLOR';window.status='';return true\">";


$table2 .= "<FONT COLOR=\"$alert_bg\">";

# for making page color red / yellow
if ($$hash_ref{'SEC_DIFF'} < 600){
	if (($high_alert_level==$default_priority_level) || ($$hash_ref_2{'sig_name'}=~/^P-$high_alert_level-/)){
		$recent_alert = 1;
		$table2 .= "\n<BLINK><B>" . &format_seconds($$hash_ref{'SEC_DIFF'}) . " ago</B></BLINK><RECENT_ALERT>\n";
	}
	else{
		$recent_alert = 2;
		$table2 .= "\n<B>" . &format_seconds($$hash_ref{'SEC_DIFF'}) . " ago</B><RECENT_ALERT_WARN>\n";
	}
}
else{
	$table2 .= &format_seconds($$hash_ref{'SEC_DIFF'}) . " ago";
}

$table2 .= "</FONT>";

#	$table2 =~s/RECENT_COLOR/990000/g; #red

if ($recent_alert == 1){
	$table2 =~s/RECENT_COLOR/#990000/g; #red
	$alert_link = "class=alert";
}
elsif ($recent_alert == 2){
	$table2 =~s/RECENT_COLOR/#CC6600/g; #orange 
	$alert_link = "class=alert" ;
}
else{
   	$table2 =~s/RECENT_COLOR/#000033/g; #blue
		$alert_link = "";
}
#truncated signature:
$table2 .= "<BR>";
$table2 .= "<A HREF=\"$home_url?td=view_payload&sid=$$hash_ref_2{'sid'}&cid=$$hash_ref_2{'cid'}\" $mini_me_target style=\"color:#FFFF00;\">" ;
$table2 .= ($$hash_ref_2{'sig_name'}=~/(^.{40})/) ? "$1..." : $$hash_ref_2{'sig_name'};
$table2 .= "</A>" ;
$table2 .= "</TD>";
$table2 .= "</TR>\n";

# Monitored host minimum table
$table2 .= "<TR><TD COLSPAN=2 ALIGN=center BGCOLOR=$title_color>";
$table2 .= "<B>Monitored Hosts</B></TD></TR>\n";
if ($downed_hosts_array_ref && @$downed_hosts_array_ref){
	my $downed_host_count;
	foreach (@$downed_hosts_array_ref){
		if ($downed_host_count++ > 3){
			$table2 .= "<TR><TD COLSPAN=2 ALIGN=center BGCOLOR=\"$inner_color\">";
			$table2 .= "<A HREF=\"$home_url?td=view_monitoring_page\" $mini_me_target><B>More...</B></A>";
			$table2 .= "</TD></TR>\n";
			last;
		}
		my @host_breakdown = split(/,-,/,$_);
		my $link = "$home_url?td=view_monitored_host&host_name=$host_breakdown[1]&service=" . &linkify($host_breakdown[3]);
		$table2 .= "<TR><TD ALIGN=right BGCOLOR=\"$inner_color\">";
		$table2 .= "$host_breakdown[1] - <A HREF=\"$link\" $mini_me_target>$host_breakdown[3]</A>";
		$table2 .= "</TD><TD ALIGN=center BGCOLOR=\"$inner_color\">";
#push (@man_down,"$current_group,-,$$hosts_ref[$i],-,$$ips_ref[$i],-,$_,$status");
		$table2 .= "<A HREF=\"$link\" $mini_me_target>$host_breakdown[4]</A>";
		$table2 .= "</TD></TR>\n";
	}
}
else{
	$table2 .= "<TR><TD ALIGN=left BGCOLOR=$inner_color>";
	$table2 .= "All monitored hosts</TD>";
	$table2 .= "<TD ALIGN=center BGCOLOR=$inner_color><A HREF=\"$home_url?td=view_monitoring_page\" $mini_me_target>";
	$table2 .= &color_code("GREEN");
	$table2 .= "</A></TD></TR>\n";
}

# MD5 minimum display

my @md5_min = &get_minimum_md5_alert_status;
$table2 .= "<TR><TD COLSPAN=2 ALIGN=center BGCOLOR=$title_color>";
$table2 .= "<B>Monitored Files</B></TD></TR>\n";
if (@md5_min){
	my $c2;
	foreach (@md5_min){
		if ($c2++ >= 4){
			$table2 .= "<TR><TD ALIGN=center COLSPAN=2 BGCOLOR=$inner_color><A HREF=\"$home_url?td=view_md5_page&minimal=1\" $mini_me_target>";
			$table2 .= "more...</A></TD></TR>";
			last;
		}
		my @split_a = split(/\;/,$_);
		$table2 .= "<TR><TD BGCOLOR=$inner_color>&nbsp;<A HREF=\"$home_url?td=view_md5_page&minimal=1\" $mini_me_target>";
		$table2 .= "$split_a[0]</a></TD>";
		$table2 .= "<TD ALIGN=center BGCOLOR=$inner_color><A HREF=\"$home_url?td=view_md5_page&minimal=1\" $mini_me_target>";
		$table2 .= "$split_a[1]</A></TD></TR>";
	}
}
else{
         $table2 .= "<TR><TD ALIGN=left BGCOLOR=$inner_color>All monitored files</TD>";
			$table2 .= "<TD ALIGN=center BGCOLOR=$inner_color><A HREF=\"$home_url?td=view_md5_page\" $mini_me_target>";
			$table2 .= &color_code("GREEN");
         $table2 .= "</A></TD></TR>";
}
		

###################################
# cacheable stats:
#=head
if (($current_page ne "mini_me") && $use_cache){
	($table,$cached_expire_seconds) = &recent_cached_copy('side_menu',$allowed_cache_minutes);
	if ($table){
		$cached_expire_seconds = ($allowed_cache_minutes * 60) - $cached_expire_seconds;
		$cached_expire_seconds = &format_seconds($cached_expire_seconds);
		my $trick_proxy = &rand_string(4);#so you don't get a cached version from your browser/proxy
		my $cache_message;
		$cache_message  .= "<TR><TD COLSPAN=2 ALIGN=center bgcolor=\"$title_color\">";
		$cache_message  .= "Stats below are cached<BR>and <A HREF=\"$home_url?no_cache=1&tp=$trick_proxy\">expire</A> in $cached_expire_seconds";
		$cache_message  .= "</TD></TR>\n";
		#$table2 =~s/Quick Stats\s*<\/B>/Quick Stats<\/B> $cache_message/;
		$table =~s/<MINI_CACHE_MESSAGE>/$cache_message/;
		$recent_alert = 1 if ($table=~/<RECENT_ALERT>/);
		$recent_alert = 2 if ($table=~/<RECENT_ALERT_WARN>/);
		return $table2 . $table;
	}
}
#=cut
$table .= "<MINI_CACHE_MESSAGE>";
$table .= &get_hourly_stats(target => $mini_me_target);


$table .= &get_sensor_stats(target => $mini_me_target);


# Title it:
$table .= "<TR><TD COLSPAN=2 ALIGN=center bgcolor=\"$title_color\"><B>Protocol Breakdown</B></TD></TR>\n";
# TCP first
$table .= "<TR><TD bgcolor=\"$inner_color\">&nbsp;";
$table .= "TCP  ";
$table .= "<A HREF=\"$home_url?td=show_events&tcp=tcp&limit=$default_limit\" $mini_me_target>";
$table .= "($tcp_percent%)</A></TD>";
$table .= "<TD bgcolor=\"$inner_color\">";
$table .= "<A HREF=\"$home_url?td=show_events&tcp=tcp&limit=$default_limit\" $mini_me_target>";
$table .= "<IMG SRC=\"$v_graphics_path/ln_graph.gif\" border=0 height=20 width=\"" . &round(($tcp_percent/100)*$max_width) . "\"><IMG SRC=\"$v_graphics_path/ln_graphcap.gif\" border=0 height=20 width=4></A></TD></TR>\n";

# UDP
$table .= "<TR><TD bgcolor=\"$inner_color\">&nbsp;";
$table .= "UDP  ";
$table .= "<A HREF=\"$home_url?td=show_events&udp=udp&limit=$default_limit\" $mini_me_target>";
$table .= "($udp_percent%)</A></TD>";
$table .= "<TD bgcolor=\"$inner_color\">";
$table .= "<A HREF=\"$home_url?td=show_events&udp=udp&limit=$default_limit\" $mini_me_target>";
$table .= "<IMG SRC=\"$v_graphics_path/ln_graph.gif\" height=20 border=0 width=\"" . &round(($udp_percent/100)*$max_width) . "\"><IMG SRC=\"$v_graphics_path/ln_graphcap.gif\" border=0 height=20 width=4></A></TD></TR>\n";

# ICMP
$table .= "<TR><TD bgcolor=\"$inner_color\">&nbsp;";
$table .= "ICMP  ";
$table .= "<A HREF=\"$home_url?td=show_events&icmp=icmp&limit=$default_limit\" $mini_me_target>";
$table .= "($icmp_percent%)</A></TD>";
$table .= "<TD bgcolor=\"$inner_color\">";
$table .= "<A HREF=\"$home_url?td=show_events&icmp=icmp&limit=$default_limit\" $mini_me_target>";
$table .= "<IMG SRC=\"$v_graphics_path/ln_graph.gif\" height=20 border=0 width=\"" . &round(($icmp_percent/100)*$max_width) . "\"><IMG SRC=\"$v_graphics_path/ln_graphcap.gif\" border=0 height=20 width=4></A></TD></TR>\n";

#################
# Porscans apearing here seem to have ended with Snort 1.7, if you want to see if there are
# any leftovers, uncomment this section
=head
# OTHER (portscans)
$table .= "<TR><TD bgcolor=\"$inner_color\">&nbsp;";
$table .= "SCANS  ";
$table .= "<A HREF=\"$home_url?td=show_events&other=other&limit=$default_limit\" $mini_me_target>";
$table .= "($other_percent%)</A></TD>";
$table .= "<TD bgcolor=\"$inner_color\">";
$table .= "<A HREF=\"$home_url?td=show_events&other=other&limit=$default_limit\" $mini_me_target>";
$table .= "<IMG SRC=\"$v_graphics_path/ln_graph.gif\" border=0 height=20 width=\"" . &round(($other_percent/100)*$max_width) . "\"><IMG SRC=\"$v_graphics_path/ln_graphcap.gif\" border=0 height=20 width=4></A></TD></TR>\n";
=cut


### Top offenders src_ip:
$sql_query =<< "EOF";
SELECT
     count(*) AS COUNT,ip_src,ip_dst
FROM
  iphdr
GROUP BY ip_src
ORDER BY COUNT DESC
LIMIT 6
EOF


$db_ptr 		= &run_query($sql_query);
$table .= "<TR bgcolor=\"$title_color\"><TD colspan=2 ALIGN=center>";
$table .= "<B>Top 6 Src IPs</B>";
$table .= "</TD></TR>\n";
my $src_ip_count = 0;
while ($hash_ref   = $db_ptr->fetchrow_hashref){
	$src_ip_count++;
	$table .= "<TR><TD bgcolor=\"$inner_color\">&nbsp;";
	my $src_ip = &convert_long_ip($$hash_ref{'ip_src'});
	$table .= "<A HREF=\"$home_url?td=show_events&limit=$default_limit&src_ip=$src_ip\" $mini_me_target>";
	$table .= "$src_ip</A></TD><TD align=center bgcolor=\"$inner_color\">($$hash_ref{'COUNT'})</TD></TR>\n";
}
$table .= "<TR><TD bgcolor=\"$inner_color\" align=center colspan=2>No Results</TD></TR>\n" if (!$src_ip_count);

### Top offenders dst_ip:
$sql_query =<< "EOF";
SELECT
     count(*) AS COUNT,ip_src,ip_dst
FROM
  iphdr
GROUP BY ip_dst
ORDER BY COUNT DESC
LIMIT 6
EOF

$db_ptr 		= &run_query($sql_query);
$table .= "<TR bgcolor=\"$title_color\"><TD colspan=2 ALIGN=center>";
$table .= "<B>Top 6 Dst IPs</B>";
$table .= "</TD></TR>\n";
my $src_ip_count = 0;
while ($hash_ref   = $db_ptr->fetchrow_hashref){
	$src_ip_count++;
	$table .= "<TR bgcolor=\"$inner_color\"><TD>&nbsp;";
	my $dst_ip = &convert_long_ip($$hash_ref{'ip_dst'});
	$table .= "<A HREF=\"$home_url?td=show_events&limit=$default_limit&dst_ip=$dst_ip\" $mini_me_target>";
	$table .= "$dst_ip</A></TD><TD align=center>($$hash_ref{'COUNT'})</TD></TR>\n";
}
$table .= "<TR><TD bgcolor=\"$inner_color\" align=center colspan=2>No Results</TD></TR>\n" if (!$src_ip_count);
=head
$table .= "<TR bgcolor=\"$title_color\"><TD COLSPAN=2 ALIGN=center><A HREF=\"$home_url\" target=\"big_poppa\" onClick=\"close_me();return false;\"  style=\"color:yellow\"><B>Main Screen</B></A></TD></TR>\n" if ($mini_me_target);
if ($current_page ne "mini_me"){
$table .= "<TR><TD bgcolor=\"$title_color\" align=center colspan=2>";
$table .= << "EOF";
<A HREF="$home_url?td=mini_me" target="MiniMe" onClick="load_mini_me();return false;" style="color:yellow;"><B>Miniview</B></A>
</TD></TR>
EOF
}
=cut

$table .= "</TABLE>\n";
$table .= "</TD></TR>\n</TABLE>\n";
$table .= "</TD></TR>\n</TABLE>\n";

if (($current_page ne "mini_me") && ($cache_disabled || $use_cache)){
	#update the cached version of the side menu if we're cacheing
	&update_cache('side_menu',$table);
}
return "$table2 $table";
}
#######################
sub round {
    my($number,$lt_rule) = @_;
	my $num = int($number + .5);
	return $num if ($num > 1);
	if ($lt_rule){
		return "<1";
	}
	return "0";
}
#######################
sub unique_events_since{
my ($offset_type,$offset_number,$limit_rows) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
my $cached_expire_seconds;
my $count;
my $inner_color = "#000000";

######
##check for a cached copy if allowed:
if ($use_cache && ($current_page eq "main")){
    ($table,$cached_expire_seconds) = &recent_cached_copy('unique_events_table',$allowed_long_cache_minutes);
}

if (!$use_cache || !$table){
# do it from scratch:

my %sid_hash = &get_sid_hash;

($offset_number=~/^\d+$/) || ($offset_number=1); #default offset if none passed
($offset_type=~/^day$|^hour$/) || ($offset_type="day"); #default type to day

$sql_query = "	SELECT \
						count(*) as COUNT,max(timestamp) as max,\ 
						min(timestamp) as min,event.sid,sig_name as signature \
					FROM event\
						LEFT JOIN signature \
							ON (event.signature = signature.sig_id) \
					WHERE \
						timestamp >= date_add(now(),interval -$offset_number $offset_type) \
					GROUP BY signature,sid \
					ORDER BY COUNT DESC";


$db_ptr = &run_query($sql_query);

$table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 WIDTH=\"100%\">\n";
$table .= "<TR bgcolor=\"$head_color\"><TD background=\"$v_graphics_path/bg_title.gif\" colspan=6 align=center>";
$table .= "<B>Unique Events in the past $offset_number $offset_type</B>";
$table .= "</TD></TR>\n";
$table .= "<TR bgcolor=\"$title_color\"><TD align=center><B>Freq</B></TD>";
$table .= "<TD align=center><B>Signature</B></TD>";
$table .= "<TD align=center><B>Graph</B></TD>";
$table .= "<TD align=center><B>Sensor</B></TD>";
$table .= "<TD align=center><B>First Event</B></TD>";
$table .= "<TD align=center><B>Last Event</B></TD>";
$table .= "</TR>\n";

while ($hash_ref = $db_ptr->fetchrow_hashref){
	$count++;
	if ($limit_rows && ($count >= $limit_rows)){
		last;
	}
	$table .= "<TR bgcolor=\"$desc_color\"><TD align=center>$$hash_ref{'COUNT'}</TD>";
	$table .= "<TD>&nbsp;";
	$table .= "<A HREF=\"$home_url?td=show_events&sid=$$hash_ref{'sid'}&limit=30&offset_type=$offset_type&offset_number=$offset_number&signature=" . &linkify($$hash_ref{'signature'}) . "\">";
	$table .= "$$hash_ref{'signature'}";
	$table .= "</A>";
	$table .= "</TD>";
	$table .= "<TD align=center nowrap>";

	$table .= "<A HREF=\"$home_url?td=show_events&sid=$$hash_ref{'sid'}&graph=1&signature_is=" . &linkify($$hash_ref{'signature'}) . "\">";
	$table .= "1d";
	$table .= "</A>";
	$table .= " <font color=$title_color><b>&middot;</b></font> ";
	$table .= "<A HREF=\"$home_url?td=show_events&sid=$$hash_ref{'sid'}&graph=7&signature_is=" . &linkify($$hash_ref{'signature'}) . "\">";
	$table .= "1w";
	$table .= "</A>";
	$table .= " <font color=$title_color><b>&middot;</b></font> ";
	$table .= "<A HREF=\"$home_url?td=show_events&sid=$$hash_ref{'sid'}&graph=28&signature_is=" . &linkify($$hash_ref{'signature'}) . "\">";
	$table .= "4w";
	$table .= "</A>";

	$table .= "</TD>";
	$table .= "<TD align=center>$sid_hash{$$hash_ref{'sid'}}</TD>";
	$$hash_ref{'min'}=~s/:\d\d$//;
	$$hash_ref{'min'}=~s/^\d{4}\-//;
	$$hash_ref{'min'}=~s/(\d\d\-\d\d) (\d\d:\d\d)/$2 $1/;
	$table .= "<TD align=center>$$hash_ref{'min'}</TD>";
	$$hash_ref{'max'}=~s/:\d\d$//;
	$$hash_ref{'max'}=~s/^\d{4}\-//;
	$$hash_ref{'max'}=~s/(\d\d\-\d\d) (\d\d:\d\d)/$2 $1/;
	$table .= "<TD align=center>$$hash_ref{'max'}</TD>";
	#$table .= "<TD align=center>$$hash_ref{''}</TD>";
	$table .= "</TR>\n";
}

if (!$count){
	$table .= "<TR bgcolor=\"$desc_color\"><TD align=center colspan=5>";
	$table .= "<B>No records returned</B></TD></TR>\n";
}
$table .= "<FORM ACTION=\"$home_url\" METHOD=POST>\n";
$table .= "<TR bgcolor=\"$desc_color\"><TD align=center colspan=6>";
$table .= "<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=\"100%\">";
$table .= "<TR bgcolor=\"$desc_color\">";
$table .= "<TD width=\"25%\"><CACHE_COW></TD>";#to sub out if we're caching
$table .= "<TD width=\"50%\" align=center><B>";
$table .= "Unique Events/sensor in the past:";
$table .= ($offset_number>1)? "s" : "";
$table .= "</B>";
$table .= << "EOF";
<INPUT TYPE=hidden NAME=td VALUE=unique_events_since>
<SELECT NAME=offset_number style="font-size:8pt;">
<OPTION SELECTED>$offset_number</OPTION>
<OPTION>1</OPTION>
<OPTION>2</OPTION>
<OPTION>3</OPTION>
<OPTION>4</OPTION>
<OPTION>5</OPTION>
<OPTION>6</OPTION>
<OPTION>7</OPTION>
<OPTION>8</OPTION>
<OPTION>9</OPTION>
<OPTION>10</OPTION>
<OPTION>11</OPTION>
<OPTION>12</OPTION>
<OPTION>13</OPTION>
<OPTION>14</OPTION>
<OPTION>15</OPTION>
<OPTION>16</OPTION>
<OPTION>17</OPTION>
<OPTION>18</OPTION>
<OPTION>19</OPTION>
<OPTION>20</OPTION>
<OPTION>21</OPTION>
<OPTION>22</OPTION>
<OPTION>23</OPTION>
<OPTION>24</OPTION>
</SELECT>
<SELECT NAME=offset_type  style="font-size:8pt;">
EOF
if ($offset_type=~/hour/){
   $table .= "<OPTION value=day>Days</OPTION>";
   $table .= "<OPTION value=hour selected>Hours</OPTION>";
}
else{
   $table .= "<OPTION value=day selected>Days</OPTION>";
   $table .= "<OPTION value=hour>Hours</OPTION>";
}
$table .= << "EOF";
</SELECT>
<INPUT TYPE=Submit Name=Submit Value=Go style="font-size:8pt">
EOF
$table .= "</TD>";
$table .= "<TD width=\"50%\" ALIGN=right>";
	if ($current_page eq "main"){
      $table .= "<A HREF=\"$home_url?td=unique_events_since&offset_type=day&offset_number=1\">";
      $table .= "<B>More...</B></A> &nbsp; &nbsp;";
	}
	else{
		$table .= "&nbsp;";
	}
$table .= "</TD></TR>\n";
$table .= "</FORM>";
$table .= "</TABLE>\n";
$table .= "</TD></TR>\n";
$table .= "<TR HEIGHT=2><TD BGCOLOR=\"$head_color\" COLSPAN=6><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>\n";
$table .= "</TABLE>\n";

# update the cache if we are using one
&update_cache('unique_events_table',$table) if (($cache_disabled || $use_cache) &&  ($current_page eq "main"));
}
else{
	#then we're using a cached copy, lets let the user in on this little time saving secret:
	$cached_expire_seconds = ($allowed_long_cache_minutes * 60) - $cached_expire_seconds;
	$cached_expire_seconds = &format_seconds($cached_expire_seconds);
	my $trick_proxy = &rand_string(4);#so you don't get a cached version from your browser/proxy
	my $cache_message = "&nbsp;Cached: <A HREF=\"$home_url?no_cache=1&tp=$trick_proxy\">expires</A> in $cached_expire_seconds";
	$table=~s/<CACHE_COW>/$cache_message/;
}


return $table;
}
#######################
sub linkify{
my ($st) = @_;
	$st=~s/\s/%20/g;
return $st;
}
######################
sub query_arin{
my ($host,$server) = @_;
my $result;
my $p;

#check that it only has acceptable dns characters or numbers and at least one "."
($server=~/^[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-\.]+$/)
	|| ($server="whois.arin.net");

	# show what we looked up
	$result .= "<CENTER><B>whois $host @ $server</B></CENTER><P>";

	#No exploit here thank you very much
	$host=~tr/a-zA-Z0-9\.\-\_//dc;

##########
# Check to see which syntax the whois command should take:
my $temp_result = `$whois_command 2>&1`;

if ($temp_result=~/-h host/i){
	#then this is a BSD type whois
	$result .= `$whois_command -h $server $host`;
}
else{
	#default to Linux style
	$result .= `$whois_command $host\@$server`;
}

	# Add links for further queries
	$result=~s/\(([a-zA-Z\_\-\.0-9]{4,}?)\)/<A HREF=\"$home_url\?td=arin_whois&whois_server=$server&ip=$1\">\($1\)<\/A>/g;
	# add mailto: tags
	$result=~s/\s(\S+?\@\S+?\.\w{2,4})\s/<A HREF="mailto:$1">$1<\/A>/g;
	$result=~s/\n/<BR>\n/g;

##################
# Get the whois select options:
my $noopen;
open (IN,$whois_select_form) || ($noopen=1);
if (!$noopen){
	$result .= "<FORM ACTION=\"$home_url\" METHOD=post>";
	$result .= "<TABLE BORDER=0 CELLPADDING=10>";
	$result .= "<TR><TD>";
	$result .= "<INPUT TYPE=text NAME=ip VALUE=\"$host\">";
	$result .= "<INPUT TYPE=hidden NAME=td VALUE=arin_whois>";
	$result .= "</TD><TD>";
	$result .= "<SELECT NAME=whois_server>";
	$result .= "<OPTION selected>$server</OPTION>";
	while (<IN>){
		$result .= $_;
	}
	$result .= "</SELECT>";
	$result .= "</TD><TD>";
	$result .= "<INPUT TYPE=Submit VALUE=Whois style=\"font-size:8pt\">";
	$result .= "</TD></TR>";
	$result .= "</TABLE>";
	$result .= "</FORM>";
}


push (@substitutions,"\\[MAIN_TABLE\\],-,$result");
&print_main_with_key($main_template);
	
}
##############
sub get_hourly_stats{
# Get stats for the last 6 hours
my (%args) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my %hours_hash;
my %yesterday_hours_hash;
my $current_hour;
my @last_6_hours;
my $yesterday;
my $max_height=30;
my $max_value;
my $row1;
my $row2;
my $table;
my $title_color = $minititle_color;
my $inner_color = $minidesc_color;

$sql_query = "	SELECT \
						count(*) AS COUNT,\
						EXTRACT(HOUR FROM timestamp) AS HOURS, \
						EXTRACT(HOUR FROM NOW()) AS NOW \
					FROM \
						event \
					WHERE \
						TO_DAYS(timestamp) = TO_DAYS(NOW()) \
					GROUP BY  \
						HOURS";

$db_ptr = &run_query($sql_query);
while ($hash_ref = $db_ptr->fetchrow_hashref){
	$hours_hash{$$hash_ref{'HOURS'}} = $$hash_ref{'COUNT'};
	$current_hour = $$hash_ref{'NOW'} if (!$current_hour);
}
if ($current_hour <= 6){
$sql_query = " SELECT \
                  count(*) AS COUNT,\
                  EXTRACT(HOUR FROM timestamp) AS HOURS \
               FROM \
                  event \
               WHERE \
                  TO_DAYS(timestamp) = TO_DAYS(DATE_ADD(NOW(), INTERVAL -1 DAY)) \
               GROUP BY  \
                  HOURS";	
$db_ptr = &run_query($sql_query);
while ($hash_ref = $db_ptr->fetchrow_hashref){
   $yesterday_hours_hash{$$hash_ref{'HOURS'}} = $$hash_ref{'COUNT'};
}
}

for (1..6){
	push (@last_6_hours,"$current_hour");
	$current_hour--;
	$current_hour = 23 if ($current_hour < 0);
}


# Do a run through just to get the max value:
for (my $i=0;$i<(@last_6_hours);$i++){
   if ((!$yesterday) && ($i>0) && ($last_6_hours[$i] > $last_6_hours[($i - 1)])){
      $yesterday = 1;
   }
   if (!$yesterday){
		$max_value = $hours_hash{$last_6_hours[$i]} if ($hours_hash{$last_6_hours[$i]} > $max_value);
   }
   else{
		$max_value = $yesterday_hours_hash{$last_6_hours[$i]} if ($yesterday_hours_hash{$last_6_hours[$i]} > $max_value);
   }

}


$yesterday = ();#Reset for the "real deal"


for (my $i=0;$i<(@last_6_hours);$i++){
	if ((!$yesterday) && ($i>0) && ($last_6_hours[$i] > $last_6_hours[($i - 1)])){
		$yesterday = 1;
	}
# Get date info from DB call to avoid problems at start of mon/day/yr:
$sql_query = "	SELECT \
						EXTRACT(MONTH FROM DATE_ADD(NOW(), INTERVAL -$i HOUR)) AS MONTH, \
						EXTRACT(DAY FROM DATE_ADD(NOW(), INTERVAL -$i HOUR)) AS DAY, \
						EXTRACT(YEAR FROM DATE_ADD(NOW(), INTERVAL -$i HOUR)) AS YEAR, \
						EXTRACT(MONTH FROM DATE_ADD(NOW(), INTERVAL (-$i+1) HOUR)) AS MONTH_F, \
						EXTRACT(DAY FROM DATE_ADD(NOW(), INTERVAL (-$i+1) HOUR)) AS DAY_F, \
						EXTRACT(YEAR FROM DATE_ADD(NOW(), INTERVAL (-$i+1) HOUR)) AS YEAR_F \

";
$db_ptr = &run_query($sql_query);
($hash_ref = $db_ptr->fetchrow_hashref) || &error("Error retrieving date information");
my $year 	= $$hash_ref{'YEAR'};
my $month	= $$hash_ref{'MONTH'};
my $day		= $$hash_ref{'DAY'};
my $hour		= $last_6_hours[$i];
my $year_f 	= $$hash_ref{'YEAR_F'};
my $month_f	= $$hash_ref{'MONTH_F'};
my $day_f	= $$hash_ref{'DAY_F'};
my $hour_f	= ($last_6_hours[$i]+1);
$hour_f = 0 if ($hour_f == 24);


	if (!$yesterday){
		my $row1_temp;
		my $temp_link = "<A HREF=\"$home_url?td=show_events&limit=30&yr_s=$year&mon_s=$month&day_s=$day&hr_s=$hour&yr_f=$year_f&mon_f=$month_f&day_f=$day_f&hr_f=$hour_f\" $args{'target'} >";
		$row1_temp .= "<TD valign=bottom align=left bgcolor=\"$inner_color\" WIDTH=40 NOWRAP>";

		$row1_temp .= $temp_link;
		$row1_temp .= "<IMG SRC=\"$v_graphics_path/ln_graph.gif\" border=0 height=20 width=\"";
		$row1_temp .= (($max_value) && ($hours_hash{$last_6_hours[$i]})) ? 
				&round( ($hours_hash{$last_6_hours[$i]}/$max_value) * $max_height) : "1";
		$row1_temp .= "\">";
		$row1_temp .= "<IMG SRC=\"$v_graphics_path/ln_graphcap.gif\" border=0 width=4 height=20>";
#		$hours_hash{$last_6_hours[$i]}=~s/(^\d+)(\d)\d\d$/$1\.$2k/;
		$row1_temp .= "</A></TD>";

		my $hour = $last_6_hours[$i];
		#$hour = ($hour > 12) ? ($hour-12) . " PM" : "$hour AM";
		if ($hour==0){
				$hour = "12 AM";
		}
		elsif($hour < 12){
				if ($hour < 10){
					$hour = "&nbsp;$hour AM";
				}
				else{
					$hour = "$hour AM";
				}
		}
		elsif($hour == 12){
				$hour = "12 PM";
		}
		else{
				if ($hour < 22){
					$hour = "&nbsp;".($hour-12)." PM";
				}
				else{
					$hour = ($hour-12) . " PM";
				}
		}

		$row1 .= "<TR><TD bgcolor=\"$inner_color\">$hour ". $temp_link ;
		$row1 .= ($hours_hash{$last_6_hours[$i]})? "($hours_hash{$last_6_hours[$i]})" : "(0)";
		$row1 .= "</A></TD>$row1_temp</TR>\n";
		
	}
	else{
		my $row1_temp;
		my $temp_link = "<A HREF=\"$home_url?td=show_events&limit=30&yr_s=$year&mon_s=$month&day_s=$day&hr_s=$hour&yr_f=$year_f&mon_f=$month_f&day_f=$day_f&hr_f=$hour_f\" $args{'target'} >";
		$row1_temp .= "<TD align=left valign=bottom bgcolor=\"$inner_color\" WIDTH=40 NOWRAP>";
		$row1_temp .= $temp_link;
		$row1_temp .= "<IMG SRC=\"$v_graphics_path/ln_graph.gif\" border=0 height=20 width=\"";
		$row1_temp .= (($max_value) && ($yesterday_hours_hash{$last_6_hours[$i]})) ? 
				&round( ($yesterday_hours_hash{$last_6_hours[$i]}/$max_value) * $max_height) : "1";
      $row1_temp .= "\">";
		$row1_temp .= "<IMG SRC=\"$v_graphics_path/ln_graphcap.gif\" border=0 width=4 height=20>";
#		$yesterday_hours_hash{$last_6_hours[$i]}=~s/(^\d+)(\d)\d\d$/$1\.$2k/;
      $row1_temp .= "</A></TD>";

		my $hour = $last_6_hours[$i];
		if ($hour==0){
				$hour = "12 AM";
		}
		elsif($hour < 12){
				if ($hour < 10){
					$hour = "&nbsp;$hour AM";
				}
				else{
					$hour = "$hour AM";
				}
		}
		elsif($hour == 12){
				$hour = "12 PM";
		}
		else{
				if ($hour < 22){
					$hour = "&nbsp;".($hour-12)." PM";
				}
				else{
					$hour = ($hour-12) . " PM";
				}
		}
		$row1 .= "<TR><TD  bgcolor=\"$inner_color\" ALIGN=left>$hour ". $temp_link ;
      $row1 .= ($yesterday_hours_hash{$last_6_hours[$i]})? "($yesterday_hours_hash{$last_6_hours[$i]})" : "(0)";
		$row1 .= "</A></TD>$row1_temp</TR>\n";
	}

}
$table .= "<TR><TD colspan=2 align=center bgcolor=\"$title_color\"><B>Alerts (Last 6 Hrs)</B></TD></TR>";
$table .= $row1;
return $table;
}
##############
sub get_sensor_stats{
# Get stats for alert %/sensor
my (%args) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $max_height=30;
my $max_value;
my $total_value;
my $table;
my %host_values;

my %sid_hash = &get_sid_hash;

$sql_query = "	SELECT COUNT(*) AS COUNT,event.sid \
					FROM event \
					GROUP BY event.sid \
					ORDER BY COUNT";
#&debug($sql_query);
$db_ptr = &run_query($sql_query);
while ($hash_ref = $db_ptr->fetchrow_hashref){
   $host_values{$$hash_ref{'sid'} ." - ". $sid_hash{$$hash_ref{'sid'}}} = $$hash_ref{'COUNT'};
   $total_value +=  $$hash_ref{'COUNT'};
}


# Do a run through just to get the max value:
foreach (keys %host_values){
	$max_value = $host_values{$_} if ($host_values{$_} > $max_value);
}

# Now create the table (rows) for mini-view

foreach (sort(keys %host_values)){
	$table .= "<TR><TD align=left bgcolor=\"$minidesc_color\" WIDTH=40 NOWRAP>&nbsp;";
	$_=~/^(\d+)\s+\-\s+(.*)$/;
	my $sid 	= $1;
	my $host	= $2;
	$table .= "$host";
	$table .= "&nbsp;<A HREF=\"$home_url?td=show_events&limit=60&sid=$sid\" $args{'target'} >(";
	$table .= (($total_value) && ($host_values{$_}))
            ? &round( (($host_values{$_}/$total_value) * 100),"lt1") 
            : "0";
	$table .= "%)</A>";
	$table .= "</TD>";
	$table .= "<TD align=left valign=bottom bgcolor=\"$minidesc_color\">";
	$table .= "<A HREF=\"$home_url?td=show_events&limit=60&sid=$sid\" $args{'target'} >";
	$table .= "<IMG SRC=\"$v_graphics_path/ln_graph.gif\" border=0 height=20 width=\"";
	$table .= (($max_value) && ($host_values{$_}))
				? &round( ($host_values{$_}/$max_value) * $max_height)
				: 1;
	$table .= "\">";
	$table .= "<IMG SRC=\"$v_graphics_path/ln_graphcap.gif\" border=0 width=4 height=20>";
	$table .= "</A></TD></TR>";

}
$table = "<TR><TD colspan=2 align=center bgcolor=\"$minititle_color\"><B>% Alerts/Sensor</B></TD></TR>" . $table;
return $table;
}
################
sub print_search{

	my $table = &get_search_form;
	my $sid_list = &get_sids_dropdown("sid");
	$table=~s/\[SID_LIST\]/$sid_list/;
	my $signatures_list = &get_signatures_dropdown("signature_is");
	$table=~s/\[SIGNATURE_LIST\]/$signatures_list/;

	push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
	&print_main_with_key($main_template);

}
#################
sub get_total_events_count{
my $sql_query;
my $db_ptr;
my $hash_ref;

$sql_query = "SELECT count(*) AS COUNT FROM event";
$db_ptr = &run_query($sql_query);
return ($hash_ref = $db_ptr->fetchrow_hashref)? $$hash_ref{'COUNT'} : "0";
}
#################
sub get_unique_events_count{
my $sql_query;
my $db_ptr;
my $hash_ref;
my $unique_count;
my $cached_expire_seconds;

#if ($use_cache){
#	($unique_count,$cached_expire_seconds) = &recent_cached_copy('unique_events',$allowed_cache_minutes);
#}
#if (!$use_cache || !$unique_count){
	$sql_query = "SELECT count(distinct signature) AS COUNT FROM event";
	$db_ptr = &run_query($sql_query);
	($hash_ref = $db_ptr->fetchrow_hashref) || return;
	$unique_count = $$hash_ref{'COUNT'};
#}
#&update_cache('unique_events',$unique_count) if ($use_cache || $cache_disabled);
return $unique_count;
}
#################
sub get_delete_table{
my ($args_ref) = @_;
my $table;

(&is_admin("f1")) || return;

$table .= "<FORM METHOD=POST ACTION=\"$home_url\">";
$table .= "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH=\"100%\">\n<TR><TD ALIGN=center>";
$table .= "<INPUT TYPE=hidden NAME=td VALUE=delete>";
foreach (keys %$args_ref){
	$table .= "<INPUT TYPE=hidden NAME='$_' VALUE='$$args_ref{$_}'>\n";
}
$table .= << "EOF";
<SELECT NAME=delete_type>
<OPTION VALUE=0>-Select Action-</OPTION>
<OPTION VALUE=limit>Delete only this page from this query</OPTION>
<OPTION VALUE=all>Delete all the results from this query</OPTION>
</SELECT>
<INPUT TYPE=Submit VALUE=Go style="font-size:8pt">
<p>
EOF

$table .= "</TD></TR>\n</TABLE>\n</FORM>\n";

return $table;
}
##################
sub delete_events{
my ($delete_array_ref) = @_;
my $sql_query;
my $db_ptr;

#my $counted = @$delete_array_ref;
#&debug("Would have deleted $counted records!");
#return 1;

my @tables_array = ('data','event','icmphdr','tcphdr','udphdr','iphdr','opt');

# a lot more efficient:
# delete in groups of up to 50 deletes per sql statement
my $dcount = 0;
my @where_array;

foreach (@$delete_array_ref){
	$dcount++;
    my @temp_array = split(/,/,$_);
	push (@where_array," (sid='$temp_array[0]' AND cid='$temp_array[1]') ");
	
	#only execute if we've passed the threshhold
	if ($dcount >= 50){	
		my $where_statement;
		foreach (@where_array){
			$where_statement .= " OR " if ($where_statement);
			$where_statement .= $_;
		}
    	foreach (@tables_array){
    	    $sql_query = "DELETE FROM $_ WHERE $where_statement";
    	    $db_ptr = &run_query($sql_query);
#&debug("DELETE : $sql_query");
#last;
    	}
		$dcount = 0;
		@where_array = ();
	}
}
#check for leftovers  (didn't hit threshhold)
if ($dcount){
   my $where_statement;
        foreach (@where_array){
            $where_statement .= " OR " if ($where_statement);
            $where_statement .= $_;
        }
        foreach (@tables_array){
            $sql_query = "DELETE FROM $_ WHERE $where_statement";
            $db_ptr = &run_query($sql_query);
#&debug("LEFT OVER : $sql_query");
#last;
        }
}

# now optimize tables:
    foreach (@tables_array){
       $sql_query = "OPTIMIZE TABLE $_";
            $db->do($sql_query);
    }

return 1;
}
###############
sub push_message{
my ($message) = @_;
	push (@messages,$message);
}
###########################
sub print_config{

my $table;

$table .= << "EOF";
<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 align=center>
<TR bgcolor="$head_color">
<TD ALIGN=center COLSPAN=2 background="$v_graphics_path/bg_title.gif"><B>Configuration Menu</B></TD>
</TR>

<TR bgcolor="$title_color">
<TD ALIGN=center COLSPAN=2>Monitor Configuration</TD>
</TR>

<TR bgcolor="$desc_color">
<TD><br>&nbsp;<A HREF="$home_url?td=config_sid_menu"><b>Configure Sensor's Snort Rules</b></A>&nbsp;<br><br></TD>
<TD WIDTH=300>Remotely configure Snort conf and rules</TD>
</TR>
<TR bgcolor="$desc_color">
<TD><br>&nbsp;<A HREF="$home_url?td=add_monitoring_event"><b>Add Host/Service Monitoring Event</b></A>&nbsp;<br><br></TD>
<TD>Add services/hosts for DEMARC to monitor</TD>
</TR>
<TR bgcolor="$desc_color">
<TD><br>&nbsp;<A HREF="$home_url?td=md5_config_select"><b>Configure Integrity Checks</b></A>&nbsp;<br><br></TD>
<TD>Configure File Integrity Checks and Web Integrity Checks on a per sensor basis</TD>
</TR>

<TR bgcolor="$title_color">
<TD ALIGN=center COLSPAN=2>Alert Configuration</TD>
</TR>

<TR bgcolor="$desc_color">
<TD><br>&nbsp;<A HREF="$home_url?td=config_service_monitor"><b>Configure Host/Service Alerts</b></A>&nbsp;<br><br></TD>
<TD>Define alert rules for changes in monitored host/service status</TD>
</TR>
<TR bgcolor="$desc_color">
<TD><br>&nbsp;<A HREF="$home_url?td=config_ids_monitor"><b>Configure IDS Alerts</b></A>&nbsp;<br><br></TD>
<TD>Define alert rules for IDS alerts from Snort</TD>
</TR>
<TR bgcolor="$desc_color">
<TD><br>&nbsp;<A HREF="$home_url?td=config_md5_monitor"><b>Configure Integrity Check Alerts</b></A>&nbsp;<br><br></TD>
<TD>Define alert rules for File Integrity Check and Web Integrity Check discrepancies
</TD>
</TR>

<TR bgcolor="$title_color">
<TD ALIGN=center COLSPAN=2>System Configuration</TD>
</TR>

<TR bgcolor="$desc_color">
<TD><br>&nbsp;<A HREF="$home_url?td=user_config"><b>Configure Users</b></A>&nbsp;<br><br></TD>
<TD>Configuration of DEMARC users and administrators</TD>
</TR>
<TR bgcolor="$desc_color">
<TD><br>&nbsp<A HREF="$home_url?td=age_data"><b>Expire Old Data</b></A>&nbsp;<br><br></TD>
<TD>Select old IDS/Monitoring data to delete and speed up database access</TD>
</TR>
<TR bgcolor="$desc_color">
<TD><br>&nbsp<A HREF="$home_url?td=view_log_entries&tail=1000"><b>View Last 1000 Log Entries</b></A>&nbsp;<br><br></TD>
<TD>View last 1000 log entries from the master log</TD>
</TR>
<TR HEIGHT=2 BGCOLOR="$head_color"><TD COLSPAN=2><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>
</TABLE>
EOF

=head
<TR bgcolor="$desc_color">
<TD><br>&nbsp;<A HREF="$home_url?td=general_config"><b>General Configuration Options</b></A>&nbsp;<p></TD>
<TD>View/modify general configuration options for the system.</TD>
</TR>
=cut

push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
###########################
sub print_config_user_level{

my $table;

$table .= << "EOF";
<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=0 ALIGN=center>
<TR><TD BGCOLOR="#000000">
<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=11>
<TR bgcolor="$head_color"><TD ALIGN=center COLSPAN=2 background="$v_graphics_path/bg_title.gif">
	<B>Configuration Menu</B>
</TD></TR>
<TR bgcolor="$desc_color">
<TD><A HREF="$home_url?td=user_level_config">Update User Settings</A></TD>
<TD>Configuration of DEMARC user profile</TD>
</TR>
<TR bgcolor="$desc_color">
<TD><A HREF="$home_url?td=config_service_monitor">Configure Host/Service Alerts</A></TD>
<TD>Define alert rules for changes in monitored host/service status</TD>
</TR>
<TR bgcolor="$desc_color">
<TD><A HREF="$home_url?td=config_ids_monitor">Configure IDS Alerts</A></TD>
<TD>Define alert rules for IDS alerts from Snort</TD>
</TR>
<TR bgcolor="$desc_color">
<TD><A HREF="$home_url?td=config_md5_monitor">Configure Integrity Check Alerts</A></TD>
<TD>Define alert rules for File Integrity Check and Web Integrity Check discrepancies</TD>
</TR>
</TABLE>
</TD></TR>
</TABLE>
EOF




push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
#########################
sub print_config_sid_menu{
my $table;

#	$table .= &get_sid_select_table;
	$table .= "<CENTER>Please click on the sensor you would like to configure</CENTER>";
	$table .= &get_sid_info_table;
push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
###########################
sub print_config_rules{
my ($sid) = @_;
($sid=~/^\d+$/) || &error("Invalid SID:$sid");

my $table;

$table .= &get_sid_select_table($sid);
$table .= "<BR>";
$table .= &get_sid_info_table($sid);

$table .= &get_rules_select_table($sid);

push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
###########################
sub config_rules{
my ($sid,$rules_name) = @_;
($sid=~/^\d+$/) || &error("Invalid SID:$sid");
&safe_slash(\$rules_name);

my $table;

$table .= &get_sid_select_table($sid);
$table .= &get_rules_select_table($sid,$rules_name);
$table .= &print_edit_rules($sid,$rules_name);

push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
###########################
sub do_config_rules{
my ($sid,$rules_type,$rules_text,$new_ruleset_name,$action) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;

($sid=~/^\d+$/) || &error("Invalid SID : $sid");
&safe_slash(\$rules_type);
&safe_slash(\$rules_text);
&safe_slash(\$new_ruleset_name) if ($new_ruleset_name);

if($action=~/^change_priority_to/){
	if ($rules_type eq "snort.conf"){
		&error("You may not change priorities in snort.conf.");
	}
	$action=~/^change_priority_to_(\d+$)/ || &error("Invalid Priority to change to: $action");
	my $new_priority = $1;
	#first take off all old priorities
	$rules_text=~s/msg:\s*\"P\-\d\-/msg: \"/g;
	#Now add new priorities:
	$rules_text=~s/msg:\s*\"/msg: \"P\-$new_priority\-/g;
	# then allow it to flow through the rules and it will write
	# the update at the end:
	&push_message("<FONT COLOR=red>Priorities updated to P-$new_priority</FONT>");
}
elsif($action=~/^remove_priorities/){
	if ($rules_type eq "snort.conf"){
		&error("You may not change priorities in snort.conf.");
	}
	#take off all old priorities
   $rules_text=~s/msg:\s*\"P\-\d\-/msg: \"/g;
   # then allow it to flow through the rules and it will write
   # the update at the end:
	&push_message("<FONT COLOR=red>All priorities have been removed</FONT>");
}
elsif($action=~/^copy_snort_conf_to_new_sid/){
	my $last_sid = &get_last_sid();
	$last_sid++;
	#First check to see if we already have one for this sensor:
   $sql_query = "SELECT snort_conf FROM dm_conf WHERE sid='$sid'";
   $db_ptr = &run_query($sql_query);
   if ($hash_ref=$db_ptr->fetchrow_hashref){
		&safe_slash(\$$hash_ref{'snort_conf'});
      #then we can copy it to the new sid:
      $sql_query = "INSERT INTO dm_conf VALUES ('$last_sid',NOW(),'','$$hash_ref{'snort_conf'}')";
   }
   else{
		&error("There is no snort.conf file for sensor $sid.");
   }
   $db_ptr = &run_query($sql_query);
   &touch_rules_update_time($last_sid);
}
elsif($action=~/^delete_all_rules/){
	$sql_query = "DELETE FROM dm_rules WHERE sid='$sid'";
	$db_ptr = &run_query($sql_query);
	&touch_rules_update_time($sid);
	&push_message("<FONT COLOR=red>All rules have been removed for this sensor.</FONT>");
	&config_rules($sid);
	&safe_exit;
}
elsif ($rules_type eq "new"){
	&error("You must specify a name for the new ruleset.") if (!$new_ruleset_name);
	&error("You may not enter a blank new ruleset.") if (!$rules_text);
	$sql_query = "SELECT rules_type FROM dm_rules WHERE rules_type = '$rules_type' AND sid='$sid'";
	$db_ptr = &run_query($sql_query);
	&error("Ruleset with same name already exists for this sensor.") if ($hash_ref=$db_ptr->fetchrow_hashref);
	# OK, its unique, so lets insert it
	$sql_query = "INSERT INTO dm_rules VALUES('$sid','$new_ruleset_name','$rules_text')";
	$db_ptr = &run_query($sql_query);
	&touch_rules_update_time($sid);
}
elsif($action=~/^copy_to/){
	if ($rules_type eq "snort.conf"){
		&error("You may not copy snort.conf over to another sensor because manual editing of the file is most likely required.");
	}
	$action=~/^copy_to_(\d+$)/ || &error("Invalid SID to copy to: $action");
	my $copy_to_sid = $1;
	#make sure sensor exists:
	$sql_query = "SELECT sid FROM sensor WHERE sid = '$copy_to_sid'";
	$db_ptr = &run_query($sql_query);
	if (!($hash_ref=$db_ptr->fetchrow_hashref)){
		# check if its a new sensor that isn't online yet
		$sql_query = "SELECT sid FROM dm_conf WHERE sid = '$copy_to_sid'";
		$db_ptr = &run_query($sql_query);
		&error("Sensor $copy_to_sid doesn't exist.") if (!($hash_ref=$db_ptr->fetchrow_hashref));
	}
	#make sure that sensor doesn't already have a ruleset by that name:
   $sql_query = "SELECT rules_type FROM dm_rules WHERE rules_type = '$rules_type' AND sid='$copy_to_sid'";
   $db_ptr = &run_query($sql_query);
   &error("Ruleset with that name already exists for that sensor.") if ($hash_ref=$db_ptr->fetchrow_hashref);
	#ok, we should be safe, lets insert it
	$sql_query = "INSERT INTO dm_rules VALUES('$copy_to_sid','$rules_type','$rules_text')";
	$db_ptr = &run_query($sql_query);
	&touch_rules_update_time($copy_to_sid);
}
elsif($action=~/^copy_all_to/){
	my $db_ptr_2;
	my $hash_ref_2;
	if ($rules_type eq "snort.conf"){
		&error("You may not copy snort.conf over to another sensor because manual editing of the file is most likely required.");
	}
	$action=~/^copy_all_to_(\d+$)/ || &error("Invalid SID to copy to: $action");
	my $copy_to_sid = $1;
	#make sure sensor exists:
	$sql_query = "SELECT sid FROM sensor WHERE sid = '$copy_to_sid'";
	$db_ptr = &run_query($sql_query);
	if (!($hash_ref=$db_ptr->fetchrow_hashref)){
		# check if its a new sensor that isn't online yet
		$sql_query = "SELECT sid FROM dm_conf WHERE sid = '$copy_to_sid'";
		$db_ptr = &run_query($sql_query);
		&error("Sensor $copy_to_sid doesn't exist.") if (!($hash_ref=$db_ptr->fetchrow_hashref));
	}

	# get list of all the rulesets to copy:
	$sql_query = "SELECT rules_type,snort_rules FROM dm_rules WHERE sid = '$sid'";
	$db_ptr = &run_query($sql_query);
	while ($hash_ref=$db_ptr->fetchrow_hashref){
		#make sure that sensor doesn't already have a ruleset by that name:
   	$sql_query = "SELECT rules_type FROM dm_rules WHERE rules_type = '$$hash_ref{'rules_type'}' AND sid='$copy_to_sid'";
   	$db_ptr_2 = &run_query($sql_query);
   	#next if ($hash_ref_2=$db_ptr_2->fetchrow_hashref);
   	if ($hash_ref_2=$db_ptr_2->fetchrow_hashref){
		&push_message("Ruleset named \"$$hash_ref{'rules_type'}\" already exists on that sensor... skipping.");
		next;
	}
		# lets slash it:
		&safe_slash(\$$hash_ref{'rules_type'});
		&safe_slash(\$$hash_ref{'snort_rules'});
		#ok, we should be safe, lets insert it
		$sql_query = "INSERT INTO dm_rules VALUES('$copy_to_sid','$$hash_ref{'rules_type'}','$$hash_ref{'snort_rules'}')";
		$db_ptr_2 = &run_query($sql_query);
	}
	&touch_rules_update_time($copy_to_sid);
}
elsif($rules_type eq "snort.conf"){
	#First check to see if we already have one for this sensor:
	$sql_query = "SELECT snort_conf FROM dm_conf WHERE sid='$sid'";
   $db_ptr = &run_query($sql_query);
	if ($hash_ref=$db_ptr->fetchrow_hashref){
		#then we're just updating:
		$sql_query = "UPDATE dm_conf SET snort_conf = '$rules_text', last_updated = NOW() WHERE sid='$sid'";
	}
	else{
		# then its a new record for this sid
		$sql_query = "INSERT INTO dm_conf VALUES ('$sid',NOW(),'','$rules_text')";
	}
	$db_ptr = &run_query($sql_query);
	&touch_rules_update_time($sid);
}
else{
	$sql_query = "SELECT rules_type FROM dm_rules WHERE rules_type = '$rules_type' AND sid='$sid'";
   $db_ptr = &run_query($sql_query);
   &error("Ruleset with that name doesn't exist for this sensor.") if (!($hash_ref=$db_ptr->fetchrow_hashref));
	# check if we're supposed to delete this ruleset:
	if ($action eq "delete"){
		$sql_query = "DELETE FROM dm_rules WHERE sid = '$sid' AND rules_type = '$rules_type'";
   	$db_ptr = &run_query($sql_query);
		&touch_rules_update_time($sid);
		&push_message("<FONT COLOR=red><CENTER>Ruleset Deleted.</CENTER></FONT>");
		&config_rules($sid);
		return;
	}
	$sql_query = "UPDATE dm_rules SET snort_rules = '$rules_text' WHERE sid='$sid' AND rules_type = '$rules_type'";
   $db_ptr = &run_query($sql_query);
	&touch_rules_update_time($sid);
}

&push_message("<FONT COLOR=red><CENTER>Rules Updated.</CENTER></FONT>");
&config_rules($sid,$rules_type);
}
###########################
sub print_config_sid{
my ($sid,$configtype) = @_;
my $table;

&error("Invalid SID : $sid") if ($sid!~/^\d+$/);
&error("Invalid configure type: $configtype") if ($configtype!~/^snort\.conf$|^rules$/);
$table .= &get_sid_select_table($sid);
$table .= "<FORM ACTION=\"$home_url\" METHOD=post><INPUT TYPE=hidden NAME=td VALUE=\"do_config_sid\">";
$table .= "<INPUT TYPE=hidden NAME=sid VALUE=\"$sid\">";
$table .= "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=2>";
if ($configtype eq "snort.conf"){
	$table .= "<TR><TD ALIGN=center><B>snort.conf file for SID # $sid</B></TD></TR>\n";
	$table .= "<TR><TD><TEXTAREA NAME=\"snort.conf\" rows=20 cols=70>";
	$table .= &get_snort_conf($sid);
	$table .= "</TEXTAREA>";

}
elsif ($configtype eq "rules"){
	$table .= "<TR><TD ALIGN=center><B>IDS rules file for SID # $sid</B></TD></TR>\n";
	$table .= "<TR><TD><TEXTAREA NAME=\"rules\" rows=20 cols=70>";
	$table .= &get_snort_rules($sid);
	$table .= "</TEXTAREA>";

}
$table .= "</TD></TR>\n";
$table .= "<TR><TD ALIGN=center>";
$table .= "<INPUT TYPE=Submit VALUE=Update style=\"font-size:8pt\">";
$table .= "</TD></TR>\n</TABLE>\n";
push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
############################
sub get_sid_select_table{
my ($sid,$td) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
my $hostname;
my $where_rules;

$td = "config_sid" if (!$td);

$table  = "<FORM ACTION=\"$home_url\" METHOD=post>";
$table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 align=center>";
$table .= "<TD><B>Sensor to configure:</B></TD>";
$table .= "<TD><INPUT TYPE=hidden NAME=td VALUE=\"$td\"><SELECT NAME=sid>";

$sql_query = "SELECT sid,hostname FROM sensor";
$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
	$where_rules .= " sid != '$$hash_ref{'sid'}' AND";
	if ($sid && ($sid == $$hash_ref{'sid'})){
		$table .= "<OPTION VALUE=$$hash_ref{'sid'} SELECTED>$$hash_ref{'sid'} - $$hash_ref{'hostname'}</OPTION>";
		$hostname = $$hash_ref{'hostname'};
	}
	else{
		$table .= "<OPTION VALUE=$$hash_ref{'sid'}>$$hash_ref{'sid'} - $$hash_ref{'hostname'}</OPTION>";
	}
#	$table .= "$$hash_ref{'sid'}<BR>";
}
$where_rules =~s/AND$//;
$sql_query = " SELECT sid FROM dm_conf WHERE $where_rules";
$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
   $table .= "<OPTION VALUE=$$hash_ref{'sid'}>$$hash_ref{'sid'} - [NOT_CHECKED_IN_YET]</OPTION>";
}




$table .= "</SELECT>";
# Add last updated data if there's a sid:
$table .= "</TD>";
$table .= "<TD><INPUT TYPE=Submit VALUE=Change style=\"font-size:8pt\"></TD>";

$table .= "</TR>\n";

=head
if ($sid=~/^\d+$/){
	$sql_query = "	SELECT \
						last_updated,last_implemented,\
(UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(last_implemented)) AS DIFF \
						FROM dm_conf \
						WHERE sid = '$sid'";
	$db_ptr = &run_query($sql_query);
	if ($hash_ref=$db_ptr->fetchrow_hashref){
		my $ago;
		if ($$hash_ref{'DIFF'}<60){
			$ago = "$$hash_ref{'DIFF'} seconds ago";
		}
		elsif ($$hash_ref{'DIFF'}<(60*60)){
         $ago = sprintf ("%.2f minutes ago", ($$hash_ref{'DIFF'}/60));
      }
		elsif ($$hash_ref{'DIFF'}<(60*60*24)){
         $ago = sprintf ("%.2f hours ago", (($$hash_ref{'DIFF'}/60)/60));
      }
		else{
         $ago = sprintf ("%.2f days ago",( (($$hash_ref{'DIFF'}/60)/60)/24));
		}

		$table .= "<TR><TD COLSPAN=4>";
		$table .= "Host $hostname (SID $sid) was last updated with current conf/rulesets $ago<BR>";
		$table .= "Rules for this host were last modified $$hash_ref{'last_updated'}";
		$table .= "</TD></TR>\n";
	}
}
=cut

$table .= "</TABLE></FORM>";
return $table;
}
############################
sub get_rules_select_table{
my ($sid,$rule_type) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;

$table = &get_sid_select_table($sid);
my @rules_types = &get_rules_types($sid);

$table  = "<FORM ACTION=\"$home_url\" METHOD=post>";
$table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 align=center>";
$table .= "<TR>";
$table .= "<TD><B>Ruleset to configure:</B></TD>";
$table .= "<TD>";
$table .= "<INPUT TYPE=hidden NAME=td VALUE=\"config_rules\">";
$table .= "<INPUT TYPE=hidden NAME=sid VALUE=\"$sid\">";
$table .= "<SELECT NAME=rules_type>";
$table .= "<OPTION selected>snort.conf</OPTION>\n";
foreach (@rules_types){
	if ($rule_type && ($rule_type eq "$_")){
		$table .= "<OPTION selected>$_</OPTION>\n";
	}
	else{
		$table .= "<OPTION>$_</OPTION>\n";
	}
}
if ($rule_type && ($rule_type eq "new")){
	$table .= "<OPTION value=new selected>Create NEW ruleset</OPTION>\n" 
}
else{
	$table .= "<OPTION value=new>Create NEW ruleset</OPTION>\n" 
}


$table .= "</SELECT>";
$table .= "</TD>";
$table .= "<TD><INPUT TYPE=Submit VALUE=Go style=\"font-size:8pt\"></TD>";

$table .= "</TR>\n</TABLE>\n</FORM>\n";

return $table;
}
#########################
sub get_rules_types{
my ($sid) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my @rules_types;

$sql_query = "SELECT rules_type FROM dm_rules WHERE sid = '$sid' ORDER BY UPPER(rules_type)";
$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
	push (@rules_types,$$hash_ref{'rules_type'});
}

return @rules_types;
}
##########################
sub get_snort_conf{
my ($sid) = @_;
($sid=~/^\d+$/) || return;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $value;

$sql_query = "SELECT * FROM dm_conf WHERE sid='$sid'";
$db_ptr = &run_query($sql_query);
return ($hash_ref=$db_ptr->fetchrow_hashref)? return $$hash_ref{'snort_conf'} : return;
}
##########################
sub get_snort_rules{
my ($sid,$rules_name) = @_;
($sid=~/^\d+$/) || return;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $value;
&safe_slash(\$rules_name);

$sql_query = "SELECT * FROM dm_rules WHERE sid='$sid' AND rules_type = '$rules_name'";
$db_ptr = &run_query($sql_query);
return ($hash_ref=$db_ptr->fetchrow_hashref)? return $$hash_ref{'snort_rules'} : return;
}
##########################
sub update_config{
my ($sid,$text,$field) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $create_new_record;
&safe_slash(\$text);

($sid=~/^\d+$/) || &error("No SID passed");
($field=~/^snort\.conf$|^rules$/) || &error("Invalid field to update: $field");

# first check to see if this sid already has a record:
$sql_query = "SELECT sid FROM dm_rules WHERE sid='$sid'";
$db_ptr = &run_query($sql_query);
($hash_ref=$db_ptr->fetchrow_hashref) || ($create_new_record = 1);

if ($create_new_record){
	$sql_query = "INSERT INTO dm_rules VALUES ('$sid',NOW(),'',";
	if ($field eq "snort.conf"){
		$field = "snort_conf";
		$sql_query .= "'$text','')";
	}
	else{
		$sql_query .= "'','$text')";
	}
}
else{
	# just update the old record:
	$field = "snort_conf" if ($field eq "snort.conf"); #change to work with db fieldname
	$field = "snort_rules" if ($field eq "rules"); #change to work with db fieldname
	$sql_query = "UPDATE dm_rules SET $field = '$text' WHERE sid = '$sid'";
}
$db_ptr = &run_query($sql_query);
&touch_rules_update_time($sid);

return 1;
}
#################
sub safe_slash{
my ($string_ref) = @_;

#$$string_ref=~s/(['\\\%])/\\$1/g;
$$string_ref=~s/(['\\])/\\$1/g;
}
#################
sub unsafe_slash{
my ($string_ref) = @_;

$$string_ref=~s/\\\\/\\/g;
$$string_ref=~s/\\'/'/g;
$$string_ref=~s/\\%/%/g;
}
#################
sub get_md5{
my ($sid) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $digest;
my $snort_rules_data;

$sql_query = "SELECT * FROM dm_rules WHERE sid = '$sid'";
$db_ptr = &run_query($sql_query);
($hash_ref=$db_ptr->fetchrow_hashref) || return;

$snort_rules_data = $$hash_ref{'snort_conf'} . "\n" . $$hash_ref{'snort_rules'};

$digest = md5_hex($snort_rules_data);

return $digest;
}
###################
sub print_edit_rules{
my ($sid,$rules_name) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $text;
my $table;
my $new_stuff;
&safe_slash(\$rules_name);

if ($rules_name eq "new"){
	$new_stuff = "<TR><TD>Ruleset Name (required) : <INPUT TYPE=text size=20 NAME=new_ruleset_name></TD></TR>\n";
}


if ($rules_name eq "snort.conf"){
	$sql_query = "SELECT snort_conf FROM dm_conf WHERE sid = '$sid'";
	$db_ptr = &run_query($sql_query);
	$text = ($hash_ref=$db_ptr->fetchrow_hashref)? $$hash_ref{'snort_conf'} : "";
}
else{
	$sql_query = "SELECT snort_rules FROM dm_rules WHERE rules_type = '$rules_name' AND sid = '$sid'";
	$db_ptr = &run_query($sql_query);
	$text = ($hash_ref=$db_ptr->fetchrow_hashref)? $$hash_ref{'snort_rules'} : "";
}
$table .= << "EOF";
<FORM ACTION="$home_url" METHOD=post>
<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 align=center>
$new_stuff
<TR><TD>
<INPUT TYPE=hidden NAME=td VALUE=do_config_rules>
<INPUT TYPE=hidden NAME=sid VALUE="$sid">
<INPUT TYPE=hidden NAME=rules_type VALUE="$rules_name">
</TD></TR>
<TR bgcolor="$head_color"><TD background="$v_graphics_path/bg_title.gif" align=center><B>Editing: $rules_name</B></TD></TR>
<TR bgcolor="$desc_color"><TD nowrap align=center>
&nbsp;<TEXTAREA rows=20 cols=70 NAME=rules_text wrap=off>$text</TEXTAREA>&nbsp;<br><br>
<SELECT NAME=action>
<OPTION value=update selected>Update</OPTION>
<OPTION value=delete>Delete</OPTION>
EOF
if ($rules_name!~/^snort\.conf$|^new$/){
my @sids = &get_sids();
   foreach (@sids){
         my @temp_array = split(/,/,$_);
         $table .= "<OPTION value=\"copy_to_$temp_array[0]\">Copy ruleset to SID $temp_array[0] - $temp_array[1]</OPTION>\n";
   }
   foreach (@sids){
         my @temp_array = split(/,/,$_);
         $table .= "<OPTION value=\"copy_all_to_$temp_array[0]\">Copy ALL rulesets for current sensor to SID $temp_array[0] - $temp_array[1]</OPTION>\n";
   }
### Options for changing priority:
my @p_array = split(//,$priority_levels);
   foreach (@p_array){
      $table .= "<OPTION value=\"change_priority_to_$_\">Change ALL priorities in ruleset to P-$_</OPTION>\n";
   }
   $table .= "<OPTION value=\"remove_priorities\">Remove ALL priorities in ruleset</OPTION>\n";
   $table .= "<OPTION value=\"delete_all_rules\">Remove ALL RULES for this sensor.</OPTION>\n";

}

#Option for copying snort.conf to new SID
my $last_sid = &get_last_sid;
if ($last_sid){
   $last_sid++;
   $table .= "<OPTION value=\"copy_snort_conf_to_new_sid\">Copy snort.conf to NEW SID ($last_sid) about to come online.</OPTION>";
}


$table .= << "EOF";
</SELECT>
<INPUT TYPE=Submit VALUE=Go style=\"font-size:8pt\"><br><br>
</TD></TR>
<TR HEIGHT=2 BGCOLOR="$head_color"><TD><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>
</TABLE>
</FORM>
EOF



return $table;
}
##################
sub get_sids{
my $sql_query;
my $db_ptr;
my $hash_ref;
my @sids;
my $where_rules;

$sql_query = "SELECT sid,hostname FROM sensor";
$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
	push (@sids,"$$hash_ref{'sid'},$$hash_ref{'hostname'}");
	$where_rules .= " sid != '$$hash_ref{'sid'}' AND";
}

$where_rules =~s/AND$//;
$sql_query = "	SELECT sid FROM dm_conf WHERE $where_rules";
$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
	push (@sids,"$$hash_ref{'sid'},[NOT_CHECKED_IN_YET]");
}

return @sids;
}
###############
sub touch_rules_update_time{
my ($sid) = @_;
my $sql_query;
my $db_ptr;

($sid=~/^\d+$/) || &error("SID not passed to update rules time function.");
$sql_query = "UPDATE dm_conf SET last_updated=NOW() WHERE sid='$sid'";
$db_ptr = &run_query($sql_query);
}
##################
sub get_sid_info_table{
my ($sid) = @_;
# $sid is if we only want to see one sensor's info
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
my $where;

if ($sid=~/^\d$/){
	$where = " WHERE sensor.sid = '$sid' ";
}

$sql_query = "	SELECT \
						sensor.sid,hostname,interface,\
						last_updated,last_implemented, \
(UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(last_implemented)) AS DIFF, \
(UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(last_updated)) AS DIFF2, \
(UNIX_TIMESTAMP(last_updated)-UNIX_TIMESTAMP(last_implemented)) AS LAPSE \
					FROM \
						sensor \
							LEFT JOIN dm_conf ON sensor.sid = dm_conf.sid $where \
					ORDER BY sid";

$table =<< "EOF";
<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 width=\"100%\">
<TR BGCOLOR=$head_color><TD BACKGROUND="$v_graphics_path/bg_title.gif" align=center colspan=7><B>Sensor Details</B></TD></TR>
<TR bgcolor=\"$title_color\">
<TD ALIGN=center><b>SID</b></TD>
<TD ALIGN=center><b>Hostname</b></TD>
<TD ALIGN=center><b>Interface</b></TD>
<TD ALIGN=center><b>Ruleset Last Updated</b></TD>
<TD ALIGN=center><b>Ruleset Last Implemented</b></TD>
<TD ALIGN=center><b>In-Sync</b></TD>
<TD ALIGN=center><b>Delete</b></TD>
</TR>
EOF

	$db_ptr = &run_query($sql_query);
	while ($hash_ref=$db_ptr->fetchrow_hashref){
		my $never = 0;
		$table .= "<TR bgcolor=\"$desc_color\">";
		$table .= "<TD align=center>&nbsp;$$hash_ref{'sid'}</TD>";
		$table .= "<TD align=center>&nbsp;";
			$table .= "<A HREF=\"$home_url?td=config_sid&sid=$$hash_ref{'sid'}\">" if (!$where);
		$table .= $$hash_ref{'hostname'};
			$table .= "</A>" if (!$where);
		$table .= "</TD>";
		$table .= "<TD align=center>&nbsp;$$hash_ref{'interface'}</TD>";
		$table .= "<TD align=center>&nbsp;$$hash_ref{'last_updated'}</TD>";
		if ($$hash_ref{'last_implemented'}=~/[1-9]/){
					$table .=  "<TD align=center>&nbsp;$$hash_ref{'last_implemented'} ("  . &time_ago($$hash_ref{'DIFF'}) . ")";
		}
		else{
					$table .=  "<TD align=center>Never<BR><FONT COLOR=red>Rules have never been implemented on host.  <BR>Client possibly not running?</FONT>";
					$never = 1;
		}
		my $no_link = "<BR><A HREF=\"$home_url?td=resync_sid&sid=$$hash_ref{'sid'}\"><b>Set In-Sync Manually?</b></A>";
		$table .= (!$never && ($$hash_ref{'LAPSE'}) && ($$hash_ref{'DIFF2'} > (60*10)))
					? "<BR><FONT COLOR=red>Rules on host have been stale for over 10 minutes. <BR>Client possibly not running?</FONT>$no_link</TD>"
					: "</TD>";
		$table .= "<TD align=center>";
		$table .= ($$hash_ref{'last_implemented'} ne $$hash_ref{'last_updated'}) ? "<FONT COLOR=red>NO</FONT>" : "YES";
		$table .= "</TD>";
		$table .= "<TD ALIGN=center><A HREF=\"$home_url?td=delete_sid&sid=$$hash_ref{'sid'}\"><b>Delete</b></A></TD>";

		$table .= "</TR>\n";
	}
$table .= "<TR HEIGHT=2 BGCOLOR=\"$head_color\"><TD COLSPAN=7><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE>\n";
return $table;
}
##############
sub time_ago{
my ($seconds) = @_;
my $ago;
($seconds) || return "0 seconds ago";

      if ($seconds<60){
         $ago = "$seconds seconds ago";
      }
      elsif ($seconds<(60*60)){
         $ago = sprintf ("%.2f minutes ago", ($seconds/60));
      }
      elsif ($seconds<(60*60*24)){
         $ago = sprintf ("%.2f hours ago", (($seconds/60)/60));
      }
      else{
         $ago = sprintf ("%.2f days ago",( (($seconds/60)/60)/24));
      }

return $ago;
}
############
sub recent_cached_copy{
my ($key,$cache_limit) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;

&safe_slash(\$key);

# Check to see if there's a cached version of the
# side menu that we can deliver to save a whole 
# bunch o' queries


$sql_query = "	SELECT \
						dm_content, \
						UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(last_updated) AS cache_age
					FROM \
						dm_cache \
					WHERE \
						sid 		= '$monitor_sid' AND \
						dm_key 	= '$key' AND \
						((UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(last_updated)) < ($cache_limit * 60))";

$db_ptr = &run_query($sql_query);
($hash_ref=$db_ptr->fetchrow_hashref) || return;
return ($$hash_ref{'dm_content'},$$hash_ref{'cache_age'});


}
##############
sub update_cache{
my ($key,$cache) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;

&safe_slash(\$key);
&safe_slash(\$cache);


#check to see if there's already a cached version in there:
$sql_query = "	SELECT \
						last_updated \
					FROM dm_cache \
					WHERE \
						sid = '$monitor_sid' AND \
						dm_key = '$key'";
$db_ptr = &run_query($sql_query);

if ($hash_ref=$db_ptr->fetchrow_hashref){
	# then we're just updating:
	$sql_query = "	UPDATE dm_cache \
						SET \
							last_updated = NOW(), \
							dm_content = '$cache' \
						WHERE \
							sid = '$monitor_sid' AND \
							dm_key = '$key'";
}
else{
	# we have to add a new row:
	$sql_query = "	INSERT INTO dm_cache \
						VALUES ( \
							'$monitor_sid', \
							'$key', \
							'$cache', \
							NOW()  \
						)";
}
$db_ptr = &run_query($sql_query);
}
######################
sub traceroute{
my ($host,$timeout_seconds,$no_name_resolution) = @_;

$host						=~tr/a-zA-Z0-9\.\-\_//dc;
($host) 				|| return;
$|                   = 1;
($timeout_seconds 	=~/^\d+$/) || ($timeout_seconds= 10);
my $flags 				= ($no_name_resolution)? " -n " : " ";
my $data					= "<CENTER><B>Traceroute to $host</B></CENTER>\n<P>";


eval {
   local $SIG{ALRM} = sub { die"timed_out\n"};
   alarm $timeout_seconds;

open (IN,"$traceroute_command $flags $host |") || &error("Can't do it: $!");

   while (<IN>){
		$_	=~s/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/<A HREF=\"$home_url\?td=arin_whois&ip=$1\">$1<\/A>/;
      $data .=  "$_ <BR>";
   }
   close IN;
};
	alarm 0;
if ($@){
   $data .= "<BR><B>TIMED OUT!</B>\n";
}

$timeout_seconds+=10;
my $trace_link = ($no_name_resolution)
	? "<A HREF=\"$home_url\?td=traceroute&ip=$host\">Rerun traceroute with name resolution</A>" 
	:"<A HREF=\"$home_url\?td=traceroute&no_name_resolution=1&ip=$host\">Rerun traceroute with no name resolution</A>";

$data .= << "EOF";
<P ALIGN=left>
$trace_link
<BR>
<A HREF=\"$home_url\?td=traceroute&timeout=$timeout_seconds&ip=$host\">Rerun traceroute with longer timeout</A>
<P>
EOF

push (@substitutions,"\\[MAIN_TABLE\\],-,$data");
&print_main_with_key($main_template);
}
######################
sub nslookup{
my ($host) = @_;

my $timeout_seconds;
$host						=~tr/a-zA-Z0-9\.\-\_//dc;
($host) 				|| return;
$|                   = 1;
($timeout_seconds 	=~/^\d+$/) || ($timeout_seconds= 10);
my $data					= "<CENTER><B>NSlookup for $host</B></CENTER>\n<P>";


eval {
   local $SIG{ALRM} = sub { die"timed_out\n"};
   alarm $timeout_seconds;

#2>&1 makes erros go to stdout instead of stderr so we can see them
open (IN,"$nslookup_command $host 2>&1 |") || &error("Can't do it: $!");

   while (<IN>){
#		$_	=~s/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/<A HREF=\"$home_url\?td=arin_whois&ip=$1\">$1<\/A>/;
      $data .=  "$_ <BR>";
   }
   close IN;
};
	alarm 0;
if ($@){
   $data .= "<BR><B>TIMED OUT!</B>\n";
}

push (@substitutions,"\\[MAIN_TABLE\\],-,$data");
&print_main_with_key($main_template);
}
######################
sub ping{
my ($host,$count) = @_;

$host						=~tr/a-zA-Z0-9\.\-\_//dc;
($host) 				|| return;
$|                   = 1;
($count =~/^\d+$/) || ($count= 4);
my $data					= "<CENTER><B>Pinging $host</B></CENTER>\n<P>";
my $timeout_seconds	= 2*$count;


eval {
   local $SIG{ALRM} = sub { die"timed_out\n"};
   alarm $timeout_seconds;

open (IN,"$ping_command -c $count $host |") || &error("Can't do it: $!");

   while (<IN>){
#		$_	=~s/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/<A HREF=\"$home_url\?td=arin_whois&ip=$1\">$1<\/A>/;
      $data .=  "$_ <BR>";
   }
   close IN;
};
	alarm 0;
if ($@){
   $data .= "<BR><B>TIMED OUT!</B>\n";
}

$count+=4;

$data .= << "EOF";
<P ALIGN=left>
<BR>
<A HREF=\"$home_url\?td=ping&count=$count&ip=$host\">Rerun with longer ping count.</A>
<P>
EOF

push (@substitutions,"\\[MAIN_TABLE\\],-,$data");
&print_main_with_key($main_template);
}
############################
sub get_monitor_menu_table{
my $table;

$table = "<A HREF=\"$home_url?td=add_monitoring_event\">Add Monitoring Event</A>";

return $table;
}
##########################
sub print_add_monitoring_event_page{
my $table;
my $html = &get_new_service_page;

my $services_dropdown = &get_remote_services_dropdown;
push (@substitutions,"\\[REMOTE_SERVICE_LIST\\],-,$services_dropdown");
$services_dropdown = &get_local_services_dropdown;
push (@substitutions,"\\[LOCAL_SERVICE_LIST\\],-,$services_dropdown");
$services_dropdown = &get_special_services_dropdown;
push (@substitutions,"\\[SPECIAL_SERVICE_LIST\\],-,$services_dropdown");

my $group_list = &get_groups_dropdown;
push (@substitutions,"\\[GROUP_LIST\\],-,$group_list");
my $sid_list = &get_sids_dropdown("client_sid"," - Select - ");
push (@substitutions,"\\[SID_LIST\\],-,$sid_list");
my $host_list = &get_hosts_dropdown;
push (@substitutions,"\\[IP_LIST\\],-,$host_list");


$table = &print_with_key('',"TO_STRING",$html);
#@substitutions = ();

push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
############################
sub get_remote_services_dropdown{
my $dropdown;

#simply formats global @services var

$dropdown = "<SELECT NAME=remote_service>\n";

$dropdown .= "<OPTION VALUE=\"NOT_SELECTED\" selected>- Select -</OPTION>\n";

foreach (@remote_services){
	$dropdown .= "<OPTION>$_</OPTION>\n";
}
$dropdown .= "</SELECT>";

return $dropdown;
}
############################
sub get_special_services_dropdown{
my $dropdown;

#simply formats global @services var

$dropdown = "<SELECT NAME=special_service>\n";

$dropdown .= "<OPTION VALUE=\"NOT_SELECTED\" selected>- Select -</OPTION>\n";

foreach (@special_services){
	$dropdown .= "<OPTION>$_</OPTION>\n";
}
$dropdown .= "</SELECT>";

return $dropdown;
}
############################
sub get_local_services_dropdown{
my $dropdown;

#simply formats global @services var

$dropdown = "<SELECT NAME=local_service>\n";

$dropdown .= "<OPTION VALUE=\"NOT_SELECTED\" selected>- Select -</OPTION>\n";

foreach (@local_services){
	$dropdown .= "<OPTION>$_</OPTION>\n";
}
$dropdown .= "</SELECT>";

return $dropdown;
}
############################
sub get_services_dropdown{
my $dropdown;

#simply formats global @services var

$dropdown = "<SELECT NAME=local_service>\n";

$dropdown .= "<OPTION VALUE=\"NOT_SELECTED\" selected>- Select -</OPTION>\n";

foreach (@local_services){
	$dropdown .= "<OPTION>$_</OPTION>\n";
}
foreach (@remote_services){
	$dropdown .= "<OPTION>$_</OPTION>\n";
}
$dropdown .= "</SELECT>";

return $dropdown;
}
############################
sub get_groups_dropdown{
my $dropdown;
my $sql_query;
my $db_ptr;
my $hash_ref;

$dropdown = "<SELECT NAME=grouping>\n";
$dropdown .= "<OPTION VALUE=\"NOT_SELECTED\" selected>- Select -</OPTION>\n";

$sql_query = "SELECT DISTINCT grouping FROM dm_monitor_current ORDER BY UPPER(grouping)";
$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
   $dropdown .= "<OPTION>$$hash_ref{'grouping'}</OPTION>\n";
}
$dropdown .= "</SELECT>";

return $dropdown;
}
############################
sub get_sids_dropdown{
my ($select_name,$label_option) = @_;

($select_name) || ($select_name = "client_sid");
($label_option) || ($label_option = "- Select -");

my $dropdown;
my $sql_query;
my $db_ptr;
my $hash_ref;

$dropdown = "<SELECT NAME=$select_name>\n";
$dropdown .= "<OPTION VALUE=\"NOT_SELECTED\" selected>$label_option</OPTION>\n";

$sql_query = "SELECT sid,hostname FROM sensor ORDER BY sid";
$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
   $dropdown .= "<OPTION VALUE=\"$$hash_ref{'sid'}\">$$hash_ref{'sid'} - $$hash_ref{'hostname'}</OPTION>\n";
}
$dropdown .= "</SELECT>";

return $dropdown;
}
############################
sub get_hosts_dropdown{
my $dropdown;
my $sql_query;
my $db_ptr;
my $hash_ref;

$dropdown = "<SELECT NAME=host_name>\n";
$dropdown .= "<OPTION VALUE=\"NOT_SELECTED\" selected>- Select -</OPTION>\n";

$sql_query = "SELECT DISTINCT host_name,ip_addr FROM dm_monitor_current GROUP BY UPPER(host_name) ORDER BY UPPER(host_name)";
$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
#	my $dotted_ip = &convert_long_ip($$hash_ref{'ip_addr'});
#   $dropdown .= "<OPTION VALUE=\"$$hash_ref{'ip_addr'}\">$$hash_ref{'host_name'} - $dotted_ip</OPTION>\n";
   $dropdown .= "<OPTION VALUE=\"$$hash_ref{'host_name'}\">$$hash_ref{'host_name'}</OPTION>\n";
}
$dropdown .= "</SELECT>";

return $dropdown;
}
##########################
sub do_add_monitoring_event{
# vars are taken from global FORM vars
my $sql_query;
my $db_ptr;
my $hash_ref;
my $long_ip;
my $host_name;
my $grouping;
my $service;
my $port;
my $client_sid;
my $check_dns = ($FORM{'dns_check'}=~/yes/i) 
				? "1"
				: '';

$client_sid = $FORM{'client_sid'} if  ($FORM{'client_sid'}=~/^\d+$/);
# Check for Service
$FORM{'local_service'} = () if ($FORM{'local_service'}=~/NOT_SELECTED/);
$FORM{'remote_service'} = () if ($FORM{'remote_service'}=~/NOT_SELECTED/);
$FORM{'local_service'}=~tr/a-zA-Z0-9\.\- //dc;#take out invalid characters
$FORM{'remote_service'}=~tr/a-zA-Z0-9\.\- //dc;#take out invalid characters

#make sure they have one of the dropdowns selected
if (!$FORM{'local_service'} && !$FORM{'remote_service'}){
	&error("No service selected to monitor!");
}
# but not both!
if ($FORM{'local_service'} && $FORM{'remote_service'}){
	&error("Both remote and local services are selected to monitor.  Please deselect one and try again.");
}
if ($FORM{'local_service'}){
	($client_sid=~/^\d+$/) || &error("You have chosen to monitor a local service, but did not select which sensor should do the local monitoring.  Please go back and select a sensor from the SID dropdown.");
	$service = $FORM{'local_service'};
}
else{
	$service = $FORM{'remote_service'};
}


(!$FORM{'port'} || ($FORM{'port'}=~/^\d+$/)) || &error("Port number must consist only of digits");
$port = $FORM{'port'};



# Check for new host to monitor
if ($FORM{'host_name_manual'}){
	$FORM{'host_name_manual'}=~tr/a-zA-Z0-9\.\-//dc;#take out invalid dns characters
	if ($FORM{'host_name_manual'}!~/[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-]{2,}/){
		&error("You seem to have entered an invalid DNS hostname.");
	}
	$host_name = $FORM{'host_name_manual'};

# Make sure we do not already have this host:
my $temp_string;
my $host_name_temp;
($temp_string,$host_name_temp,$grouping) = &get_monitored_host_info($FORM{'host_name_manual'});
if ($temp_string){
	&error("Host with that hostname already exists : $host_name_temp is in the group: $grouping");
}

	if ($FORM{'group_manual'}){
		$grouping = $FORM{'group_manual'};
	}
	elsif ($FORM{'grouping'} ne "NOT_SELECTED"){
		$grouping = $FORM{'grouping'};
	}
	else{
		&error("You must either type in a new group name for this host or select a preexisting group from the dropdown list");
	}
	

}
else{
# Check to make sure host exists:
($FORM{'host_name'} eq "NOT_SELECTED") 
		&&  &error("You must either select a preexisting host to monitor or supply the IP address AND hostname for a new host to monitor");

$FORM{'host_name'}=~tr/a-zA-Z0-9\.\-//dc;#take out invalid dns characters
$host_name = $FORM{'host_name'};

($long_ip,$host_name,$grouping) = &get_monitored_host_info($FORM{'host_name'});
($host_name) || &error("chosen host does not exist!");

}

#ok, now lets just try and save them from putting the same entry in twice:
$sql_query = "	SELECT sid FROM dm_monitor_current \
					WHERE \
						sid 		= '$monitor_sid' AND \
						UPPER(host_name)	= UPPER('$host_name') AND \
						service 	= '$service' AND \
						port		= '$port'";
$db_ptr = &run_query($sql_query);
 ($hash_ref=$db_ptr->fetchrow_hashref)
	&& &error("There is already a monitoring event set with the same hostname, service, and port");


&safe_slash(\$service);
&safe_slash(\$host_name);
&safe_slash(\$grouping);
$sql_query = "INSERT INTO dm_monitor_current VALUES( \
					'$monitor_sid','$service','', \
					'$host_name','$grouping', NOW() , \
					'','','','$client_sid','$port',NOW(), \
					'','','','$check_dns'
				)";
&connect_to_db;
($db->do($sql_query)) || &error("DB error occured while adding new service, please try again.");
&push_message("<FONT COLOR=red><CENTER>New Monitor Event Added.</CENTER></FONT>");

&log_event(	username => "$logged_in_as",
				action 	=> "added host monitoring event",
				target	=> "$host_name - $service",
			 );


}
##########################
sub print_add_special_monitoring_event{
# vars are taken from global FORM vars
my $sql_query;
my $db_ptr;
my $hash_ref;
my $client_sid;
my $host_name;
my $service;
my $old_conf;

# Check for Service
$FORM{'special_service'} = () if ($FORM{'special_service'}=~/NOT_SELECTED/);
$FORM{'client_sid'} = () if ($FORM{'client_sid'}=~/NOT_SELECTED/);
$FORM{'special_service'}=~tr/a-zA-Z0-9\.\- //dc;#take out invalid characters
$FORM{'client_sid'}=~tr/a-zA-Z0-9\.\- //dc;#take out invalid characters
$client_sid = $FORM{'client_sid'} if  ($FORM{'client_sid'}=~/^\d+$/);
$FORM{'host_name'} = () if ($FORM{'host_name'}=~/NOT_SELECTED/);
$FORM{'host_name'}=~tr/a-zA-Z0-9\.\-//dc;#take out invalid dns characters
$host_name = $FORM{'host_name'};
($host_name) || &error("You must select a host to monitor from the dropdown list.");



#make sure they have one of the dropdowns selected
if (!$FORM{'special_service'}){
	&error("No service selected to monitor!");
}


($client_sid=~/^\d+$/) || &error("You have chosen to monitor a special service, but did not select which sensor should do the local monitoring.  Please go back and select a sensor from the SID dropdown.");
$service = $FORM{'special_service'};


#lets see if there's already a special service like this:

$sql_query = "	SELECT ext3,sid FROM dm_monitor_current \
					WHERE \
						sid 		= '$monitor_sid' AND \
						UPPER(host_name)	= UPPER('$host_name') AND \
						service 	= '$service' ";
$db_ptr = &run_query($sql_query);

if  ($hash_ref=$db_ptr->fetchrow_hashref){
	$old_conf = $$hash_ref{'ext3'};
}


#special services are hard-coded right now
if ($service =~/^Proc$/){
	&print_special_monitor_proc($client_sid,$host_name,$old_conf);
}
elsif($service=~/^Logs$/){
	&print_special_monitor_logs($client_sid,$host_name,$old_conf);
}
else{
	&error("Invalid service chosen.  Please try again.");
}


}
#######################
sub print_special_monitor_proc{
my ($sid,$host_name,$old_conf) = @_;
my $table;
my $sql_query;
my $db_ptr;
my $hash_ref;


push (@substitutions,"\\[CURRENT_CONF\\],-,$old_conf");
push (@substitutions,"\\[SID\\],-,$sid");
push (@substitutions,"\\[HOST_NAME\\],-,$host_name");
$table = &print_with_key($monitor_proc_form,'TO_STRING');

push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
#######################
sub print_special_monitor_logs{
my ($sid,$host_name,$old_conf) = @_;
my $table;
my $sql_query;
my $db_ptr;
my $hash_ref;


push (@substitutions,"\\[CURRENT_CONF\\],-,$old_conf");
push (@substitutions,"\\[SID\\],-,$sid");
push (@substitutions,"\\[HOST_NAME\\],-,$host_name");
$table = &print_with_key($monitor_logs_form,'TO_STRING');

push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
#################################
sub update_special_monitor_proc{
my ($sid,$host_name,$rules) = @_;
($sid=~/^\d+$/) || &error("Invalid SID: $sid");
my @new_rules;
my @rule_array;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $new_rules_string;
my $grouping;

&connect_to_db;

@rule_array = split(/\n/,$rules);

foreach (@rule_array){
	$_=~tr/\!-~ //dc;#take out non standard characters
	my @rule = split(/;/,$_);

	# take out spaces from beg/end of regex
	$rule[1]=~s/^\s+|\s+$//g;

	next if (!$rule[1]); #skip bad records
	# make sure alert level is in correct format
	
	if ($rule[0]=~/yellow$/i){
		$rule[0] = "YELLOW";
	}
	else{
		#Default to RED
		$rule[0] = "RED";
	}
	#default to 1 for minimum processes
	($rule[2]=~/^[1-9]+\d*$/) || ($rule[2]=1);
	#default to 0 (unlimited) for maximum processes
	($rule[3]=~/^[1-9]+\d*$/) || ($rule[3]=0);

	#safety first:
	&safe_slash(\$rule[1]);#regex
	&safe_slash(\$rule[4]);#comment
	&safe_slash(\$rule[5]);#regen_cmd
	&safe_slash(\$rule[6]);#regen_user

	push (@new_rules,"$rule[0];$rule[1];$rule[2];$rule[3];$rule[4];$rule[5];$rule[6]");

}
#make sure we can get a grouping mapping for this hostname / validate hostname exists in DB:
$grouping = &get_grouping_for_host($host_name);

($grouping) || &error("Can't find mapping from host \"$host_name\" to grouping, please make sure there is already at least one service for this hostname before adding a process monitoring event.");

# now add/update rules to db
$new_rules_string = join("\n",@new_rules);

#check if we already have an entry, or if we need to create one:

$sql_query = "	SELECT sid \
				FROM dm_monitor_current \
				WHERE \
                    sid         = '$monitor_sid' AND \
					service LIKE 'Proc' AND \
                    UPPER(host_name)    = UPPER('$host_name')"; 
$db_ptr = &run_query($sql_query);
if ($hash_ref=$db_ptr->fetchrow_hashref){
	#then we just need to update the old record
	$sql_query = "	UPDATE dm_monitor_current \
					SET \
						ext3 = '$new_rules_string' \
					WHERE \
						sid         = '$monitor_sid' AND \
                    	service LIKE 'Proc' AND \
                    	UPPER(host_name)    = UPPER('$host_name')";
}
else{
	#new record
	$sql_query = "INSERT INTO dm_monitor_current VALUES( \
					'$monitor_sid','Proc','', \
					'$host_name','$grouping', NOW() , \
					'','','','$sid','',NOW(), \
					'','','$new_rules_string',''
				)";
}

($db->do($sql_query)) || &error("DB error occured while updating process record, please try again.");

&log_event(	username => "$logged_in_as",
				action 	=> "updated proc rules",
				target	=> "SID: $sid",
			 );

return $new_rules_string;
}
#################################
sub update_special_monitor_logs{
my ($sid,$host_name,$rules) = @_;
($sid=~/^\d+$/) || &error("Invalid SID: $sid");
my @new_rules;
my @rule_array;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $new_rules_string;
my $grouping;

&connect_to_db;

@rule_array = split(/\n/,$rules);

foreach (@rule_array){
	$_=~tr/\!-~ //dc;#take out non standard characters
	my $inode;
	my $prev_matches;
	my @rule = split(/;/,$_);

	# take out spaces from beg/end of regex and path
	$rule[1]=~s/^\s+|\s+$//g;
	$rule[2]=~s/^\s+|\s+$//g;
    if ($rule[0]=~/INODE=(\d+)/){
        $inode = $1;
    }
    if ($rule[0]=~/PREV_MATCHES=(\d+)/){
        $prev_matches = $1;
    }
	$rule[1]=~s/\/$//g; # g is for: /root//////

	next if (!$rule[1]); #skip bad records
	next if (!$rule[2]); #skip bad records
	# make sure alert level is in correct format
	
	if ($rule[0]=~/yellow$/i){
		$rule[0] = "YELLOW";
	}
	else{
		#Default to RED
		$rule[0] = "RED";
	}
	#default to 1 for threshhold number
	($rule[3]=~/^[1-9]+\d*$/) || ($rule[3]=1);

	#safety first:
	&safe_slash(\$rule[1]);#regex
	&safe_slash(\$rule[2]);#regex
	&safe_slash(\$rule[4]);#comment

	push (@new_rules, "[INODE=$inode][PREV_MATCHES=$prev_matches]$rule[0];$rule[1];$rule[2];$rule[3];$rule[4]");

}
#make sure we can get a grouping mapping for this hostname / validate hostname exists in DB:
$grouping = &get_grouping_for_host($host_name);

($grouping) || &error("Can't find mapping from host \"$host_name\" to grouping, please make sure there is already at least one service for this hostname before adding a log monitoring event.");

# now add/update rules to db
$new_rules_string = join("\n",@new_rules);

#check if we already have an entry, or if we need to create one:

$sql_query = "	SELECT sid \
				FROM dm_monitor_current \
				WHERE \
                    sid         = '$monitor_sid' AND \
					service LIKE 'Logs' AND \
                    UPPER(host_name)    = UPPER('$host_name')"; 
$db_ptr = &run_query($sql_query);
if ($hash_ref=$db_ptr->fetchrow_hashref){
	#then we just need to update the old record
	$sql_query = "	UPDATE dm_monitor_current \
					SET \
						ext3 = '$new_rules_string' \
					WHERE \
						sid         = '$monitor_sid' AND \
                    	service LIKE 'Logs' AND \
                    	UPPER(host_name)    = UPPER('$host_name')";
}
else{
	#new record
	$sql_query = "INSERT INTO dm_monitor_current VALUES( \
					'$monitor_sid','Logs','', \
					'$host_name','$grouping', NOW() , \
					'','','','$sid','',NOW(), \
					'','','$new_rules_string',''
				)";
}

($db->do($sql_query)) || &error("DB error occured while updating logs record, please try again.");

&log_event(	username => "$logged_in_as",
				action 	=> "updated logs rules",
				target	=> "SID: $sid",
			 );
return $new_rules_string;

}
####################
sub get_monitored_host_info{
my ($host_name) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;

$sql_query = "	SELECT \
						ip_addr,host_name,grouping \
					FROM \
						dm_monitor_current \
					WHERE \
						UPPER(host_name) 	= UPPER('$host_name') AND \
						sid		= '$monitor_sid'";

$db_ptr = &run_query($sql_query);
($hash_ref=$db_ptr->fetchrow_hashref) || return;
return ($$hash_ref{'ip_addr'},$$hash_ref{'host_name'},$$hash_ref{'grouping'});

}
###############
sub print_monitor_page{
my $table;

$table = &get_full_monitoring_table;
$table .=  &get_last_monitoring_changes();

push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
###############
sub get_full_monitoring_table{
my @groupings;
my @services;
my $table;

@groupings = &get_groupings;
foreach (@groupings){
my $cols = 1;

$table .= "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH=\"100%\" BGCOLOR=\"#000000\">\n<TR><TD>\n";
$table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 WIDTH=\"100%\">\n";
	my $group = $_;
	&safe_slash(\$group);
	@services = &get_services_for_grouping($group);
	$cols = (@services) + 1;
	$table .= "<TR BGCOLOR=\"$head_color\"><TD BACKGROUND=\"$v_graphics_path/bg_title.gif\" align=center colspan=\"$cols\"><B>$_</B></TD></TR>\n";
	$table .= "<TR bgcolor=\"$title_color\"><TD ALIGN=left><IMG SRC=\"$v_graphics_path/spacer.gif\" width=60 height=2><B>Host</B></TD>";
	foreach (@services){
		$table .= "<TD ALIGN=center width=50><B>$_</B></TD>";
	}
	$table .= "</TR>\n";
	my ($hosts_ref,$ips_ref) = &get_hosts_in_group($group);
	for (my $i=0;$i<(@$hosts_ref);$i++){
#		my $dotted_ip = &convert_long_ip($$ips_ref[$i]);
#		$table .= "<TR bgcolor=\"$desc_color\"><TD ALIGN=left>&nbsp;$$hosts_ref[$i] $dotted_ip</TD>";
		$table .= "<TR bgcolor=\"$desc_color\"><TD ALIGN=left>&nbsp;$$hosts_ref[$i]</TD>";
		foreach (@services){
			my $status = &get_status_color_for(	host_name	=> $$hosts_ref[$i],
												service		=> $_);
#&debug("STATUS FOR: $$hosts_ref[$i] - SERVICE: $_ IS: $status");
															
			my $link = ($status=~/src/)? "<A HREF=\"$home_url?td=view_monitored_host&host_name=$$hosts_ref[$i]&service=$_\">$status</A>" : $status;
			$table .= "<TD ALIGN=center>$link</TD>";
		}
		$table .= "</TR>\n";
	}
$table .= "<TR HEIGHT=2 BGCOLOR=\"$head_color\"><TD COLSPAN=\"$cols\"><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>\n";
$table .= "</TABLE>\n";
$table .= "</TD></TR>\n</TABLE>\n<BR>\n";
}

return $table;
}
###############
sub get_minimum_monitoring_table{
my ($mini_me_target) = @_;
my @groupings;
my @services;
my $table;
my $bad_mojo;
my $bad_host_mojo;
my $bad_group_mojo;
my $final_table;
my @man_down; # for mini-me
my $cols = 1;

@groupings = &get_groupings;

#HEADER table
$final_table .= "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH=\"100%\">";
$final_table .= "<TR BGCOLOR=\"$head_color\"><TD ALIGN=center BACKGROUND=\"$v_graphics_path/bg_title.gif\">";
$final_table .= "<B>Host Monitoring Alerts</B>";
$final_table .= "</TD></TR>\n";
$final_table .= "</TABLE>\n";
#$final_table .= "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH=\"100%\">";
#$final_table .= "<TR><TD ALIGN=center BGCOLOR=\"#000000\">\n";

foreach (@groupings){
$table 		= (); #clear the temp table
$bad_group_mojo	= ();

my $current_group = $_;
	my $group = $_;
	&safe_slash(\$group);
	@services = &get_services_for_grouping($group);
	$cols = (@services) + 1;

	$table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 WIDTH=\"100%\">";
	$table .= "<TR BGCOLOR=\"$title_color\"><TD ALIGN=left>&nbsp;<B>$current_group</B></TD>";
	foreach (@services){
		$table .= "<TD ALIGN=center width=\"50\"><B>$_</B></TD>";
	}
	$table .= "</TR>\n";
	my ($hosts_ref,$ips_ref) = &get_hosts_in_group($group);
	for (my $i=0;$i<(@$hosts_ref);$i++){
		my $table_2;
		$bad_host_mojo = ();
		my $dotted_ip = &convert_long_ip($$ips_ref[$i]);
		$table_2 .= "<TR BGCOLOR=\"$desc_color\"><TD ALIGN=left>&nbsp;$$hosts_ref[$i] $dotted_ip</TD>";
		foreach (@services){
			
			my $status = &get_status_color_for(	host_name		=> $$hosts_ref[$i],
												service	 		=> $_);
															
			my $link = ($status=~/SRC/i)? "<A HREF=\"$home_url?td=view_monitored_host&host_name=$$hosts_ref[$i]&service=$_\">$status</A>" : $status;
			$table_2 .= "<TD ALIGN=center width=\"50\">$link</TD>";
			if (($status=~/SRC/i) && ($status!~/green/i)){
				$bad_host_mojo = 1; 
				push (@man_down,"$current_group,-,$$hosts_ref[$i],-,$$ips_ref[$i],-,$_,-,$status");
			}
		}
		$table_2 .= "</TR>\n";
		if ($bad_host_mojo){
			$table .= $table_2; 
			$bad_mojo 			= 1;
			$bad_group_mojo	= 1;
		}
	}
$table .= "</TD></TR></TABLE>";

$final_table .= $table if ($bad_group_mojo);
}
if (!$bad_mojo){
	#$final_table .= "<tr bgcolor=\"$desc_color\"><td align=center><B>All Monitored Hosts/Services&nbsp;" . &color_code("GREEN"). "</B></td></tr>";
	$final_table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 WIDTH=\"100%\">";
	$final_table .= "<TR BGCOLOR=\"$title_color\"><TD ALIGN=center>";
	$final_table .= "<B>All Monitored Hosts/Services&nbsp;" . &color_code("GREEN"). "</B>";
	$final_table .= "</TD></TR></TABLE>";
}


$final_table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 WIDTH=\"100%\">\n";
$final_table .= "<tr bgcolor=\"$desc_color\"><td align=right><A HREF=\"$home_url?td=view_monitoring_page\"><B>More...&nbsp;&nbsp;</B></A></tr>";
$final_table .= "</TABLE>\n";

$final_table .= "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=2 WIDTH=\"100%\">\n";
$final_table .= "<TR HEIGHT=2 BGCOLOR=\"$head_color\"><TD><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$final_table .= "</TABLE><BR>";

return (\@man_down,$final_table);
}
###############
sub get_groupings{
my $sql_query;
my $db_ptr;
my $hash_ref;
my @groupings;

$sql_query = " SELECT \
                  DISTINCT grouping \
               FROM \
                  dm_monitor_current \
               WHERE \
                  sid = '$monitor_sid' \
               ORDER BY UPPER(grouping)";

$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
	push (@groupings,$$hash_ref{'grouping'});
}

return @groupings;
}
###############
sub get_hosts_in_group{
my ($group) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my @hosts;
my @ips;

$sql_query = " SELECT \
                  DISTINCT host_name,ip_addr \
               FROM \
                  dm_monitor_current \
               WHERE \
                  sid 		= '$monitor_sid' AND \
						grouping	= '$group' \
				GROUP BY host_name
               ORDER BY UPPER(host_name)";

#&debug($sql_query);
$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
   push (@hosts,$$hash_ref{'host_name'});
   push (@ips,$$hash_ref{'ip_addr'});
}

return (\@hosts,\@ips);
}

###############
sub get_services_for_grouping{
my ($grouping) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my @services;

$sql_query = " SELECT \
                  DISTINCT service \
               FROM \
                  dm_monitor_current \
               WHERE \
                  sid = '$monitor_sid' AND \
						grouping = '$grouping' \
					ORDER BY UPPER(service)";

$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
	push (@services,$$hash_ref{'service'});
}

return @services;
}
###############
sub get_services_for_host{
my ($host_name) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my @services;

$sql_query = " SELECT \
                   service \
               FROM \
                  dm_monitor_current \
               WHERE \
                  	sid = '$monitor_sid' AND \
					host_name = '$host_name' \
					ORDER BY UPPER(service)";

$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
	push (@services,$$hash_ref{'service'});
}

return @services;
}
###############
sub get_grouping_for_host{
my ($host_name) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my @services;

$sql_query = " SELECT \
                   grouping \
               FROM \
                  dm_monitor_current \
               WHERE \
                  	sid = '$monitor_sid' AND \
					host_name = '$host_name' \
					LIMIT 1";

$db_ptr = &run_query($sql_query);
($hash_ref=$db_ptr->fetchrow_hashref) || return;

return $$hash_ref{'grouping'};
}
#################
sub get_status_color_for{
my (%args) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;

($args{'host_name'}) || return;
($args{'service'}) || return;

$sql_query = "	SELECT \
						current_status, \
						(UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(last_checked)) AS DIFF \
					FROM \
						dm_monitor_current \
					WHERE \
						host_name = '$args{'host_name'}' AND \
						service = '$args{'service'}'";
$db_ptr = &run_query($sql_query);
($hash_ref=$db_ptr->fetchrow_hashref) || return "<B>-</B>";

# check if it is still a valid reading (less than 11 mins old)
if ($$hash_ref{'DIFF'} >= (11 * 60)){
	return &color_code("BLUE");
}
else{
	return &color_code($$hash_ref{'current_status'});
}
}
#####################
sub color_code{
my ($current_status) = @_;
my $green_image = "<img src=\"$v_graphics_path/green.gif\" alt=\"Ok\" width=16 height=16 border=0>";
my $yellow_image = "<img src=\"$v_graphics_path/yellow.gif\"alt=\"Warning\"  width=16 height=16 border=0>";
my $red_image = "<img src=\"$v_graphics_path/red.gif\" alt=\"Critical\" width=16 height=16 border=0>";
my $blue_image = "<img src=\"$v_graphics_path/blue.gif\" alt=\"No Report\" width=16 height=16 border=0>";

if ($current_status =~/GREEN/){
	return $green_image;
}
elsif ($current_status =~/YELLOW/){
	return $yellow_image;
}
elsif ($current_status =~/RED/){
	return $red_image;
}
else{
	return $blue_image;
}

}
########################
sub view_monitored_host{
my (%args) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;

$args{'host_name'}=~tr/a-zA-Z0-9\.\-\_//dc;
($args{'host_name'}) || &error("No hostname passed");
$args{'service'}=~tr/a-zA-Z0-9\.\-\_//dc;
($args{'service'}) || &error("No service passed");

$sql_query = " SELECT * \
               FROM \
                  dm_monitor_current \
               WHERE \
                  UPPER(host_name) = UPPER('$args{'host_name'}') AND \
                  service = '$args{'service'}'";
$db_ptr = &run_query($sql_query);
($hash_ref=$db_ptr->fetchrow_hashref) || &error("No status was found for that host/service");


$table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2  WIDTH=\"80%\" align=center>\n";
$table .=   "<TR BGCOLOR=\"$head_color\">";
$table .=   "<TD background=\"$v_graphics_path/bg_title.gif\" colspan=5 align=center><b>Event Information</b></TD>";
$table .=   "</TR>\n";
$table .=   "<TR BGCOLOR=\"$title_color\">\n";
$table .=	"<TD align=center><b>Service</b></TD><TD align=center><b>Host</b></TD>";
$table .=   "<TD align=center><b>Grouping</b></TD>";
$table .=	"<TD align=center><b>Status</b></TD>";
$table .=	"<TD align=center><b>Check DNS</b></TD>";
$table .=	"</TR>\n";


$table .=	"<TR bgcolor=\"$desc_color\">";
$table .= 	"<TD align=center valign=middle>";
#$table .= 		"<B>$$hash_ref{'service'}</B>";
my @services = &get_services_for_host($args{'host_name'});

$table .= << "EOF";
<FORM ACTION=$home_url METHOD=get NAME=other_service>
<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0>
<TR><TD valign=middle>
<INPUT TYPE=hidden NAME=td VALUE=view_monitored_host>
<INPUT TYPE=hidden NAME=host_name VALUE=\"$args{'host_name'}\">
EOF

$table .= "<SELECT NAME=service OnChange=\"document.forms.other_service.submit()\">";
$table .= "<OPTION selected>$$hash_ref{'service'}</OPTION>\n";
foreach (@services){
	$table .= "<OPTION>$_</OPTION>" if ($_ ne $$hash_ref{'service'});
}
$table .= "</SELECT>";

#$table .= << "EOF";
#</TD><TD>
#<INPUT TYPE=Submit VALUE=Go style=\"font-size:8pt\">
#EOF

$table .= << "EOF";
</TD></TR>
</FORM>
</TABLE>
EOF

$table .=   "</TD>";
$table .= 	"<TD align=center>";
$table .= 	"<B>$$hash_ref{'host_name'} " ;
my $temp_ip = &convert_long_ip($$hash_ref{'ip_addr'});
$table .= ($temp_ip=~/[1-9]/) ? " - $temp_ip" : '';
$table .= 	" (Port: $$hash_ref{'port'}) " if ($$hash_ref{'port'});
$table .= 	"</B></TD>";
$table .= 	"<TD align=center><b>$$hash_ref{'grouping'}</b></TD>";
$table .= 	"<TD align=center><b>$$hash_ref{'current_status'}</b></TD>";
$table .= 	"<TD align=center><b>";
$table .= ($$hash_ref{'check_dns'}) ? "Yes" : "No";
$table .= "</b></TD>";
$table .= 	"</TR>\n";

$table .=   "<TR bgcolor=\"$desc_color\">";
$table .=   "<TD colspan=5 align=center>";
if (&is_admin("f2")){
   $table .= "<A HREF=\"$home_url?td=edit_monitored_service&host_name=$args{'host_name'}&service=$args{'service'}\"><B>Edit Monitoring of $$hash_ref{'service'} on this Host</B></A>";
}
$table .=   "</TR>\n";
$table .= "<TR HEIGHT=2 BGCOLOR=\"$head_color\"><TD COLSPAN=5><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE><br>\n";


$$hash_ref{'current_detail'}=~s/\n/\n<BR>/g;
$table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 width=\"80%\" align=center>\n";
$table .=   "<TR BGCOLOR=\"$head_color\">";
$table .=   "<TD background=\"$v_graphics_path/bg_title.gif\" colspan=2 align=center><b>Current Event Detail</b></TD>";
$table .= 	"</TR>\n";
$table .=   "<TR BGCOLOR=\"$title_color\">";
$table .=   "<TD valign=top align=center>";
$table .=   &color_code($$hash_ref{'current_status'});
$table .= 	"</TD>";
#$table .=	"<TD>&nbsp;<B>[TIMESTAMP]</B></TD>";
$table .=	"<TD>&nbsp;<B>Since: $$hash_ref{'last_changed'}</B></TD>";
$table .=	"</TR>\n";
$table .= 	"<TR BGCOLOR=\"$desc_color\">";
$table .=   "<TD>&nbsp;</TD>";
$table .=	"<TD>";
$$hash_ref{'current_detail'}=~s/(\S{80})/$1 \n/g;
$table .= 	"$$hash_ref{'current_detail'}";
$table .= "</TD></TR>\n";
$table .= "<TR HEIGHT=2 BGCOLOR=\"$head_color\"><TD COLSPAN=2><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE><br>\n";


$table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2  WIDTH=\"80%\" align=center>\n";
$table .=   "<TR BGCOLOR=\"$head_color\">";
$table .=   "<TD background=\"$v_graphics_path/bg_title.gif\" align=center><b>Last 24 Hours</b></TD>";
$table .=   "</TR>\n";
$table .=   "<TR BGCOLOR=\"$desc_color\">";
$table .=   "<TD align=center>";
# Get the history graph:
$table .= &get_history_graph($args{'host_name'},$args{'service'});

$table .= "</TD></TR>\n";
$table .= "<TR HEIGHT=2 BGCOLOR=\"$head_color\"><TD><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE><br>\n";
$table .= &get_previous_events(  host_name=> $args{'host_name'},
                                 service  => $args{'service'},
                                 limit    => 40,
                              );

push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
############################
sub get_history_graph{
my ($host_name,$service) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
my $now;
my $max_minutes = 11; #after this we figure the client is dead and reflect that in the graph
my @durations;
my @time_refs;
my @time_status;
my $day_seconds = 60 * 60 * 24;
my $now_hour;
my $start_time;
my $last_status;
my $spacer_gif		= "<IMG SRC=\"$v_graphics_path/spacer.gif\" width=2 height=20>";
my $dead_client = 0;
my $current_status = "BLUE"; #in case we get no return;

# check if it's been updated lately
# to determine what our endpoint should be:
$sql_query = " SELECT \
						current_status, \
                  UNIX_TIMESTAMP(NOW()) AS NOW, \
                  UNIX_TIMESTAMP(last_checked) AS LAST, \
                  EXTRACT(HOUR FROM NOW()) AS NOW_HOUR, \
                  UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(last_checked) AS DIFF \
               FROM \
                  dm_monitor_current \
                WHERE \
                  (UPPER(host_name) = UPPER('$host_name')) AND \
                  (service = '$service')";


$db_ptr = &run_query($sql_query);
$hash_ref=$db_ptr->fetchrow_hashref;
$current_status = $$hash_ref{'current_status'} if ($$hash_ref{'current_status'});
if ($$hash_ref{'DIFF'} > ($max_minutes*60)){
	$now = $$hash_ref{'NOW'};
	$dead_client = 1;
}
else{
	$now = $$hash_ref{'LAST'};
}
$now_hour = $$hash_ref{'NOW_HOUR'};

# make time scale:
$table .= "<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH=\"100%\">\n<TR>\n";
$table .= "<TD WIDTH=\"2%\">&nbsp;</TD>";
my $temp_reverse;
for (1..24){
	$temp_reverse = "<TD ALIGN=left WIDTH=\"4%\">$now_hour</TD>" . $temp_reverse;
	&subtract_hour(\$now_hour);
}
$table .= $temp_reverse;
$table .= "<TD WIDTH=\"2%\">&nbsp;</TD>";
$table .= "</TR>\n<TR><TD>&nbsp;</TD><TD colspan=24 NOWRAP>";
$table .= "<TABLE BORDER=0 WIDTH=\"100%\" CELLSPACING=1 CELLPADDING=0><TR HEIGHT=20>\n";


$sql_query = "	SELECT \ 
						UNIX_TIMESTAMP(event_timestamp) AS TIME, \
						UNIX_TIMESTAMP(DATE_ADD(FROM_UNIXTIME($now), INTERVAL -1 DAY)) AS START, \
						status \
					FROM \
						dm_monitor_events \
					WHERE \
						(event_timestamp >= DATE_ADD(FROM_UNIXTIME($now), INTERVAL -1 DAY)) AND \
						(host_name = '$host_name') AND \
						(service = '$service') \
					ORDER BY time DESC";

$db_ptr = &run_query($sql_query);
my $time;
my $recent_events;

while ($hash_ref=$db_ptr->fetchrow_hashref){
	$recent_events = 1 if (!$recent_events);#shows that there was at least one result
	if (!$start_time){ #then this is our first run through :
		if ($dead_client){
			push (@durations,($now - $$hash_ref{'TIME'}));
			push (@time_refs,$now);
			push (@time_status,"BLUE");
		}
		$start_time = $$hash_ref{'START'};
	}
	my $duration = ($time_refs[((@time_status) - 1)]) 
			? ($time_refs[((@time_status) - 1)] - $$hash_ref{'TIME'})
			: ($now - $$hash_ref{'TIME'});
	push (@durations,$duration);
	push (@time_refs,$$hash_ref{'TIME'});
	push (@time_status,$$hash_ref{'status'});
	$time = $$hash_ref{'TIME'};
}


if ($recent_events){

	# Check for the leftover value:
	if ($time != $start_time){
		my $duration = ($time_refs[((@time_status) - 1)])
	         ? ($time_refs[((@time_status) - 1)] - $start_time)
	         : ($now - $start_time);
	#check for old value:
	$sql_query = "	SELECT status FROM dm_monitor_events \
						WHERE \
							(event_timestamp <= DATE_ADD(FROM_UNIXTIME($now), INTERVAL -1 DAY)) AND \
	                  (host_name = '$host_name') AND \
	                  (service = '$service') AND \
							(sid = '$monitor_sid') \
						ORDER BY event_timestamp DESC \
						LIMIT 1";
	my $db_ptr_2 = &run_query($sql_query);
	my $hash_ref_2;
	my $old_status = ($hash_ref_2=$db_ptr_2->fetchrow_hashref)
		? $$hash_ref_2{'status'}
		: 'BLUE';

	   push (@durations,$duration);
	   push (@time_refs,$start_time);
	   push (@time_status,$old_status);# = no report
	}
}
else{
# then there were no recent results, so we'll assume that the current status is 
# what it's been for the past 24 hrs:
	push (@durations,($now - $start_time));
	$sql_query = " SELECT \
                  UNIX_TIMESTAMP(DATE_ADD(FROM_UNIXTIME($now), INTERVAL -1 DAY)) AS START";
	$db_ptr = &run_query($sql_query);
	($hash_ref=$db_ptr->fetchrow_hashref) || &error("DB error while trying to get date information.");
	push (@time_refs,$$hash_ref{'START'});
   push (@time_status,$current_status);# = current status we got in the beginning
}

for (my $i=((@durations)-1);$i>=0;$i--){
	my $percent = &round(($durations[$i] / $day_seconds) * 100);
#	$percent -= 1 if ($percent > 1);
	$percent = ($percent > 0) 
		? "$percent%"
		: "1%";
		#: "4";
#&debug(&convert_long_ip($long_ip) . " has $percent of the day at $time_status[$i]");
	$table .= "<TD WIDTH=\"$percent\" BGCOLOR=\"";
	if ($time_status[$i] =~/green/i){
		$table .= "green";
		$last_status = "green";
	}
	elsif ($time_status[$i] =~/red/i){
		$table .= "red";
		$last_status = "red";
	}
	elsif ($time_status[$i] =~/yellow/i){
		$table .= "yellow";
		$last_status = "yellow";
	}
	else{
		$table .= "blue";
		$last_status = "blue";
	}
	$table .= "\">$spacer_gif</TD>";
}

$table .= "<TD>&nbsp;</TD></TR>\n</TABLE>\n";
$table .="</TD></TR></TABLE>\n";
return $table;


}
##################
sub get_previous_events{
my (%args) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
my $results;

($args{'host_name'}) 	|| return;# non-critical, don't error out
($args{'service'}) 		|| return;# non-critical, don't error out
($args{'limit'}=~/^\d+$/)|| ($args{'limit'} = 40);
&safe_slash(\$args{'service'});

$sql_query = "	SELECT \
						eid, status, event_timestamp, detail \
					FROM \
						dm_monitor_events \
					WHERE \
                  (host_name = '$args{'host_name'}') AND \
                  (service = '$args{'service'}') AND \
                  (sid = '$monitor_sid') \
               ORDER BY event_timestamp DESC \
               LIMIT $args{'limit'}";
#&debug($sql_query);

$db_ptr = &run_query($sql_query);
$table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 width=\"80%\" align=center>\n";

# Header row:
$table .= "<TR BGCOLOR=\"$head_color\"><TD COLSPAN=2 BACKGROUND=\"$v_graphics_path/bg_title.gif\" ALIGN=center>";
$table .= "<B>Last $args{'limit'} Events</B>";
$table .= "</TD></TR>\n";


while ($hash_ref=$db_ptr->fetchrow_hashref){
	$table .= "<TR BGCOLOR=\"$title_color\">";
	$table .= "<TD ALIGN=center>";
	$table .= "<A HREF=\"$home_url?td=view_monitored_service_history_detail&eid=$$hash_ref{'eid'}\">";
	$table .= &color_code($$hash_ref{'status'});
	$table .= "</A>";
	$table .= "</TD>";
	#$table .= "<TD>&nbsp;<b>[TIMESTAMP]</b></TD>";
	$table .= "<TD>&nbsp;<b>$$hash_ref{'event_timestamp'}</b></TD>";
	$$hash_ref{'detail'}=~s/(^[\s\S]*?\n[\s\S]*?\n[\s\S]*?)\n[\s\S]*$/$1\.\.\./; #truncate detail to 3 lines
	$$hash_ref{'detail'}=~s/^[\s\S]*?\n//; #take out first line (timedate stamp)
	$$hash_ref{'detail'}=~s/\n/<BR>\n/g;
	$table .= "</TR>";
	$table .= "<TR BGCOLOR=\"$desc_color\">";
	$table .= "<TD>&nbsp;</TD>";
	$$hash_ref{'detail'}=~s/(\S{80})/$1 \n/g;
	$table .= "<TD>$$hash_ref{'detail'}</TD>";
	$table .= "</TR>\n";
	$results = 1;
}
$table .= "<TR><TD ALIGN=center><B>No Events in history yet</B></TD></TR>\n" if (!$results);
$table .= "<TR HEIGHT=2 BGCOLOR=\"$head_color\"><TD COLSPAN=2><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE>\n";

return $table;
}
##################
sub subtract_hour{
my ($hour_ref) = @_;

$$hour_ref-- ;
$$hour_ref = 23 if ($$hour_ref < 0);

}
###################
sub is_admin{
my ($admin_level) = @_;

return 1 if ($is_admin);

return 2 if (($admin_level eq "f1") && ($is_f1_admin));
return 2 if (($admin_level eq "f2") && ($is_f2_admin));
return 2 if (($admin_level eq "f3") && ($is_f3_admin));

return 0;
}
###################
sub is_any_admin{
my ($admin_level) = @_;

return 1 if ($is_admin);
return 2 if ($is_f1_admin);
return 2 if ($is_f2_admin);
return 2 if ($is_f3_admin);

return 0;
}
###################
sub delete_monitored_service{
my ($host_name,$service) = @_;

#check that it only has acceptable dns characters or numbers and at least one "."
($host_name=~/^[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-\.]+$/)
 						|| &error("Invalid hostname passed.");
$service					=~tr/a-zA-Z0-9\.\-\_//dc;
($service) 				|| &error("No service passed");

my $sql_query;

$sql_query = "	DELETE FROM \
						dm_monitor_current \
					WHERE \
						sid 		= '$monitor_sid' AND \
						UPPER(host_name) 	= UPPER('$host_name') AND \
						service	= '$service' ";
&connect_to_db;
($db->do($sql_query)) || &error("DB error occured while deleting service, please try again.");

&push_message("<FONT COLOR=red><CENTER>Monitored service $service for $host_name deleted.</CENTER></FONT>");
}
###################
sub print_edit_monitored_service{
my ($host_name,$service) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;

#check that it only has acceptable dns characters or numbers and at least one "."
($host_name=~/^[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-\.]+$/)
 						|| &error("Invalid hostname passed.");
$service					=~tr/a-zA-Z0-9\.\-\_//dc;
($service) 				|| &error("No service passed.");


$sql_query = "	SELECT \
					client_sid,grouping,port,check_dns \	
				FROM \
						dm_monitor_current \
				WHERE \
						sid 		= '$monitor_sid' AND \
						host_name 	= '$host_name' AND \
						service	= '$service' ";
&connect_to_db;
$db_ptr = &run_query($sql_query);
($hash_ref=$db_ptr->fetchrow_hashref) || &error("Error retrieving monitored service record.  Please make sure it has not been deleted.");

$table .= "<TABLE BORDER=0 ALIGN=center CELLSPACING=0 CELLPADDING=0>";
$table .= "<TR bgcolor=\"$head_color\"><TD background=\"$v_graphics_path/bg_title.gif\" ALIGN=center><B>Edit Service Monitoring Event</B></TD></TR>";
$table .= "<TR bgcolor=\"#000000\"><TD ALIGN=center>";


$table .= "<FORM ACTION=\"$home_url\" METHOD=post>";
$table .= "<TABLE BORDER=0 ALIGN=center CELLSPACING=1 CELLPADDING=6>";
$table .= "<TR><TD bgcolor=\"$desc_color\" ALIGN=center>";
$table .= "<INPUT TYPE=hidden NAME=td VALUE=do_edit_monitored_service>";
$table .= "<INPUT TYPE=hidden NAME=service VALUE=\"$service\">";
$table .= "<INPUT TYPE=hidden NAME=old_host_name VALUE=\"$host_name\">";#needed bc we allow them to change this
$table .= "Monitored Service:";
$table .= "</TD><TD bgcolor=\"$desc_color\" ALIGN=center>";
$table .= "Hostname:";
$table .= "</TD><TD bgcolor=\"$desc_color\" ALIGN=center>";
$table .= "Grouping:";
$table .= "</TD><TD bgcolor=\"$desc_color\" ALIGN=center>";

if ($$hash_ref{'client_sid'}){
	$table .= "Local Service for SID:";
}
else{
	$table .= "Non-standard Port:";
}

$table .= "</TD><TD bgcolor=\"$desc_color\" ALIGN=center>";
$table .= "Check DNS";
$table .= "</TD></TR>";

$table .= "<TR><TD bgcolor=\"$desc_color\">";
$table .= "<B>$service</B>";
$table .= "</TD><TD bgcolor=\"$desc_color\">";
$table .= "<INPUT TYPE=text NAME=host_name VALUE=\"$host_name\" SIZE=28>";
$table .= "</TD><TD bgcolor=\"$desc_color\" ALIGN=center>";

$table .= "<SELECT NAME=grouping>";
$table .= "<OPTION selected>$$hash_ref{'grouping'}</OPTION>";
my @groups = &get_group_array;
foreach (@groups){
	$table .= "<OPTION>$_</OPTION>" unless ($_ eq "$$hash_ref{'grouping'}");
}
$table .= "</SELECT>";

$table .= "</TD><TD bgcolor=\"$desc_color\" ALIGN=center>";
$$hash_ref{'port'} = '' if (!$$hash_ref{'port'});#Set "0"'s to ''
if ($$hash_ref{'client_sid'}){
	$table .= "<SELECT NAME=client_sid>\n";
	$table .= "<OPTION VALUE=\"$$hash_ref{'client_sid'}\" selected>";
	$table .= &get_hostname_from_sid($$hash_ref{'client_sid'});
	$table .= "</OPTION>\n";

	my $db_ptr_2;
	my $hash_ref_2;
	my $sql_query_2;
	$sql_query_2 = "SELECT sid,hostname FROM sensor ORDER BY sid";
	$db_ptr_2 = &run_query($sql_query_2);
	while ($hash_ref_2=$db_ptr_2->fetchrow_hashref){
	   $table .= "<OPTION VALUE=\"$$hash_ref_2{'sid'}\">$$hash_ref_2{'sid'} - $$hash_ref_2{'hostname'}</OPTION>\n";
	}
	$table .= "</SELECT>";

}
else{
	$table .= "<INPUT TYPE=text NAME=port VALUE=\"$$hash_ref{'port'}\" SIZE=4>";
}

$table .= "</TD><TD bgcolor=\"$desc_color\">";
$table .= "<SELECT NAME=dns_check>";
if ($FORM{'check_dns'}){
	$table .= "<OPTION selected>Yes</OPTION>";
	$table .= "<OPTION>No</OPTION>";
}
else{
	$table .= "<OPTION selected>No</OPTION>";
	$table .= "<OPTION>Yes</OPTION>";
}
$table .= "</SELECT>";
$table .= "</TD></TR>";
$table .= "<TR><TD bgcolor=\"$desc_color\" COLSPAN=5 ALIGN=center>";

$table .= << "EOF";
<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0><TR><TD>
<SELECT NAME=todo>
<OPTION selected>Update</OPTION>
<OPTION>Delete</OPTION>
</SELECT>
</TD><TD WIDTH=20>&nbsp;</TD><TD>
<INPUT TYPE=Submit VALUE=Update style=\"font-size:8pt\">
</TD></TR>
</TABLE>
EOF

$table .= "</TD></TR>";

if ($service=~/^proc$/i){
$table .= << "EOF";
<TR><TD bgcolor="$desc_color" COLSPAN=5 ALIGN=center>
<A HREF="$home_url?td=print_add_special_monitoring_event&host_name=$host_name&client_sid=$$hash_ref{'client_sid'}&special_service=Proc">Edit Process Monitoring Rules</A>
</TD>
</TR>
EOF
}
elsif ($service=~/^logs$/i){
$table .= << "EOF";
<TR><TD bgcolor="$desc_color" COLSPAN=5 ALIGN=center>
<A HREF="$home_url?td=print_add_special_monitoring_event&host_name=$host_name&client_sid=$$hash_ref{'client_sid'}&special_service=Logs">Edit Log Monitoring Rules</A>
</TD>
</TR>
EOF
}

$table .= "</TABLE>";
$table .= "</FORM>";


$table .= "</TD></TR>";
$table .= "<TR BGCOLOR=\"$head_color\" HEIGHT=2><TD><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE>";


push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
#######################
sub set_cookie{
my ($session_uid) = @_;
    my $cookie = new CGI::Cookie(-name => 's_key', -value => $session_uid, -path => '/');
    print "Set-Cookie: ",$cookie->as_string, "\n";

}
#######################
sub set_no_mini_view_cookie{
    my $cookie = new CGI::Cookie(-name => 'nmv', -value => "yes", -path => '/');
    print "Set-Cookie: ",$cookie->as_string, "\n";
}
#######################
sub set_show_mini_view_cookie{
my ($val) = @_;
    my $cookie = new CGI::Cookie(-name => 'nmv', -value => 'no', -path => '/');
    print "Set-Cookie: ",$cookie->as_string, "\n";
}
#######################
sub print_login_screen{
my $html = &get_login_page;
my $message;
if (@messages){
	foreach (@messages){
		$message .= "<CENTER>$_</CENTER><BR>";
	}
}
push (@substitutions,"\\[MESSAGE\\],-,$message");

&print_with_key('','',$html);

}
######################
sub get_login_page{

my $html;
$html = << "EOF";
<html>
<head>
<title>DEMARC</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
<!--
td { font-family: Arial, Helvetica, sans-serif; font-size: 8pt; font-weight: normal }
A:link    {  font-family: Arial, Helvetica, sans-serif; font-size: 8pt; text-decoration: none; color: #FF9900 }
A:visited {  font-family: Arial, Helvetica, sans-serif; font-size: 8pt; text-decoration: none; color: #FF9900 }
A:hover   {  font-family: Arial, Helvetica, sans-serif; font-size: 8pt; text-decoration: underline; color: yellow}
A:link.nav {  font-family: Verdana, Arial, Helvetica, sans-serif; color: #000000}
A:visited.nav {  font-family: Verdana, Arial, Helvetica, sans-serif; color: #000000}
A:hover.nav {  font-family: Verdana, Arial, Helvetica, sans-serif; color: red;}
form { margin-bottom: 0}
-->
</style>
<script language="JavaScript1.1">
<!-- //Begin
function turnOn(imgName) {document[imgName].src=eval(imgName+"1.src");return false;}
function turnOff(imgName) {document[imgName].src=eval(imgName+"0.src");return false;}

function load_mini_me(){
window_handle=window.open('/dm/demarc?td=mini_me', 'MiniMe', 'top=0,left=0,scrollbars,resizable,width=166,height=500');
window_handle.focus();
return false;
}



// End -->
</script>
</head>

<body bgcolor="#000000" background="$v_graphics_path/background.gif" marginwidth=0 marginheight=0 topmargin=0 leftmargin=0 rightmargin=0 border=0 text=white>
<table border=0 cellpadding=0 cellspacing=0 width="100%">
<tr height=1 bgcolor=#CB9400><td><spacer type=block height=1></td></tr>
<tr height=20><td height=20 background="$v_graphics_path/bg_top.jpg" valign=top nowrap><center><img src="$v_graphics_path/demarc.jpg" width="215" height="38" alt="::demarc::" border="0"></center></td></tr>
<tr height=1 bgcolor=#B22404><td><spacer type=block height=1></td></tr>
<tr height=1 bgcolor=#000000><td><spacer type=block height=1></td></tr>
<tr height=1 bgcolor=#71797F><td><spacer type=block height=1></td></tr>

<tr bgcolor=#5A6267 height=20><td valign=top nowrap><center><spacer type=block height=20></center></td></tr>

<tr height=1 bgcolor=#333333><td><spacer type=block height=1></td></tr>
<tr height=1 bgcolor=#000000><td><spacer type=block height=1></td></tr>
<tr height=1 bgcolor=#CB9400><td><spacer type=block height=1></td></tr>
<tr height=1 bgcolor=#B22404><td><spacer type=block height=1></td></tr>
<tr height=2 bgcolor=#000000><td><spacer type=block height=2></td></tr>
</table>
<center>
<form method="post" action="[HOME_URL]">

        <table border="0" cellspacing="0" cellpadding="1">
          <tr><TD colspan=2 align=center>[MESSAGE]</TD></TR> 
          <tr> 
EOF
if ($allow_anonymous_access){
	$html .= << 'EOF';
            <td colspan="2" align="center"><b>Please login or click &quot;anonymous&quot; 
              button to login as an anonymous user.</b></td>
EOF
}
else{
	$html .= << 'EOF';
            <td colspan="2" align="center"><b>Please login</b></td>  
EOF
}
$html .= << 'EOF';
          </tr>
<tr><td>&nbsp;</td></tr>
	</table>
EOF
$html .= "<table border=\"0\" cellspacing=\"1\" cellpadding=\"1\" bgcolor=\"$miniborder_color\" align=\"center\">";          
$html .= << "EOF";
   <tr>
    <td>
        <table width="100%" border="0" cellspacing="0" cellpadding="2" bgcolor="#5A6267">
	<tr height=15><td rowspan=8 width=60>&nbsp;</td><td colspan=2><spacer type=block height=15></td><td rowspan=8 width=90>&nbsp;</td></tr>   
	<tr> 
            <td><b>Username</b></td>
            <td> 
              <input type="text" name="username" size="15" maxlength="16" autocomplete="off">
            </td>
          </tr>
          <tr> 
            <td><b>Password</b></td>
            <td> 
              <input type="password" name="password" size="15" maxlength="16" autocomplete="off">
  		<input type=hidden name=td value="login">
            </td>
          </tr>
	<tr height=5><td colspan=2><spacer type=block height=5></td></tr>
          <tr><td>&nbsp;</td> 
            <td align=center> 
              <input type="image" src="$v_graphics_path/bt_login0.gif" name="[login]" value="Login" alt="[login]" border=0>
            </td>
          </tr>
EOF
if ($allow_anonymous_access){
	$html .= << 'EOF';
          <tr><td>&nbsp;</td>
            <td align=center><a href="[HOME_URL]?td=login&username=anonymous&password=anonymous">anonymous</a></td>
          </tr>
EOF
}
$html .= << 'EOF';
	<tr height=15><td colspan=3><spacer type=block height=15></td></tr>
        </table>
    </td>
  </tr>
</table>
</form>
</center>
<SCRIPT LANGUAGE="JavaScript"><!--//
document.forms[0].elements[0].focus();
//--></SCRIPT>
</body>
</html>

EOF

return $html;
}
################
sub check_login{
my ($session_id) = @_;

($session_id) || return;
&expire_sessions;
my $sql_query;
my $db_ptr;
my $hash_ref;

if ($session_id eq "ANONYMOUS"){
	if ($allow_anonymous_access){
		$is_admin = 1 if ($anonymous_user_is_admin);#BAD BAD BAD - see warning at top of script
		return "Anonymous";
	}
	else{
		&error("Anonymous access is not allowed. BTW how did you get that session key unless you're trying to be a bad bad boy?","PLAIN");
	}
}

$sql_query = "	SELECT \
						f1,f2,f3,admin,username,UNIX_TIMESTAMP(current_login_timedate) AS LOGINTIME \
					FROM \
						dm_sessions \
					WHERE current_session_id = '$session_id' ";

if ($validate_ip){
	# make sure their session key hasn't been jacked
	$sql_query .= " AND current_ip = '" . &convert_dotted_ip($ENV{'REMOTE_ADDR'}) . "' ";
}
$db_ptr = &run_query($sql_query);
($hash_ref=$db_ptr->fetchrow_hashref) || return;

# extend users session if we're near the end and they're still using the session:
if (($$hash_ref{'LOGIN_TIME'} + ($session_timeout_minutes*60))  < (time() + 600)){
	#ie : user has less than 5 minutes left before s/he is expired
	$sql_query = "	UPDATE dm_sessions \
						SET current_login_timedate = NOW() \
						WHERE username = '$$hash_ref{'username'}'"; 
	&connect_to_db;
	($db->do($sql_query)) || &error("DB error occured while updating user's timeout. Please try again.","PLAIN");
}
# store admin value if they're an admin
$is_admin 		= 1 if ($$hash_ref{'admin'});
$is_f1_admin 	= 1 if ($$hash_ref{'f1'});
$is_f2_admin 	= 1 if ($$hash_ref{'f2'});
$is_f3_admin 	= 1 if ($$hash_ref{'f3'});
return $$hash_ref{'username'};

}
##################
sub expire_sessions{
my $sql_query;
my $db_ptr;
my $hash_ref;

$sql_query = " UPDATE dm_sessions \
               SET current_session_id = '' \
               WHERE \
						DATE_ADD(current_login_timedate, INTERVAL $session_timeout_minutes MINUTE) < NOW()";
&connect_to_db;
($db->do($sql_query));
}
###################
sub login{
my ($username,$password) = @_;

&safe_slash(\$username);
&safe_slash(\$password);

my $sql_query;
my $db_ptr;
my $hash_ref;
my $crypted_pw = crypt($password,$password);
my $long_ip 	= &convert_dotted_ip($ENV{'REMOTE_ADDR'});
my $new_session_id;

if ($username eq "anonymous"){
	if ($allow_anonymous_access){
		&set_cookie("ANONYMOUS");
		&log_event(	username => "Anonymous",
						action 	=> "login",
						target	=> '',
					 );
	$is_admin = 1 if ($anonymous_user_is_admin);#BAD BAD BAD - see warning at top of script

		return "Anonymous";	
	}
	else{
		&error("Anonymous access is not allowed.","PLAIN");
	}
}

$sql_query = "	SELECT \
						f1,f2,f3,ip_restrict,admin,username,current_ip, \
					DATE_FORMAT(current_login_timedate,\"%W %M %e, %Y at %r\") AS FORMATTED_DATE	 \
					FROM \
						dm_sessions \
					WHERE \
						username = '$username' AND \
						password = '$crypted_pw'";

#&debug($sql_query);
$db_ptr = &run_query($sql_query);
($hash_ref=$db_ptr->fetchrow_hashref) || return;

if (!(&check_if_immune($ENV{'REMOTE_ADDR'},$$hash_ref{'ip_restrict'}))){
		&log_event(	username => "$username",
						action 	=> "attempted login from restricted ip",
						target	=> '',
					 );
		&error("You are not allowed to log in to this service from $ENV{'REMOTE_ADDR'}","BLANK");
}


if ($$hash_ref{'current_ip'} && $$hash_ref{'FORMATTED_DATE'}){
	&push_message("<FONT COLOR=red style=\"font-family:arial; font-size:8pt;\"><CENTER>Last login from ". &convert_long_ip($$hash_ref{'current_ip'}) . " on $$hash_ref{'FORMATTED_DATE'}.</CENTER></FONT>");
}

#Register the new login:
$new_session_id = time() . &rand_string(6);

$sql_query = " UPDATE dm_sessions \
               SET \
						current_session_id 	  = '$new_session_id', \
						current_ip				  = '$long_ip' , \
						current_login_timedate = NOW() \
					WHERE \
						username = '$username' AND \
                  password = '$crypted_pw'";
&connect_to_db;
($db->do($sql_query)) || &error("DB Error while registering login.");	

&log_event(	username => "$username",
				action 	=> "login",
				target	=> '',
);

# store admin value if they're an admin
$is_admin = 1 if ($$hash_ref{'admin'});

$is_f1_admin 	= 1 if ($$hash_ref{'f1'});
$is_f2_admin 	= 1 if ($$hash_ref{'f2'});
$is_f3_admin 	= 1 if ($$hash_ref{'f3'});

&set_cookie($new_session_id);

return $username;
}
####################################
sub rand_string{
my ($suggested_length,$exact_length) = @_;
my $randstring;
my $i;

    for($i=0,$randstring="";$i<$suggested_length;$i++){
        if(int(rand(2))){
            $randstring.=chr(65+(int(rand(26))));
        }
        else{
            $randstring.=chr(97+(int(rand(26))));
        }
		if (!$exact_length){
        if(int(rand(2))){
            $randstring.=int(rand(10));
        }
		}
    }
    return $randstring;
}
####################################
sub logout{
	&set_cookie("REVOKED");
	&log_event(	username => "$logged_in_as",
					action 	=> "logout",
					target	=> '',
	);
}
####################################
sub print_monitor_ids_form{
my $sql_query;
my $db_ptr;
my $hash_ref;
my $html;
my @signatures;
my $sig_list;
my $table;
my $email_tag;
my $users_email;
my $non_admin_where;
my $ip_list;
my $group_list;
my $service_list;

$html = &get_monitor_ids_form;

@signatures = &get_signatures_array;

#$sig_list = "<SELECT NAME=signature>\n";
#$sig_list .= "<OPTION VALUE=0> - Select - </OPTION>";
foreach (@signatures){
	my $shorter_sig = $_;
	$shorter_sig=~s/(^.{50}).*$/$1\.\.\./;
	$sig_list .= "<OPTION VALUE=\'$_\'>$shorter_sig</OPTION>\n";
}
$sig_list .= "</SELECT>";
push (@substitutions,"\\[SIGNATURE_LIST\\],-,<SELECT NAME=signature>\n<OPTION VALUE=0> - Select - </OPTION>$sig_list");

$users_email = &get_users_email;

if (&is_any_admin){
	$email_tag = "<INPUT TYPE=text SIZE=20 NAME=email_address VALUE=\"$users_email\">";
}
else{
	$email_tag = "<B>$users_email</B>";
}
push (@substitutions,"\\[EMAIL_ADDRESS\\],-,$email_tag");
$table = &print_with_key('','TO_STRING',$html);

######
# List of current alert rules:

if (!(&is_any_admin)){
	$non_admin_where = " AND (email_address = '$users_email') ";
}

	$sql_query = "	SELECT * \
						FROM	dm_ids_alert_rules \
						WHERE (sid = '$monitor_sid') $non_admin_where \
						ORDER BY \
							email_address";
$db_ptr = &run_query($sql_query);

	
while ($hash_ref=$db_ptr->fetchrow_hashref){
	$table .= "<FORM ACTION=\"$home_url\" METHOD=POST>";
   $table .= "<INPUT TYPE=hidden NAME=td VALUE=\"alter_ids_alert_rule\">";
   $table .= "<INPUT TYPE=hidden NAME=alert_uid VALUE=\"$$hash_ref{'alert_uid'}\">";
	$table .= "<TABLE BORDER=0 WIDTH=\"80%\" CELLSPACING=1 CELLPADDING=2 align=center>\n";
   $table .= "<TR bgcolor=\"$head_color\"><TD colspan=4 align=center background=\"$v_graphics_path/bg_title.gif\"><B>Modify IDS Monitor Alert Rule $$hash_ref{'alert_uid'}</B></TD></TR>\n";
   $table .= "<TR bgcolor=\"$title_color\">";
	$table .= "<TD align=center width=\"25%\"><b>Email Recipient</b></TD><TD align=center width=\"25%\"><b>Alert Level</b></TD>";
   $table .= "<TD align=center width=\"25%\"><b>Notify From</b></TD><TD align=center width=\"25%\"><b>Notify Until</b></TD>";
	$table .= "</TR>";
	$table .= "<TR bgcolor=\"$desc_color\">";
   $table .= "<TD align=center>";
   $table .= (&is_any_admin || ($users_email eq $$hash_ref{'email_address'}))
            ? "<INPUT TYPE=text SIZE=20 NAME=email_address VALUE=\"$$hash_ref{'email_address'}\">"
            : $$hash_ref{'email_address'};
   $table .= "</TD>";
	$table .= "<TD align=center>";
	$table .= "<SELECT NAME=priority_level>";
my @p_array;
	$p_array[1] = "RED / P-1-";
	$p_array[2] = "YELLOW / P-2-";
	$p_array[3] = "P-3-";
	$p_array[4] = "P-4-";
	$p_array[5] = "P-5-";
	$p_array[6] = "P-6-";
	$table .= ($$hash_ref{'priority_level'})
				? "<OPTION VALUE=\"$$hash_ref{'priority_level'}\" selected>$p_array[$$hash_ref{'priority_level'}]</OPTION><OPTION VALUE=0>-Select-</OPTION>"
				: "<OPTION value=0 selected>-Select-</OPTION>";
	$table .= << "EOF";
                <option value="1">RED / P-1-</option>
                <option value="2">YELLOW / P-2-</option>
                <option value="3">P-3-</option>
                <option value="4">P-4-</option>
                <option value="5">P-5-</option>
                <option value="6">P-6-</option>
              </select>
EOF
	$table .= "</TD>";
   $table .= "<TD align=center>";
   $table .= "<SELECT NAME=only_alert_from_hour>";
   my $hr_alert_hour = $$hash_ref{'only_alert_from_hour'};
   if ($hr_alert_hour == 0){
      $hr_alert_hour = "12 AM";
   }
   elsif ($hr_alert_hour < 12){
      $hr_alert_hour = "$hr_alert_hour AM";
   }
   elsif ($hr_alert_hour == 12){
      $hr_alert_hour = "12 PM";
   }
   else{
      $hr_alert_hour -= 12;
      $hr_alert_hour = "$hr_alert_hour PM";
   }

   $table .= "<OPTION VALUE=\"$$hash_ref{'only_alert_from_hour'}\" selected>$hr_alert_hour</OPTION>";
$table .= << "EOF";
                <option value="0">12 AM</option>
                <option value="1">1 AM</option>
                <option value="2">2 AM</option>
                <option value="3">3 AM</option>
                <option value="4">4 AM</option>
                <option value="5">5 AM</option>
                <option value="6">6 AM</option>
                <option value="7">7 AM</option>
                <option value="8">8 AM</option>
                <option value="9">9 AM</option>
                <option value="10">10 AM</option>
                <option value="11">11 AM</option>
                <option value="12">12 PM</option>
                <option value="13">1 PM</option>
                <option value="14">2 PM</option>
                <option value="15">3 PM</option>
                <option value="16">4 PM</option>
                <option value="17">5 PM</option>
                <option value="18">6 PM</option>
                <option value="19">7 PM</option>
                <option value="20">8 PM</option>
                <option value="21">9 PM</option>
                <option value="22">10 PM</option>
                <option value="23">11 PM</option>
              </select>
EOF
   $table .= "</TD><TD align=center>";
   $table .= "<SELECT NAME=only_alert_to_hour>";
   $hr_alert_hour = $$hash_ref{'only_alert_to_hour'};
   if ($hr_alert_hour == 0){
      $hr_alert_hour = "12 AM";
   }
   elsif ($hr_alert_hour < 12){
      $hr_alert_hour = "$hr_alert_hour AM";
   }
   else{
      $hr_alert_hour -= 12;
      $hr_alert_hour = "$hr_alert_hour PM";
   }

   $table .= "<OPTION VALUE=\"$$hash_ref{'only_alert_to_hour'}\" selected>$hr_alert_hour</OPTION>";
$table .= << "EOF";
                <option value="0">12 AM</option>
                <option value="1">1 AM</option>
                <option value="2">2 AM</option>
                <option value="3">3 AM</option>
                <option value="4">4 AM</option>
                <option value="5">5 AM</option>
                <option value="6">6 AM</option>
                <option value="7">7 AM</option>
                <option value="8">8 AM</option>
                <option value="9">9 AM</option>
                <option value="10">10 AM</option>
                <option value="11">11 AM</option>
                <option value="12">12 PM</option>
                <option value="13">1 PM</option>
                <option value="14">2 PM</option>
                <option value="15">3 PM</option>
                <option value="16">4 PM</option>
                <option value="17">5 PM</option>
                <option value="18">6 PM</option>
                <option value="19">7 PM</option>
                <option value="20">8 PM</option>
                <option value="21">9 PM</option>
                <option value="22">10 PM</option>
                <option value="23">11 PM</option>
              </select>
EOF
	$table .= "</TD>";
	$table .= "</TR>\n";
   $table .= "<TR bgcolor=\"$title_color\">";
   $table .= "<TD align=center colspan=2><b>Existing Signature</b></TD><TD align=center colspan=2><b>Signature Contains</b></TD>";
   $table .= "</TR>";
   $table .= "<TR bgcolor=\"$desc_color\">";
	$table .= "<TD align=center colspan=2>";
	$table .= "<SELECT NAME=signature>";
	$table .= ($$hash_ref{'signature_is'})
				? "<OPTION selected>$$hash_ref{'signature_is'}</OPTION><OPTION value=0>-Select-</OPTION>"
				: "<OPTION selected value=0>-Select-</OPTION>";
	$table .= $sig_list;
	$table .= "</TD>";
	$table .= "<TD align=center colspan=2><INPUT TYPE=text SIZE=30 maxlength=60 NAME=signature_contains VALUE=\"$$hash_ref{'signature_contains'}\"></TD>";
	$table .= "</TR>\n";

## Third Row
	$table .= "<TR bgcolor=\"$desc_color\">";
	$table .= "<TD COLSPAN=4 ALIGN=center>";
	$table .= << "EOF";
<SELECT NAME=action>
<OPTION selected>Update</OPTION>
<OPTION>Delete</OPTION>
</SELECT>
EOF
	$table .= "<INPUT TYPE=Submit VALUE=Update style=\"font-size:8pt\"></TD>";
	$table .= "</TR>\n";
	$table .= "<TR HEIGHT=2 BGCOLOR=\"$head_color\"><TD COLSPAN=4><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
	$table .= "</TABLE>\n";
	$table .= "</FORM><br>\n";
}




push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
####################################
sub print_monitor_md5_form{
my $sql_query;
my $db_ptr;
my $hash_ref;
my $html;
my $table;
my $email_tag;
my $users_email;
my $non_admin_where;


$users_email = &get_users_email;

if (&is_any_admin){
	$email_tag = "<INPUT TYPE=text SIZE=20 NAME=email_address VALUE=\"$users_email\">";
}
else{
	$email_tag = "<B>$users_email</B>";
}
push (@substitutions,"\\[EMAIL_ADDRESS\\],-,$email_tag");

my $sid_list = &get_sids_dropdown("monitored_sid","ANY");
push (@substitutions,"\\[SID_LIST\\],-,$sid_list");

$table = &print_with_key($monitor_md5_form,'TO_STRING');

######
# List of current alert rules:

if (!(&is_any_admin)){
	$non_admin_where = " AND (email_address = '$users_email') ";
}

	$sql_query = "	SELECT *, \
						((TIME_TO_SEC(suspend_until) - TIME_TO_SEC(NOW()))/60) AS MINUTE_DIFF \
						FROM	dm_md5_alert_rules \
						WHERE (sid = '$monitor_sid') $non_admin_where \
						ORDER BY \
							UPPER(email_address)";
$db_ptr = &run_query($sql_query);

	
$sid_list=~s/^[\s\S]*?\/option\s*>//i;

while ($hash_ref=$db_ptr->fetchrow_hashref){
	$table .= "<FORM ACTION=\"$home_url\" METHOD=POST>";
   $table .= "<INPUT TYPE=hidden NAME=td VALUE=\"alter_md5_alert_rule\">";
   $table .= "<INPUT TYPE=hidden NAME=alert_uid VALUE=\"$$hash_ref{'alert_uid'}\">";
	$table .= "<TABLE BORDER=0 WIDTH=\"80%\" CELLSPACING=1 CELLPADDING=2 align=center>\n";
	$table .= "<TR BGCOLOR=\"$head_color\"><TD align=center background=\"$v_graphics_path/bg_title.gif\" colspan=4><B>Current File / Web Integrity Alert Rule $$hash_ref{'alert_uid'}</B></TD></TR>\n";
#ROW 1 
  	$table .= "<TR bgcolor=\"$title_color\">";
	$table .= "<TD colspan=2 align=center width=\"50%\"><b>Email Recipient</b></TD><TD align=center width=\"50%\" colspan=2><b>Sensor</b></TD>";
	$table .= "</TR>\n";

	$table .= "<TR bgcolor=\"$desc_color\">";
   $table .= "<TD align=center colspan=2 >";
   $table .= (&is_any_admin || ($users_email eq $$hash_ref{'email_address'}))
            ? "<INPUT TYPE=text SIZE=20 NAME=email_address VALUE=\"$$hash_ref{'email_address'}\">"
            : $$hash_ref{'email_address'};
   $table .= "</TD>";
	$table .= "<TD align=center colspan=2>";
	$table .= "<SELECT NAME=monitored_sid>\n";
	$table .= ($$hash_ref{'monitored_sid'})
				? "<OPTION selected>$$hash_ref{'monitored_sid'}</OPTION><OPTION VALUE=0>ANY</OPTION>"
				: "<OPTION selected VALUE=0>ANY</OPTION>";
	$table .= $sid_list;
	$table .= "</TD>";
	$table .= "</TR>";

   $table .= "<TR bgcolor=\"$title_color\">";
   $table .= "<TD align=center><b>Alert Level</b></TD><TD align=center><b>Email Detail Level</b></TD><TD align=center><b>Notify From</b></TD><TD align=center><b>Notify Until</b></TD>";
   $table .= "</TR>\n";
	$table .= "<TR bgcolor=\"$desc_color\">";
   $table .= "<TD ALIGN=center>";
   $table .= "<SELECT NAME=alert_level>\n";
      if ($$hash_ref{'alert_level'} == 1){
         $table .= "<OPTION VALUE=0>ANY</OPTION>";
         $table .= "<OPTION VALUE=1 selected>RED</OPTION>";
         $table .= "<OPTION VALUE=2>YELLOW</OPTION>";
      }
      elsif ($$hash_ref{'alert_level'} == 2){
         $table .= "<OPTION VALUE=0>ANY</OPTION>";
         $table .= "<OPTION VALUE=1>RED</OPTION>";
         $table .= "<OPTION VALUE=2 selected>YELLOW</OPTION>";
      }
      else{
         $table .= "<OPTION VALUE=0 selected>ANY</OPTION>";
         $table .= "<OPTION VALUE=1>RED</OPTION>";
         $table .= "<OPTION VALUE=2>YELLOW</OPTION>";
      }
   $table .= "</SELECT>";

   $table .= "</TD>";
   $table .= "<TD ALIGN=center>";
   $table .= "<SELECT NAME=detail_level>\n";
      if ($$hash_ref{'detail_level'} == 1){
         $table .= "<OPTION VALUE=1 selected>High</OPTION>";
      }
      else{
         $table .= "<OPTION VALUE=0 selected>Low</OPTION>";
      }
   $table .= << "EOF";
<OPTION VALUE=0>Low</OPTION>
<OPTION VALUE=1>High</OPTION>
EOF

   $table .= "</SELECT>";
	$table .= "</TD>";

   $table .= "<TD ALIGN=center>";
   $table .= "<SELECT NAME=only_alert_from_hour>";
   my $hr_alert_hour = $$hash_ref{'only_alert_from_hour'};
   if ($hr_alert_hour == 0){
      $hr_alert_hour = "12 AM";
   }
   elsif ($hr_alert_hour < 12){
      $hr_alert_hour = "$hr_alert_hour AM";
   }
   elsif ($hr_alert_hour == 12){
      $hr_alert_hour = "12 PM";
   }
   else{
      $hr_alert_hour -= 12;
      $hr_alert_hour = "$hr_alert_hour PM";
   }

   $table .= "<OPTION VALUE=\"$$hash_ref{'only_alert_from_hour'}\" selected>$hr_alert_hour</OPTION>";
$table .= << "EOF";
                <option value="0">12 AM</option>
                <option value="1">1 AM</option>
                <option value="2">2 AM</option>
                <option value="3">3 AM</option>
                <option value="4">4 AM</option>
                <option value="5">5 AM</option>
                <option value="6">6 AM</option>
                <option value="7">7 AM</option>
                <option value="8">8 AM</option>
                <option value="9">9 AM</option>
                <option value="10">10 AM</option>
                <option value="11">11 AM</option>
                <option value="12">12 PM</option>
                <option value="13">1 PM</option>
                <option value="14">2 PM</option>
                <option value="15">3 PM</option>
                <option value="16">4 PM</option>
                <option value="17">5 PM</option>
                <option value="18">6 PM</option>
                <option value="19">7 PM</option>
                <option value="20">8 PM</option>
                <option value="21">9 PM</option>
                <option value="22">10 PM</option>
                <option value="23">11 PM</option>
              </select>
EOF

   $table .= "</TD><TD align=center>";
   $table .= "<SELECT NAME=only_alert_to_hour>";
   $hr_alert_hour = $$hash_ref{'only_alert_to_hour'};
   if ($hr_alert_hour == 0){
      $hr_alert_hour = "12 AM";
   }
   elsif ($hr_alert_hour < 12){
      $hr_alert_hour = "$hr_alert_hour AM";
   }
   else{
      $hr_alert_hour -= 12;
      $hr_alert_hour = "$hr_alert_hour PM";
   }

   $table .= "<OPTION VALUE=\"$$hash_ref{'only_alert_to_hour'}\" selected>$hr_alert_hour</OPTION>";
$table .= << "EOF";
                <option value="0">12 AM</option>
                <option value="1">1 AM</option>
                <option value="2">2 AM</option>
                <option value="3">3 AM</option>
                <option value="4">4 AM</option>
                <option value="5">5 AM</option>
                <option value="6">6 AM</option>
                <option value="7">7 AM</option>
                <option value="8">8 AM</option>
                <option value="9">9 AM</option>
                <option value="10">10 AM</option>
                <option value="11">11 AM</option>
                <option value="12">12 PM</option>
                <option value="13">1 PM</option>
                <option value="14">2 PM</option>
                <option value="15">3 PM</option>
                <option value="16">4 PM</option>
                <option value="17">5 PM</option>
                <option value="18">6 PM</option>
                <option value="19">7 PM</option>
                <option value="20">8 PM</option>
                <option value="21">9 PM</option>
                <option value="22">10 PM</option>
                <option value="23">11 PM</option>
              </select>
EOF


   $table .= "</TD></TR>\n";

   $table .= "<TR bgcolor=\"$title_color\">";
   $table .= "<TD align=center colspan=4><b>Suspend Alerts (Hours)</b></TD>";
   $table .= "</TR>\n";
	$table .= "<TR bgcolor=\"$desc_color\">";
   $table .= "<TD ALIGN=center colspan=4>";
   $table .= << "EOF";
<SELECT NAME=suspend_alerts>
<OPTION VALUE=0 selected>NA</OPTION>
<OPTION VALUE=99>RESET</OPTION>
<OPTION VALUE=1> 1 </OPTION>
<OPTION VALUE=2> 2 </OPTION>
<OPTION VALUE=3> 3 </OPTION>
<OPTION VALUE=4> 4 </OPTION>
<OPTION VALUE=5> 5 </OPTION>
<OPTION VALUE=6> 6 </OPTION>
</SELECT>
</TD>
EOF
	$table .= "</TR>";


   $table .= "<TR bgcolor=\"$desc_color\">";
   $table .= "<TD COLSPAN=4 ALIGN=center>";	
	if ($$hash_ref{'MINUTE_DIFF'} > 0){
		$table .= "<B>Alerts suspended for $$hash_ref{'MINUTE_DIFF'} more minutes.</B><BR>";
	}

	$table .= << "EOF";
<SELECT NAME=action>
<OPTION selected>Update</OPTION>
<OPTION>Delete</OPTION>
</SELECT>
EOF
	$table .= "<INPUT TYPE=Submit VALUE=Update style=\"font-size:8pt\"></TD>";
	$table .= "</TR>\n";
	$table .= "<TR BGCOLOR=\"$head_color\" HEIGHT=2><TD colspan=4><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
	$table .= "</TABLE>\n";
	$table .= "</FORM><BR>\n";
}




push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
####################################
sub print_monitor_service_form{
my $sql_query;
my $db_ptr;
my $hash_ref;
my $html;
my @services;
my $service_list;
my $table;
my $email_tag;
my $users_email;
my $non_admin_where;
my @ip_addresses;
my @hosts;
my $ip_list;
my @groups;
my $group_list;

$html = &get_monitor_service_form;

$service_list = &get_services_dropdown;

$service_list=~s/^[\s\S]+?<\/OPTION>//i; #take it out for the update form later
push (@substitutions,"\\[SERVICE_LIST\\],-,<SELECT NAME=service><OPTION VALUE=NOT_SELECTED selected>ANY</OPTION>$service_list");


# changed from IP addresses to hostnames, but lets keep most of the same variable names...
@hosts = &get_hostname_array;
foreach (@hosts){
	$ip_list .= "<OPTION VALUE=\"$_\">$_</OPTION>";
}
$ip_list .= "</SELECT>";
push (@substitutions,"\\[IP_LIST\\],-,<SELECT NAME=host_name><OPTION selected>ANY</OPTION>$ip_list");

@groups = &get_group_array;
foreach (@groups){
	$group_list .= "<OPTION>$_</OPTION>";
}
$group_list .= "</SELECT>";
push (@substitutions,"\\[GROUP_LIST\\],-,<SELECT NAME=grouping><OPTION selected>ANY</OPTION>$group_list");


$users_email = &get_users_email;

if (&is_any_admin){
	$email_tag = "<INPUT TYPE=text SIZE=20 NAME=email_address VALUE=\"$users_email\">";
}
else{
	$email_tag = "<B>$users_email</B>";
}
push (@substitutions,"\\[EMAIL_ADDRESS\\],-,$email_tag");
$table = &print_with_key('','TO_STRING',$html);

###
# Now for the existing alerts:
if (!(&is_admin("f2"))){
	$non_admin_where = " AND (email_address = '$users_email') ";
}

	$sql_query = "	SELECT * \
						FROM	dm_monitor_alert_rules \
						WHERE (sid = '$monitor_sid') $non_admin_where \
						ORDER BY \
							grouping,host_name";
$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
   $table .= "<TABLE BORDER=0 WIDTH=\"85%\" CELLSPACING=1 CELLPADDING=2 align=center>\n";
   $table .= "<TR bgcolor=\"$head_color\"><TD colspan=4 align=center background=\"$v_graphics_path/bg_title.gif\"><B>Host/Service Monitor Alert Rule $$hash_ref{'alert_uid'}</B></TD></TR>\n";
	$table .= "<FORM ACTION=\"$home_url\" METHOD=POST>";
	$table .= "<TR bgcolor=\"$title_color\">\n";
	$table .= "<TD ALIGN=center width=\"25%\"><b>Email Recipient</b></TD>";
	$table .= "<TD ALIGN=center width=\"25%\"><b>Hostname</b></TD>";
	$table .= "<TD ALIGN=center width=\"25%\"><b>Group</b></TD>";
	$table .= "<TD ALIGN=center width=\"25%\"><b>Maximum Alert Frequency</b></TD>";
$table .= "</TR>\n";
	$table .= "<TR bgcolor=\"$desc_color\">\n";
   $table .= "<TD align=center>";
   if (&is_any_admin){
         $table .= "<INPUT TYPE=text SIZE=22 NAME=email_address VALUE=\"$$hash_ref{'email_address'}\">";
   }
   else{
         $table .= "<B>$$hash_ref{'email_address'}</B>";
   }
   $table .= "</TD>";
	$table .= "<TD align=center>";
	$table .= "<INPUT TYPE=hidden NAME=td VALUE=\"alter_monitor_alert_rule\">";
	$table .= "<INPUT TYPE=hidden NAME=alert_uid VALUE=\"$$hash_ref{'alert_uid'}\">";
	$table .= "<SELECT NAME=host_name>";
	$table .= ($$hash_ref{'host_name'})
				? "<OPTION VALUE=\"$$hash_ref{'host_name'}\" selected>$$hash_ref{'host_name'}</OPTION><OPTION VALUE=any>ANY</OPTION>"
				: "<OPTION value=any selected>ANY</OPTION>";
	$table .= $ip_list;
	$table .= "</TD>";
	$table .= "<TD align=center>";
	$table .= "<SELECT NAME=grouping>";
	$table .= ($$hash_ref{'grouping'})
				? "<OPTION selected>$$hash_ref{'grouping'}</OPTION><OPTION value=any>ANY</OPTION>"
				: "<OPTION selected>ANY</OPTION>";
	$table .= $group_list;
	$table .= "</TD>";
	$table .= "<TD align=center>";
	$table .= "<SELECT NAME=limit_alerts>";
	$table .= ($$hash_ref{'limit_alerts'})
				? "<OPTION VALUE=\"$$hash_ref{'limit_alerts'}\" selected>$$hash_ref{'limit_alerts'} Mins</OPTION><OPTION VALUE=0>No Rate Limit</OPTION>"
				: "<OPTION selected>No Rate Limit</OPTION>";
	$table .= << "EOF";
<OPTION VALUE=10>10 Mins</OPTION>
<OPTION VALUE=15>15 Mins</OPTION>
<OPTION VALUE=30>30 Mins</OPTION>
<OPTION VALUE=45>45 Mins</OPTION>
<OPTION VALUE=60>60 Mins</OPTION>
</SELECT>
EOF
	$table .= "</TD>";
	$table .= "</TR>\n";
## Second Row
	$table .= "<TR bgcolor=\"$title_color\">\n";
	$table .= "<TD align=center nowrap><b>Notify of REDs until Resolved</b></TD><TD align=center nowrap><b>Notify of YELLOWs until Resolved</b></TD><TD align=center><b>Notify From</b></TD><TD align=center><b>Notify Until</b></TD>";
	$table .= "</TR>\n";
   $table .= "<TR bgcolor=\"$desc_color\">\n";
	$table .= "<TD align=center>";
	$table .= "<SELECT NAME=continual_reds>";
	$table .= ($$hash_ref{'continual_reds'})
				? "<OPTION VALUE=1 selected>Yes</OPTION>"
				: "<OPTION VALUE=0 selected>No</OPTION>";
	$table .= << "EOF";
<OPTION VALUE=1>Yes</OPTION>
<OPTION VALUE=0>No</OPTION>
</SELECT>
EOF
	$table .= "</TD>";
   $table .= "<TD align=center>";
	$table .= "<SELECT NAME=continual_yellows>";
	$table .= ($$hash_ref{'continual_yellows'})
				? "<OPTION VALUE=1 selected>Yes</OPTION>"
				: "<OPTION VALUE=0 selected>No</OPTION>";
	$table .= << "EOF";
<OPTION VALUE=1>Yes</OPTION>
<OPTION VALUE=0>No</OPTION>
</SELECT>
EOF
   $table .= "</TD>";
   $table .= "<TD align=center>";
	$table .= "<SELECT NAME=only_alert_from_hour>";
	my $hr_alert_hour = $$hash_ref{'only_alert_from_hour'};
	if ($hr_alert_hour == 0){
		$hr_alert_hour = "12 AM";
	}
	elsif ($hr_alert_hour < 12){
		$hr_alert_hour = "$hr_alert_hour AM";
	}
	elsif ($hr_alert_hour == 12){
		$hr_alert_hour = "12 PM";
	}
	else{
		$hr_alert_hour -= 12;
		$hr_alert_hour = "$hr_alert_hour PM";
	}

	$table .= "<OPTION VALUE=\"$$hash_ref{'only_alert_from_hour'}\" selected>$hr_alert_hour</OPTION>";
$table .= << "EOF";
                <option value="0">12 AM</option>
                <option value="1">1 AM</option>
                <option value="2">2 AM</option>
                <option value="3">3 AM</option>
                <option value="4">4 AM</option>
                <option value="5">5 AM</option>
                <option value="6">6 AM</option>
                <option value="7">7 AM</option>
                <option value="8">8 AM</option>
                <option value="9">9 AM</option>
                <option value="10">10 AM</option>
                <option value="11">11 AM</option>
                <option value="12">12 PM</option>
                <option value="13">1 PM</option>
                <option value="14">2 PM</option>
                <option value="15">3 PM</option>
                <option value="16">4 PM</option>
                <option value="17">5 PM</option>
                <option value="18">6 PM</option>
                <option value="19">7 PM</option>
                <option value="20">8 PM</option>
                <option value="21">9 PM</option>
                <option value="22">10 PM</option>
                <option value="23">11 PM</option>
              </select>
EOF
   $table .= "</TD>";
   $table .= "<TD align=center>";
	$table .= "<SELECT NAME=only_alert_to_hour>";
	$hr_alert_hour = $$hash_ref{'only_alert_to_hour'};
	if ($hr_alert_hour == 0){
		$hr_alert_hour = "12 AM";
	}
	elsif ($hr_alert_hour < 12){
		$hr_alert_hour = "$hr_alert_hour AM";
	}
	else{
		$hr_alert_hour -= 12;
		$hr_alert_hour = "$hr_alert_hour PM";
	}

	$table .= "<OPTION VALUE=\"$$hash_ref{'only_alert_to_hour'}\" selected>$hr_alert_hour</OPTION>";
$table .= << "EOF";
                <option value="0">12 AM</option>
                <option value="1">1 AM</option>
                <option value="2">2 AM</option>
                <option value="3">3 AM</option>
                <option value="4">4 AM</option>
                <option value="5">5 AM</option>
                <option value="6">6 AM</option>
                <option value="7">7 AM</option>
                <option value="8">8 AM</option>
                <option value="9">9 AM</option>
                <option value="10">10 AM</option>
                <option value="11">11 AM</option>
                <option value="12">12 PM</option>
                <option value="13">1 PM</option>
                <option value="14">2 PM</option>
                <option value="15">3 PM</option>
                <option value="16">4 PM</option>
                <option value="17">5 PM</option>
                <option value="18">6 PM</option>
                <option value="19">7 PM</option>
                <option value="20">8 PM</option>
                <option value="21">9 PM</option>
                <option value="22">10 PM</option>
                <option value="23">11 PM</option>
              </select>
EOF


	$table .= "</TD></TR>\n";
## Third Row
   $table .= "<TR bgcolor=\"$title_color\">\n";
	$table .= "<TD ALIGN=center><b>Alert Level</b></TD><TD ALIGN=center><b>Email Detail Level</b></TD><TD ALIGN=center colspan=2><b>Service</b></TD>";
   $table .= "</TR>\n";
   $table .= "<TR bgcolor=\"$desc_color\">\n";
   $table .= "<TD align=center>";
	$table .= "<SELECT NAME=alert_level>\n";
   $table .= ($$hash_ref{'status_level'})
            ? "<OPTION selected>$$hash_ref{'status_level'}</OPTION><OPTION VALUE=\"any\">ANY</OPTION>"
            : "<OPTION VALUE=\"any\" selected>ANY</OPTION>";
	$table .= << "EOF";
<OPTION VALUE="red">RED</OPTION>
<OPTION VALUE="yellow">YELLOW</OPTION>
<OPTION VALUE="blue">BLUE</OPTION>
</SELECT>
EOF

	$table .= "</TD>";
   $table .= "<TD align=center>";
   $table .= "<SELECT NAME=detail_level>\n";
   if ($$hash_ref{'detail_level'} == 1){
		$table .= "<OPTION VALUE=1 selected>High</OPTION>";
	}
	else{
		$table .= "<OPTION VALUE=0 selected>Low</OPTION>";
	}
   $table .= << "EOF";
<OPTION VALUE="0">Low</OPTION>
<OPTION VALUE="1">High</OPTION>
</SELECT>
</TD>
EOF

	$table .= "<TD COLSPAN=2 ALIGN=center>";
	$table .= "<SELECT NAME=service>\n";
	$table .= ($$hash_ref{'service'})
				? "<OPTION selected>$$hash_ref{'service'}</OPTION><OPTION VALUE=\"NOT_SELECTED\" >ANY</OPTION>"
				: "<OPTION VALUE=\"NOT_SELECTED\" selected>ANY</OPTION>";
	$table .= $service_list;
	$table .= "</TD></TR>\n";
###
# Update Button Row
	$table .= "<TR bgcolor=\"$desc_color\"><TD COLSPAN=4 ALIGN=center>";
	$table .= << "EOF";
<SELECT NAME=action>
<OPTION selected>Update</OPTION>
<OPTION>Delete</OPTION>
</SELECT>
EOF
	$table .= "<INPUT TYPE=Submit VALUE=Update style=\"font-size:8pt\"></TD>";
	$table .= "</TR>\n";
   $table .= "<TR HEIGHT=2 bgcolor=\"$head_color\"><TD colspan=4><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>\n";
	$table .= "</TABLE>\n";
	$table .= "</FORM><br>";
}
	
	


push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
#####################################
sub get_signatures_array{
my $sql_query;
my $db_ptr;
my $hash_ref;
my @signatures;

$sql_query = "	SELECT \
						DISTINCT signature,sig_name \
					FROM event \
					LEFT JOIN signature ON event.signature = signature.sig_id
					ORDER BY UPPER(sig_name)";

$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
	push (@signatures,$$hash_ref{'sig_name'});
}


return @signatures;
}
#####################################
sub get_services_array{
my $sql_query;
my $db_ptr;
my $hash_ref;
my @services;

$sql_query = "	SELECT \
						DISTINCT service \
					FROM dm_monitor_current \
					ORDER BY UPPER(service)";

$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
	push (@services,$$hash_ref{'signature'});
}


return @services;
}
#####################################
sub get_ip_address_array{
my $sql_query;
my $db_ptr;
my $hash_ref;
my @ips;

$sql_query = "	SELECT \
						DISTINCT ip_addr \
					FROM dm_monitor_current \
					ORDER BY UPPER(ip_addr)";

$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
	push (@ips,$$hash_ref{'ip_addr'});
}


return @ips;
}
#####################################
sub get_hostname_array{
my $sql_query;
my $db_ptr;
my $hash_ref;
my @hosts;

$sql_query = "	SELECT \
						DISTINCT host_name \
					FROM dm_monitor_current \
					GROUP BY host_name
					ORDER BY UPPER(host_name)";

$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
	push (@hosts,$$hash_ref{'host_name'});
}


return @hosts;
}
#####################################
sub get_group_array{
my $sql_query;
my $db_ptr;
my $hash_ref;
my @groups;

$sql_query = "	SELECT \
						DISTINCT grouping \
					FROM dm_monitor_current \
					ORDER BY UPPER(grouping)";

$db_ptr = &run_query($sql_query);
while ($hash_ref=$db_ptr->fetchrow_hashref){
	push (@groups,$$hash_ref{'grouping'});
}


return @groups;
}
######################################
sub get_monitor_ids_form{
my $html;

open (IN,$monitor_ids_form) || &error("Can't open IDS form");
while (<IN>){
	$html .= $_;
}
close IN;

return $html;
}
###############
sub get_search_form{
my $html;

open (IN,$search_form) || &error("Can't open Search form");
while (<IN>){
	$html .= $_;
}
close IN;

return $html;
}
######################################
sub get_monitor_service_form{
my $html;

open (IN,$monitor_service_form) || &error("Can't open Service form");
while (<IN>){
	$html .= $_;
}
close IN;

return $html;
}
##############
sub get_new_service_page{
my $html;

open (IN,$new_service_form) || &error("Can't open New Service form");
while (<IN>){
	$html .= $_;
}
close IN;

return $html;

}
##############
sub get_generic_page{
my ($file) = @_;
if (!(-r $file)){
	print STDERR "Can't read template file: $file : $!\n";#For the web logs!
	&error("Can't read template file");
}
my $html;

open (IN,$file) || &error("Can't open form template");
while (<IN>){
   $html .= $_;
}
close IN;

return $html;

}
######################################
sub get_users_email{
my $sql_query;
my $db_ptr;
my $hash_ref;
&safe_slash(\$logged_in_as);

$sql_query = "	SELECT \
						email_address \
					FROM dm_sessions \
					WHERE \
						username = '$logged_in_as'";
$db_ptr = &run_query($sql_query);
($hash_ref=$db_ptr->fetchrow_hashref) || return;

return $$hash_ref{'email_address'};
}
######################################
sub add_host_monitoring_event{
my $sql_query;
my $db_ptr;
my $hash_ref;
my $users_email;

#check the input:
($FORM{'alert_level'}=~/^red$|^yellow$|^blue$/)
	|| ($FORM{'alert_level'}='');
($FORM{'service'}) || ($FORM{'service'} = "");
$FORM{'service'} = '' if ($FORM{'service'} eq "NOT_SELECTED");
($FORM{'continual_reds'}=~/^1$/)
	|| ($FORM{'continual_reds'}="0");
($FORM{'continual_yellows'}=~/^1$/)
	|| ($FORM{'continual_yellows'}="0");
($FORM{'limit_alerts'}=~/^\d+$/)
	|| ($FORM{'limit_alerts'}="0");
($FORM{'only_alert_from_hour'}=~/^\d+$/)
	|| ($FORM{'only_alert_from_hour'}="0");
(($FORM{'only_alert_from_hour'}>=0) && ($FORM{'only_alert_from_hour'}<24))
	|| ($FORM{'only_alert_from_hour'}="0");
($FORM{'only_alert_to_hour'}=~/^\d+$/)
	|| ($FORM{'only_alert_to_hour'}="23");
(($FORM{'only_alert_to_hour'}>=0) && ($FORM{'only_alert_to_hour'}<24))
	|| ($FORM{'only_alert_to_hour'}="23");
$FORM{'host_name'} =~tr/a-zA-Z0-9\.\-//dc;
($FORM{'host_name'}=~/^[a-zA-Z0-9\-]+\.[a-zA-Z0-9]{2,}/)
	|| ($FORM{'host_name'}='');
$FORM{'grouping'} = '' if ($FORM{'grouping'}=~/^any$/i);
($FORM{'detail_level'}=~/^\d+$/)
	|| ($FORM{'detail_level'}='0');

&safe_slash(\$FORM{'service'});
&safe_slash(\$FORM{'grouping'});

if (&is_any_admin){
	($FORM{'email_address'}=~/^\S+\@\S+\.[a-zA-Z]{2,4}$/)
		|| &error("Email address does not seem to be valid: $FORM{'email_address'}");
	$users_email = $FORM{'email_address'};


}
else{
	($users_email = &get_users_email) || &error("Can't find an email address for you $logged_in_as!");
}
&safe_slash(\$users_email);

$sql_query = "	INSERT INTO \
						dm_monitor_alert_rules \
					VALUES( \
						'$monitor_sid', '$FORM{'grouping'}', \
						'$FORM{'service'}', \
						'$FORM{'limit_alerts'}','$users_email', \
						'$FORM{'continual_reds'}','$FORM{'continual_yellows'}', \
						'$FORM{'only_alert_from_hour'}','$FORM{'only_alert_to_hour'}', \
						'','$FORM{'alert_level'}','$FORM{'detail_level'}','$FORM{'host_name'}')";
&connect_to_db;
($db->do($sql_query)) || &error("DB Error while inserting monitoring alert.");	
&push_message("<FONT COLOR=red><CENTER>Monitoring Event Added</CENTER></FONT>");

&log_event(	username => "$logged_in_as",
				action 	=> "added host monitoring alert rule",
				target	=> "$users_email",
			 );
					


}
######################################
sub add_ids_monitoring_event{
my $sql_query;
my $db_ptr;
my $hash_ref;
my $users_email;

#check the input:
($FORM{'signature'}) || ($FORM{'signature'} = ''); #takes out the "0" if no selection
($FORM{'priority_level'}=~/^\d$/)
	|| ($FORM{'priority_level'}='');
($FORM{'only_alert_from_hour'}=~/^\d+$/)
	|| ($FORM{'only_alert_from_hour'}="0");
(($FORM{'only_alert_from_hour'}>=0) && ($FORM{'only_alert_from_hour'}<24))
	|| ($FORM{'only_alert_from_hour'}="0");
($FORM{'only_alert_to_hour'}=~/^\d+$/)
	|| ($FORM{'only_alert_to_hour'}="23");
(($FORM{'only_alert_to_hour'}>=0) && ($FORM{'only_alert_to_hour'}<24))
	|| ($FORM{'only_alert_to_hour'}="23");


&safe_slash(\$FORM{'signature'});
&safe_slash(\$FORM{'signature_contains'});

if (&is_any_admin){
	($FORM{'email_address'}=~/^\S+\@\S+\.[a-zA-Z]{2,4}$/)
		|| &error("Email address does not seem to be valid: $FORM{'email_address'}");
	$users_email = $FORM{'email_address'};


}
else{
	($users_email = &get_users_email) || &error("Can't find an email address for you $logged_in_as!");
}
&safe_slash(\$users_email);
$sql_query = "	INSERT INTO \
						dm_ids_alert_rules \
					VALUES( \
						'$monitor_sid', '',
						'$FORM{'signature'}', '$FORM{'signature_contains'}', \
						'$FORM{'priority_level'}','$users_email', \
						'$FORM{'only_alert_from_hour'}','$FORM{'only_alert_to_hour'}','' \
					) ";
&connect_to_db;
($db->do($sql_query)) || &error("DB Error while inserting monitoring alert.");	
&push_message("<FONT COLOR=red><CENTER>IDS Monitoring Event Added</CENTER></FONT>");

&log_event(	username => "$logged_in_as",
				action 	=> "added IDS monitoring alert rule",
				target	=> "$users_email",
			 );
					


}
######################################
sub add_md5_monitoring_event{
my $sql_query;
my $db_ptr;
my $hash_ref;
my $users_email;

#check the input:
($FORM{'alert_level'}=~/^[12]$/)
	|| ($FORM{'alert_level'}='');
($FORM{'only_alert_from_hour'}=~/^\d+$/)
	|| ($FORM{'only_alert_from_hour'}="0");
(($FORM{'only_alert_from_hour'}>=0) && ($FORM{'only_alert_from_hour'}<24))
	|| ($FORM{'only_alert_from_hour'}="0");
($FORM{'only_alert_to_hour'}=~/^\d+$/)
	|| ($FORM{'only_alert_to_hour'}="23");
(($FORM{'only_alert_to_hour'}>=0) && ($FORM{'only_alert_to_hour'}<24))
	|| ($FORM{'only_alert_to_hour'}="23");
($FORM{'monitored_sid'}=~/^\d+$/)
	|| ($FORM{'monitored_sid'}="");
($FORM{'detail_level'}=~/^\d+$/)
	|| ($FORM{'detail_level'}="0");


if (&is_any_admin){
	($FORM{'email_address'}=~/^\S+\@\S+\.[a-zA-Z]{2,4}$/)
		|| &error("Email address does not seem to be valid: $FORM{'email_address'}");
	$users_email = $FORM{'email_address'};


}
else{
	($users_email = &get_users_email) || &error("Can't find an email address for you $logged_in_as!");
}
&safe_slash(\$users_email);

$sql_query = "	INSERT INTO \
						dm_md5_alert_rules \
					VALUES( \
						'$monitor_sid', '$FORM{'monitored_sid'}',
						'','$FORM{'alert_level'}','$users_email', \
						'$FORM{'only_alert_from_hour'}','$FORM{'only_alert_to_hour'}','','$FORM{'detail_level'}' \
					) ";
&connect_to_db;
($db->do($sql_query)) || &error("DB Error while inserting monitoring alert.");	
&push_message("<FONT COLOR=red><CENTER>File / Web Integrity Monitoring Event Added</CENTER></FONT>");

&log_event(	username => "$logged_in_as",
				action 	=> "added MD5 monitoring alert rule",
				target	=> "$users_email",
			 );
					


}
###################################################
sub update_md5_alert_rule{
my $sql_query;
my $db_ptr;
my $hash_ref;
my $where;
my $users_email;

($FORM{'alert_level'}=~/^[12]$/)
	|| ($FORM{'priority_level'}='');
($FORM{'only_alert_from_hour'}=~/^\d+$/)
	|| ($FORM{'only_alert_from_hour'}="0");
($FORM{'only_alert_to_hour'}=~/^\d+$/)
	|| ($FORM{'only_alert_to_hour'}="23");
($FORM{'monitored_sid'}=~/^\d+$/)
	|| ($FORM{'monitored_sid'}='');
($FORM{'detail_level'}=~/^\d+$/)
	|| ($FORM{'detail_level'}='0');
($FORM{'alert_uid'}=~/^\d+$/) || &error("Alert UID not found/ in wrong format: $FORM{'alert_uid'}");


if (&is_any_admin){
	($FORM{'email_address'}=~/^\S+\@\S+\.[a-zA-Z]{2,4}$/)
		|| &error("Email address does not seem to be valid: $FORM{'email_address'}");
	$users_email = $FORM{'email_address'};
	&safe_slash(\$FORM{'email_address'});
	if ($FORM{'action'} eq "Delete"){
		$sql_query = "DELETE FROM dm_md5_alert_rules ";
	}
	else{
		$sql_query = "	UPDATE \
								dm_md5_alert_rules \
							SET \
								email_address			= '$FORM{'email_address'}', \
								only_alert_from_hour	= '$FORM{'only_alert_from_hour'}', \
								only_alert_to_hour	= '$FORM{'only_alert_to_hour'}', \
								monitored_sid			= '$FORM{'monitored_sid'}', \
								detail_level			= '$FORM{'detail_level'}', \
								alert_level				= '$FORM{'alert_level'}' ";
	}

	$where 		= " WHERE \
							alert_uid	= '$FORM{'alert_uid'}' ";
	$sql_query .= $where;
}
else{
	($users_email = &get_users_email) || &error("Can't find an email address for you $logged_in_as!");
	&safe_slash(\$users_email);
	if ($FORM{'action'} eq "Delete"){
		$sql_query = "DELETE FROM dm_md5_alert_rules ";
	}
	else{
		$sql_query = "	UPDATE \
								dm_md5_alert_rules \
							SET \
								only_alert_from_hour	= '$FORM{'only_alert_from_hour'}', \
								only_alert_to_hour	= '$FORM{'only_alert_to_hour'}', \
								monitored_sid			= '$FORM{'monitored_sid'}', \
								detail_level			= '$FORM{'detail_level'}', \
								alert_level				= '$FORM{'alert_level'}' ";
	}

	$where		= "	WHERE \
								email_address = '$users_email' AND \
								alert_uid	= '$FORM{'alert_uid'}' ";
	$sql_query .= $where;
}
&connect_to_db;
($db->do($sql_query)) || &error("No matching alert found to update.");	
if ($FORM{'action'} eq "Delete"){
	&push_message("<FONT COLOR=red><CENTER>File / Web Integrity Alert $FORM{'alert_uid'} Deleted</CENTER></FONT>");
}
else{
	&push_message("<FONT COLOR=red><CENTER>File / Web Integrity Alert $FORM{'alert_uid'} Modified</CENTER></FONT>");
}

###############
# Check if they wanted to suspend alerts:
if ($FORM{'suspend_alerts'}){
	if ($FORM{'suspend_alerts'} == 99){
		#then we're supposed to reset it
		$sql_query = "	UPDATE dm_md5_alert_rules \
							SET suspend_until = NOW() $where";
		($db->do($sql_query)) || &error("No matching alert found to reset suspend time.");
	}
	else{
		$sql_query = "	UPDATE dm_md5_alert_rules \
							SET suspend_until = DATE_ADD(NOW(), INTERVAL $FORM{'suspend_alerts'} HOUR) $where";
		($db->do($sql_query)) || &error("No matching alert found to update suspend time.");
	}
}

&log_event(	username => "$logged_in_as",
				action 	=> "updated MD5 monitoring alert rule",
				target	=> "$users_email",
			 );

}
###################################################
sub update_ids_alert_rule{
my $sql_query;
my $db_ptr;
my $hash_ref;
my $users_email;

($FORM{'priority_level'}=~/^[1-6]$/)
	|| ($FORM{'priority_level'}='');
($FORM{'only_alert_from_hour'}=~/^\d+$/)
	|| ($FORM{'only_alert_from_hour'}="0");
($FORM{'only_alert_to_hour'}=~/^\d+$/)
	|| ($FORM{'only_alert_to_hour'}="23");
($FORM{'alert_uid'}=~/^\d+$/) || &error("Alert UID not found/ in wrong format: $FORM{'alert_uid'}");

&safe_slash(\$FORM{'signature'});
&safe_slash(\$FORM{'signature_contains'});

if (&is_any_admin){
	($FORM{'email_address'}=~/^\S+\@\S+\.[a-zA-Z]{2,4}$/)
		|| &error("Email address does not seem to be valid: $FORM{'email_address'}");
	$users_email = $FORM{'email_address'};
	if ($FORM{'action'} eq "Delete"){
		$sql_query = "DELETE FROM dm_ids_alert_rules ";
	}
	else{
		$sql_query = "	UPDATE \
								dm_ids_alert_rules \
							SET \
								signature_is			= '$FORM{'signature'}', \
								signature_contains	= '$FORM{'signature_contains'}', \
								email_address			= '$FORM{'email_address'}', \
								only_alert_from_hour	= '$FORM{'only_alert_from_hour'}', \
								only_alert_to_hour	= '$FORM{'only_alert_to_hour'}', \
								priority_level			= '$FORM{'priority_level'}' ";
	}

	$sql_query .= " WHERE \
							alert_uid	= '$FORM{'alert_uid'}' ";
}
else{
	($users_email = &get_users_email) || &error("Can't find an email address for you $logged_in_as!");
	if ($FORM{'action'} eq "Delete"){
		$sql_query = "DELETE FROM dm_ids_alert_rules ";
	}
	else{
		$sql_query = "	UPDATE \
								dm_ids_alert_rules \
							SET \
								signature_is			= '$FORM{'signature'}', \
								signature_contains	= '$FORM{'signature_contains'}', \
								only_alert_from_hour	= '$FORM{'only_alert_from_hour'}', \
								only_alert_to_hour	= '$FORM{'only_alert_to_hour'}', \
								priority_level			= '$FORM{'priority_level'}' ";
	}

	$sql_query .= "	WHERE \
								email_address = '$users_email' AND \
								alert_uid	= '$FORM{'alert_uid'}' ";
}
&connect_to_db;
($db->do($sql_query)) || &error("No matching alert found to update.");	
if ($FORM{'action'} eq "Delete"){
	&push_message("<FONT COLOR=red><CENTER>IDS Alert $FORM{'alert_uid'} Deleted</CENTER></FONT>");
}
else{
	&push_message("<FONT COLOR=red><CENTER>IDS Alert $FORM{'alert_uid'} Modified</CENTER></FONT>");
}


&log_event(	username => "$logged_in_as",
				action 	=> "updated IDS monitoring alert rule",
				target	=> "$users_email",
			 );


}
###################################################
sub update_monitor_alert_rule{
my $sql_query;
my $db_ptr;

($FORM{'alert_level'}=~/^red$|^yellow$|^blue$/)
	|| ($FORM{'alert_level'}='');
($FORM{'service'}) || ($FORM{'service'} = "");
$FORM{'service'} = '' if ($FORM{'service'} eq "NOT_SELECTED");
($FORM{'continual_reds'}=~/^1$/)
	|| ($FORM{'continual_reds'}="0");
($FORM{'continual_yellows'}=~/^1$/)
	|| ($FORM{'continual_yellows'}="0");
($FORM{'limit_alerts'}=~/^\d+$/)
	|| ($FORM{'limit_alerts'}="0");
($FORM{'only_alert_from_hour'}=~/^\d+$/)
	|| ($FORM{'only_alert_from_hour'}="0");
($FORM{'only_alert_to_hour'}=~/^\d+$/)
	|| ($FORM{'only_alert_to_hour'}="23");
$FORM{'host_name'} =~tr/a-zA-Z0-9\.\-//dc;
($FORM{'host_name'}=~/^[a-zA-Z0-9\-]+\.[a-zA-Z0-9]{2,}/)
	|| ($FORM{'host_name'}='');
($FORM{'detail_level'}=~/^\d+$/)
	|| ($FORM{'detail_level'}='0');
$FORM{'grouping'} = '' if ($FORM{'grouping'}=~/^any$/i);
($FORM{'alert_uid'}=~/^\d+$/) || &error("Alert UID not found/ in wrong format: $FORM{'alert_uid'}");

my $users_email;
&safe_slash(\$FORM{'service'});
&safe_slash(\$FORM{'grouping'});

if (&is_any_admin){
	($FORM{'email_address'}=~/^\S+\@\S+\.[a-zA-Z]{2,4}$/)
		|| &error("Email address does not seem to be valid: $FORM{'email_address'}");
	$users_email = $FORM{'email_address'};
	&safe_slash(\$FORM{'email_address'});
	if ($FORM{'action'} eq "Delete"){
		$sql_query = "DELETE FROM dm_monitor_alert_rules ";
	}
	else{
		$sql_query = "	UPDATE \
								dm_monitor_alert_rules \
							SET \
								grouping 				= '$FORM{'grouping'}', \
								host_name				= '$FORM{'host_name'}', \
								service					= '$FORM{'service'}', \
								limit_alerts			= '$FORM{'limit_alerts'}', \
								email_address			= '$FORM{'email_address'}', \
								continual_reds			= '$FORM{'continual_reds'}', \  
								continual_yellows		= '$FORM{'continual_yellows'}', \
								only_alert_from_hour	= '$FORM{'only_alert_from_hour'}', \
								only_alert_to_hour	= '$FORM{'only_alert_to_hour'}', \
								detail_level			= '$FORM{'detail_level'}', \
								status_level			= '$FORM{'alert_level'}' ";
	}

	$sql_query .= " WHERE \
							alert_uid	= '$FORM{'alert_uid'}' ";
}
else{
	($users_email = &get_users_email) || &error("Can't find an email address for you $logged_in_as!");
	if ($FORM{'action'} eq "Delete"){
		$sql_query = "DELETE FROM dm_monitor_alert_rules ";
	}
	else{
		$sql_query = "	UPDATE \
								dm_monitor_alert_rules \
							SET \
								grouping 				= '$FORM{'grouping'}', \
								host_name				= '$FORM{'host_name'}', \
								service					= '$FORM{'service'}', \
								limit_alerts			= '$FORM{'limit_alerts'}', \
								continual_reds			= '$FORM{'continual_reds'}', \  
								continual_yellows		= '$FORM{'continual_yellows'}', \
								only_alert_from_hour	= '$FORM{'only_alert_from_hour'}', \
								only_alert_to_hour	= '$FORM{'only_alert_to_hour'}', \
								detail_level			= '$FORM{'detail_level'}', \
								status_level			= '$FORM{'alert_level'}' ";
	}

	$sql_query .= "	WHERE \
								email_address = '$users_email' AND \
								alert_uid	= '$FORM{'alert_uid'}' ";
}
&connect_to_db;
($db->do($sql_query)) || &error("No matching alert found to update.");	
if ($FORM{'action'} eq "Delete"){
	&push_message("<FONT COLOR=red><CENTER>Monitoring Alert $FORM{'alert_uid'} Deleted</CENTER></FONT>");
}
else{
	&push_message("<FONT COLOR=red><CENTER>Monitoring Alert $FORM{'alert_uid'} Modified</CENTER></FONT>");
}

&log_event(	username => "$logged_in_as",
				action 	=> "updated host monitoring alert rule",
				target	=> "$users_email",
			 );



}
########################
sub get_menu_bar{
my $html;

$html .= "<tr bgcolor=#5A6267><td valign=top nowrap><center>";
$html .= "<img src=\"$v_graphics_path/tn_endcapl.gif\" width=\"4\" height=\"20\" alt=\"\" border=\"0\">";

if ($current_page eq "main"){
	$html .= "<A HREF=\"$home_url\" TARGET=\"_top\"><img src=\"$v_graphics_path/tn_summary2.gif\" width=\"83\" height=\"20\" alt=\"[:summary:]\" border=\"0\" name=tn_summary></a>";
}
else{
	$html .= "<A HREF=\"$home_url\" TARGET=\"_top\" onMouseOver=\"on('0')\" onMouseOut=\"off('0')\" onMouseDown=\"down('0')\"><img src=\"$v_graphics_path/tn_summary0.gif\" width=\"83\" height=\"20\" alt=\"[summary]\" border=\"0\" name=tn_summary></a>";
}

if ($current_page eq "show_events"){
	$html .= "<A HREF=\"$home_url?td=show_events&offset_type=day&offset_number=1&limit=60\" TARGET=\"_top\"><img src=\"$v_graphics_path/tn_events2.gif\" width=\"83\" height=\"20\" alt=\"[:events:]\" border=\"0\" name=tn_events></a>";
}
else{
	$html .= "<A HREF=\"$home_url?td=show_events&offset_type=day&offset_number=1&limit=60\" TARGET=\"_top\" onMouseOver=\"on('1')\" onMouseOut=\"off('1')\" onMouseDown=\"down('1')\"><img src=\"$v_graphics_path/tn_events0.gif\" width=\"83\" height=\"20\" alt=\"[events]\" border=\"0\" name=tn_events></a>";
}


if ($current_page eq "monitor"){
	$html .= "<A HREF=\"$home_url?td=view_monitoring_page\" TARGET=\"_top\"><img src=\"$v_graphics_path/tn_monitor2.gif\" width=\"83\" height=\"20\" alt=\"[:monitor:]\" border=\"0\" name=tn_monitor></a>";
}
else{
	$html .= "<A HREF=\"$home_url?td=view_monitoring_page\" TARGET=\"_top\" onMouseOver=\"on('2')\" onMouseOut=\"off('2')\" onMouseDown=\"down('2')\"><img src=\"$v_graphics_path/tn_monitor0.gif\" width=\"83\" height=\"20\" alt=\"[monitor]\" border=\"0\" name=tn_monitor></a>";
}

if ($current_page eq "md5"){
	$html .= "<A HREF=\"$home_url?td=view_md5_page&minimal=1\" TARGET=\"_top\"><img src=\"$v_graphics_path/tn_integrity2.gif\" width=\"83\" height=\"20\" alt=\"[:integrity:]\" border=\"0\" name=tn_integrity></a>";
}
else{
	$html .= "<A HREF=\"$home_url?td=view_md5_page&minimal=1\" TARGET=\"_top\" onMouseOver=\"on('3')\" onMouseOut=\"off('3')\" onMouseDown=\"down('3')\"><img src=\"$v_graphics_path/tn_integrity0.gif\" width=\"83\" height=\"20\" alt=\"[integrity]\" border=\"0\" name=tn_integrity></a>";
}


if ($current_page eq "search"){
	$html .= "<A HREF=\"$home_url?td=search\" TARGET=\"_top\"><img src=\"$v_graphics_path/tn_search2.gif\" width=\"83\" height=\"20\" alt=\"[:search:]\" border=\"0\" name=tn_search></a>";
}
else{
	$html .= "<A HREF=\"$home_url?td=search\" TARGET=\"_top\" onMouseOver=\"on('4')\" onMouseOut=\"off('4')\" onMouseDown=\"down('4')\"><img src=\"$v_graphics_path/tn_search0.gif\" width=\"83\" height=\"20\" alt=\"[search]\" border=\"0\" name=tn_search></a>";
}


if ($current_page eq "config"){
	$html .= "<A HREF=\"$home_url?td=config\" TARGET=\"_top\"><img src=\"$v_graphics_path/tn_configure2.gif\" width=\"83\" height=\"20\" alt=\"[:configure:]\"border=\"0\" name=tn_configure></a>";
}
else{
	$html .= "<A HREF=\"$home_url?td=config\" TARGET=\"_top\" onMouseOver=\"on('5')\" onMouseOut=\"off('5')\" onMouseDown=\"down('5')\"><img src=\"$v_graphics_path/tn_configure0.gif\" width=\"83\" height=\"20\" alt=\"[configure]\"border=\"0\" name=tn_configure></a>";
}

$html .= "<img src=\"$v_graphics_path/tn_endcapr.gif\" width=\"4\" height=\"20\" alt=\"\" border=\"0\"></center></td></tr>";

return $html;
}
######################
sub print_age_data_form{
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
my $html = &print_with_key($age_data_form,"TO_STRING");
my $local_count;
my $table1;
my $table2;

$local_count = &count_total_records;


$sql_query = "	SELECT \
						(TO_DAYS(NOW()) - TO_DAYS(timestamp)) as AGO,
						count(*) as COUNT, \
						EXTRACT(YEAR FROM timestamp) as YEAR , \
						EXTRACT(MONTH FROM timestamp) as MONTH , \
						EXTRACT(DAY FROM timestamp) as DAY \
					FROM event \
					GROUP BY \
						YEAR,MONTH,DAY \
					ORDER BY \
						YEAR, MONTH, DAY ";

$db_ptr = &run_query($sql_query);
$table1 .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 ALIGN=center WIDTH=\"80%\">\n";
$table1 .= "<TR BGCOLOR=\"$head_color\"><TD ALIGN=center COLSPAN=4 background=\"$v_graphics_path/bg_title.gif\"><B>Breakdown of potential savings by day of IDS data</B></TD></TR>\n";
	$table1 .= "<TR bgcolor=\"$title_color\">";
	$table1 .= "<TD ALIGN=center><B>Days Ago</B></TD>";
	$table1 .= "<TD ALIGN=center><B>Date</B></TD>";
	$table1 .= "<TD ALIGN=center><B>Records</B></TD>";
	$table1 .= "<TD ALIGN=center><B>Cumulitive Savings If Aged Here</B></TD>";
$table1 .= "</TR>\n";

my $rev_table;
while ($hash_ref=$db_ptr->fetchrow_hashref){
	my $temp_table;
	$temp_table .= "<TR bgcolor=\"$desc_color\">";
	$temp_table .= "<TD align=center>$$hash_ref{'AGO'}</TD>";
	$temp_table .= "<TD align=center>$$hash_ref{'MONTH'}/$$hash_ref{'DAY'}/$$hash_ref{'YEAR'}</TD>";
	$temp_table .= "<TD ALIGN=center>$$hash_ref{'COUNT'}</TD>";
	$local_count -= $$hash_ref{'COUNT'};
	$temp_table .= "<TD ALIGN=center>". ($total_count - $local_count) . "</TD>";
	$temp_table .= "</TR>\n";
	$rev_table = $temp_table . $rev_table;
}
$table1 .= $rev_table;
$table1 .= "<TR bgcolor=\"$head_color\" height=2><TD colspan=4><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table1 .= "</TABLE>";

### Host/Service data:
$sql_query = "SELECT COUNT(*) as COUNT FROM dm_monitor_events";
$db_ptr = &run_query($sql_query);
($hash_ref=$db_ptr->fetchrow_hashref);
my $service_row_count = $$hash_ref{'COUNT'};
my $local_service_row_count = $service_row_count;
	
$sql_query = "	SELECT \ 
						(TO_DAYS(NOW()) - TO_DAYS(event_timestamp)) as AGO, \
						count(*) as COUNT, EXTRACT(YEAR FROM event_timestamp) as YEAR , \
						EXTRACT(MONTH FROM event_timestamp) as MONTH , \
						EXTRACT(DAY FROM event_timestamp) as DAY \
					FROM \
						dm_monitor_events \
					GROUP BY \
						YEAR,MONTH,DAY \
					ORDER BY \
						YEAR, MONTH, DAY";
$db_ptr = &run_query($sql_query);
$table2 .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 ALIGN=center width=\"80%\">\n";
$table2 .= "<TR bgcolor=\"$head_color\"><TD ALIGN=center background=\"$v_graphics_path/bg_title.gif\" COLSPAN=4><B>Breakdown of potential savings by day of Host data</B></TD></TR>\n";
   $table2 .= "<TR bgcolor=\"$title_color\">";
   $table2 .= "<TD ALIGN=center><B>Days Ago</B></TD>";
   $table2 .= "<TD ALIGN=center><B>Date</B></TD>";
   $table2 .= "<TD ALIGN=center><B>Records</B></TD>";
   $table2 .= "<TD ALIGN=center><B>Cumulitive Savings If Aged Here</B></TD>";
$table2 .= "</TR>\n";

my $rev_table;
while ($hash_ref=$db_ptr->fetchrow_hashref){
   my $temp_table;
   $temp_table .= "<TR bgcolor=\"$desc_color\">";
   $temp_table .= "<TD align=center>$$hash_ref{'AGO'}</TD>";
   $temp_table .= "<TD align=center>$$hash_ref{'MONTH'}/$$hash_ref{'DAY'}/$$hash_ref{'YEAR'}</TD>";
   $temp_table .= "<TD align=center>$$hash_ref{'COUNT'}</TD>";
   $local_service_row_count -= $$hash_ref{'COUNT'};
   $temp_table .= "<TD align=center>". ($service_row_count - $local_service_row_count) . "</TD>";
   $temp_table .= "</TR>\n";
   $rev_table = $temp_table . $rev_table;
}
$table2 .= $rev_table;
$table2 .= "<TR bgcolor=\"$head_color\" height=2><TD colspan=4><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table2 .= "</TABLE>\n";

#################
# Put the two Age DB Data tables together:
$table = << "EOF";
$table1
<br>
$table2
EOF

$html .= $table;

push (@substitutions,"\\[MAIN_TABLE\\],-,$html");
&print_main_with_key($main_template);
}
#######################
sub age_data{
my (%args) = @_;
($args{'services'}=~/^\d+$/) || ($args{'services'} = '');
($args{'ids'}=~/^\d+$/) || ($args{'ids'} = '');
my $sql_query;
my $db_ptr;
my $hash_ref;
my $delete_count;

#Make sure we have at least one argument:
($args{'ids'} || $args{'services'}) 
	|| &error("You must select at least one area to age.");

&connect_to_db;# Make sure we're connected bc we're doing a straight  "->do" later

if ($args{'ids'}){
	(&is_admin("f1")) || &error("You must be the Super User or NIDS Administrator to delete host/service data");
	my $nogo;
	my @tables_array = ('data','event','icmphdr','tcphdr','udphdr','iphdr','opt');
	$sql_query = "	SELECT sid,cid \	
						FROM event \
						WHERE \
							timestamp < DATE_ADD(NOW(), INTERVAL -$args{'ids'} DAY)";
	$db_ptr = &run_query($sql_query);
	my @del_array;
	while ($hash_ref = $db_ptr->fetchrow_hashref){
		push (@del_array,"$$hash_ref{'sid'},$$hash_ref{'cid'}");
	}
	if (!(@del_array)){
		&push_message("<FONT COLOR=red><CENTER>No IDS records found to delete.</CENTER></FONT>");
		$nogo = 1;
	}
	else{
		$delete_count = @del_array;
	}

  if (!$nogo){
	foreach (@del_array){
   	my @temp_array = split(/,/,$_);
   	foreach (@tables_array){
   	   $sql_query = "DELETE FROM $_ WHERE sid='$temp_array[0]' AND cid='$temp_array[1]'";
			$db->do($sql_query);
   	}
	}
	&push_message("<FONT COLOR=red><CENTER>$delete_count IDS records deleted.</CENTER></FONT>");
  }
# now optimize tables:
    foreach (@tables_array){
       $sql_query = "OPTIMIZE TABLE $_";
            $db->do($sql_query);
    }

}
if ($args{'services'}){
	(&is_admin("f2")) || &error("You must be the Super User or Host / Service Administrator to delete host/service data");
	$sql_query = "	DELETE FROM \
							dm_monitor_events \
						WHERE \
							event_timestamp < DATE_ADD(NOW(), INTERVAL -$args{'services'} DAY)";
	my $delete_count = $db->do($sql_query);
   &push_message("<FONT COLOR=red><CENTER>$delete_count Host event records deleted.</CENTER></FONT>");
}

&log_event(	username => "$logged_in_as",
				action 	=> "aged DB data",
				target	=> "IDS: $args{'ids'} , SERVICES: $args{'services'}",
			 );


}
#######################
sub count_total_records{
my $sql_query;
my $db_ptr;
my $hash_ref;

return $total_count if ($total_count);

# Total:
$sql_query = "SELECT count(*) as count FROM event";
$db_ptr = &run_query($sql_query);
$total_count = ($hash_ref = $db_ptr->fetchrow_hashref)? $$hash_ref{'count'} : 0;

return $total_count;
}
######################
sub get_signatures_dropdown{
my ($select_name) = @_;
my $sig_list;
my @signatures;

@signatures = &get_signatures_array;

$sig_list = "<SELECT NAME=\"$select_name\">\n";
$sig_list .= "<OPTION VALUE=0> - Select - </OPTION>";
foreach (@signatures){
	my $shorter_sig = $_;
	$shorter_sig=~s/(^.{50}).*$/$1\.\.\./;
	$sig_list .= "<OPTION VALUE=\'$_\'>$shorter_sig</OPTION>\n";
}
$sig_list .= "</SELECT>";

 
return $sig_list;
}	
#############################
#sub print_general_config_form{
#my $html;
#
#$html = &print_with_key($general_config_form,'TO_STRING');
#
#push (@substitutions,"\\[MAIN_TABLE\\],-,$html");
#&print_main_with_key($main_template);
#}
###############################
sub print_md5_select_menu{
my $html;

$html .= "<TABLE BORDER=0 ALIGN=center CELLSPACING=1 CELLPADDING=2>";
$html .= "<TR bgcolor=\"$head_color\"><TD background=\"$v_graphics_path/bg_title.gif\" ALIGN=center><B>Configure File / Web Integrity Check</B></TD></TR>";
$html .= "<TR bgcolor=\"$desc_color\"><TD ALIGN=center>";
$html .= &get_sid_select_table('',"update_md5_rules");
$html .= "</TD></TR>";
$html .= "<TR BGCOLOR=\"$head_color\" HEIGHT=2><TD><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$html .= "</TABLE>";

push (@substitutions,"\\[MAIN_TABLE\\],-,$html");
&print_main_with_key($main_template);
}
###############################
sub print_md5_config{
my ($sid) = @_;
($sid=~/^\d+$/) || &error("Invalid SID: $sid");
my $html;
my $hostname;
my @current_rules_array;
my $current_rules_scalar;

($hostname = &get_hostname_from_sid($sid)) 
		|| &error("SID not found in DB: $sid");
push (@substitutions,"\\[SID\\],-,$sid");
push (@substitutions,"\\[HOSTNAME\\],-,$hostname");

@current_rules_array = &get_current_md5_rules($sid);
foreach (@current_rules_array){
	$current_rules_scalar .= "$_\n";
}
push (@substitutions,"\\[MD5_RULES\\],-,$current_rules_scalar");



$html = &print_with_key($configure_md5_form,'TO_STRING');


push (@substitutions,"\\[MAIN_TABLE\\],-,$html");
&print_main_with_key($main_template);
}
##################################
sub get_hostname_from_sid{
my ($sid) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
($sid=~/^\d+$/) || return;


$sql_query = "SELECT hostname FROM sensor WHERE sid = '$sid'";
$db_ptr = &run_query($sql_query);
($hash_ref = $db_ptr->fetchrow_hashref) || return;

return $$hash_ref{'hostname'};
}
##################################
sub get_current_md5_rules{
my ($sid) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my @array;
($sid=~/^\d+$/) || return;


$sql_query = "	SELECT \
						priority,path,recursive,description \
					FROM dm_md5_rules \
					WHERE sid = '$sid' \
					ORDER BY UPPER(priority),UPPER(path)";

$db_ptr = &run_query($sql_query);
while ($hash_ref = $db_ptr->fetchrow_hashref){
	push (@array,"$$hash_ref{'priority'};$$hash_ref{'path'};$$hash_ref{'recursive'};$$hash_ref{'description'}");
}

return @array;
}
#################################
sub update_md5_rules{
my ($sid,$md5_rules) = @_;
($sid=~/^\d+$/) || &error("Invalid SID: $sid");
my @rule_array;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $session_uid;
my @rules_to_delete;
&connect_to_db;

@rule_array = split(/\n/,$md5_rules);



$session_uid = &rand_string(4,1);
foreach (@rule_array){
	my @rule = split(/;/,$_);
# take out spaces from beg./end of path
$rule[1]=~s/^\s+|\s+$//g;
# take out trailing slash - not needed
$rule[1]=~s/\/$//g; # g is for: /root//////
	next if (!$rule[1]); #skip bad records
	# make sure alert level is in correct format
	if ($rule[0]=~/^yellow$/i){
		$rule[0] = "YELLOW";
	}
	elsif ($rule[0]=~/^ignore$/i){
		$rule[0] = "IGNORE";
	}
	else{
		#Default to RED
		$rule[0] = "RED";
	}
	#default to 0 for recursive option if not 1
	($rule[2]==1) || ($rule[2]=0);
	#safety first:
	&safe_slash(\$rule[3]);
	&safe_slash(\$rule[1]);

#Check to see if this is an old entry
	$sql_query = "	SELECT path FROM dm_md5_rules \
						WHERE sid = '$sid' AND path = '$rule[1]'";
	$db_ptr = &run_query($sql_query);
	if ($hash_ref = $db_ptr->fetchrow_hashref){
		$sql_query = "	UPDATE dm_md5_rules \
							SET \
								session_uid = '$session_uid', \
								description = '$rule[3]', \
								priority		= '$rule[0]', \
								recursive	= '$rule[2]' \
							WHERE \
								sid 	= '$sid' AND \
								path	= '$rule[1]'";
		$db->do($sql_query);
#&debug($sql_query) if ($rule[0]=~/^ignore$/i);
	}
	else{
		#Then its a new record
		$sql_query = "	INSERT INTO dm_md5_rules \
							VALUES( \
								'$sid', '', \
								'$rule[0]','$rule[1]', \
								'$rule[2]','$rule[3]', \
								NOW(),'$session_uid','1')";
		$db->do($sql_query);
	}

if ($rule[0] eq "IGNORE"){
	#### If it is an ignore statement, we'll have to check 
	# the dm_md5_data table and delete any matching existing rows

	$sql_query = "	DELETE FROM dm_md5_data \
					WHERE \
						path = '$rule[1]' AND \
						sid = '$sid'";
	$db->do($sql_query);
	
	### let's help people out and delete conflicting rules
	$sql_query = "  DELETE FROM dm_md5_rules \
					WHERE \
						path = '$rule[1]' AND \
                        sid = '$sid' AND \
						priority != 'IGNORE'";
	$db->do($sql_query);
}




}
# now delete all old entries:
$sql_query = "	SELECT rule_uid \
					FROM dm_md5_rules \
					WHERE \
						sid			= '$sid' AND \
						session_uid != '$session_uid'";
$db_ptr = &run_query($sql_query);
while ($hash_ref = $db_ptr->fetchrow_hashref){
	push (@rules_to_delete,$$hash_ref{'rule_uid'});
}
#delete the data attributed to the outdated rules:
foreach (@rules_to_delete){
	$sql_query = "	DELETE FROM dm_md5_data \
						WHERE rule_uid = '$_'";
	$db->do($sql_query);
}
# now delete the rules
$sql_query = "DELETE FROM dm_md5_rules WHERE  \
						sid			= '$sid' AND \
						session_uid != '$session_uid'";
$db->do($sql_query);


&log_event(	username => "$logged_in_as",
				action 	=> "updated md5 rules",
				target	=> "SID: $sid",
			 );

}
##################################
sub view_md5_page{
my ($minimal,$sid) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
($sid=~/^\d+$/) || ($sid = '');

if (!$sid){
	if (!$minimal){
		$table .= "<CENTER><A HREF=\"$home_url?td=view_md5_page&minimal=1\"><b>Show Minimal View</b></A></CENTER>";
	}
	else{
		$table .= "<CENTER><A HREF=\"$home_url?td=view_md5_page\"><b>Show Detailed View For All Hosts</b></A></CENTER><P>";
	}
}
else{
	$minimal = '';
}

if (!$sid){
	$sql_query = "	SELECT \
							DISTINCT sensor.sid,hostname  \
						FROM \
							dm_md5_rules \
						LEFT JOIN sensor \
						ON dm_md5_rules.sid = sensor.sid";
	$db_ptr = &run_query($sql_query);
}
else{
 $sql_query = " SELECT \
                     sensor.sid,hostname  \
                  FROM \
                     dm_md5_rules \
                  LEFT JOIN sensor \
                  ON dm_md5_rules.sid = sensor.sid \
						WHERE dm_md5_rules.sid = '$sid' \
						LIMIT 1";
   $db_ptr = &run_query($sql_query);
}
while ($hash_ref = $db_ptr->fetchrow_hashref){
	my ($temp_result,$last_checked) = &md5_find_changes($$hash_ref{'sid'},$minimal);
$table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 ALIGN=center width=80%>";
	$table .= "<TR bgcolor=\"$head_color\"><TD COLSPAN=2 background=\"$v_graphics_path/bg_title.gif\">";

	if (!$temp_result){
		$table .= "&nbsp;<B>$$hash_ref{'sid'} - $$hash_ref{'hostname'}</B></TD></TR>";
		if ($last_checked){
			$table .= "<TR bgcolor=\"$title_color\"><TD COLSPAN=2>";
			$table .= "&nbsp;<B>Last checked on:</B> $last_checked";
			$table .= "</TD></TR>";
		}
		else{
			$table .= "<TR><TD COLSPAN=2 ALIGN=left BGCOLOR=\"$title_color\">";
			$table .= "&nbsp;<B>It appears that this host's files have never been checked.<BR>Please make sure that the client is running and is set to perform local File / Web Integrity Checks</B>";
			$table .= "</TD></TR>";
		}
		$table .= "<TR bgcolor=\"$desc_color\"><TD WIDTH=\"10%\" align=center>";
		$table .= &color_code("GREEN");
		$table .= "</TD><TD WIDTH=\"90%\">";
		$table .= " No alerts.";
   	$table .= "</TD></TR>\n";
$table .= "<TR HEIGHT=2 BGCOLOR=\"$head_color\"><TD COLSPAN=2><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE>\n<br>\n";
	}
	else{
		$table .= "&nbsp;<A HREF=\"$home_url?td=view_md5_details_page&sid=$$hash_ref{'sid'}\" style=\"color:white\"><B>$$hash_ref{'sid'} - $$hash_ref{'hostname'}</B></a>";

		if (!$sid){
			#Give them the chance to view details for this sensor
			$table .= " &nbsp; &nbsp; <A HREF=\"$home_url?td=view_md5_details_page&sid=$$hash_ref{'sid'}\">";
			$table .= "<B>View Details</B>";
			$table .= "</A>";
		}
		$table .= "</TD></TR>";
			$table .= "<TR bgcolor=\"$title_color\"><TD COLSPAN=2>";
			$table .= "&nbsp;<B>Last checked on:</B> $last_checked";
			$table .= "</TD></TR>";
		$table .= "<TR bgcolor=\"$desc_color\"><TD COLSPAN=2 align=center>";
      $table .= $temp_result;
      if (&is_admin("f3")){

         #Give them the chance to selectively update md5s:
         $table .= "<A HREF=\"$home_url?td=confirm_selective_md5_changes&sid=$$hash_ref{'sid'}&minimal=$FORM{'minimal'}\">";
         $table .= "<B>Confirm changes for this host only</B>";
         $table .= "</A>";
      }

   	$table .= "</TD></TR>\n";
$table .= "<TR HEIGHT=2 BGCOLOR=\"$head_color\"><TD COLSPAN=2><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE>\n<br>\n"; 
	}
}

=head
if (!$sid){
    if (!$minimal){
        $table .= "<CENTER><A HREF=\"$home_url?td=view_md5_page&minimal=1\"><b>Show Minimal View</b></A></CENTER>";
    }
    else{
        $table .= "<CENTER><A HREF=\"$home_url?td=view_md5_page\"><b>Show Detailed View For All Hosts</b></A></CENTER><P>";
    }
}
else{
    $minimal = '';
}
=cut

if (&is_admin("f3")){
	$table .= "<P><CENTER><A HREF=\"$home_url?td=confirm_all_md5_changes\"><B>Confirm/Update All Changes For All Hosts</B></A></CENTER></p><br>";
}



push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}
##################################
sub print_user_config_form{
my $sql_query;
my $db_ptr;
my $hash_ref;
my $html;
my $user_list;
my $user_table;

if ($logged_in_as=~/^anonymous$/i){
	&error("Anonymous users have no options here.");
}
elsif (&is_admin()){
	#print admin user config menu
	($user_list,$user_table) = &get_user_list("current_user");
	push (@substitutions,"\\[USER_TABLE\\],-,$user_table");
	push (@substitutions,"\\[USER_LIST\\],-,$user_list");
	$html .= &print_with_key($admin_user_config_form,"TO_STRING");

}
else{
	#print user level user config menu
	my $users_email = &get_users_email;
	push (@substitutions,"\\[USERS_EMAIL\\],-,$users_email");
   $html .= &print_with_key($ul_user_config_form,"TO_STRING");
	if ($allow_user_to_change_email){
   	$html .= &print_with_key($ul_email_config_form,"TO_STRING");
	}
}


push (@substitutions,"\\[MAIN_TABLE\\],-,$html");
&print_main_with_key($main_template);
}
##################################
sub print_user_level_config_form{
my $sql_query;
my $db_ptr;
my $hash_ref;
my $html;
my $user_list;
my $user_table;

&error("Anonymous users have no options here.") if ($logged_in_as=~/^anonymous$/i);

#print user level user config menu
my $users_email = &get_users_email;
push (@substitutions,"\\[USERS_EMAIL\\],-,$users_email");

$html .= "<TABLE BORDER=0 ALIGN=center><TR><TD>";
$html .= &print_with_key($ul_user_config_form,"TO_STRING");
if ($allow_user_to_change_email){
	$html .= "</TD></TR><TR><TD>";
   		$html .= &print_with_key($ul_email_config_form,"TO_STRING");
	$html .= "</TD></TR>";
}
$html .= "</TABLE>";



push (@substitutions,"\\[MAIN_TABLE\\],-,$html");
&print_main_with_key($main_template);
}
################################
sub get_user_list{
my ($select_name) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $html;
my $table;

($select_name) || ($select_name = "username");

$sql_query = "	SELECT \
							admin,f1,f2,f3,username,email_address, \
							ip_restrict,current_login_timedate,current_ip \
					FROM dm_sessions \
					ORDER BY UPPER(username)";
$db_ptr = &run_query($sql_query);

$html .= "<SELECT NAME=\"$select_name\">\n";
$html .= "<OPTION VALUE=\"NOT_SELECTED\"> - Select -</OPTION>\n";

# User Table Header
$table .= "<TR bgcolor=\"$title_color\">";
$table .= "<TD ALIGN=center><B>Username</B></TD>";
$table .= "<TD ALIGN=center><B>Email</B></TD>";
$table .= "<TD ALIGN=center><B>SU</B></TD>";
$table .= "<TD ALIGN=center><B>NIDS</B><BR><B>Admin</B></TD>";
$table .= "<TD ALIGN=center><B>Service</B><BR><b>Admin</B></TD>";
$table .= "<TD ALIGN=center><B>Integrity</B><BR><b>Admin</B></TD>";
$table .= "<TD ALIGN=center><B>IP Restriction</B></TD>";
$table .= "</TR>";

while ($hash_ref = $db_ptr->fetchrow_hashref){
	#user table:
	$table .= "<TR bgcolor=\"$desc_color\">";
	$table .= "<TD>&nbsp;$$hash_ref{'username'}</TD>";
	$table .= "<TD>&nbsp;$$hash_ref{'email_address'}</TD>";
	$table .= "<TD align=center>";
	$table .= ($$hash_ref{'admin'})
			? "YES"
			: "NO";
	$table .= "</TD>";
	$table .= "<TD align=center>";
	$table .= ($$hash_ref{'f1'})
			? "YES"
			: "NO";
	$table .= "</TD>";
	$table .= "<TD align=center>";
	$table .= ($$hash_ref{'f2'})
			? "YES"
			: "NO";
	$table .= "</TD>";
	$table .= "<TD align=center>";
	$table .= ($$hash_ref{'f3'})
			? "YES"
			: "NO";
	$table .= "</TD>";
	# wrap every other rule
	$$hash_ref{'ip_restrict'}=~s/([0-9\.\-]*?;[0-9\.\-]*)?;/$1:/g;
	$$hash_ref{'ip_restrict'}=~s/:/;<BR>/g;

	$table .= "<TD>&nbsp;$$hash_ref{'ip_restrict'}</TD>";
	$table .= "</TR>";
	$table .= "<TR bgcolor=\"$desc_color\">";
	$table .= "<TD align=center COLSPAN=7>$$hash_ref{'username'}'s Last Login: $$hash_ref{'current_login_timedate'} from ";
	$table .= &convert_long_ip($$hash_ref{'current_ip'});
	$table .= "</TD>";
	$table .= "</TR>";
	#select list
	$html .= "<OPTION VALUE=\"$$hash_ref{'username'}\">$$hash_ref{'username'}";
	$html .= "</OPTION>\n";
}
$html .= "</SELECT>";


return ($html,$table);
}
################################
sub do_add_user{
my ($username,$password,$email_address,$ip_restrict,$su,$nids_admin,$service_admin,$md5_admin) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;

$su 				= ($su) 			? 1 : '';
$nids_admin 		= ($nids_admin) 	? 1 : '';
$service_admin 		= ($service_admin) 	? 1 : '';
$md5_admin 			= ($md5_admin) 		? 1 : '';

($username=~/^[a-zA-Z0-9 ]{3,30}$/)
	|| &error("Usernames may only include alphanumeric characters and be between 3 and 30 characters");

($password=~/.{4,}/) 
	|| &error("Password must be at least 4 characters.");
#make sure it's not all spaces:
&check_ip_restrict_value($ip_restrict);
if ($password=~/\s{2}/){
	&error("You may not have more then one whitespace character in a row.");
}
if ($username eq $password){
	&error("Come on now, you really want your username and password to be the same? <BR> Not on my watch!");
}

if ($email_address=~/.{61}/){
	&error("Email address may only be up to 60 characters.");
}

&safe_slash(\$password);
&safe_slash(\$email_address);

if (&user_exists($username)){
	&error("User with username \"$username\" already exists.");
}

if ($username=~/^anonymous$/i){
	&error("You can't add another user named $username");
}

$password = crypt($password,$password);
# OK, lets add 'em
$sql_query = "	INSERT INTO dm_sessions \
					VALUES ( \
						'$username','$password', \
						'','','','$email_address', \
						'$su','$ip_restrict','$nids_admin','$service_admin','$md5_admin')";
&connect_to_db;
($db->do($sql_query)) || &error("Error adding user.");	

&push_message("<FONT COLOR=red><CENTER>User \"$username\" Added.</CENTER></FONT>");

&log_event(	username => "$logged_in_as",
				action 	=> "added user",
				target	=> "$username",
			 );

return 1;
}
###################################
sub do_modify_user{
my ($username,$action,$value) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;

if ($logged_in_as=~/^anonymous$/i){
	&error("Anonymous users have no options here.");
}

#Don't allow non_admin in this section either
&error("You must be a Super User to do that.") unless (&is_admin());

($action=~/^change_password$|^make_su$|^remove_su$|^make_nids_admin$|^remove_nids_admin$|^make_service_admin$|^remove_service_admin$|^make_md5_admin$|^remove_md5_admin$|change_email$|^change_ip_restrict$|^delete$/)
	|| &error("Invalid action: $action");

&log_event(	username => "$logged_in_as",
				action 	=> "modified user ($action)",
				target	=> "$username",
			 );

if ($username=~/NOT_SELECTED/){
	&error("You must select a user to modify from the dropdown menu.");
}
(&user_exists($username)) 
   || &error("User \"$username\" doesn't exist.");

if ($action=~/^change_password$/){
		($value=~/.{4,}/) 
			|| &error("Password must be at least 4 characters.");
		#make sure it's not all spaces:
		if ($value=~/\s{2}/){
			&error("You may not have more then one whitespace character in a row.");
		}
	# lets do it:
	$value = crypt($value,$value);
	$sql_query = "	UPDATE dm_sessions \
						SET password = '$value' \
						WHERE username = '$username'";
	&connect_to_db;
	($db->do($sql_query)) || &error("Error changing password.");
	&push_message("<FONT COLOR=red><CENTER>Password Changed.</CENTER></FONT>");
	return 1;
}
if ($action=~/^make_su$/){
	$sql_query = "	UPDATE dm_sessions \
						SET admin = '1' \
						WHERE username = '$username'";
	&connect_to_db;
	($db->do($sql_query)) || &error("Error changing admin privileges.");
	&push_message("<FONT COLOR=red><CENTER>User escalated to <B>Super User</B> status.</CENTER></FONT>");
	return 1;
}
if ($action=~/^remove_su$/){
	$sql_query = "	UPDATE dm_sessions \
						SET admin = '0' \
						WHERE username = '$username'";
	&connect_to_db;
	($db->do($sql_query)) || &error("Error changing admin privileges.");
	&push_message("<FONT COLOR=red><CENTER>User's <B>Super User</B> status revoked.</CENTER></FONT>");
	return 1;
}
if ($action=~/^make_nids_admin$/){
	$sql_query = "	UPDATE dm_sessions \
						SET f1 = '1' \
						WHERE username = '$username'";
	&connect_to_db;
	($db->do($sql_query)) || &error("Error changing admin privileges.");
	&push_message("<FONT COLOR=red><CENTER>User Escalated to <B>NIDS Admin</B> status.</CENTER></FONT>");
	return 1;
}
if ($action=~/^remove_nids_admin$/){
	$sql_query = "	UPDATE dm_sessions \
						SET f1 = '0' \
						WHERE username = '$username'";
	&connect_to_db;
	($db->do($sql_query)) || &error("Error changing admin privileges.");
	&push_message("<FONT COLOR=red><CENTER>User's <B>NIDS Admin</B> status revoked.</CENTER></FONT>");
	return 1;
}
if ($action=~/^make_service_admin$/){
	$sql_query = "	UPDATE dm_sessions \
						SET f2 = '1' \
						WHERE username = '$username'";
	&connect_to_db;
	($db->do($sql_query)) || &error("Error changing admin privileges.");
	&push_message("<FONT COLOR=red><CENTER>User Escalated to <B>Host / Service Admin</B> status.</CENTER></FONT>");
	return 1;
}
if ($action=~/^remove_service_admin$/){
	$sql_query = "	UPDATE dm_sessions \
						SET f2 = '0' \
						WHERE username = '$username'";
	&connect_to_db;
	($db->do($sql_query)) || &error("Error changing admin privileges.");
	&push_message("<FONT COLOR=red><CENTER>User's <B>Host / Service Admin</B> status revoked.</CENTER></FONT>");
	return 1;
}
if ($action=~/^make_md5_admin$/){
	$sql_query = "	UPDATE dm_sessions \
						SET f3 = '1' \
						WHERE username = '$username'";
	&connect_to_db;
	($db->do($sql_query)) || &error("Error changing admin privileges.");
	&push_message("<FONT COLOR=red><CENTER>User Escalated to <B>File / Web Integrity Admin</B> Status.</CENTER></FONT>");
	return 1;
}
if ($action=~/^remove_md5_admin$/){
	$sql_query = "	UPDATE dm_sessions \
						SET f3 = '0' \
						WHERE username = '$username'";
	&connect_to_db;
	($db->do($sql_query)) || &error("Error changing admin privileges.");
	&push_message("<FONT COLOR=red><CENTER>User's <B>File / Web Integrity Admin</B> Status Revoked.</CENTER></FONT>");
	return 1;
}
if ($action=~/^change_ip_restrict$/){
	&check_ip_restrict_value($value);
	$sql_query = "	UPDATE dm_sessions \
						SET ip_restrict = '$value' \
						WHERE username = '$username'";
	&connect_to_db;
	($db->do($sql_query)) || &error("Error changing IP restrict value.");
	&push_message("<FONT COLOR=red><CENTER>IP restrictions changed.</CENTER></FONT>");
	return 1;
}
if ($action=~/^change_email$/){
		if ($value=~/.{61}/){
			&error("Email address may only be up to 60 characters.");
		}
	$sql_query = " UPDATE dm_sessions \
                  SET email_address = '$value' \
						WHERE username = '$username'";
   &connect_to_db;
   ($db->do($sql_query)) || &error("Error changing email address.");
   &push_message("<FONT COLOR=red><CENTER>Email Address Changed to \"$value\".</CENTER></FONT>");
   return 1;
}
if ($action=~/^delete$/){
	if ($username =~/^admin$/i){
		&error("You are not allowed to delete the Admin account");
	}
	$sql_query = "	DELETE FROM dm_sessions \
						WHERE username = '$username'";
   &connect_to_db;
   ($db->do($sql_query)) || &error("Error deleting user \"$username\".");
   &push_message("<FONT COLOR=red><CENTER>User \"$username\" deleted.</CENTER></FONT>");
   return 1;

}

}
###################################
sub user_exists{
my ($username) = @_;

my $sql_query;
my $db_ptr;
my $hash_ref;
&safe_slash(\$username);

$sql_query = "	SELECT username \
					FROM dm_sessions \
					WHERE username = '$username'";
$db_ptr = &run_query($sql_query);

if ($hash_ref = $db_ptr->fetchrow_hashref){
	return 1;
}
else{
	return;
}

}
#####################################
sub is_anonymous{
if ($logged_in_as=~/^anonymous$/i){
	return 1;
}
	
return;
}



####################################################
sub md5_find_changes{
my ($SID,$minimal_detail) = @_;
($SID=~/^\d+$/) || &error("Invalid SID passed: $SID");

my $sql_query;
my $db_ptr;
my $hash_ref;
my $final_message;
my $count;
my $last_checked;


$sql_query = "	SELECT \
						dm_md5_data.md5_uid, 
						dm_md5_data.rule_uid, 
						dm_md5_data.path, 
						dm_md5_data.k_inode, 
						dm_md5_data.k_perms, 
						dm_md5_data.k_uid, 
						dm_md5_data.k_gid, 
						dm_md5_data.k_size, 
						dm_md5_data.k_mtime, 
						dm_md5_data.k_ctime, 
						dm_md5_data.k_md5sum, 
						dm_md5_data.c_inode, 
						dm_md5_data.c_perms, 
						dm_md5_data.c_uid, 
						dm_md5_data.c_gid, 
						dm_md5_data.c_size, 
						dm_md5_data.c_mtime, 
						dm_md5_data.c_ctime, 
						dm_md5_data.c_md5sum, 
						dm_md5_data.last_confirmed, 
						dm_md5_data.last_checked , 
						dm_md5_data.last_changed, 
						dm_md5_data.out_of_sync, 
						dm_md5_data.added_flag, 
						dm_md5_data.modified_flag, 
						dm_md5_data.deleted_flag, 
						dm_md5_data.session_uid,
						dm_md5_rules.sid,
						dm_md5_rules.priority,
						dm_md5_rules.description
					FROM \
						dm_md5_data \
					LEFT JOIN dm_md5_rules \
						ON dm_md5_data.rule_uid = dm_md5_rules.rule_uid \
					WHERE \
						dm_md5_rules.sid			= '$SID' AND \
						out_of_sync = 1 \
					ORDER BY \
						priority,rule_uid";

$db_ptr = &run_query($sql_query);
while ($hash_ref = $db_ptr->fetchrow_hashref){
	if (!$count){
		$last_checked = $$hash_ref{'last_checked'};
	}
	$count++;
	my $added_message;
	my $deleted_message;
	my $modified_message;
	my $modified_title;

	if ($$hash_ref{'added_flag'}){
			$added_message = "<TR BGCOLOR=\"$desc_color\"><TD COLSPAN=3><B>ADDED FILE:</B> $$hash_ref{'path'}</TD></TR>\n";
	}
	if ($$hash_ref{'deleted_flag'}){
			$deleted_message = "<TR BGCOLOR=\"$desc_color\"><TD COLSPAN=3><B>DELETED FILE:</B> $$hash_ref{'path'}</TD></TR>\n";
	}
	if ($$hash_ref{'modified_flag'}){
			$modified_title = "<TR bgcolor=\"$desc_color\"><TD COLSPAN=3 ALIGN=left><B>MODIFIED FILE:</B> $$hash_ref{'path'}</TD></TR>\n";
            if ($$hash_ref{'k_inode'} != $$hash_ref{'c_inode'}){
					$modified_message .= "<TR BGCOLOR=\"$desc_color\"><TD><B>INODE:</B></TD>";
					$modified_message .= "<TD>&nbsp; $$hash_ref{'k_inode'}</TD>";
					$modified_message .= "<TD>&nbsp;$$hash_ref{'c_inode'}</TD></TR>\n";

				}
            if ($$hash_ref{'k_perms'} ne $$hash_ref{'c_perms'}){
					$modified_message .= "<TR BGCOLOR=\"$desc_color\"><TD><B>PERMISSIONS:</B></TD>";
					$modified_message .= "<TD>&nbsp;$$hash_ref{'k_perms'}</TD>";
					$modified_message .= "<TD>&nbsp;$$hash_ref{'c_perms'}</TD></TR>\n";

				}
            if ($$hash_ref{'k_uid'} ne $$hash_ref{'c_uid'}){
					$modified_message .= "<TR BGCOLOR=\"$desc_color\"><TD><B>UID:</B></TD>";
					$modified_message .= "<TD>&nbsp;$$hash_ref{'k_uid'}</TD>";
					$modified_message .= "<TD>&nbsp;$$hash_ref{'c_uid'}</TD></TR>\n";

				}
            if ($$hash_ref{'k_gid'} ne $$hash_ref{'c_gid'}){
					$modified_message .= "<TR BGCOLOR=\"$desc_color\"><TD><B>GID:</B></TD>";
					$modified_message .= "<TD>&nbsp;$$hash_ref{'k_gid'}</TD>";
					$modified_message .= "<TD>&nbsp;$$hash_ref{'c_gid'}</TD></TR>\n";

				}
            if ($$hash_ref{'k_size'} != $$hash_ref{'c_size'}){
					$modified_message .= "<TR BGCOLOR=\"$desc_color\"><TD><B>SIZE:</B></TD>";
					$modified_message .= "<TD>&nbsp;$$hash_ref{'k_size'}</TD>";
					$modified_message .= "<TD>&nbsp;$$hash_ref{'c_size'}</TD></TR>\n";

				}
            if ($$hash_ref{'k_mtime'} != $$hash_ref{'c_mtime'}){
					$$hash_ref{'k_mtime'} = localtime($$hash_ref{'k_mtime'});
					$$hash_ref{'c_mtime'} = localtime($$hash_ref{'c_mtime'});
					$modified_message .= "<TR BGCOLOR=\"$desc_color\"><TD><B>MTIME:</B></TD>";
					$modified_message .= "<TD>&nbsp;$$hash_ref{'k_mtime'}</TD>";
					$modified_message .= "<TD>&nbsp;$$hash_ref{'c_mtime'}</TD></TR>\n";

				}
            if ($$hash_ref{'k_ctime'} != $$hash_ref{'c_ctime'}){
					$$hash_ref{'k_ctime'} = localtime($$hash_ref{'k_ctime'});
					$$hash_ref{'c_ctime'} = localtime($$hash_ref{'c_ctime'});
					$modified_message .= "<TR BGCOLOR=\"$desc_color\"><TD><B>CTIME:</B></TD>";
					$modified_message .= "<TD>&nbsp;$$hash_ref{'k_ctime'}</TD>";
					$modified_message .= "<TD>&nbsp;$$hash_ref{'c_ctime'}</TD></TR>\n";

				}
            if ($$hash_ref{'k_md5sum'} ne $$hash_ref{'c_md5sum'}){
					$modified_message .= "<TR BGCOLOR=\"$desc_color\"><TD><B>MD5_SUM:</B></TD>";
					$modified_message .= "<TD>&nbsp; $$hash_ref{'k_md5sum'}</TD>";
					$modified_message .= "<TD>&nbsp; $$hash_ref{'c_md5sum'}</TD></TR>\n";

				}
	}
	# Put it all together:
	$final_message .= "<TABLE BORDER=0 WIDTH=\"100%\" CELLSPACING=0 CELLPADDING=0>";
	$final_message .= "<TR><TD BGCOLOR=\"#000000\" align=center valign=top>";
    $final_message .= "<TABLE BORDER=0 WIDTH=\"100%\" CELLSPACING=1 CELLPADDING=2 BGCOLOR=\"#000000\">";
	$final_message .= "<TR bgcolor=\"$title_color\"><TD ALIGN=center WIDTH=\"10%\">";
	$final_message .= &color_code($$hash_ref{'priority'});
	$final_message .= "</TD><TD width=\"45%\">&nbsp;";
	$final_message .= "<B>$$hash_ref{'path'}</B></TD>";
	$final_message .= "<TD width=\"45%\">&nbsp;";
	$final_message .= "<B>$$hash_ref{'description'}</B></TD></TR>";
	$final_message .= $added_message;
	$final_message .= $deleted_message;
	$final_message .= $modified_title;
	if ($modified_message && !$minimal_detail){
		$final_message .= "<TR bgcolor=\"$desc_color\"><TD>&nbsp;</TD>";
		$final_message .= "<TD ALIGN=center><B>Known</B></TD>";
		$final_message .= "<TD ALIGN=center><B>Observed</B></TD></TR>";
	}
	$final_message .= $modified_message if (!$minimal_detail);
	$final_message .= "</TABLE>\n</TD></TR>\n</TABLE>\n";
}
if (!$last_checked){
	$sql_query = " SELECT max(last_checked)  AS LC\
						FROM dm_md5_data \
						WHERE sid = '$SID'";
	$db_ptr = &run_query($sql_query);
	$hash_ref = $db_ptr->fetchrow_hashref;
	$last_checked = $$hash_ref{'LC'};
}

return ($final_message,$last_checked);
}
####################
sub confirm_all_md5_changes{
my $sql_query;
my $db_ptr;
my $hash_ref;

#Delete all sub-rules where the file has been deleted:
$sql_query = "	DELETE \
						from dm_md5_data \
					WHERE \	
						deleted_flag = '1'	";
   &connect_to_db;
   $db->do($sql_query);

$sql_query = "	UPDATE \
						dm_md5_data \
					SET \
						k_inode = c_inode, \
						k_perms = c_perms, \
						k_uid = c_uid, \
						k_gid = c_gid, \
						k_size = c_size, \
						k_mtime= c_mtime, \
						k_ctime = c_ctime, \
						k_md5sum = c_md5sum, \	
						last_confirmed = NOW(), \
						added_flag = '', \
						modified_flag = '', \
						deleted_flag = '', \
						out_of_sync = '' \
				";
   ($db->do($sql_query)) || &error("Error updating File / Web Integrity information.");
   &push_message("<FONT COLOR=red><CENTER>All current file attributes confirmed/updated.</CENTER></FONT>");
	&log_event(	username => "$logged_in_as",
					action 	=> "confirmed all md5 changes",
					target	=> "",
				 );

}
####################
sub confirm_selective_md5_changes{
my ($c_sid) = @_;
($c_sid=~/^\d+$/) || &error("Invalid Sendor ID passed: $c_sid.");
my $sql_query;
my $db_ptr;
my $hash_ref;

#Delete all sub-rules where the file has been deleted:
$sql_query = "	DELETE \
						from dm_md5_data \
					WHERE \	
						sid				= '$c_sid' AND \
						deleted_flag 	= '1'	";
   &connect_to_db;
   $db->do($sql_query);

$sql_query = "	UPDATE \
						dm_md5_data \
					SET \
						k_inode = c_inode, \
						k_perms = c_perms, \
						k_uid = c_uid, \
						k_gid = c_gid, \
						k_size = c_size, \
						k_mtime= c_mtime, \
						k_ctime = c_ctime, \
						k_md5sum = c_md5sum, \	
						last_confirmed = NOW(), \
						added_flag = '', \
						modified_flag = '', \
						deleted_flag = '', \
						out_of_sync = '' \
					WHERE \
						sid = '$c_sid'
				";
   ($db->do($sql_query)) || &error("Error updating File / Web Integrity information for SID $c_sid.");
   &push_message("<FONT COLOR=red><CENTER>All current file attributes confirmed/updated for SID $c_sid.</CENTER></FONT>");

	&log_event(	username => "$logged_in_as",
					action 	=> "confirmed selective md5 changes",
					target	=> "SID: $c_sid",
				 );

}
######################
sub get_minimum_md5_alert_status{
my $sql_query;
my $db_ptr;
my $hash_ref;
my @bad_md5s;

$sql_query = "	SELECT \
						count(*) AS COUNT,
						dm_md5_data.added_flag, \
						dm_md5_data.modified_flag, \ 
						dm_md5_data.deleted_flag, \
						dm_md5_rules.sid, \
						dm_md5_rules.priority, \
						sensor.hostname \
					FROM \
						dm_md5_data \
					LEFT JOIN dm_md5_rules \
						ON dm_md5_data.rule_uid = dm_md5_rules.rule_uid \
					LEFT JOIN sensor \
						ON dm_md5_rules.sid = sensor.sid \
					WHERE \
						out_of_sync = 1 \
					GROUP BY \
						sid,UPPER(priority) \
					ORDER BY \
						dm_md5_rules.sid,priority";


$db_ptr = &run_query($sql_query);
while ($hash_ref = $db_ptr->fetchrow_hashref){
	push (@bad_md5s,"$$hash_ref{'hostname'} ($$hash_ref{'COUNT'});" . &color_code($$hash_ref{'priority'}));
}


return @bad_md5s
}
############################
sub get_reference_link{
my ($ref_id) = @_;
($ref_id=~/^\d+$/) || return;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $link;

$sql_query = "	SELECT \
						reference.ref_system_id, \
						ref_tag,ref_system_name \
					FROM reference \
					LEFT JOIN reference_system \
						ON (reference_system.ref_system_id = reference.ref_system_id) \
					WHERE \
						reference.ref_id = '$ref_id'";
$db_ptr = &run_query($sql_query);
($hash_ref = $db_ptr->fetchrow_hashref) || return;

if ($$hash_ref{'ref_system_name'}=~/^arachnids$/i){
	$link = "http://www.whitehats.com/info/IDS$$hash_ref{'ref_tag'}";
}
elsif ($$hash_ref{'ref_system_name'}=~/^cve$/i){
	$link = "http://cve.mitre.org/cgi-bin/cvename.cgi?name=$$hash_ref{'ref_tag'}";
}


if ($link){
	$link = "<A HREF=\"$link\" TARGET=\"IDS_WINDOW\">More Info</A>";
}
return $link;
}
###########################
sub format_localtime{

my $ltime = localtime();
##Format AM/PM
$ltime;
if ($ltime=~/^(\S+\s+\S+\s+\S+\s+)(\d{1,2}):(\d{1,2}:\d{1,2}\s+)(\S+)$/){
	my $hour;
	my $date_string 	= $1;
	my $time_string	= $3;
	my $year_string	= $4;
	my $ampm;
	if ($2 == 0){
	#12 AM
	$hour = 12;
	$ampm = "AM";
	}
	elsif ($2 > 11){
	#PM
	$hour = ($2 == 12) 
			? 12 
			:($2-12);
	$ampm = "PM";
	}
	else{
	#AM
	$hour = $2;
	$ampm = "AM";
	}
	$ltime = "$hour:$time_string $ampm, $date_string $year_string";
}
return $ltime;
}
##################################
sub check_ip_restrict_value{
my ($value) = @_;
($value) || return 1;
my $error;
my $error_string;

my @rules = split(/;/,$value);
foreach (@rules){
	($_ =~/^([0-9\-]{1,})\.([0-9\-]{1,})\.([0-9\-]{1,})\.([0-9\-]{1,})$/) ||
	($error = 1);
}

if ($error){
$error_string = << "EOF";
At least one of the restrictions is in an invalid format.<BR>
They must be in the format:<BR>
<B>192.168.0.1;192.168.1-2.0-255;192.168-169.0-255.10-20</B><BR>
<P>
All restrictions must be separated by a semi-colon.
EOF
&error($error_string);
}

return 1;
}
#######################
sub check_if_immune{
my ($ip_to_check,$ip_restrictions) = @_;
my $ip_found;
my $check;
my @address_array = split(/\./,$ip_to_check);
($ip_restrictions) || return 1;
my @immune_array = split(/;/,$ip_restrictions);

      foreach $check(@immune_array){
         #check for properly formatted condition
         next unless  ($check =~/^([0-9]{1,3}\-{0,1}[0-9]{0,3})\.([0-9]{1,3}\-{0,1}[0-9]{0,3})\.([0-9]{1,3}\-{0,1}[0-9]{0,3})\.([0-9]{1,3}\-{0,1}[0-9]{0,3})$/);
         my $ip_1_from = $1;
         my $ip_1_to;
         my $ip_2_from = $2;
         my $ip_2_to;
         my $ip_3_from = $3;
         my $ip_3_to;
         my $ip_4_from = $4;
         my $ip_4_to;
         if ($ip_1_from =~/\-/){ #then it contains a range
            my @temp_ip = split (/-/,$ip_1_from);
            $ip_1_from = $temp_ip[0];
            $ip_1_to = $temp_ip[1];
         }
         else{$ip_1_to = $ip_1_from;}

         if ($ip_2_from =~/\-/){ #then it contains a range
            my @temp_ip = split (/-/,$ip_2_from);
            $ip_2_from = $temp_ip[0];
            $ip_2_to = $temp_ip[1];
         }
         else{$ip_2_to = $ip_2_from;}

         if ($ip_3_from =~/\-/){ #then it contains a range
            my @temp_ip = split (/-/,$ip_3_from);
            $ip_3_from = $temp_ip[0];
            $ip_3_to = $temp_ip[1];
         }
         else{$ip_3_to = $ip_3_from;}

         if ($ip_4_from =~/-/){ #then it contains a range
            my @temp_ip = split (/-/,$ip_4_from);
            $ip_4_from = $temp_ip[0];
            $ip_4_to = $temp_ip[1];
         }
         else{$ip_4_to = $ip_4_from;}

      #now all the conditions are in parsed, lets check if the ip matches:

        if(
            ($address_array[0] >= $ip_1_from) &&
            ($address_array[0] <= $ip_1_to) &&
            ($address_array[1] >= $ip_2_from) &&
            ($address_array[1] <= $ip_2_to) &&
            ($address_array[2] >= $ip_3_from) &&
            ($address_array[2] <= $ip_3_to) &&
            ($address_array[3] >= $ip_4_from) &&
            ($address_array[3] <= $ip_4_to)
         ){
            $ip_found = 1;
            last;
         }
      }
if ($ip_found){
   #then the IP address is immune, so we'll return 1;
   return 1;
}
else{
   # not found in the immune list, so return null
   return;
}
}
#####################################
sub ul_change_email{
my ($new_email) = @_;
my $sql_query;

($allow_user_to_change_email) || &error("You are not allowed to change your email address.<BR>Please consult the system administrator.");

($new_email=~/^\S+\@\S+\.[a-zA-Z]{2,4}$/)
	|| &error("Email address does not seem to be valid: $new_email");
$new_email=~tr/\@a-zA-Z0-9\.\-\_//dc;

$sql_query = " UPDATE dm_sessions \
               SET email_address = '$new_email' \
					WHERE username = '$logged_in_as'";
&connect_to_db;
($db->do($sql_query)) || &error("Error changing email address.");

&push_message("<FONT COLOR=red><CENTER>Email Address Changed to \"$new_email\".</CENTER></FONT>");

&log_event( username => "$logged_in_as",
            action   => "changed email address",
            target   => "$new_email",
          );
}
#####################################
sub ul_change_password{
my ($old_password,$new_password,$new_password_confirm) = @_;
my $sql_query;
my $old_c;
my $new_c;
my $db_ptr;
my $hash_ref;

($old_password) || &error("You must fill in your current password.");

if ($new_password ne $new_password_confirm){
	&error("Passwords don't match.. please try again.");
}
if ($logged_in_as eq $new_password){
	&error("Come on now, you really want your username and password to be the same? <BR> Not on my watch!");
}
($new_password=~/.{4,}/) 
	|| &error("Password must be at least 4 characters.");
#make sure it's not all spaces:
if ($new_password=~/\s{2}/){
	&error("You may not have more then one whitespace character in a row.");
}


# lets do it:
$old_c = crypt($old_password,$old_password);
$new_c = crypt($new_password,$new_password);

#check to see if old password matches:
$sql_query = "	SELECT username FROM dm_sessions \
					WHERE \
						username = '$logged_in_as' AND \
                  password = '$old_c'";
$db_ptr = &run_query($sql_query);
($hash_ref = $db_ptr->fetchrow_hashref) || &error("Error changing password.<BR>Current password does not match.");

$sql_query = "	UPDATE dm_sessions \
					SET password = '$new_c' \
					WHERE \
						username = '$logged_in_as' AND \
						password = '$old_c'";
&connect_to_db;
($db->do($sql_query)) || &error("Error changing password.");
&push_message("<FONT COLOR=red><CENTER>Password Changed.</CENTER></FONT>");

&log_event( username => "$logged_in_as",
            action   => "changed password",
            target   => "",
          );

}
############################
sub get_last_sid{
my $sql_query;
my $db_ptr;
my $hash_ref;

$sql_query = "	SELECT max(sid) AS MAXSID FROM sensor";

$db_ptr = &run_query($sql_query);
($hash_ref = $db_ptr->fetchrow_hashref) || return;

return $$hash_ref{'MAXSID'};
}
######################
sub print_monitor_event_detail{
my ($eid) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;

($eid=~/^\d+$/) || &error("No/Invalid event id specified: $eid");

$sql_query = "	SELECT \
 						service, \
						ip_addr, \
						status, \
						detail, \
						event_timestamp \
					FROM \
						dm_monitor_events \
					WHERE \
						eid = '$eid'";
$db_ptr = &run_query($sql_query);
($hash_ref = $db_ptr->fetchrow_hashref) || &error("So such event exists.");

$table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 width=\"80%\" align=center>\n";
$table .=   "<TR BGCOLOR=\"$head_color\">";
$table .=   "<TD background=\"$v_graphics_path/bg_title.gif\" colspan=2 align=center><b>Event Detail</b></TD>";
$table .= 	"</TR>\n";
$table .=   "<TR BGCOLOR=\"$title_color\">";
$table .=   "<TD valign=top align=center>";
$table .=   &color_code($$hash_ref{'status'});
$table .= 	"</TD>";
#$table .=	"<TD>&nbsp;<B>[TIMESTAMP]</B></TD>";
$table .=	"<TD>&nbsp;<B>$$hash_ref{'event_timestamp'}</B></TD>";
$table .=	"</TR>\n";
$table .= 	"<TR BGCOLOR=\"$desc_color\">";
$table .=   "<TD>&nbsp;</TD>";
$table .=	"<TD>";
$$hash_ref{'detail'}=~s/\n/\n<BR>/g;
$table .= 	"$$hash_ref{'detail'}";
$table .= "</TD></TR>\n";
$table .= "<TR HEIGHT=2 BGCOLOR=\"$head_color\"><TD COLSPAN=2><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE><br>\n";

push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
	
}
######################
sub log_event{
my (%args) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;

&safe_slash(\$args{'username'});
&safe_slash(\$args{'action'});
&safe_slash(\$args{'target'});

($args{'username'}) || 
	($args{'username'} = "UNKNOWN");

my $long_ip = &convert_dotted_ip($ENV{'REMOTE_ADDR'});

$sql_query = "	INSERT INTO \
						dm_log \
					VALUES ( \
						'','$args{'username'}', \
						'$args{'action'}', '$args{'target'}', \
						NOW(),'$long_ip' \
					)";

&connect_to_db;
($db->do($sql_query)) || &error("Error logging event.");

}
######################
sub print_log{
my ($last_amount) = @_;
($last_amount=~/^\d+$/) || ($last_amount=1000);
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table_row;
my $table_rows;


$sql_query = "	SELECT * FROM dm_log \
					ORDER BY timestamp DESC \
					LIMIT $last_amount ";

$db_ptr = &run_query($sql_query);
	$table_rows .= "<TR bgcolor=\"$head_color\"><TD background=\"$v_graphics_path/bg_title.gif\" colspan=5 align=center>";
	$table_rows .= "<B>Log Entrees</B></TD></TR>\n";
	$table_rows .= "<TR bgcolor=\"$title_color\"><TD align=center><B>Username</B></TD><TD align=center><B>Action</B></TD><TD align=center><B>Target</B></TD><TD align=center><B>Date/Time</B></TD><TD align=center><B>Login IP</B></TD></TR>\n";
while ($hash_ref = $db_ptr->fetchrow_hashref){
	$table_row = "<TR bgcolor=\"$desc_color\"><TD align=center>$$hash_ref{'username'}</TD>";
	$table_row .= "<TD>&nbsp;$$hash_ref{'action'}</TD>";
	$table_row .= "<TD>&nbsp;$$hash_ref{'target'}</TD>";
	$table_row .= "<TD align=center>$$hash_ref{'timestamp'}</TD>";
	$table_row .= "<TD align=center>" . &convert_long_ip($$hash_ref{'ip_address'}) . "</TD>";
	$table_row .= "</TR>\n";

	#prepending vs appending?...
	#$table_rows = $table_row . $table_rows;
	$table_rows .= $table_row;
}

$table_rows = "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 align=center width=\"80%\">$table_rows";
$table_rows .= "<TR HEIGHT=2 BGCOLOR=\"$head_color\"><TD COLSPAN=5><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>\n";
$table_rows .= "</TABLE>\n<BR>\n";
push (@substitutions,"\\[MAIN_TABLE\\],-,$table_rows");
&print_main_with_key($main_template);

}
#####################################
sub graph_data{
my ($graphed_days,$sql_query) = @_;

my $hash_ref;
my $db_ptr;
my $max_record;
my %records;
my %dates;
my $today;
my $this_hour;
my $yesterday;
my $table;
my @data;
my @labels; 
my $max_value;


$db_ptr = &run_query($sql_query);
while ($hash_ref = $db_ptr->fetchrow_hashref){
	$max_record = $$hash_ref{'COUNT'} if ($$hash_ref{'COUNT'} > $max_record);

	$records{$$hash_ref{'DAILY'}} = $$hash_ref{'COUNT'};
	$max_value = $$hash_ref{'COUNT'} if ($$hash_ref{'COUNT'} > $max_value);
	#Truncate datestamp:
	$$hash_ref{'timestamp'}=~s/^(\S+)\s.*$/$1/;
	$dates{$$hash_ref{'DAILY'}} = $$hash_ref{'timestamp'};
	$today = $$hash_ref{'TODAY'} if (!$today);#one time only
	$yesterday = $$hash_ref{'YESTERDAY'} if (($graphed_days == 1) && !$yesterday);#one time only
	$this_hour = $$hash_ref{'THIS_HOUR'} if (($graphed_days == 1) && !$this_hour);#one time only

}



#my ($year,$month,$mday) = (&get_date_array)[5,4,3];
#my $today = "$year$month$mday";

if ($graphed_days > 1){
	# > 1 day graph
	for (my $i=$today;$i>($today - $graphed_days);$i--){
		if ($records{$i}){
#			$table .= "Count for today ( $dates{$i} ) is $records{$i}<BR>\n";
			push (@data,$records{$i});
			push (@labels,$dates{$i});
		}	
		else{
			#no records for this day:
			# get the date for this day by a DB query... not the most efficient, but it's accurate
			$sql_query = "SELECT FROM_DAYS($i) AS DATESTRING";
			$db_ptr = &run_query($sql_query);
			my $lost_date = ($hash_ref = $db_ptr->fetchrow_hashref)
							? $$hash_ref{'DATESTRING'}
							: "???";
#			$table .= "NO RECORDS for day: $i which is $lost_date<BR>\n";
			push (@data,"0");
			push (@labels,$lost_date);
		}
	}
}
else{
	# == 1 day graph (24 hours)
	
	#convert ($this_hour) to just that:
	$this_hour=~s/^.*(\d\d)$/$1/;
	for (my $i=0;$i<24;$i++){
			if ($records{"$today$this_hour"}){
#				$table .= "count for this hour : $today - $this_hour IS " . $records{"$today$this_hour"} . "\n<BR>";
				push (@data,$records{"$today$this_hour"});
				push (@labels,$this_hour);
			}
			else{
#				$table .= "NO COUNT FOR THIS HOUR : $today - $this_hour IS " . $records{"$today$this_hour"} . "\n<BR>";
				push (@data,"0");
				push (@labels,$this_hour);
			}
		#decrement target hour:
		if (($this_hour - 1) < 0){
			$this_hour = 23;
			$today = $yesterday; #switch to yesterday's prefix for the hash
		}
		else{
			$this_hour--;
		}
		$this_hour =~s/^(\d)$/0$1/; # add an initial "0" for hrs < 10
	}
}

#&debug("GOT:\n<BR>$table");

$table = &do_graph_data(\@data,\@labels,$max_value,$graphed_days);

#&debug($table);
push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);

}
######################################
sub do_graph_data{
my ($data_ref,$labels_ref,$max_value,$graphed_days) = @_;

my $horiz_bars = 1 if ($FORM{'h_bars'});



my $table;
my $table_vrow_t;
my $table_vrow;
my $max_pix = ($horiz_bars)
			? 600
			: 240;#600 if bars go side to side, 240 if they go up n down
$max_pix -= 100 if ($graphed_days == 7); # looked "too tall" for one week graph;

# Make sure we have a max value... or else we'll get a illegal division by 0 error:
($max_value > 0) || &error("Graph not possible: No values returned for this query.");

$table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=0 ALIGN=center BGCOLOR=\"#214D7A\">\n";
$table .= "<TR><TD BGCOLOR=\"#214D7A\">\n";
$table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=1 ";
$table .= "ALIGN=CENTER BGCOLOR=\"#021439\">\n" if (!$horiz_bars);

$table .= "<TR BGCOLOR=\"#021439\">" if (!$horiz_bars);

for (my $i=0;$i<(@$data_ref);$i++){
	if ($horiz_bars){
		#horizontal bar graph
		$table .= "<TR BGCOLOR=\"#021439\">";
		$table .= "<TD bgcolor=\"$title_color\">&nbsp;";
			$table .= "$$labels_ref[$i]";
		$table .= "&nbsp;</TD>";
		$table .= "<TD BACKGROUND=\"$v_graphics_path/bg_hgraph.gif\">";
			$table .= "<IMG SRC=\"$v_graphics_path/ln_graph.gif\" border=0 height=20 width=\"";
		my $temp_width = &round(($$data_ref[$i] / $max_value) * $max_pix);
		$table .= ($temp_width > 0)
				? $temp_width
				: 1;#always be at least 1 pix wide
			$table .= "\">";
			$table .= " ($$data_ref[$i])";
		$table .= "</TD>";
		$table .= "</TR>";
	}
	else{
		#vertical bar graph
		my $temp_cell;
		my $temp_cell_2;
		$temp_cell_2 .= "<TD ALIGN=center bgcolor=\"$title_color\">";
			#check if we should go vertical
			my $vert_it = (length($$labels_ref[$i]) > 3)
						? 1
						: '';
			if ($vert_it){
				$temp_cell_2 .= &html_verticalize($$labels_ref[$i],"DATE");
			}
			else{
				$temp_cell_2 .= &ampm($$labels_ref[$i]);
			}
		$temp_cell_2 .= "</TD>";
		$temp_cell .= "<TD VALIGN=bottom ALIGN=center  BACKGROUND=\"$v_graphics_path/bg_vgraph.gif\">";
			$temp_cell .= &html_verticalize($$data_ref[$i]) . "<BR>";
			$temp_cell .= "<IMG SRC=\"$v_graphics_path/ln_graph_v.gif\" valign=bottom border=0 width=20 height=\"";
		my $temp_height = &round(($$data_ref[$i] / $max_value) * $max_pix);
		$temp_cell .= ($temp_height > 0)
				? $temp_height
				: 1;#always be at least 1 pix tall
			$temp_cell .= "\">";
		$temp_cell .= "</TD>";
		
		#prepend the results
		$table_vrow_t = $temp_cell . $table_vrow_t;
		$table_vrow = $temp_cell_2 . $table_vrow;
	}
}

$table .= "$table_vrow_t</TR><TR>$table_vrow</TR>" if (!$horiz_bars);

$table .= "</TABLE>";
$table .= "</TD></TR></TABLE>";

my $request_uri = $ENV{'REQUEST_URI'};
if ($request_uri){

	if ($request_uri=~s/h_bars=1/h_bars=0/){
		$table .= "<BR><p><CENTER><A HREF=\"$request_uri\"><b>Vertical Graph</b></A></CENTER>";
	}
	else{
		$request_uri=~s/&*h_bars=\d//g;
		$request_uri.="&h_bars=1";
		$table .= "<BR><p><CENTER><A HREF=\"$request_uri\"><b>Horizontal Graph</b></A></CENTER>";
	}
}
#foreach (keys %ENV){
#	&debug("$_ = $ENV{$_}");
#}
return $table;
}
######################################
sub html_verticalize{
my ($string,$trim_date) = @_;
my @arrayed = split(//,$string);
my $new_string;
my $count = 1;

foreach (@arrayed){
	if ($trim_date){
		next if ($count++ < 6);
		next if (($count++ == 7) && ($_=~/0/));
	}
	$new_string .= $_ . "<BR>";
}

return $new_string;
}
######################################
sub ampm{
my ($time_string) = @_;

   if ($time_string == 0){
      $time_string = "12<BR>AM";
   }
   elsif ($time_string < 12){
      $time_string = "$time_string<BR>AM";
   }
   elsif ($time_string == 12){
      $time_string = "12<BR>PM";
   }
   else{
      $time_string -= 12;
      $time_string = "$time_string<BR>PM";
   }
return $time_string;
}
######################################
sub get_date_array{
my ($seconds, $minutes, $hours, $mday, $month, $year, $wday, $yday, $isdst) = localtime(time);
    $year+=1900;
    $month++;
    $mday = "0$mday" if ($mday < 10);
    $month = "0$month" if ($month < 10);
return ($seconds, $minutes, $hours, $mday, $month, $year, $wday, $yday, $isdst);
}
########################################
sub format_seconds{
my ($start_sec) = @_;

my ($hr,$min,$sec);

if ($start_sec < 60){
	return "$start_sec sec";
}
elsif ($start_sec < 3600){
 	#then it's less than an hour:
	$min   = sprintf("%d min",($start_sec/60));
	$sec  = ($start_sec % 60) . " sec";
	return "$min $sec";
}
else{
    #long time, only go so far as to show hrs
	$hr = sprintf("%d",($start_sec/3600));
	$start_sec -= $hr;
	$hr .= " hr";
	$min   = sprintf("%d min",($start_sec/60));
    $sec  = ($start_sec % 60) . " sec";
    return "$hr $min $sec";
}

return "0 sec"; #should never get here, but just in case ;)
}
########################################
sub get_sid_hash{
my $sql_query;
my $db_ptr;
my $hash_ref;

return %global_sid_hash if (%global_sid_hash);

$sql_query = "SELECT sid,hostname FROM sensor";
$db_ptr = &run_query($sql_query);
while ($hash_ref = $db_ptr->fetchrow_hashref){
	#&debug("$$hash_ref{'sid'} = $$hash_ref{'hostname'}");
	$global_sid_hash{$$hash_ref{'sid'}} = $$hash_ref{'hostname'};
}

return %global_sid_hash;

}
###################
sub print_events_opt{
my ($number_of_events) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
my $row_count;

######################################################
# Optimized version of &print_events for first page
######################################################

my %args;
#(taken from normal &print_events)
# Table stuff:
($args{'cellpadding'}=~/^\d+$/)
    || ($args{'cellpadding'} = "0");
($args{'cellspacing'}=~/^\d+$/)
    || ($args{'cellspacing'} = "1");
($args{'table_width'}=~/^\d+\%{0,1}$/)
    || ($args{'table_width'} = "100%");
($args{'first_color'})
    || ($args{'first_color'} = "#000000");
($args{'second_color'})
    || ($args{'second_color'} = "#000000");
($args{'head_color'})
    || ($args{'head_color'} = $head_color);
($args{'border_color'})
    || ($args{'border_color'} = "#000000");

($number_of_events=~/^[1-9]+\d*$/) || ($number_of_events = 6);


# Instead of having the sql db do a join on the sensor array.
my %sid_hash = &get_sid_hash;

$sql_query = << "EOF";
SELECT
     event.*,iphdr.ip_src,iphdr.ip_dst,
     sig_name   FROM event
             LEFT JOIN iphdr         ON  ((event.cid = iphdr.cid) AND (event.sid = iphdr.sid))
             LEFT JOIN signature  ON (event.signature = signature.sig_id)
ORDER BY timestamp DESC  LIMIT $number_of_events
EOF

$db_ptr = &run_query($sql_query);


$table .= "<TABLE width=\"$args{'table_width'}\" border=0 cellspacing=\"$args{'cellspacing'}\" cellpadding=\"2\">";

			$table .= "<TR BGCOLOR=$head_color><TD BACKGROUND=\"$v_graphics_path/bg_title.gif\" COLSPAN=5 align=center><B>Last $number_of_events Events</B></TD></TR>\n";




$table .= "<TR BGCOLOR=$title_color><TD align=center><b>Signature</b></TD>";
$table .= "<TD align=center><b>Source</b></TD>";
$table .= "<TD align=center><b>Destination</b></TD>";
$table .= "<TD align=center><b>Sensor</b></TD>";
$table .= "<TD align=center><b>Time/Date</b></TD></TR>\n";

while ($hash_ref = $db_ptr->fetchrow_hashref){
	$row_count++;
	$table .= "<TR bgcolor=\"$desc_color\">";
	$table .= "<TD width=90%>&nbsp;";
	$table .= "<A HREF=\"$home_url?td=view_payload&sid=$$hash_ref{'sid'}&cid=$$hash_ref{'cid'}\">";
	$table .= "$$hash_ref{'sig_name'}";
	$table .= "</A>";
	$table .= "&nbsp;</TD>";

   $table .= "<TD nowrap>&nbsp;";

# Src IP:
	if ($$hash_ref{'ip_src'}){
		my $src_ip = &convert_long_ip($$hash_ref{'ip_src'});
		$table .= "<A HREF=\"$home_url?td=show_events&src_ip=$src_ip&limit=$default_limit\">$src_ip</A>";
	}
	else{
		$table .= "NA";
	}
	$table .= "&nbsp;</TD><TD nowrap>&nbsp;";

# Dest IP:
	
   if ($$hash_ref{'ip_dst'}){
      my $dst_ip = &convert_long_ip($$hash_ref{'ip_dst'});
      $table .= "<A HREF=\"$home_url?td=show_events&limit=$default_limit&dst_ip=$dst_ip\">$dst_ip</A>";
   }
   else{
      $table .= "NA";
   }
   $table .= "&nbsp;</TD>";

# Sensor / host
   $table .= "<TD align=center>&nbsp;$sid_hash{$$hash_ref{'sid'}}&nbsp;</TD>";
# Time / Date
	#strip seconds off to save space:
	$$hash_ref{'timestamp'}=~s/:\d\d$//;
	#strip year off to save space (not needed!):
	$$hash_ref{'timestamp'}=~s/^\d\d\d\d\-//;
	$$hash_ref{'timestamp'}=~s/(\d\d\-\d\d) (\d\d:\d\d)/$2 $1/;
   $table .= "<TD NOWRAP>&nbsp;$$hash_ref{'timestamp'}&nbsp;</TD>\n";
	$table .= "</TR>\n";
}
$table .= "<TR bgcolor=\"$desc_color\"><TD align=center colspan=5><B>No records returned</B></TD></TR>\n"
	if (!$row_count);

# Start the form:
$table .= << "EOF";
<TR><TD align=center colspan=5 bgcolor="$desc_color">
<TABLE cellpadding=0 cellspacing=0 border=0 WIDTH=\"100%\">
<TR>
<TD width=\"25%\">&nbsp;</TD>
<TD ALIGN=center width=\"50%\">
<TABLE cellpadding=2 cellspacing=0 border=0 BGCOLOR=\"#000000\">
EOF

$table .= "<FORM ACTION=\"$home_url\" METHOD=get>";
$table .= "<TR bgcolor=\"$desc_color\">";
$table .= "<TD nowrap><B>Events in the past: </B>";
$table .= "</TD><TD nowrap>"; 
$table .= "<SELECT NAME=offset_number style=\"font-size:8pt;\">";
$table .= "<OPTION SELECTED>$args{'offset_number'}</OPTION>" if ($args{'offset_number'});
$table .= << "EOF";
<OPTION>1</OPTION>
<OPTION>2</OPTION>
<OPTION>3</OPTION>
<OPTION>4</OPTION>
<OPTION>5</OPTION>
<OPTION>6</OPTION>
<OPTION>7</OPTION>
<OPTION>8</OPTION>
<OPTION>9</OPTION>
<OPTION>10</OPTION>
<OPTION>11</OPTION>
<OPTION>12</OPTION>
<OPTION>13</OPTION>
<OPTION>14</OPTION>
<OPTION>15</OPTION>
<OPTION>16</OPTION>
<OPTION>17</OPTION>
<OPTION>18</OPTION>
<OPTION>19</OPTION>
<OPTION>20</OPTION>
<OPTION>21</OPTION>
<OPTION>22</OPTION>
<OPTION>23</OPTION>
<OPTION>24</OPTION>
</SELECT>
<INPUT TYPE=hidden NAME=td VALUE=show_events>
<SELECT NAME=offset_type style="font-size:8pt;">
EOF
if ($args{'offset_type'}=~/hour/){
   $table .= "<OPTION value=day>Days</OPTION>";
   $table .= "<OPTION value=hour selected>Hours</OPTION>";
}
elsif ($args{'offset_type'}=~/day/){
   $table .= "<OPTION value=day selected>Days</OPTION>";
   $table .= "<OPTION value=hour>Hours</OPTION>";
}
else {
   $table .= "<OPTION value=day selected>Days</OPTION>";
   $table .= "<OPTION value=hour>Hours</OPTION>";
}
$table .= << "EOF";
</SELECT>
 </TD>
<TD nowrap>
<B>#</B><FONT SIZE="3"><B>/</B></FONT><B>Page:</B>
</TD>
<TD nowrap>
<SELECT NAME=limit style="font-size:8pt">
EOF
$table .= "<OPTION selected>$args{'limit'}</OPTION>" if ($args{'limit'} && ($args{'limit'} > 10));
$table .= << "EOF";
<OPTION>60</OPTION>
<OPTION>50</OPTION>
<OPTION>40</OPTION>
<OPTION>30</OPTION>
<OPTION>20</OPTION>
<OPTION>10</OPTION>
</SELECT>
 </TD>
EOF
$table .= "<TD valign=top align=center>TCP:<INPUT TYPE=checkbox NAME=tcp checked></TD>" ;
$table .= "<TD valign=top align=center>UDP:<INPUT TYPE=checkbox NAME=udp checked></TD>" ;
$table .= "<TD valign=top align=center>ICMP:<INPUT TYPE=checkbox NAME=icmp checked></TD>" ;
$table .= "<TD><INPUT TYPE=Submit Value=\"Go\" style=\"font-size:8pt\">";
$table .= "</TD>";
$table .= "</FORM>";
$table .= "</TR>\n";
$table .= "</TABLE>";
#$table .= "</TABLE></TD></TR>\n"; 

#</TABLE>
$table .= "</TD><TD width=\"25%\" ALIGN=right>";

if ($current_page eq "main"){
	$table .= "<A HREF=\"$home_url?offset_number=1&td=show_events&offset_type=day&limit=60\"><B>More...</B></A> &nbsp; &nbsp;";
}
else{
	$table .= "&nbsp;";
}

$table .= << "EOF";
</TD></TR>
</TABLE>
</TD></TR>
<TR HEIGHT=2 BGCOLOR="$head_color"><TD COLSPAN=5><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>
</TABLE>
EOF



return $table;
}
#############################
sub get_last_monitoring_changes{
my ($events) = @_;
my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;

($events=~/^\d+$/) || ($events=20);

#$sql_query = "SELECT service,ip_addr,host_name,status,event_timestamp FROM dm_monitor_events ORDER BY event_timestamp DESC LIMIT $events";
$sql_query = "	SELECT \
					host_name,service,ip_addr,status,event_timestamp, \
					DATE_FORMAT(event_timestamp,\"%W %M %e, %Y\") AS FORMATTED_DATE	, \
					DATE_FORMAT(event_timestamp,\"%r\") AS FORMATTED_TIME	\
				FROM dm_monitor_events \
				ORDER BY event_timestamp DESC \
				LIMIT $events";
$db_ptr = &run_query($sql_query);

$table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 ALIGN=center>\n";
$table .= "<TR BGCOLOR=$head_color><TD COLSPAN=6 ALIGN=center BACKGROUND=\"$v_graphics_path/bg_title.gif\">";
$table .= "<b>$events Most Recent Status Changes</b>";
$table .= "</TD></TR>\n";
$table .= "<TR BGCOLOR=$title_color>";
$table .= "<TD align=center width=25>&nbsp;&nbsp;<b>Status</b>&nbsp;&nbsp;</TD>";
$table .= "<TD align=center width=25>&nbsp;&nbsp;<b>Service</b>&nbsp;&nbsp;</TD>";
$table .= "<TD align=center width=100><b>Host</b></TD>";
$table .= "<TD align=center nowrap width=100><b>IP Address</b></TD>";
$table .= "<TD align=center width=100><b>Time</b></TD>";
$table .= "<TD align=center width=150><b>Date</b></TD>";
$table .= "</TR>";

while ($hash_ref = $db_ptr->fetchrow_hashref){
	$table .= "<TR bgcolor=\"$desc_color\">";
	$table .= "<TD align=center>" . &color_code($$hash_ref{'status'}) . "</TD>";
	$table .= "<TD align=center>$$hash_ref{'service'}</TD>";
	$table .= "<TD nowrap>&nbsp;$$hash_ref{'host_name'}</TD>";
	$table .= "<TD nowrap>&nbsp;";
	my $dotted_quad = &convert_long_ip($$hash_ref{'ip_addr'});
	$table .= ($dotted_quad=~/[1-9]/)? $dotted_quad  : "NA"; #local checks come back as 0.0.0.0... hence the check
	$table .= "</TD>";
	$table .= "<TD align=center nowrap>&nbsp;$$hash_ref{'FORMATTED_TIME'}&nbsp;</TD>";
	$table .= "<TD align=center nowrap><nobr>&nbsp;$$hash_ref{'FORMATTED_DATE'}&nbsp;</nobr></TD>";
#	$table .= "<TD>$$hash_ref{'event_timestamp'}</TD>";
	$table .= "</TR>\n";
}

$table .= "<TR HEIGHT=2 BGCOLOR=\"$head_color\"><TD COLSPAN=6><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>\n";
$table .= "</TABLE>\n<br>\n";



}
#######################################
sub edit_monitored_service{
my ($host_name,$service) = @_;

my $sql_query;
my $db_ptr;
my $hash_ref;
my $check_dns;

#admin privs already checked.
$host_name =~tr/a-zA-Z0-9\.\-//dc;#take out invalid characters
$service =~tr/a-zA-Z0-9\.\- //dc;#take out invalid characters

$FORM{'grouping'} =~tr/a-zA-Z0-9\.\- //dc;#take out invalid characters
$FORM{'host_name'} =~tr/a-zA-Z0-9\.\-//dc;#take out invalid characters

#Validate info:
if ($FORM{'port'}){
	($FORM{'port'}=~/^\d+$/)  || &error("Invalid port. Must be numeric.");
}
if ($FORM{'client_sid'}){
	($FORM{'client_sid'}=~/^\d+$/)  || &error("Invalid client SID. Must be numeric.");
}
if ($FORM{'dns_check'}=~/yes/i){
	$check_dns = 1;
}
($FORM{'grouping'}=~/\S/) || &error("You must select a grouping for this event");
($FORM{'host_name'}=~/^[a-zA-Z0-9\-]+\.[a-zA-Z0-9]{2,}/)
	|| &error("You must select a grouping for this event");


$sql_query = "  SELECT \
                    grouping,port,check_dns \
                FROM \
                        dm_monitor_current \
                WHERE \
                        sid         = '$monitor_sid' AND \
                        UPPER(host_name)   = UPPER('$host_name') AND \
                        service 	= '$service' ";
$db_ptr = &run_query($sql_query);
($hash_ref=$db_ptr->fetchrow_hashref) || &error("Error retrieving monitored service record.  Please make sure it has not been deleted.");

#options they are allowed to update: host_name, grouping, port, dns_check, and client_sid

#ok, now lets just try and save them from putting the same entry in twice:
if ($host_name ne "$FORM{'host_name'}"){
	$sql_query = "	SELECT sid FROM dm_monitor_current \
						WHERE \
							sid 		= '$monitor_sid' AND \
							UPPER(host_name)	= UPPER('$FORM{'host_name'}') AND \
							service 	= '$service' AND \
							port		= '$FORM{'port'}'";
	$db_ptr = &run_query($sql_query);
 	($hash_ref=$db_ptr->fetchrow_hashref)
		&& &error("There is already a monitoring event set with the same hostname, service, and port");
}

$sql_query = "	UPDATE dm_monitor_current \
				SET \
					host_name = '$FORM{'host_name'}', \
					grouping = '$FORM{'grouping'}', \
					port	= '$FORM{'port'}',\
					client_sid	= '$FORM{'client_sid'}',\
					check_dns = '$check_dns' \
				WHERE \
						sid         = '$monitor_sid' AND \
                        UPPER(host_name)   = UPPER('$host_name') AND \
                        service     = '$service' ";
					
#&debug($sql_query);
($db->do($sql_query)) || &error("Error updating Event.");

#to be safe, we have to sanitize the DB and make all groupings for this hostname the same:

$sql_query = "  UPDATE dm_monitor_current \
                SET \
                    grouping = '$FORM{'grouping'}' \
                WHERE \
                        sid         = '$monitor_sid' AND \
                        UPPER(host_name)   = UPPER('$FORM{'host_name'}') ";
($db->do($sql_query)) || &error("Error updating groupings.");



}
########################################
sub resync_sid{
my ($sid) = @_;

($sid=~/^\d+$/) || &error("Invalid SID");

my $sql_query;
my $db_ptr;
my $hash_ref;

$sql_query = "	UPDATE dm_conf \
				SET \
					last_updated = NOW(), \
					last_implemented = NOW() \
				WHERE \
					sid = '$sid'";

#&debug($sql_query);
&connect_to_db;
($db->do($sql_query)) || &error("Error while manually setting SID to In-Sync.");


&push_message("<FONT COLOR=red><CENTER>SID $sid manually Set As In-Sync.</CENTER></FONT>");
}
##########################################
sub delete_sid{
my ($sid) = @_;

($sid=~/^\d+$/) || &error("Invalid SID");

my $sql_query;
my $db_ptr;
my $hash_ref;

$sql_query = "	DELETE FROM sensor \
				WHERE \
					sid = '$sid'";

&connect_to_db;
($db->do($sql_query)) || &error("Error while manually deleting SID from snort's sensor table.");


&push_message("<FONT COLOR=red><CENTER>SID $sid manually deleted from sensor table.</CENTER></FONT>");
}
##################################
sub find_sig_in_rules{
my ($signature) = @_;

my $sql_query;
my $db_ptr;
my $hash_ref;
my $table;
&safe_slash(\$signature);

$table .= "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=2 ALIGN=center width=\"50%\">\n";
$table .= "<TR BGCOLOR=$head_color><TD COLSPAN=3 ALIGN=center BACKGROUND=\"$v_graphics_path/bg_title.gif\">";
$table .= "<b>Search Results for \"$signature\"</b>";
$table .= "</TD></TR>\n";
$table .= "<TR BGCOLOR=$title_color><TD align=center><b>SID</b></TD><TD align=center><b>Sensor Name</b></TD><TD align=center><b>Signature Location</b></TD></TR>\n";

$sql_query = "	SELECT sid,rules_type \
				FROM dm_rules \
				WHERE \
					snort_rules LIKE '%$signature%'
			";

$db_ptr = &run_query($sql_query);
while($hash_ref=$db_ptr->fetchrow_hashref){
    $table .= "<TR bgcolor=\"$desc_color\">";
    $table .= "<TD align=center>";
	$table .= "$$hash_ref{'sid'}";
	$table .= "</TD>";
    $table .= "<TD align=center>";
	$table .= &get_hostname_from_sid($$hash_ref{'sid'});
	$table .= "</TD>";
    $table .= "<TD align=center>";
	$table .= "<A HREF=\"$home_url?td=config_rules&sid=$$hash_ref{'sid'}&rules_type=$$hash_ref{'rules_type'}\">$$hash_ref{'rules_type'}</A>";
	$table .= "</TD></TR>";
}
$table .= "<TR HEIGHT=2><TD BGCOLOR=\"$head_color\" COLSPAN=3><SPACER TYPE=BLOCK HEIGHT=2></TD></TR>";
$table .= "</TABLE>";

push (@substitutions,"\\[MAIN_TABLE\\],-,$table");
&print_main_with_key($main_template);
}



