1#!/usr/local/bin/perl 2# 3# Purpose: 4# FlowViewer_Main.cgi permits a Web user to analyze Net Flow data stored 5# in flow tools format and create an HTML report. 6# 7# Description: 8# The script responds to an HTML form from the user in order to collect 9# parameters that will control the analysis (e.g., router, time-period, ip 10# addresses etc.) Upon receipt of the form input the script creates a flow tools 11# filter file which controls the selection of the data via the invocation of 12# additional flow tools utilities. An HTML report is then generated. 13# 14# Input arguments (received from the form): 15# Name Description 16# ----------------------------------------------------------------------- 17# device_name An identifying name of the device (e.g. router1) 18# flow_select Identifies which flows to include wrt time period 19# start_date Start date of analysis period 20# start_time Start time of analysis period 21# end_date End date of analysis period 22# end_time End time of analysis period 23# source_addresses Constrain flows examined to these source IP addresses 24# source_ports Constrain flows examined to these source ports 25# source_ifs Constrain flows examined to these input interfaces 26# sif_names Constrain flows examined to these named interfaces 27# source_ases Constrain flows examined to these source ASes 28# dest_addresses Constrain flows examined to these dest. IP addresses 29# dest_ports Constrain flows examined to these dest. ports 30# dest_ifs Constrain flows examined to these output interfaces 31# dif_names Constrain flows examined to these named interfaces 32# dest_ases Constrain flows examined to these dest. ASes 33# tos_fields Constrain flows examined by specified TOS field values 34# tcp_flags Constrain flows examined by specified TCP flag values 35# exporter Constrain flows examined to specified exporter IP address 36# nexthop_ips Constrain flows examined to specified Next Hop IP address 37# protocols Constrain flows examined to these protocols 38# print_report Select from these various report options 39# stat_report Select from these various statistics options 40# cutoff_lines Number of report lines to print out 41# cutoff_octets Minimum number of octets for inclusion in report 42# sort_field Sorts on (Octets, Flows, Packets) for first report 43# resolve_addresses Whether or not to resolve IP addresses 44# unit_conversion Whether or not to convert octets to GB, KB, etc. 45# sampling_multiplier Value to multiply flow data (for sampled routers) 46# pie_charts Generate pie charts; optional 'others' category 47# 48# Notes: 49# 1. It is a good idea to retain the host_names GDBM file (names), even if it 50# gets large, since it is up to 1000 times faster than using 'dig'. 51# 52# Modification history: 53# Author Date Vers. Description 54# ----------------------------------------------------------------------- 55# J. Loiacono 07/04/2005 1.0 Original version. 56# J. Loiacono 01/01/2006 2.0 FlowGrapher, new functions, speed 57# J. Loiacono 01/16/2006 2.1 Fixed compute of concatenation date 58# J. Loiacono 01/26/2006 2.2 New flow_select option for inclusion 59# J. Loiacono 07/04/2006 3.0 Renamed for re-organization 60# Single script for GDBM/NDBM (thanks Ed Ravin) 61# J. Loiacono 12/25/2006 3.1 [No Change to this module] 62# J. Loiacono 02/14/2007 3.2 [No Change to this module] 63# J. Loiacono 12/07/2007 3.3 Sampling Multiplier, Pie Charts 64# AS resolving (thanks Sean Cardus) 65# Named IFs, Unit Conv. (thanks C. Kishimoto) 66# J. Loiacono 12/15/2007 3.3.1 New $no_devices ... parameter 67# J. Loiacono 03/17/2011 3.4 Support for change of device w/o reset 68# Support for meaningful Save report names 69# Concatenation now includes 'temp' files 70# Dynamic Resolved column width, flows/sec 71# J. Loiacono 05/08/2012 4.0 Major upgrade for IPFIX/v9 using SiLK, 72# New User Interface 73# J. Loiacono 04/15/2013 4.1 Removed extraneuos formatting 74# J. Loiacono 09/11/2013 4.2.1 Mods for international date formatting 75# J. Loiacono 01/26/2014 4.3 Introduced Detect Scanning 76# J. Loiacono 07/04/2014 4.4 Multiple dashboards and flow analysis 77# J. Loiacono 11/02/2014 4.5 SiLK local timezone fixes 78# Cleaned up checking of entered times 79# Extended pie-charts to some Printed Reports 80# Use of $site_config_file on SiLK commands 81# 82#$Author$ 83#$Date$ 84#$Header$ 85# 86########################################################################### 87# 88# BEGIN EXECUTABLE STATEMENTS 89# 90 91use FlowViewer_Configuration; 92use FlowViewer_Utilities; 93use FlowViewer_UI; 94use File::stat; 95 96if ($debug_viewer eq "Y") { open (DEBUG,">$work_directory/DEBUG_VIEWER"); } 97if ($debug_viewer eq "Y") { print DEBUG "In FlowViewer_Main.cgi\n"; } 98 99# Tie in the appropriate 'names' files which saves IP address resolved names 100 101if (eval 'local $SIG{"__DIE__"}= sub { }; use GDBM_File; 102 tie %host_names, "GDBM_File", "$names_directory/names", GDBM_WRCREAT, 0666;' ) { print DEBUG "Using GDBM\n"; }; 103if (eval 'local $SIG{"__DIE__"}= sub { }; use NDBM_File; use Fcntl; 104 tie %host_names, "GDBM_File", "$names_directory/names", GDBM_WRCREAT, 0666;' ) { print DEBUG "Using NDBM\n"; }; 105 106# Tie in the appropriate 'as_names' file which saves resolved AS names 107 108if (eval 'local $SIG{"__DIE__"}= sub { }; use GDBM_File; 109 tie %as_names, "GDBM_File", "$names_directory/as_names", GDBM_WRCREAT, 0666;' ) { print DEBUG "Using GDBM\n"; }; 110if (eval 'local $SIG{"__DIE__"}= sub { }; use NDBM_File; use Fcntl; 111 tie %as_names, "GDBM_File", "$names_directory/as_names", GDBM_WRCREAT, 0666;' ) { print DEBUG "Using NDBM\n"; }; 112 113if ((eval 'local $SIG{"__DIE__"}= sub { }; use GD; use GD::Graph::pie; use GD::Text') && ($pie_charts > 0)) { 114 if ($debug_viewer eq "Y") { print DEBUG "Using GD::Graph:Pie, etc.\n"; } 115} 116 117# Set up the Pie Chart colors 118 119GD::Graph::colour::read_rgb("FlowGrapher_Colors") or die "cannot read colors"; 120 121# Retrieve the form inputs 122 123read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); 124@pairs = split(/&/, $buffer); 125foreach $pair (@pairs) { 126 ($name, $value) = split(/=/, $pair); 127 $value =~ tr/+/ /; 128 $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg; 129 $FORM{$name} = $value; 130} 131 132# Clean up input 133 134($fv_link,$FORM{device_name}) = split(/DDD/,$FORM{device_name}); 135($fv_link,$FORM{exporter}) = split(/EEE/,$FORM{exporter}); 136 137if ($debug_viewer eq "Y") { print DEBUG "FORM{device_name}: $FORM{device_name}\n"; } 138if ($debug_viewer eq "Y") { print DEBUG "FORM{exporter}: $FORM{exporter}\n"; } 139 140$FORM{source_address} =~ s/\s+//g; $FORM{source_address} =~ s/,/, /g; 141$FORM{source_port} =~ s/\s+//g; $FORM{source_port} =~ s/,/, /g; 142$FORM{source_if} =~ s/\s+//g; $FORM{source_if} =~ s/,/, /g; 143$FORM{source_as} =~ s/\s+//g; $FORM{source_as} =~ s/,/, /g; 144$FORM{dest_address} =~ s/\s+//g; $FORM{dest_address} =~ s/,/, /g; 145$FORM{dest_port} =~ s/\s+//g; $FORM{dest_port} =~ s/,/, /g; 146$FORM{dest_if} =~ s/\s+//g; $FORM{dest_if} =~ s/,/, /g; 147$FORM{dest_as} =~ s/\s+//g; $FORM{dest_as} =~ s/,/, /g; 148$FORM{protocols} =~ s/\s+//g; $FORM{protocols} =~ s/,/, /g; 149$FORM{tos_fields} =~ s/\s+//g; $FORM{tos_fields} =~ s/,/, /g; 150$FORM{tcp_flags} =~ s/\s+//g; $FORM{tcp_flags} =~ s/,/, /g; 151$FORM{nexthop_ip} =~ s/\s+//g; $FORM{nexthop_ip} =~ s/,/, /g; 152$FORM{sif_name} =~ s/,/, /g; 153$FORM{dif_name} =~ s/,/, /g; 154 155# Parameters for generating a FlowViewer report 156 157$active_dashboard = $FORM{'active_dashboard'}; 158$device_name = $FORM{'device_name'}; 159$flow_select = $FORM{'flow_select'}; 160$start_date = $FORM{'start_date'}; 161$start_time = $FORM{'start_time'}; 162$end_date = $FORM{'end_date'}; 163$end_time = $FORM{'end_time'}; 164$source_addresses = $FORM{'source_address'}; 165$source_ports = $FORM{'source_port'}; 166$source_ifs = $FORM{'source_if'}; 167$sif_names = $FORM{'sif_name'}; 168$source_ases = $FORM{'source_as'}; 169$dest_addresses = $FORM{'dest_address'}; 170$dest_ports = $FORM{'dest_port'}; 171$dest_ifs = $FORM{'dest_if'}; 172$dif_names = $FORM{'dif_name'}; 173$dest_ases = $FORM{'dest_as'}; 174$protocols = $FORM{'protocols'}; 175$tcp_flags = $FORM{'tcp_flags'}; 176$tos_fields = $FORM{'tos_fields'}; 177$exporter = $FORM{'exporter'}; 178$nexthop_ips = $FORM{'nexthop_ip'}; 179$print_report = $FORM{'print_report'}; 180$stat_report = $FORM{'stat_report'}; 181$cutoff_lines = $FORM{'cutoff_lines'}; 182$cutoff_octets = $FORM{'cutoff_octets'}; 183$sort_field = $FORM{'sort_field'}; 184$resolve_addresses = $FORM{'resolve_addresses'}; 185$unit_conversion = $FORM{'unit_conversion'}; 186$sampling_multiplier = $FORM{'sampling_multiplier'}; 187$pie_charts = $FORM{'pie_charts'}; 188$flow_analysis = $FORM{'flow_analysis'}; 189$silk_rootdir = $FORM{'silk_rootdir'}; 190$silk_class = $FORM{'silk_class'}; 191$silk_flowtype = $FORM{'silk_flowtype'}; 192$silk_type = $FORM{'silk_type'}; 193$silk_sensors = $FORM{'silk_sensors'}; 194$silk_switches = $FORM{'silk_switches'}; 195 196if ($site_config_file ne "") { $site_config_modifier = "--site-config-file=$site_config_file "; } 197 198# Convert into US date format for internal processing 199 200if ($date_format eq "DMY") { 201 ($temp_day_s,$temp_mnth_s,$temp_yr_s) = split(/\//,$start_date); 202 ($temp_day_e,$temp_mnth_e,$temp_yr_e) = split(/\//,$end_date); 203} elsif ($date_format eq "DMY2") { 204 ($temp_day_s,$temp_mnth_s,$temp_yr_s) = split(/\./,$start_date); 205 ($temp_day_e,$temp_mnth_e,$temp_yr_e) = split(/\./,$end_date); 206} elsif ($date_format eq "YMD") { 207 ($temp_yr_s,$temp_mnth_s,$temp_day_s) = split(/\-/,$start_date); 208 ($temp_yr_e,$temp_mnth_e,$temp_day_e) = split(/\-/,$end_date); 209} else { 210 ($temp_mnth_s,$temp_day_s,$temp_yr_s) = split(/\//,$start_date); 211 ($temp_mnth_e,$temp_day_e,$temp_yr_e) = split(/\//,$end_date); 212} 213$start_date = $temp_mnth_s ."/". $temp_day_s ."/". $temp_yr_s; 214$end_date = $temp_mnth_e ."/". $temp_day_e ."/". $temp_yr_e; 215 216if ($debug_viewer eq "Y") { print DEBUG "FORM{start_date}: $FORM{start_date} start_date: $start_date FORM{end_date}: $FORM{end_date} end_date: $end_date\n"; } 217 218# Determine if we are looking at an IPFIX device 219 220$IPFIX = 0; 221foreach $ipfix_device (@ipfix_devices) { 222 if ($device_name eq $ipfix_device) { $IPFIX = 1; if ($debug_viewer eq "Y") { print DEBUG "This device is exporting IPFIX\n";} } 223} 224 225# Start up the Saved file 226 227$saved_suffix = &get_suffix; 228$saved_hash = "FlowViewer_save_$saved_suffix"; 229$filter_hash = "FV_$saved_hash"; 230$saved_html = "$work_directory/$saved_hash"; 231&start_saved_file($saved_html); 232 233# Start the FlowViewer Report web page output 234 235&create_UI_top($active_dashboard); 236&create_UI_service("FlowViewer_Main","service_top",$active_dashboard,$filter_hash); 237print " <div id=content_wide>\n"; 238print " <span class=text16>FlowViewer Report from $device_name</span>\n"; 239&create_filter_output("FlowViewer_Main",$filter_hash); 240 241if ($time_zone eq "") { 242 open(DATE,"date 2>&1|"); 243 while (<DATE>) { 244 ($d_tz,$m_tz,$dt_tz,$t_tz,$time_zone,$y_tz) = split(/\s+/,$_); 245 } 246} 247 248# Check dates and times for input errors 249 250($mn,$da,$yr) = split(/\//,$start_date); 251if ( $mn=~/\D/ || $da=~/\D/ || $yr=~/\D/ ) { &print_error("Bad date format: $FORM{start_date}"); }; 252if ( $mn<1 || $mn>12 || $da<1 || $da>31 || $yr<1990 || $yr>2100 ) { &print_error("Bad date format: $FORM{start_date}"); } 253if (length($mn) < 2) { $mn = "0" . $mn; } 254if (length($da) < 2) { $da = "0" . $da; } 255$start_ymd = $yr . $mn . $da; 256$start_yr = $yr; $start_mn = $mn; $start_da = $da; 257 258($hr,$mi,$sc) = split(/:/,$start_time); 259if ( $hr=~/\D/ || $mi=~/\D/ || $sc=~/\D/ ) { &print_error("Bad time format: $FORM{start_time}"); }; 260if (length($hr)>2 || $hr>23 || length($mi)>2 || $mi>59 || length($sc)>2 || $sc>59 ) { &print_error("Bad time format: $FORM{start_time}"); } 261 262($mn,$da,$yr) = split(/\//,$end_date); 263if ( $mn=~/\D/ || $da=~/\D/ || $yr=~/\D/ ) { &print_error("Bad date format: $FORM{end_date}"); }; 264if ( $mn<1 || $mn>12 || $da<1 || $da>31 || $yr<1990 || $yr>2100 ) { &print_error("Bad date format: $FORM{end_date}"); } 265if (length($mn) < 2) { $mn = "0" . $mn; } 266if (length($da) < 2) { $da = "0" . $da; } 267$end_ymd = $yr . $mn . $da; 268$end_yr = $yr; $end_mn = $mn; $end_da = $da; 269 270($hr,$mi,$sc) = split(/:/,$end_time); 271if ( $hr=~/\D/ || $mi=~/\D/ || $sc=~/\D/ ) { &print_error("Bad time format: $FORM{end_time}"); }; 272if (length($hr)>2 || $hr>23 || length($mi)>2 || $mi>59 || length($sc)>2 || $sc>59 ) { &print_error("Bad time format: $FORM{end_time}"); } 273 274if (($no_devices_or_exporters eq "N") && (($device_name eq "") && ($exporter eq ""))) { 275 print "<br><b>Must select a device or an exporter. <p>Use the \"back\" key to save inputs</b><br>"; 276 exit; 277} 278 279if (($stat_report == 0) && ($print_report == 0)) { &print_error("Must specify a report."); } 280if (($stat_report != 0) && ($print_report != 0)) { &print_error("Two reports selected. Please reset one."); } 281 282if (($stat_report == 10) && ($print_report ne "0")) { 283 $stat_report = 0; 284} 285 286# Retrieve current time to use as a file suffix to permit more than one user to generate reports 287 288($sec,$min,$hr,$date,$mnth,$yr,$day,$yr_date,$DST) = localtime(time); 289$mnth++; 290$yr += 1900; 291if ((0 < $mnth) && ($mnth < 10)) { $mnth = "0" . $mnth; } 292if ((0 < $date) && ($date < 10)) { $date = "0" . $date; } 293if ((0 <= $hr) && ($hr < 10)) { $hr = "0" . $hr; } 294if ((0 <= $min) && ($min < 10)) { $min = "0" . $min; } 295if ((0 <= $sec) && ($sec < 10)) { $sec = "0" . $sec; } 296$prefix = $yr . $mnth . $date ."_". $hr . $min . $sec; 297$suffix = $hr . $min . $sec; 298 299if ($IPFIX) { 300 301 # Obtain user requested start time in SiLK-storage time zone 302 303 ($temp_hr_s,$temp_min_s,$temp_sec_s) = split(/:/,$start_time); 304 if ($silk_compiled_localtime eq "Y") { 305 $start_epoch = timelocal($temp_sec_s,$temp_min_s,$temp_hr_s,$temp_day_s,$temp_mnth_s-1,$temp_yr_s-1900); 306 ($sec,$min,$hr,$date,$mnth,$yr,$day,$yr_date,$DST) = localtime($start_epoch); 307 } else { 308 $start_epoch = timegm($temp_sec_s,$temp_min_s,$temp_hr_s,$temp_day_s,$temp_mnth_s-1,$temp_yr_s-1900); 309 ($sec,$min,$hr,$date,$mnth,$yr,$day,$yr_date,$DST) = gmtime($start_epoch); 310 } 311 $yr += 1900; $mnth++; 312 if (length($mnth) < 2) { $mnth = "0" . $mnth; } 313 if (length($date) < 2) { $date = "0" . $date; } 314 if (length($hr) < 2) { $hr = "0" . $hr; } 315 if (length($min) < 2) { $min = "0" . $min; } 316 if (length($sec) < 2) { $sec = "0" . $sec; } 317 $silk_period_start = $yr ."/". $mnth ."/". $date .":". $hr .":". $min .":". $sec; 318 319 # Obtain user requested end time in SiLK-storage time zone 320 321 ($temp_hr_e,$temp_min_e,$temp_sec_e) = split(/:/,$end_time); 322 if ($silk_compiled_localtime eq "Y") { 323 $end_epoch = timelocal($temp_sec_e,$temp_min_e,$temp_hr_e,$temp_day_e,$temp_mnth_e-1,$temp_yr_e-1900); 324 ($sec,$min,$hr,$date,$mnth,$yr,$day,$yr_date,$DST) = localtime($end_epoch); 325 } else { 326 $end_epoch = timegm($temp_sec_e,$temp_min_e,$temp_hr_e,$temp_day_e,$temp_mnth_e-1,$temp_yr_e-1900); 327 ($sec,$min,$hr,$date,$mnth,$yr,$day,$yr_date,$DST) = gmtime($end_epoch); 328 } 329 $yr += 1900; $mnth++; 330 if (length($mnth) < 2) { $mnth = "0" . $mnth; } 331 if (length($date) < 2) { $date = "0" . $date; } 332 if (length($hr) < 2) { $hr = "0" . $hr; } 333 if (length($min) < 2) { $min = "0" . $min; } 334 if (length($sec) < 2) { $sec = "0" . $sec; } 335 $silk_period_end = $yr ."/". $mnth ."/". $date .":". $hr .":". $min .":". $sec; 336 337} else { 338 339 # Determine flow-tools concatenation start and end times 340 341 $start_epoch = date_to_epoch($start_date,$start_time,"LOCAL"); 342 $end_epoch = date_to_epoch($end_date,$end_time,"LOCAL"); 343 344 $start_flows = &flow_date_time($start_epoch,"LOCAL"); 345 $end_flows = &flow_date_time($end_epoch,"LOCAL"); 346 347 $cat_start_epoch = $start_epoch - $flow_file_length - 1; 348 $cat_end_epoch = $end_epoch + $flow_capture_interval + 1; 349 $cat_start = epoch_to_date($cat_start_epoch,"LOCAL"); 350 $cat_end = epoch_to_date($cat_end_epoch,"LOCAL"); 351 352 $concatenate_parameters = "-a -t \"$cat_start\" -T \"$cat_end\" "; 353} 354 355$report_length = $end_epoch - $start_epoch; 356if ($report_length <= 0) { &print_error("End time ($end_date $end_time) earlier than Start time ($start_date $start_time)"); } 357 358if (!$IPFIX) { 359 360 if (($start_ymd ne $end_ymd) && ($end_epoch > $start_epoch)) { 361 for ($i=0;$i<$maximum_days;$i++) { 362 if (($cat_start_epoch + $i*86400) > $cat_end_epoch + 86400) { last; } 363 ($sec,$min,$hr,$cat_date,$cat_mnth,$cat_yr,$day,$yr_date,$DST) = localtime($cat_start_epoch + $i*86400); 364 $cat_mnth++; 365 $cat_yr += 1900; 366 if ((0 < $cat_mnth) && ($cat_mnth < 10)) { $cat_mnth = "0" . $cat_mnth; } 367 if ((0 < $cat_date) && ($cat_date < 10)) { $cat_date = "0" . $cat_date; } 368 369 if ($exporter ne "") { 370 $cat_directory = "$exporter_directory"; 371 } else { 372 $cat_directory = "$flow_data_directory/$device_name"; 373 } 374 375 if ($N == -3) { $cat_directory .= "/$cat_yr/$cat_yr\-$cat_mnth/$cat_yr\-$cat_mnth\-$cat_date"; } 376 if ($N == -2) { $cat_directory .= "/$cat_yr\-$cat_mnth/$cat_yr\-$cat_mnth\-$cat_date"; } 377 if ($N == -1) { $cat_directory .= "/$cat_yr\-$cat_mnth\-$cat_date"; } 378 if ($N == 1) { $cat_directory .= "/$cat_yr"; } 379 if ($N == 2) { $cat_directory .= "/$cat_yr/$cat_yr\-$cat_mnth"; } 380 if ($N == 3) { $cat_directory .= "/$cat_yr/$cat_yr\-$cat_mnth/$cat_yr\-$cat_mnth\-$cat_date"; } 381 382 if (-e $cat_directory) { $concatenate_parameters .= "$cat_directory "; } 383 384 if ($N == 0) { last; } 385 } 386 387 } elsif ($start_ymd eq $end_ymd) { 388 389 ($sec,$min,$hr,$cat_date,$cat_mnth,$cat_yr,$day,$yr_date,$DST) = localtime($cat_end_epoch); 390 $cat_mnth++; 391 $cat_yr += 1900; 392 if ((0 < $cat_mnth) && ($cat_mnth < 10)) { $cat_mnth = "0" . $cat_mnth; } 393 if ((0 < $cat_date) && ($cat_date < 10)) { $cat_date = "0" . $cat_date; } 394 395 if ($exporter ne "") { 396 $cat_directory = "$exporter_directory"; 397 } else { 398 $cat_directory = "$flow_data_directory/$device_name"; 399 } 400 401 if ($N == -3) { $cat_directory .= "/$cat_yr/$cat_yr\-$cat_mnth/$cat_yr\-$cat_mnth\-$cat_date"; } 402 if ($N == -2) { $cat_directory .= "/$cat_yr\-$cat_mnth/$cat_yr\-$cat_mnth\-$cat_date"; } 403 if ($N == -1) { $cat_directory .= "/$cat_yr\-$cat_mnth\-$cat_date"; } 404 if ($N == 1) { $cat_directory .= "/$cat_yr"; } 405 if ($N == 2) { $cat_directory .= "/$cat_yr/$cat_yr\-$cat_mnth"; } 406 if ($N == 3) { $cat_directory .= "/$cat_yr/$cat_yr\-$cat_mnth/$cat_yr\-$cat_mnth\-$cat_date"; } 407 408 $concatenate_parameters .= "$cat_directory "; 409 } 410 else { 411 &print_error("Start day ($start_date) is past End day ($end_date)"); 412 } 413 414 # Create the filter to match the input specifications 415 416 $filter_file = "$work_directory/FlowViewer_filter_$suffix"; 417 418 create_filter_file(%FORM,$filter_file); 419 420 # Set up the command to concatenate the files 421 422 $flowcat_command = "$flow_bin_directory/flow-cat" . " $concatenate_parameters"; 423 424 # Set up the command to filter the concatenated file 425 426 $flownfilter_command = "$flow_bin_directory/flow-nfilter -f $work_directory/FlowViewer_filter_$suffix -FFlow_Filter"; 427 428 # Set up the flow-stat command if requested 429 430 if ($stat_report ne "0") { 431 if ($rate_report) { 432 if ($sort_field == 1) { $ft_sort_field = 3; } 433 if ($sort_field == 2) { $ft_sort_field = 2; } 434 if ($sort_field == 3) { $ft_sort_field = 4; } 435 } else { 436 if ($sort_field == 1) { $ft_sort_field = 2; } 437 if ($sort_field == 2) { $ft_sort_field = 1; } 438 if ($sort_field == 3) { $ft_sort_field = 3; } 439 } 440 if ($stat_report eq "99") { 441 $flowstat_command = "$flow_bin_directory/flow-stat -S$ft_sort_field >$work_directory/FlowViewer_output_$suffix"; 442 $flow_run = "$flowcat_command | $flownfilter_command | $flowstat_command 2>>$work_directory/FlowViewer_output_$suffix"; 443 } elsif ($stat_report == 30) { 444 if (($source_ifs ne "") || ($sif_names ne "")) { $in_int_list = "-i" . $source_ifs . $sif_names; } else { $in_int_list = ""; } 445 if (($dest_ifs ne "") || ($dif_names ne "")) { $out_int_list = "-I" . $dest_ifs . $dif_names; } else { $out_int_list = ""; } 446 $suppress_list = "$cgi_bin_directory/dscan.suppress"; 447 $touch_command = "touch $suppress_list.src $suppress_list.dst"; 448 system($touch_command); 449 $flow_prefilter = "$flowcat_command | $flownfilter_command > $work_directory/FlowViewer_scanner_$suffix"; 450 system($flow_prefilter); 451 $flow_run = "$flow_bin_directory/flow-dscan $in_int_list $out_int_list -L$suppress_list -b $dscan_parameters < $work_directory/FlowViewer_scanner_$suffix >&$work_directory/FlowViewer_output_$suffix"; 452 } else { 453 $flowstat_command = "$flow_bin_directory/flow-stat -f$stat_report -S$ft_sort_field >$work_directory/FlowViewer_output_$suffix"; 454 $flow_run = "$flowcat_command | $flownfilter_command | $flowstat_command 2>>$work_directory/FlowViewer_output_$suffix"; 455 } 456 } 457 458 # Set up the flow-print command if requested 459 460 if ($print_report ne "0") { 461 $flowprint_command = "$flow_bin_directory/flow-print -f$print_report >$work_directory/FlowViewer_output_$suffix"; 462 $flow_run = "$flowcat_command | $flownfilter_command | $flowprint_command 2>>$work_directory/FlowViewer_output_$suffix"; 463 } 464 465 # Execute the piped flow-tools command 466 467 if ($debug_viewer eq "Y") { print DEBUG "\n$flow_run\n\n"; } 468 469 system ($flow_run); 470 471} else { 472 473 $silk_cat_start = $start_epoch - $silk_capture_buffer_pre; 474 $silk_cat_end = $end_epoch + $silk_capture_buffer_post; 475 476 if ($silk_compiled_localtime eq "Y") { 477 ($sec,$min,$hr,$date,$mnth,$yr,$day,$yr_date,$DST) = localtime($silk_cat_start); 478 } else { 479 ($sec,$min,$hr,$date,$mnth,$yr,$day,$yr_date,$DST) = gmtime($silk_cat_start); 480 } 481 $yr += 1900; 482 $mnth++; 483 if (length($mnth) < 2) { $mnth = "0" . $mnth; } 484 if (length($date) < 2) { $date = "0" . $date; } 485 if (length($hr) < 2) { $hr = "0" . $hr; } 486 $silk_cat_start = $yr ."/". $mnth ."/". $date .":". $hr; 487 488 if ($silk_compiled_localtime eq "Y") { 489 ($sec,$min,$hr,$date,$mnth,$yr,$day,$yr_date,$DST) = localtime($silk_cat_end); 490 } else { 491 ($sec,$min,$hr,$date,$mnth,$yr,$day,$yr_date,$DST) = gmtime($silk_cat_end); 492 } 493 $yr += 1900; 494 $mnth++; 495 if (length($mnth) < 2) { $mnth = "0" . $mnth; } 496 if (length($date) < 2) { $date = "0" . $date; } 497 if (length($hr) < 2) { $hr = "0" . $hr; } 498 $silk_cat_end = $yr ."/". $mnth ."/". $date .":". $hr; 499 500 # Set up SiLK selection 501 502 $selection_switches = ""; 503 if ($silk_rootdir ne "") { $selection_switches = "--data-rootdir=$silk_rootdir "; } 504 if ($silk_class ne "") { $selection_switches .= "--class=$silk_class "; } 505 if ($silk_flowtype ne "") { $selection_switches .= "--flowtype=$silk_flowtype "; } 506 if ($silk_type ne "") { $selection_switches .= "--type=$silk_type "; } 507 if ($silk_sensors ne "") { $selection_switches .= "--sensors=$silk_sensors "; } 508 if ($silk_switches ne "") { $selection_switches .= "$silk_switches "; } 509 510 $silk_info_out = $selection_switches; 511 512 # Prepare rwfilter start and end time parameters 513 514 $time_window = $silk_period_start ."-". $silk_period_end; 515 516 if ($flow_select eq 1) { $window_type = "--active"; } 517 if ($flow_select eq 2) { $window_type = "--etime"; } 518 if ($flow_select eq 3) { $window_type = "--stime"; } 519 if ($flow_select eq 4) { $window_type = "--stime"; } 520 521 $selection_switches .= "--start-date=$silk_cat_start --end-date=$silk_cat_end $window_type=$time_window "; 522 523 # Prepare source and destination IP address parameters 524 525 create_ipfix_filter(%FORM); 526 527 # Prepare rwfilter command 528 529 if ($debug_viewer eq "Y") { print DEBUG " selection_switches: $selection_switches\n"; } 530 if ($debug_viewer eq "Y") { print DEBUG "partitioning_switches:$partitioning_switches\n"; } 531 532 $rwfilter_command = "$silk_bin_directory/rwfilter $site_config_modifier $selection_switches $partitioning_switches --pass=stdout"; 533 534 if ($print_report == 1) { $rwfilter_command .= " | $silk_bin_directory/rwsort $site_config_modifier --fields=9 "; } 535 536 # Prepare rwstats output fields (this set is similar to flow-tools) 537 538 $column_separator = " "; 539 540 if ($stat_report == 99) { $report_title = "Summary"; } 541 if ($stat_report == 5) { $field_sequence = "4"; } 542 if ($stat_report == 6) { $field_sequence = "3"; } 543 if ($stat_report == 7) { $field_sequence = "3,4"; } 544 if ($stat_report == 8) { $field_sequence = "2"; } 545 if ($stat_report == 9) { $field_sequence = "1"; } 546 if ($stat_report == 10) { $field_sequence = "1,2"; } 547 if ($stat_report == 11) { $report_title = "Source or Destination IP"; $heading_1 = "Host"; } 548 if ($stat_report == 12) { $field_sequence = "5"; } 549 if ($stat_report == 17) { $field_sequence = "13"; } 550 if ($stat_report == 18) { $field_sequence = "14"; } 551 if ($stat_report == 19) { &print_error("The Source AS Report is not available for IPFIX data. The capability is not currently supported by SiLK."); } 552 if ($stat_report == 20) { &print_error("The Destination AS Report is not available for IPFIX data. The capability is not currently supported by SiLK."); } 553 if ($stat_report == 21) { &print_error("The Source/Destination AS Report is not available for IPFIX data. The capability is not currently supported by SiLK."); } 554 if ($stat_report == 22) { &print_error("The IP ToS Report is not available for IPFIX data. The capability is not currently supported by SiLK."); } 555 if ($stat_report == 23) { $field_sequence = "13,14"; } 556 if ($stat_report == 24) { &print_error("The Statistics Source Prefix Report is not available for IPFIX data. Please use the Source Prefix Aggregation Printed Report."); } 557 if ($stat_report == 25) { &print_error("The Statistics Destination Prefix Report is not available for IPFIX data. Please use the Destination Prefix Aggregation Printed Report."); } 558 if ($stat_report == 26) { &print_error("The Statistics Source/Destination Prefix Report is not available for IPFIX data. The capability is not currently supported by SiLK."); } 559 if ($stat_report == 27) { &print_error("The Exporter IP Report is not available for IPFIX data."); } 560 if ($stat_report == 30) { $report_title = "Detect Scanning"; } 561 562 if ($print_report == 1) { $field_sequence = "22,24,23,13,1,14,2,5,3,4,6,7,8"; } 563 if ($print_report == 4) { &print_error("The AS Numbers Report is not available for IPFIX data. The capability is not currently supported by SiLK."); } 564 if ($print_report == 5) { $field_sequence = "22,24,23,13,1,3,14,2,4,15,5,6,7,8"; } 565 if ($print_report == 9) { &print_error("The 1 Line with Tags Report is not available for IPFIX data. The capability is not currently supported by SiLK."); } 566 if ($print_report == 10) { &print_error("The AS Aggregation Report is not available for IPFIX data. The capability is not currently supported by SiLK."); } 567 if ($print_report == 11) { &print_error("The Protocol Port Aggregation Report is not available for IPFIX data. The capability is not currently supported by SiLK."); } 568 if ($print_report == 12) { $field_sequence = "1"; } 569 if ($print_report == 13) { $field_sequence = "2"; } 570 if ($print_report == 14) { &print_error("The Prefix Aggregation report is not available for IPFIX data. The capability is not currently supported by SiLK."); } 571 if ($print_report == 15) { $field_sequence = "1"; } 572 if ($print_report == 16) { $field_sequence = "2"; } 573 if ($print_report == 17) { $field_sequence = "1,2"; } 574 if ($print_report == 24) { &print_error("The Full Catalyst Report is not available for IPFIX data. The capability is not currently supported by SiLK."); } 575 576 if ($sort_field == 1) { $rwstat_values = "Bytes,Packets,Records"; } 577 if ($sort_field == 2) { $rwstat_values = "Records,Bytes,Packets"; } 578 if ($sort_field == 3) { $rwstat_values = "Packets,Bytes,Records"; } 579 580 time_check("start SiLK"); 581 582 if ($stat_report == 11) { 583 584 $half_cutoff_lines = int(0.5 * $cutoff_lines); 585 586 $field_sequence = "1"; 587 $rwstats_command = "$silk_bin_directory/rwstats $site_config_modifier --fields=$field_sequence --values=$rwstat_values --no-titles --no-percents --delimited=\" \" "; 588 if ($cutoff_octets > 0) { 589 $rwstats_command .= "--threshold=$cutoff_octets"; 590 } else { 591 $rwstats_command .= "--count=$half_cutoff_lines"; 592 } 593 $silk_command = "$rwfilter_command | $rwstats_command > $work_directory/FlowViewer_output_$suffix"; 594 if ($debug_viewer eq "Y") { print DEBUG "silk_command: $silk_command\n"; } 595 system ($silk_command); 596 597 $field_sequence = "2"; 598 $rwstats_command = "$silk_bin_directory/rwstats $site_config_modifier --fields=$field_sequence --values=$rwstat_values --no-titles --no-percents --delimited=\" \" "; 599 if ($cutoff_octets > 0) { 600 $rwstats_command .= "--threshold=$cutoff_octets"; 601 } else { 602 $rwstats_command .= "--count=$half_cutoff_lines"; 603 } 604 $silk_command = "$rwfilter_command | $rwstats_command >> $work_directory/FlowViewer_output_$suffix"; 605 if ($debug_viewer eq "Y") { print DEBUG "silk_command: $silk_command\n"; } 606 system ($silk_command); 607 608 $temp_sort_file = "$work_directory/FlowViewer_output_$suffix"; 609 open(TEMPSORT,"<$temp_sort_file"); 610 chomp (@temp_sort_lines = <TEMPSORT>); 611 close TEMPSORT; 612 foreach $temp_sort_line (@temp_sort_lines) { 613 ($ip_addr,$octs,$pkts,$flws) = split(/\s+/,$temp_sort_line); 614 $num_zeroes = 20 - length($octs); 615 for ($i=0;$i<$num_zeroes;$i++) { $octs = "0" . $octs; } 616 $new_sort_line = $octs ." ". $ip_addr ." ". $pkts ." ". $flws; 617 push(@new_sort_lines,$new_sort_line); 618 } 619 620 @pre_sorted_lines = sort (@new_sort_lines); 621 @newly_sorted_lines = reverse(@pre_sorted_lines); 622 open(TEMPSORT,">$temp_sort_file"); 623 foreach $temp_sort_line (@newly_sorted_lines) { 624 ($octs,$ip_addr,$pkts,$flws) = split(/\s+/,$temp_sort_line); 625 for ($i=0;$i<20;$i++) { if (substr($octs,0,1) eq "0") { $octs = substr($octs,1,20); } } 626 $sorted_output_line = $ip_addr ." ". $octs ." ". $pkts ." ". $flws; 627 print TEMPSORT "$sorted_output_line\n"; 628 } 629 close TEMPSORT; 630 631 } elsif ($stat_report == 30) { 632 633 $prefiltered_file = "$work_directory/FlowViewer_scanner_$suffix"; 634 ($left_part,$right_part) = split(/--pass=/,$rwfilter_command); 635 $rwfilter_command = $left_part . "--pass=$prefiltered_file"; 636 if ($debug_viewer eq "Y") { print DEBUG "rwfilter_command: $rwfilter_command\n"; } 637 system ($rwfilter_command); 638 $rwsort_command = "$silk_bin_directory/rwsort $site_config_modifier --fields=sip,proto,dip $prefiltered_file"; 639 $rwscan_command = "$silk_bin_directory/rwscan $site_config_modifier --scan-model=$scan_model --trw-internal-set=$trw_internal_set --model-fields"; 640 $silk_command = "$rwsort_command | $rwscan_command > $work_directory/FlowViewer_output_$suffix"; 641 if ($debug_viewer eq "Y") { print DEBUG "silk_command: $silk_command\n"; } 642 system ($silk_command); 643 644 } elsif ($stat_report == 99) { 645 646 $field_sequence = "5"; 647 $rwstats_command = "$silk_bin_directory/rwstats $site_config_modifier --fields=$field_sequence --values=$rwstat_values --count=1000 --no-titles --no-percents --delimited=\" \" "; 648 $silk_command = "$rwfilter_command | $rwstats_command > $work_directory/FlowViewer_summary_$suffix"; 649 if ($debug_viewer eq "Y") { print DEBUG "silk_command: $silk_command\n"; } 650 system ($silk_command); 651 652 open (SUMMARY,"<$work_directory/FlowViewer_summary_$suffix"); 653 while (<SUMMARY>) { 654 if (substr($_,0,1) eq "#") { next; } 655 ($x,$flows,$octets,$packets) = split(/\s+/,$_); 656 $sum_field_sequence .= "$x,"; 657 } 658 659 chop $sum_field_sequence; 660 $rwstats_command = "$silk_bin_directory/rwstats $site_config_modifier --detail-proto-stats=$sum_field_sequence"; 661 $silk_command = "$rwfilter_command | $rwstats_command > $work_directory/FlowViewer_output_$suffix"; 662 if ($debug_viewer eq "Y") { print DEBUG "silk_command: $silk_command\n"; } 663 system ($silk_command); 664 665 } elsif (($print_report == 1) || ($print_report == 5)) { 666 667 $sort_field = 5; 668 $rwcut_command = "$silk_bin_directory/rwcut $site_config_modifier --fields=$field_sequence --column-separator=\" \""; 669 if ($cutoff_lines > 0) { $rwcut_command .= "--num-recs=$cutoff_lines"; } 670 $silk_command = "$rwfilter_command | $rwcut_command > $work_directory/FlowViewer_output_$suffix"; 671 if ($debug_viewer eq "Y") { print DEBUG "silk_command: $silk_command\n"; } 672 system ($silk_command); 673 674 } elsif (($print_report >= 12) && ($print_report <= 17)) { 675 676 if ($print_report == 12) { $rwnetmask_command = "$silk_bin_directory/rwnetmask $site_config_modifier --sip-prefix-length $sip_prefix_length"; } 677 if ($print_report == 13) { $rwnetmask_command = "$silk_bin_directory/rwnetmask $site_config_modifier --dip-prefix-length $dip_prefix_length"; } 678 if ($print_report == 15) { $rwnetmask_command = "$silk_bin_directory/rwnetmask $site_config_modifier --6sip-prefix-length $sip_prefix_length --ipv6-policy=only"; } 679 if ($print_report == 16) { $rwnetmask_command = "$silk_bin_directory/rwnetmask $site_config_modifier --6dip-prefix-length $dip_prefix_length --ipv6-policy=only"; } 680 if ($print_report == 17) { $rwnetmask_command = "$silk_bin_directory/rwnetmask $site_config_modifier --6sip-prefix-length $sip_prefix_length --6dip-prefix-length $dip_prefix_length --ipv6-policy=only"; } 681 682 $rwstats_command = "$silk_bin_directory/rwstats $site_config_modifier --fields=$field_sequence --values=$rwstat_values --no-titles --no-percents --delimited=\" \" "; 683 if ($cutoff_octets > 0) { 684 $rwstats_command .= "--threshold=$cutoff_octets"; 685 } else { 686 $rwstats_command .= "--count=$cutoff_lines"; 687 } 688 $silk_command = "$rwfilter_command | $rwnetmask_command | $rwstats_command > $work_directory/FlowViewer_output_$suffix"; 689 if ($debug_viewer eq "Y") { print DEBUG "silk_command: $silk_command\n"; } 690 system ($silk_command); 691 692 } else { 693 694 $rwstats_command = "$silk_bin_directory/rwstats $site_config_modifier --fields=$field_sequence --values=$rwstat_values --no-titles --no-percents --delimited=\" \" "; 695 if ($cutoff_octets > 0) { 696 $rwstats_command .= "--threshold=$cutoff_octets"; 697 } else { 698 $rwstats_command .= "--count=$cutoff_lines"; 699 } 700 $silk_command = "$rwfilter_command | $rwstats_command > $work_directory/FlowViewer_output_$suffix"; 701 if ($debug_viewer eq "Y") { print DEBUG "silk_command: $silk_command\n"; } 702 system ($silk_command); 703 } 704 time_check("end SiLK"); 705} 706 707$heading_1 = ""; $heading_2 = ""; 708 709if ($stat_report == 99) { $report_title = "Summary"; } 710if ($stat_report == 5) { $report_title = "UDP/TCP Destination Port"; $heading_1 = "Dst Port"; } 711if ($stat_report == 6) { $report_title = "UDP/TCP Source Port"; $heading_1 = "Src Port"; } 712if ($stat_report == 7) { $report_title = "UDP/TCP Port"; $heading_1 = "Port"; } 713if (($stat_report == 7) && ($IPFIX)) { $heading_1 = "Src Port"; $heading_2 = "Dst Port";} 714if ($stat_report == 8) { $report_title = "Destination IP"; $heading_1 = "Dst Host"; } 715if ($stat_report == 9) { $report_title = "Source IP"; $heading_1 = "Src Host"; } 716if ($stat_report == 10) { $report_title = "Source/Destination IP"; $heading_1 = "Src Host"; $heading_2 = "Dst Host"; $rate_report = 1;} 717if ($stat_report == 11) { $report_title = "Source or Destination IP"; $heading_1 = "Host"; } 718if ($stat_report == 12) { $report_title = "IP Protocol"; $heading_1 = "Protocol"; } 719if ($stat_report == 17) { $report_title = "Input Interface"; $heading_1 = "In I/F"; } 720if ($stat_report == 18) { $report_title = "Output Interface"; $heading_1 = "Out I/F"; } 721if ($stat_report == 19) { $report_title = "Source AS"; $heading_1 = "Src AS"; } 722if ($stat_report == 20) { $report_title = "Destination AS"; $heading_1 = "Dst AS"; } 723if ($stat_report == 21) { $report_title = "Source/Destination AS"; $heading_1 = "Src AS"; $heading_2 = "Dst AS"; $rate_report = 1;} 724if ($stat_report == 22) { $report_title = "IP ToS"; $heading_1 = "ToS"; } 725if ($stat_report == 23) { $report_title = "Input/Output Interface"; $heading_1 = "In I/F"; $heading_2 = "Out I/F"; $rate_report = 1;} 726if ($stat_report == 24) { $report_title = "Source Prefix"; $heading_1 = "Src Prefix"; } 727if ($stat_report == 25) { $report_title = "Destination Prefix"; $heading_1 = "Dst Prefix"; } 728if ($stat_report == 26) { $report_title = "Source/Destination Prefix"; $heading_1 = "Src Prefix"; $heading_2 = "Dst Prefix"; $rate_report = 1;} 729if ($stat_report == 27) { $report_title = "Exporter IP"; $heading_1 = "Exporter"; } 730if ($stat_report == 30) { $report_title = "Detect Scanning"; $heading_1 = "Detect Scanning"; } 731 732$resolve_columns = 0; 733if (($resolve_addresses eq "Y") && ($stat_report == 8)) { $resolve_columns = 1; } 734if (($resolve_addresses eq "Y") && ($stat_report == 9)) { $resolve_columns = 1; } 735if (($resolve_addresses eq "Y") && ($stat_report == 10)) { $resolve_columns = 2; } 736if (($resolve_addresses eq "Y") && ($stat_report == 11)) { $resolve_columns = 1; } 737if (($resolve_addresses eq "Y") && ($stat_report == 17)) { $resolve_columns = 5; } 738if (($resolve_addresses eq "Y") && ($stat_report == 18)) { $resolve_columns = 5; } 739if (($resolve_addresses eq "Y") && ($stat_report == 19)) { $resolve_columns = 3; } 740if (($resolve_addresses eq "Y") && ($stat_report == 20)) { $resolve_columns = 3; } 741if (($resolve_addresses eq "Y") && ($stat_report == 21)) { $resolve_columns = 4; } 742if (($resolve_addresses eq "Y") && ($stat_report == 23)) { $resolve_columns = 6; } 743if (($resolve_addresses eq "Y") && ($stat_report == 27)) { $resolve_columns = 7; } 744 745if ($print_report == 1) { $report_title = "Flow Times"; } 746if ($print_report == 4) { $report_title = "AS Numbers"; } 747if ($print_report == 5) { $report_title = "132 Columns"; } 748if ($print_report == 9) { $report_title = "1 Line with Tags"; } 749if ($print_report == 10) { $report_title = "AS Aggregation"; } 750if ($print_report == 11) { $report_title = "Protocol Port Aggregation"; } 751if ($print_report == 12) { $report_title = "Source Prefix Aggregation"; if ($IPFIX) { $heading_1 = "Source Prefix"; }} 752if ($print_report == 13) { $report_title = "Destination Prefix Aggregation"; if ($IPFIX) { $heading_1 = "Dest Prefix"; }} 753if ($print_report == 14) { $report_title = "Prefix Aggregation"; $heading_1 = "Source Aggregate"; $heading_2 = "Dest Aggregate"; } 754if ($print_report == 15) { $report_title = "Source Prefix Aggregation v6"; $heading_1 = "Source Prefix"; } 755if ($print_report == 16) { $report_title = "Destination Prefix Aggregation v6"; $heading_1 = "Dest Prefix"; } 756if ($print_report == 17) { $report_title = "Prefix Aggregation v6"; $heading_1 = "Source Aggregate"; $heading_2 = "Dest Aggregate"; } 757if ($print_report == 24) { $report_title = "Full (Catalyst)"; } 758if(($print_report > 0) && (!$IPFIX)) { $sort_field = 4; } 759 760$short_fields = 0; 761if ($resolve_columns == 0) { 762 if (($stat_report == 5) || ($stat_report == 6) || ($stat_report == 7)) { $short_fields = 1; } 763 if (($stat_report >= 12) && ($stat_report <= 23)) { $short_fields = 1; } 764} 765 766# Determine whether to translate interface indexes 767 768if (($resolve_columns != 0) && (($stat_report == 17) || ($stat_report == 18) || ($stat_report == 23))) { 769 $short_fields = 1; 770 $interface_names = 0; 771 $test_if = 1; 772 $if_name = dig_if($test_if); 773 if ($if_name ne "NO_TRANSLATIONS") { $interface_names = 1; $short_fields = 0; } 774} 775 776# Output report input filtering criteria 777 778$start_flows_out = $start_flows ." $time_zone"; 779$end_flows_out = $end_flows ." $time_zone"; 780if ($sort_field == 1) { $sort_field_out = "Octets"; } 781if ($sort_field == 2) { $sort_field_out = "Flows"; } 782if ($sort_field == 3) { $sort_field_out = "Packets"; } 783if ($sort_field == 4) { $sort_field_out = "N/A"; } 784if ($sort_field == 5) { $sort_field_out = "sTime"; } 785 786# Generate a pie-chart if the user is interested 787 788$piechart_link = "no piechart"; 789if (($pie_charts > 0) && ((($stat_report > 0 ) && ($stat_report < 30)) || (($print_report > 10) && ($print_report <18)))) { 790 791 $array_elements = $number_slices - 1; 792 793 open (OUTPUT,"<$work_directory/FlowViewer_output_$suffix"); 794 while (<OUTPUT>) { 795 796 if (substr($_,0,1) eq "#") { next; } 797 798 $line_count++; 799 800 if (($rate_report) || (($stat_report == 7) && ($IPFIX)) || ($print_report == 14) || ($print_report == 17)) { 801 if ($IPFIX) { 802 if ($sort_field == 1) { ($x,$y,$octets,$packets,$flows) = split(/\s+/,$_); } 803 if ($sort_field == 2) { ($x,$y,$flows,$octets,$packets) = split(/\s+/,$_); } 804 if ($sort_field == 3) { ($x,$y,$packets,$octets,$flows) = split(/\s+/,$_); } 805 } else { 806 ($x,$y,$flows,$octets,$packets) = split(/\s+/,$_); 807 } 808 } else { 809 if ($IPFIX) { 810 if ($sort_field == 1) { ($x,$octets,$packets,$flows) = split(/\s+/,$_); } 811 if ($sort_field == 2) { ($x,$flows,$octets,$packets) = split(/\s+/,$_); } 812 if ($sort_field == 3) { ($x,$packets,$octets,$flows) = split(/\s+/,$_); } 813 } else { 814 ($x,$flows,$octets,$packets) = split(/\s+/,$_); 815 } 816 } 817 818 $IPv4_y = 0; $IPv6_y = 0; 819 if ($y =~ m/^\s*-*\d+/) { 820 $_ = $y; 821 $num_dots = tr/\.//; if ($num_dots > 0) { $IPv4_y = 1; } 822 $num_colons = tr/\://; if ($num_colons > 0) { $IPv6_y = 1; } 823 } 824 825 if (($stat_report != 0) && ($octets < $cutoff_octets)) { last; } 826 827 if ($top_count < $array_elements) { 828 if ($sort_field == 1) { $top_ten_values[$top_count] = $octets; } 829 if ($sort_field == 2) { $top_ten_values[$top_count] = $flows; } 830 if ($sort_field == 3) { $top_ten_values[$top_count] = $packets; } 831 $x_out = $x; 832 $y_out = $y; 833 if ($resolve_columns == 0) { 834 $IPv6_x = 0; 835 if ($x_out =~ m/^\s*-*\d+/) { 836 $_ = $x_out; 837 $num_colons = tr/\://; if ($num_colons > 0) { $IPv6_x = 1; } 838 } 839 if ($IPv6_x) { 840 $last_colon = rindex($x_out,":") - 1; 841 $last_colon = rindex($x_out,":",$last_colon); 842 $x_out = "..." . substr($x_out,$last_colon,18); 843 } else { 844 if ($x_out =~ /[a-zA-Z]/) { ($x_out) = split(/\./,$x_out); } 845 } 846 } 847 if (($resolve_columns == 1) || ($resolve_columns == 2)) { 848 $x_out = dig($x); 849 $IPv6_x = 0; 850 if ($x_out =~ m/^\s*-*\d+/) { 851 $_ = $x_out; 852 $num_colons = tr/\://; if ($num_colons > 0) { $IPv6_x = 1; } 853 } 854 if ($IPv6_x) { 855 $last_colon = rindex($x_out,":") - 1; 856 $last_colon = rindex($x_out,":",$last_colon); 857 $x_out = "..." . substr($x_out,$last_colon,18); 858 } else { 859 if ($x_out =~ /[a-zA-Z]/) { ($x_out) = split(/\./,$x_out); } 860 } 861 } 862 if ($resolve_columns == 3) { 863 $x_out = dig_as($x); 864 } 865 if (($resolve_columns == 5) && ($interface_names)) { 866 $x_out = dig_if($x); 867 } 868 if ($resolve_columns == 7) { 869 $x_out = dig_ex($x); 870 $IPv6_x = 0; 871 if ($x_out =~ m/^\s*-*\d+/) { 872 $_ = $x_out; 873 $num_colons = tr/\://; if ($num_colons > 0) { $IPv6_x = 1; } 874 } 875 if ($IPv6_x) { 876 $last_colon = rindex($x_out,":") - 1; 877 $last_colon = rindex($x_out,":",$last_colon); 878 $x_out = "..." . substr($x_out,$last_colon,18); 879 } else { 880 if ($x_out =~ /[a-zA-Z]/) { ($x_out) = split(/\./,$x_out); } 881 } 882 } 883 $top_ten_labels[$top_count] = $x_out; 884 if ($y ne "") { 885 if ($resolve_columns == 0) { 886 $IPv6_y = 0; 887 if ($y_out =~ m/^\s*-*\d+/) { 888 $_ = $y_out; 889 $num_colons = tr/\://; if ($num_colons > 0) { $IPv6_y = 1; } 890 } 891 if ($IPv6_y) { 892 $last_colon = rindex($y_out,":") - 1; 893 $last_colon = rindex($y_out,":",$last_colon); 894 $y_out = "..." . substr($y_out,$last_colon,18); 895 } else { 896 if ($y_out =~ /[a-zA-Z]/) { ($y_out) = split(/\./,$y_out); } 897 } 898 } 899 if (($resolve_columns == 1) || ($resolve_columns == 2)) { 900 $y_out = dig($y); 901 $IPv6_y = 0; 902 if ($y_out =~ m/^\s*-*\d+/) { 903 $_ = $y_out; 904 $num_colons = tr/\://; if ($num_colons > 0) { $IPv6_y = 1; } 905 } 906 if ($IPv6_y) { 907 $last_colon = rindex($y_out,":") - 1; 908 $last_colon = rindex($y_out,":",$last_colon); 909 $y_out = "..." . substr($y_out,$last_colon,18); 910 } else { 911 if ($y_out =~ /[a-zA-Z]/) { ($y_out) = split(/\./,$y_out); } 912 } 913 } 914 if ($resolve_columns == 4) { 915 $y_out = dig_as($y); 916 } 917 if (($resolve_columns == 6) && ($interface_names)) { 918 $y_out = dig_if($y); 919 } 920 $top_ten_labels[$top_count] .= " - ". $y_out; 921 } 922 $top_count++; 923 } elsif ($pie_charts == 1) { 924 if ($sort_field == 1) { $top_ten_values[$top_count] += $octets; } 925 if ($sort_field == 2) { $top_ten_values[$top_count] += $flows; } 926 if ($sort_field == 3) { $top_ten_values[$top_count] += $packets; } 927 $top_ten_labels[$array_elements] = "Other"; 928 } 929 930 if (($line_count-3) > $cutoff_lines) { last; } 931 } 932 933 if ($line_count eq "") { 934 935 print " </div>\n"; 936 &create_UI_service("FlowViewer_Main","service_bottom",$active_dashboard,$filter_hash); 937 &finish_the_page("FlowViewer_Main"); 938 939 $rm_command = "rm $work_directory/FlowViewer_filter_$suffix"; 940 if ($debug_files ne "Y") { system($rm_command); } 941 $rm_command = "rm $work_directory/FlowViewer_output_$suffix"; 942 if ($debug_files ne "Y") { system($rm_command); } 943 944 exit; 945 946 } else { $line_count = 0; } 947 948 $graph = new GD::Graph::pie(325,175); 949 950 $graph->set( 951 transparent => 1, 952 axislabelclr => 'black', 953 dclrs => $pie_colors, 954 '3d' => 1, 955 pie_height => 10, 956 start_angle => 90, 957 suppress_angle => 20 958 ) 959 or warn $graph->error; 960 961 $graph->set_label_font(GD::Font->Small); 962 $graph->set_value_font(GD::Font->Small); 963 964 @plot = ([@top_ten_labels],[@top_ten_values]); 965 $image = $graph->plot(\@plot) or die $graph->error; 966 967 $png_filename = "FlowViewer_save_" . $saved_suffix . ".png"; 968 $piechart_link = "$graphs_short/$png_filename"; 969 970 open(PNG,">$graphs_directory/$png_filename"); 971 binmode PNG; 972 print PNG $image->png; 973 974 print "<center><img src=$piechart_link></center>\n"; 975 print HTML "<center><img src=$piechart_link></center>\n"; 976 977 close (OUTPUT); 978} 979 980# Parse through the intermediate, flow tools (or now SiLK) generated, 'FlowViewer_output' file 981 982$print_header = 1; 983$first_scanner = 1; 984 985$sort_file = "$work_directory/FlowViewer_save_" . $saved_suffix; 986open (SORTED_SAVE, ">$sort_file"); 987&start_saved_file($sort_file); 988open (SORTED_SAVE, ">>$sort_file"); 989 990if ((($print_report > 0) && ($print_report < 12)) || ($stat_report == 99)) { 991 print " <pre><font face=\"Courier New\">\n"; 992 print " <table>\n"; 993 print SORTED_SAVE " <pre><font face=\"Courier New\">\n"; 994 print SORTED_SAVE " <table>\n"; 995} 996 997open (OUTPUT,"<$work_directory/FlowViewer_output_$suffix"); 998while (<OUTPUT>) { 999 1000 chop; 1001 if (substr($_,0,1) eq "#") { next; } 1002 if (substr($_,0,5) eq "flow-") { 1003 if ($stat_report == 30) { 1004 if (!$start_table) { 1005 1006 $report_suffix = &get_suffix; 1007 $report_filename = "FlowViewer_save_$report_suffix"; 1008 $filter_hash = "SC_$report_filename"; 1009 $main_hash = $filter_hash; 1010 $report_file = "$work_directory/$report_filename"; 1011 open (SCAN_SAVE, ">$report_file"); 1012 &start_saved_file($report_file); 1013 close (SCAN_SAVE); 1014 open (SCAN_SAVE, ">>$report_file"); 1015 1016 print " <table>\n"; 1017 print " <tr><td> </td></tr>\n"; 1018 print " <tr><td align=left>The following hosts were discovered to be scanners</td></tr>\n"; 1019 print " <tr><td> </td></tr>\n"; 1020 print " </table>\n"; 1021 print " <table>\n"; 1022 print " <tr>\n"; 1023 print "<td>IP Address</td><td>    </td>\n"; 1024 print "<td>Host Name</td><td>    </td>\n"; 1025 print "<td>CC</td><td>    </td>\n"; 1026 print "<td>AS Name</td><td>    </td>\n"; 1027 print "<td>Flows</td><td>    </td>\n"; 1028 print "<td>Avg Fl Time</td><td>    </td>\n"; 1029 print "<td>Avg Pkt Size</td><td>    </td>\n"; 1030 print "<td>Pkts/Flow</td><td>    </td>\n"; 1031 print "<td>Flows/Sec</td><td>    </td>\n"; 1032 print "</tr>\n"; 1033 print " <tr><td> </td></tr>\n"; 1034 1035 print SCAN_SAVE " <table>\n"; 1036 print SCAN_SAVE " <tr><td> </td></tr>\n"; 1037 print SCAN_SAVE " <tr><td align=left>The following hosts were discovered to be scanners</td></tr>\n"; 1038 print SCAN_SAVE " <tr><td> </td></tr>\n"; 1039 print SCAN_SAVE " </table>\n"; 1040 print SCAN_SAVE " <table>\n"; 1041 print SCAN_SAVE " <tr>\n"; 1042 print SCAN_SAVE "<td>IP Address</td><td>    </td>\n"; 1043 print SCAN_SAVE "<td>Host Name</td><td>    </td>\n"; 1044 print SCAN_SAVE "<td>CC</td><td>    </td>\n"; 1045 print SCAN_SAVE "<td>AS Name</td><td>    </td>\n"; 1046 print SCAN_SAVE "<td>Flows</td><td>    </td>\n"; 1047 print SCAN_SAVE "<td>Avg Fl Time</td><td>    </td>\n"; 1048 print SCAN_SAVE "<td>Avg Pkt Size</td><td>    </td>\n"; 1049 print SCAN_SAVE "<td>Pkts/Flow</td><td>    </td>\n"; 1050 print SCAN_SAVE "<td>Flows/Sec</td><td>    </td>\n"; 1051 print SCAN_SAVE "</tr>\n"; 1052 print SCAN_SAVE " <tr><td> </td></tr>\n"; 1053 $start_table = 1; 1054 } 1055 if (substr($_,0,16) eq "flow-dscan: host") { 1056 1057 ($left_part,$right_part) = split(/ ts=/); 1058 ($left_part,$ip_address) = split(/=/,$left_part); 1059 1060 $scan_suffix = &get_suffix; 1061 $scan_filename = "FlowViewer_save_$scan_suffix"; 1062 $scan_hash = "SC_$scan_filename"; 1063 $scan_file = "$work_directory/$scan_filename"; 1064 $stats_file = "$work_directory/FlowViewer_scan_stats"; 1065 $filter_hash = $scan_hash; 1066 $source_addresses = $ip_address; 1067 open (SORTED_SAVE, ">$scan_file"); 1068 &start_saved_file($scan_file); 1069 close (SORTED_SAVE); 1070 $filter_hash = $main_hash; 1071 1072 $ip_name = dig($ip_address); 1073 ($as_number,$as_country,$as_name) = dig_as_full($ip_address); 1074 1075 $filter_file = "$work_directory/FlowViewer_filter_scanner"; 1076 $FORM{source_address} = $ip_address; 1077 $FORM{cutoff_lines} = 2000; 1078 create_filter_file(%FORM,$filter_file); 1079 $flownfilter_command = "$flow_bin_directory/flow-nfilter -f $work_directory/FlowViewer_filter_scanner -FFlow_Filter"; 1080 $flowprint_command = "$flow_bin_directory/flow-print -f5 >>$scan_file"; 1081 $flow_run = "$flownfilter_command <$work_directory/FlowViewer_scanner_$suffix | $flowprint_command"; 1082 system($flow_run); 1083 1084 $flowstat_command = "$flow_bin_directory/flow-stat -f0 >$stats_file"; 1085 $flow_run = "$flownfilter_command <$work_directory/FlowViewer_scanner_$suffix | $flowstat_command"; 1086 system($flow_run); 1087 open(STATS,"<$stats_file"); 1088 while (<STATS>) { 1089 if ((substr($_,0,1) eq "#") || (substr($_,0,1) eq " ")) { next; } 1090 ($field_name,$field_value) = split(/: /); 1091 if (/Total Flows/) { $total_flows = $field_value; } 1092 if (/Average flow time/) { 1093 $avg_flow_time = $field_value; 1094 $avg_flow_time *= 0.001; 1095 if ($avg_flow_time < 0.001) { $avg_flow_time = "0.000"; } 1096 $avg_flow_time = substr($avg_flow_time,0,5); 1097 } 1098 if (/Average packet size/) { $avg_pkt_size = $field_value; } 1099 if (/Average packets per/) { $avg_pkt_flow = $field_value; } 1100 if (/Average flows \/ se/) { $avg_flow_sec = $field_value; } 1101 } 1102 $rm_command = "rm $stats_file"; 1103 system($rm_command); 1104 1105 $cgi_link = "$cgi_bin_short/FlowViewer_Replay.cgi?$active_dashboard^filter_hash=$scan_hash"; 1106 print "<tr><td align=left><a href=$cgi_link>$ip_address</a></td><td>    </td>"; 1107 print "<td>$ip_name</td><td>    </td>"; 1108 print "<td>$as_country</td><td>    </td>"; 1109 print "<td>$as_name</td><td>    </td>"; 1110 print "<td align=right>$total_flows</td><td>    </td>"; 1111 print "<td align=right>$avg_flow_time</td><td>    </td>"; 1112 print "<td align=right>$avg_pkt_size</td><td>    </td>"; 1113 print "<td align=right>$avg_pkt_flow</td><td>    </td>"; 1114 print "<td align=right>$avg_flow_sec</td><td>    </td>"; 1115 print "</tr>\n"; 1116 1117 print SCAN_SAVE "<tr><td align=left><a>$ip_address</a></td><td>    </td>"; 1118 print SCAN_SAVE "<td>$ip_name</td><td>    </td>"; 1119 print SCAN_SAVE "<td>$as_country</td><td>    </td>"; 1120 print SCAN_SAVE "<td>$as_name</td><td>    </td>"; 1121 print SCAN_SAVE "<td align=right>$total_flows</td><td>    </td>"; 1122 print SCAN_SAVE "<td align=right>$avg_flow_time</td><td>    </td>"; 1123 print SCAN_SAVE "<td align=right>$avg_pkt_size</td><td>    </td>"; 1124 print SCAN_SAVE "<td align=right>$avg_pkt_flow</td><td>    </td>"; 1125 print SCAN_SAVE "<td align=right>$avg_flow_sec</td><td>    </td>"; 1126 print SCAN_SAVE "</tr>\n"; 1127 next; 1128 } 1129 1130 } else { 1131 if (!$start_table) { 1132 print " <table>\n"; 1133 print " <tr><td> </td></tr>\n"; 1134 print " <tr><td align=left>Error: Examine presense of flow data for time period specified, etc.</td></tr>\n"; 1135 print " <tr><td> </td></tr>\n"; 1136 $start_table = 1; 1137 } 1138 print " <tr><td align=left>$_</td></tr>\n"; 1139 next; 1140 } 1141 } 1142 1143 if (($IPFIX) && ($stat_report == 30)) { 1144 1145 if (!$start_table) { 1146 1147 $report_suffix = &get_suffix; 1148 $report_filename = "FlowViewer_save_$report_suffix"; 1149 $filter_hash = "SC_$report_filename"; 1150 $main_hash = $filter_hash; 1151 $report_file = "$work_directory/$report_filename"; 1152 open (SCAN_SAVE, ">$report_file"); 1153 &start_saved_file($report_file); 1154 close (SCAN_SAVE); 1155 open (SCAN_SAVE, ">>$report_file"); 1156 1157 print " <table>\n"; 1158 print " <tr><td> </td></tr>\n"; 1159 print " <tr><td align=left>The following hosts were discovered to be scanners</td></tr>\n"; 1160 print " <tr><td> </td></tr>\n"; 1161 print " </table>\n"; 1162 print " <table>\n"; 1163 print " <tr>\n"; 1164 print " <td>IP Address</td><td>    </td>\n"; 1165 print " <td>Host Name</td><td>    </td>\n"; 1166 print " <td>CC</td><td>    </td>\n"; 1167 print " <td>AS Name</td><td>    </td>\n"; 1168 print " <td>Start Time</td><td>    </td>\n"; 1169 print " <td>End Time</td><td>    </td>\n"; 1170 print " <td>Flows</td><td>    </td>\n"; 1171 print " <td>Packets</td><td>    </td>\n"; 1172 print " <td>Octets</td><td>    </td>\n"; 1173 print " </tr>\n"; 1174 print " <tr><td> </td></tr>\n"; 1175 1176 print SCAN_SAVE " <table>\n"; 1177 print SCAN_SAVE " <tr><td> </td></tr>\n"; 1178 print SCAN_SAVE " <tr><td align=left>The following hosts were discovered to be scanners</td></tr>\n"; 1179 print SCAN_SAVE " <tr><td> </td></tr>\n"; 1180 print SCAN_SAVE " </table>\n"; 1181 print SCAN_SAVE " <table>\n"; 1182 print SCAN_SAVE " <tr>\n"; 1183 print SCAN_SAVE " <td>IP Address</td><td>    </td>\n"; 1184 print SCAN_SAVE " <td>Host Name</td><td>    </td>\n"; 1185 print SCAN_SAVE " <td>CC</td><td>    </td>\n"; 1186 print SCAN_SAVE " <td>AS Name</td><td>    </td>\n"; 1187 print SCAN_SAVE " <td>Start Time</td><td>    </td>\n"; 1188 print SCAN_SAVE " <td>End Time</td><td>    </td>\n"; 1189 print SCAN_SAVE " <td>Flows</td><td>    </td>\n"; 1190 print SCAN_SAVE " <td>Packets</td><td>    </td>\n"; 1191 print SCAN_SAVE " <td>Octets</td><td>    </td>\n"; 1192 print SCAN_SAVE " </tr>\n"; 1193 print SCAN_SAVE " <tr><td> </td></tr>\n"; 1194 $start_table = 1; 1195 } 1196 1197 ($sip,$proto,$stime,$etime,$flows,$packets,$octets) = split(/\|/,$_); 1198 1199 $sip =~ s/^\s+//; 1200 $proto =~ s/^\s+//; 1201 $stime =~ s/^\s+//; 1202 $etime =~ s/^\s+//; 1203 $flows =~ s/^\s+//; 1204 $packets =~ s/^\s+//; 1205 $octets =~ s/^\s+//; 1206 1207 if ($sip eq "sip") { next; } 1208 1209 if ($flow_analysis) { 1210 $oct_per_flow = int($octets / $flows); 1211 $pkt_per_flow = int($packets / $flows); 1212 } 1213 1214 $FORM{source_address} = $sip; 1215 create_ipfix_filter(%FORM); 1216 1217 $scan_suffix = &get_suffix; 1218 $scan_filename = "FlowViewer_save_$scan_suffix"; 1219 $scan_hash = "SC_$scan_filename"; 1220 $scan_file = "$work_directory/$scan_filename"; 1221 $stats_file = "$work_directory/FlowViewer_scan_stats"; 1222 $filter_hash = $scan_hash; 1223 $source_addresses = $sip; 1224 $cutoff_lines = 1000; 1225 open (SORTED_SAVE, ">$scan_file"); 1226 &start_saved_file($scan_file); 1227 close (SORTED_SAVE); 1228 $filter_hash = $main_hash; 1229 1230 $rwfilter_command = "$silk_bin_directory/rwfilter $site_config_modifier $partitioning_switches --pass=stdout $prefiltered_file"; 1231 $field_sequence = "22,23,10,13,1,3,14,2,4,5,8,6,7"; 1232 $rwcut_command = "$silk_bin_directory/rwcut $site_config_modifier --fields=$field_sequence --delimited=\" \" "; 1233 $silk_command = "$rwfilter_command | $rwcut_command >> $scan_file"; 1234 if ($debug_viewer eq "Y") { print DEBUG "silk_command: $silk_command\n"; } 1235 system ($silk_command); 1236 1237 $sip_name = dig($sip); 1238 ($as_number,$as_country,$as_name) = dig_as_full($sip); 1239 1240 $cgi_link = "$cgi_bin_short/FlowViewer_Replay.cgi?$active_dashboard^filter_hash=$scan_hash"; 1241 print "<tr><td align=left><a href=$cgi_link>$sip</a></td><td>    </td>"; 1242 print "<td>$sip_name</td><td>    </td>"; 1243 print "<td>$as_country</td><td>    </td>"; 1244 print "<td>$as_name</td><td>    </td>"; 1245 print "<td align=right>$stime</td><td>    </td>"; 1246 print "<td align=right>$etime</td><td>    </td>"; 1247 print "<td align=right>$flows</td><td>    </td>"; 1248 print "<td align=right>$packets</td><td>    </td>"; 1249 print "<td align=right>$octets</td><td>    </td>"; 1250 print "</tr>\n"; 1251 1252 print SCAN_SAVE "<tr><td align=left><a>$sip</a></td><td>    </td>"; 1253 print SCAN_SAVE "<td>$sip_name</td><td>    </td>"; 1254 print SCAN_SAVE "<td>$as_country</td><td>    </td>"; 1255 print SCAN_SAVE "<td>$as_name</td><td>    </td>"; 1256 print SCAN_SAVE "<td align=right>$stime</td><td>    </td>"; 1257 print SCAN_SAVE "<td align=right>$etime</td><td>    </td>"; 1258 print SCAN_SAVE "<td align=right>$flows</td><td>    </td>"; 1259 print SCAN_SAVE "<td align=right>$packets</td><td>    </td>"; 1260 print SCAN_SAVE "<td align=right>$octets</td><td>    </td>"; 1261 print SCAN_SAVE "</tr>\n"; 1262 next; 1263 } 1264 1265 if ((($print_report > 0) && (!$IPFIX)) || (($print_report > 0) && ($print_report < 12)) || ($stat_report == 99) || ($stat_report == 30)) { 1266 1267 $line_count++; 1268 if ((($line_count-1) > $cutoff_lines) && ($stat_report != 99)) { last; } 1269 1270 if (($print_report == 5) && (/DstP P/)) { s/DstP P/DstP P /; } 1271 1272 if (($stat_report == 99) && (!$IPFIX) && ($sampling_multiplier > 1)) { 1273 $line = $_; 1274 ($field_name,$field_value) = split(/:/,$line); 1275 if (($line =~ /Total Flows/) || ($line =~ /Total Octets/) || 1276 ($line =~ /Total Packets/) || ($line =~ /Total Time/) || 1277 ($line =~ /Average flows \/ second \(flow\)/) || 1278 ($line =~ /Average flows \/ second \(real\)/) || 1279 ($line =~ /Average Kbits \/ second \(flow\)/) || 1280 ($line =~ /Average Kbits \/ second \(real\)/)) { 1281 $field_value *= $sampling_multiplier; 1282 $field_value .= "*"; 1283 $line = $field_name .": $field_value"; 1284 } 1285 print " <tr><td align=left><font face=\"Courier New\">$line</font></td></tr>\n"; 1286 print SORTED_SAVE " <tr><td align=left><font face=\"Courier New\">$line</font></td></tr>\n"; 1287 next; 1288 } elsif ($stat_report == 30) { 1289 if (substr(0,16) eq "flow-dscan: host") { 1290 $line = $_; 1291 print SORTED_SAVE "$line\n"; 1292 } 1293 next; 1294 } elsif (($print_report == 1) && ($date_format =~ /DMY/)) { 1295 1296 # Converting output for data formatting 1297 1298 $line = $_; 1299 if ((substr($line,0,1) eq " ") && (substr($line,1,1) =~ /[0-9]/)) { 1300 $line_mnth = substr($line,1,2); 1301 $line_date = substr($line,3,2); 1302 $temp_mnth = $line_mnth; 1303 substr($line,1,2) = $line_date; 1304 substr($line,3,2) = $temp_mnth; 1305 $line_mnth = substr($line,20,2); 1306 $line_date = substr($line,22,2); 1307 $temp_mnth = $line_mnth; 1308 substr($line,20,2) = $line_date; 1309 substr($line,22,2) = $temp_mnth; 1310 } 1311 print " <tr><td align=left><font face=\"Courier New\">$line</font></td></tr>\n"; 1312 print SORTED_SAVE " <tr><td align=left><font face=\"Courier New\">$line</font></td></tr>\n"; 1313 next; 1314 } elsif (($print_report == 5) && ($date_format =~ /DMY/)) { 1315 1316 # Converting output for data formatting 1317 1318 $line = $_; 1319 if (substr($line,0,1) =~ /[0-9]/) { 1320 $line_mnth = substr($line,0,2); 1321 $line_date = substr($line,2,2); 1322 $temp_mnth = $line_mnth; 1323 substr($line,0,2) = $line_date; 1324 substr($line,2,2) = $temp_mnth; 1325 $line_mnth = substr($line,18,2); 1326 $line_date = substr($line,20,2); 1327 $temp_mnth = $line_mnth; 1328 substr($line,18,2) = $line_date; 1329 substr($line,20,2) = $temp_mnth; 1330 } 1331 print " <tr><td align=left><font face=\"Courier New\">$line</font></td></tr>\n"; 1332 print SORTED_SAVE " <tr><td align=left><font face=\"Courier New\">$line</font></td></tr>\n"; 1333 next; 1334 } 1335 print " <tr><td align=left><font face=\"Courier New\">$_</font></td></tr>\n"; 1336 print SORTED_SAVE " <tr><td align=left><font face=\"Courier New\">$_</font></td></tr>\n"; 1337 next; 1338 } 1339 1340 if (($stat_report == 8) || ($stat_report == 9) || ($stat_report == 11)) { $country_report = 1; } 1341 1342 # Print out the header 1343 1344 if ($print_header) { 1345 1346 # Create column headers with sort links 1347 1348 $source_link = "<a href=$cgi_bin_short/FlowViewer_Sort.cgi?$active_dashboard^$filter_hash^Source^$ascend>$heading_1</a>"; 1349 $dest_link = "<a href=$cgi_bin_short/FlowViewer_Sort.cgi?$active_dashboard^$filter_hash^Dest^$ascend>$heading_2</a>"; 1350 $country_link = "<a href=$cgi_bin_short/FlowViewer_Sort.cgi?$active_dashboard^$filter_hash^Country^$ascend>Country</a>"; 1351 $octfl_link = "<a href=$cgi_bin_short/FlowViewer_Sort.cgi?$active_dashboard^$filter_hash^OctFlow^$ascend>Octs/Flow</a>"; 1352 $pktfl_link = "<a href=$cgi_bin_short/FlowViewer_Sort.cgi?$active_dashboard^$filter_hash^PktFlow^$ascend>Pkts/Flow</a>"; 1353 1354 if ($sampling_multiplier > 0) { 1355 $flows_link = "<a href=$cgi_bin_short/FlowViewer_Sort.cgi?$active_dashboard^$filter_hash^Flows^$ascend>Flows*</a>"; 1356 $octets_link = "<a href=$cgi_bin_short/FlowViewer_Sort.cgi?$active_dashboard^$filter_hash^Octets^$ascend>Octets*</a>"; 1357 $packets_link = "<a href=$cgi_bin_short/FlowViewer_Sort.cgi?$active_dashboard^$filter_hash^Packets^$ascend>Packets*</a>"; 1358 $mbps_link = "<a href=$cgi_bin_short/FlowViewer_Sort.cgi?$active_dashboard^$filter_hash^Mbps^$ascend>Avg. Rate*</a>"; 1359 } else { 1360 $flows_link = "<a href=$cgi_bin_short/FlowViewer_Sort.cgi?$active_dashboard^$filter_hash^Flows^$ascend>Flows</a>"; 1361 $octets_link = "<a href=$cgi_bin_short/FlowViewer_Sort.cgi?$active_dashboard^$filter_hash^Octets^$ascend>Octets</a>"; 1362 $packets_link = "<a href=$cgi_bin_short/FlowViewer_Sort.cgi?$active_dashboard^$filter_hash^Packets^$ascend>Packets</a>"; 1363 $mbps_link = "<a href=$cgi_bin_short/FlowViewer_Sort.cgi?$active_dashboard^$filter_hash^Mbps^$ascend>Avg. Rate</a>"; 1364 } 1365 1366 print "<br>\n"; 1367 print "<center>\n"; 1368 print "<table>\n"; 1369 print "<tr>\n"; 1370 print "<td align=left>$source_link</td>\n"; 1371 print "<td>     </td>\n"; 1372 if ($heading_2 ne "") { 1373 print "<td align=left>$dest_link</td>\n"; 1374 print "<td>     </td>\n"; 1375 } 1376 print "<td align=right>$flows_link</td>\n"; 1377 print "<td>     </td>\n"; 1378 print "<td align=right>$octets_link</td>\n"; 1379 print "<td>     </td>\n"; 1380 print "<td align=right>$packets_link</td>\n"; 1381 print "<td>     </td>\n"; 1382 if ($rate_report) { print "<td align=right>$mbps_link</td>\n"; } 1383 if ($flow_analysis) { 1384 if ($rate_report) { print "<td>     </td>\n"; } 1385 print "<td align=right>$octfl_link</td>\n"; 1386 print "<td>     </td>\n"; 1387 print "<td align=right>$pktfl_link</td>\n"; 1388 if ($country_report) { 1389 print "<td>     </td>\n"; 1390 print "<td align=right>$country_link</td>\n"; 1391 } 1392 } 1393 print "</tr>\n"; 1394 print "<tr><td>  </td></tr>\n"; 1395 1396 print "</b>"; 1397 1398 $header_line = "$heading_1 : "; 1399 if ($heading_2 ne "") { $header_line .= "$heading_2 : "; } 1400 $header_line .= "Flows : Octets : Packets"; 1401 if ($rate_report) { $header_line .= " : Avg. Rate"; } 1402 if ($flow_analysis) { 1403 $header_line .= " : Octs/Flow : Pkts/Flow"; 1404 if ($country_report) { $header_line .= " : Country"; } 1405 } 1406 print SORTED_SAVE "$header_line\n"; 1407 1408 $print_header = 0; 1409 } 1410 1411 # Print out the individual lines 1412 1413 $line_count++; 1414 1415 if (($rate_report) || (($stat_report == 7) && ($IPFIX)) || ($print_report == 14) || ($print_report == 17)) { 1416 if ($IPFIX) { 1417 if ($sort_field == 1) { ($x,$y,$octets,$packets,$flows) = split(/\s+/,$_); } 1418 if ($sort_field == 2) { ($x,$y,$flows,$octets,$packets) = split(/\s+/,$_); } 1419 if ($sort_field == 3) { ($x,$y,$packets,$octets,$flows) = split(/\s+/,$_); } 1420 } else { 1421 ($x,$y,$flows,$octets,$packets) = split(/\s+/,$_); 1422 } 1423 } else { 1424 if ($IPFIX) { 1425 if ($sort_field == 1) { ($x,$octets,$packets,$flows) = split(/\s+/,$_); } 1426 if ($sort_field == 2) { ($x,$flows,$octets,$packets) = split(/\s+/,$_); } 1427 if ($sort_field == 3) { ($x,$packets,$octets,$flows) = split(/\s+/,$_); } 1428 } else { 1429 ($x,$flows,$octets,$packets) = split(/\s+/,$_); 1430 } 1431 } 1432 1433 if ($rate_report) { 1434 $flow_rate = int($octets*8/$report_length); 1435 if ($sampling_multiplier > 1) { $flow_rate *= $sampling_multiplier; } 1436 $flow_rate = format_number($flow_rate); 1437 } 1438 1439 # Multiply by sampling multiplier if set 1440 1441 if ($sampling_multiplier > 1) { 1442 $flows *= $sampling_multiplier; 1443 $octets *= $sampling_multiplier; 1444 $packets *= $sampling_multiplier; 1445 } 1446 1447 if ($flow_analysis) { 1448 $oct_per_flow = int($octets / $flows); 1449 $pkt_per_flow = int($packets / $flows); 1450 if ($country_report) { ($as_number,$as_country,$as_name) = dig_as_full($x); } 1451 } 1452 1453 if (($stat_report != 0) && ($octets < $cutoff_octets)) { last; } 1454 1455 # Unit conversion if requested 1456 1457 if ($unit_conversion eq "Y") { 1458 $octets = convert_octets2string($octets); 1459 } 1460 1461 if ($resolve_columns == 1) { 1462 $x = dig($x); 1463 } elsif ($resolve_columns == 2) { 1464 $x = dig($x); 1465 $y = dig($y); 1466 } elsif ($resolve_columns == 3) { 1467 $x = dig_as($x); 1468 } elsif ($resolve_columns == 4) { 1469 $x = dig_as($x); 1470 $y = dig_as($y); 1471 } elsif (($resolve_columns == 5) && ($interface_names)) { 1472 $x = dig_if($x); 1473 } elsif (($resolve_columns == 6) && ($interface_names)) { 1474 $x = dig_if($x); 1475 $y = dig_if($y); 1476 } elsif ($resolve_columns == 7) { 1477 $x = dig_ex($x); 1478 } 1479 1480 if (($print_report == 12) || ($print_report == 15)) { $x = $x . "/". $sip_prefix_length; } 1481 if (($print_report == 13) || ($print_report == 16)) { $x = $x . "/". $dip_prefix_length; } 1482 if (($print_report == 14) || ($print_report == 17)) { $x = $x . "/". $sip_prefix_length; $y = $y . "/". $dip_prefix_length; } 1483 1484 # Build the line 1485 1486 if ($heading_2 ne "" ) { 1487 $line = $x ." ^ ". $y ." ^ ". $flows ." ^ ". $octets ." ^ ". $packets; 1488 if ($rate_report) { $line = $line ." ^ ". $flow_rate; } 1489 if ($flow_analysis) { $line .= " ^ ". $oct_per_flow ." ^ ". $pkt_per_flow; } 1490 } elsif (($heading_1 ne "") && ($heading_2 eq "")) { 1491 $line = $x ." ^ ". $flows ." ^ ". $octets ." ^ ". $packets; 1492 if ($flow_analysis) { $line .= " ^ ". $oct_per_flow ." ^ ". $pkt_per_flow; } 1493 if ($country_report) { $line .= " ^ ". $as_country; } 1494 } elsif ($print_report eq "0") { 1495 $line = sprintf("%-12s %-19s %-19s %-19s", $x, $y, $octets, $flows); 1496 if ($flow_analysis) { $line = sprintf("%-12s %-19s %-19s %-19s %-19s %-19s %-19s", $x, $y, $octets, $flows, $oct_per_flow, $pkt_per_flow, $as_country); } 1497 } else { 1498 $line = $_; 1499 } 1500 1501 if ($line ne "") { print SORTED_SAVE "$line\n"; } 1502 1503 print "<tr>\n"; 1504 print "<td align=left>$x</td>\n"; 1505 print "<td>     </td>\n"; 1506 if ($heading_2 ne "") { 1507 print "<td align=left>$y</td>\n"; 1508 print "<td>     </td>\n"; 1509 } 1510 print "<td align=right>$flows</td>\n"; 1511 print "<td>     </td>\n"; 1512 print "<td align=right>$octets</td>\n"; 1513 print "<td>     </td>\n"; 1514 print "<td align=right>$packets</td>\n"; 1515 print "<td>     </td>\n"; 1516 if ($rate_report) { print "<td align=right>$flow_rate</td>\n"; } 1517 if ($flow_analysis) { 1518 if ($rate_report) { print "<td>     </td>\n"; } 1519 print "<td align=right>$oct_per_flow</td>\n"; 1520 print "<td>     </td>\n"; 1521 print "<td align=right>$pkt_per_flow</td>\n"; 1522 if ($country_report) { 1523 print "<td>     </td>\n"; 1524 print "<td align=right>$as_country</td>\n"; 1525 } 1526 } 1527 print "</tr>\n"; 1528 1529 if (($stat_report > 0) && ($stat_report != 99)) { if (($line_count+1) > $cutoff_lines) { last; } } 1530} 1531close(SORTED_SAVE); 1532 1533print " <tr><td> </td></tr>"; 1534print " <tr><td> </td></tr>"; 1535print " </table>\n"; 1536print " </div>\n"; 1537 1538&create_UI_service("FlowViewer_Main","service_bottom",$active_dashboard,$filter_hash); 1539&finish_the_page("FlowViewer_Main"); 1540 1541# Remove intermediate files 1542 1543$rm_command = "rm $work_directory/FlowViewer_filter_$suffix"; 1544if ($debug_files ne "Y") { system($rm_command); } 1545$rm_command = "rm $work_directory/FlowViewer_output_$suffix"; 1546if ($debug_files ne "Y") { system($rm_command); } 1547$rm_command = "rm $work_directory/FlowViewer_scanner_$scan_suffix"; 1548if ($debug_files ne "Y") { system($rm_command); } 1549 1550# Subroutines 1551 1552sub print_error { 1553 1554 my ($error_text) = @_; 1555 print " <br>"; 1556 print " $error_text\n"; 1557 print " </div>\n"; 1558 &create_UI_service("FlowViewer_Main","service_bottom",$active_dashboard,$filter_hash); 1559 &finish_the_page("FlowViewer_Main"); 1560 exit; 1561} 1562 1563sub dig { 1564 my ($host_address) = @_; 1565 1566 $host_name = $host_address; 1567 1568 if (defined($host_names{$host_address})) { 1569 $host_name = $host_names{$host_address}; 1570 $length_name = length($host_name); 1571 if ($length_name > $dns_column_width) { 1572 $left_start = $length_name - $dns_column_width; 1573 $host_name = substr($host_name,$left_start,$dns_column_width); 1574 } 1575 } else { 1576 open(DIG,"$dig $host_address 2>&1|"); 1577 $answer_record = 0; 1578 while (<DIG>) { 1579 chop; 1580 if (/ANSWER SECTION/) { 1581 $answer_record = 1; 1582 next; 1583 } 1584 if ($answer_record) { 1585 ($in_addr,$rec_timeout,$rec_direction,$rec_type,$host_name) = split(/\s+/,$_); 1586 $last_period = rindex($host_name,"\."); 1587 $host_name = substr($host_name,0,$last_period); 1588 $length_name = length($host_name); 1589 if ($length_name > $dns_column_width) { 1590 $left_start = $length_name - $dns_column_width; 1591 $host_name = substr($host_name,$left_start,$dns_column_width); 1592 } 1593 if (/CNAME/) { $host_name = $host_address; } 1594 last; 1595 } 1596 } 1597 1598 if (length($host_name) < 1) { $host_name = $host_address; } 1599 $host_names{$host_address} = $host_name; 1600 } 1601 return $host_name; 1602} 1603 1604sub dig_as { 1605 1606 my ($host_address) = @_; 1607 $as_name = $host_address; 1608 1609 if (defined($as_names{$host_address})) { 1610 $as_name = $as_names{$host_address}; 1611 } else { 1612 open(DIG_AS,"dig +short AS$host_address.asn.cymru.com TXT 2>&1|"); 1613 $answer_record = 0; 1614 while (<DIG_AS>) { 1615 chomp; 1616 if (/[0-9]+ | [A-Z]+ |.*/) { 1617 s/"//g; 1618 ($as_number, $as_country, $as_rir, $as_date, $as_name) = split(/ \| /, $_); 1619 @as_info = split(/\s/, $as_name); 1620 $as_name = shift(@as_info); 1621 } 1622 } 1623 if ($as_name eq "") { $as_name = $host_address; } 1624 $as_names{$host_address} = $as_name; 1625 } 1626 return $as_name; 1627} 1628 1629sub dig_as_full { 1630 1631 my ($host_address) = @_; 1632 1633 ($a,$b,$c,$d) = split(/\./,$host_address); 1634 $reverse_address = $d .".". $c .".". $b .".". $a; 1635 1636 open(DIG_AS,"dig +short $reverse_address.origin.asn.cymru.com TXT 2>&1|"); 1637 while (<DIG_AS>) { 1638 chomp; 1639 if (/[0-9]+ | [A-Z]+ |.*/) { 1640 s/"//g; 1641 ($as_number, $ip_range, $as_country, $as_rir, $as_date) = split(/ \| /, $_); 1642 } 1643 } 1644 close (DIG_AS); 1645 1646 if ($as_number =~ / /) { ($as_number,$right_part) = split(/ /,$as_number); } 1647 $as_country = ""; $as_rir = ""; $as_date = ""; $as_name = ""; 1648 1649 open(DIG_AS,"dig +short AS$as_number.asn.cymru.com TXT 2>&1|"); 1650 while (<DIG_AS>) { 1651 chomp; 1652 if (/[0-9]+ | [A-Z]+ |.*/) { 1653 s/"//g; 1654 ($as_number, $as_country, $as_rir, $as_date, $as_name) = split(/ \| /, $_); 1655 } 1656 } 1657 close (DIG_AS); 1658 1659 $as_name = substr($as_name,0,$asn_width); 1660 return ($as_number,$as_country,$as_name); 1661} 1662 1663sub dig_if { 1664 1665 my ($if_number) = @_; 1666 $if_name = $if_number; 1667 1668 if ($device_name ne "") { 1669 $interfaces_file = "$cgi_bin_directory/NamedInterfaces_Devices"; 1670 } elsif ($exporter ne "") { 1671 $interfaces_file = "$cgi_bin_directory/NamedInterfaces_Exporters"; 1672 } 1673 1674 open (NAMED,"<$interfaces_file"); 1675 chomp (@interfaces = <NAMED>); 1676 close (NAMED); 1677 1678 foreach $interface (@interfaces) { 1679 if (($interface eq "") || (substr($interface,0,1) eq "#")) { next; } 1680 ($device,$interface_index,$interface_name) = split(/:/,$interface); 1681 if (($device eq $device_name) || ($device eq $exporter)) { 1682 if ($interface_index eq $if_number) { $if_name = $interface_name; } 1683 $found_device = 1; 1684 } 1685 } 1686 if ($found_device == 0) { $if_name = "NO_TRANSLATIONS"; } 1687 return $if_name; 1688} 1689 1690sub dig_ex { 1691 1692 my ($exporter_number) = @_; 1693 $exporter_name = $exporter_number; 1694 1695 foreach $exporter (@exporters) { 1696 ($exporter_ip,$exp_name) = split(/:/,$exporter); 1697 if ($exporter_number eq $exporter_ip) { $exporter_name = $exp_name; } 1698 } 1699 return $exporter_name; 1700} 1701