1#!/usr/local/bin/perl
2#
3#  Purpose:
4#  FlowMonitor_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#
47#  Notes:
48#  1. It is a good idea to retain the host_names GDBM file (names), even if it
49#     gets large, since it is up to 1000 times faster than using 'dig'.
50#
51#  Modification history:
52#  Author       Date            Vers.   Description
53#  -----------------------------------------------------------------------
54#  J. Loiacono  07/04/2005      1.0     Original version.
55#  J. Loiacono  01/01/2006      2.0     FlowGrapher, new functions, speed
56#  J. Loiacono  01/16/2006      2.1     Fixed compute of concatenation date
57#  J. Loiacono  01/26/2006      2.2     New flow_select option for inclusion
58#  J. Loiacono  07/04/2006      3.0     Renamed for re-organization
59#                                       Single script for GDBM/NDBM (thanks Ed Ravin)
60#  J. Loiacono  12/25/2006      3.1     [No Change to this module]
61#  J. Loiacono  02/14/2007      3.2     [No Change to this module]
62#  J. Loiacono  12/07/2007      3.3     Sampling Multiplier, Pie Charts
63#                                       AS resolving (thanks Sean Cardus)
64#                                       Named IFs, Unit Conv. (thanks C. Kishimoto)
65#  J. Loiacono  12/15/2007      3.3.1   New $no_devices ... parameter
66#  J. Loiacono  03/17/2011      3.4     Support for change of device w/o reset
67#                                       Support for meaningful Save report names
68#                                       Concatenation now includes 'temp' files
69#                                       Dynamic Resolved column width, flows/sec
70#  J. Loiacono  05/08/2012      4.0     Major upgrade for IPFIX/v9 using SiLK,
71#                                       New User Interface
72#  J. Loiacono  02/14/2013      4.0     Fixed error when directories not created
73#  J. Loiacono  07/14/2013      4.2     FlowMonitor was accepting SiLK excluded
74#                                       capabilities (e.g., Protocols)
75#  J. Loiacono  09/11/2013      4.2.1   Minor formatting changes
76#                                       Mods for international date formatting
77#  J. Loiacono  07/04/2014      4.4     Multiple dashboards
78#  J. Loiacono  11/02/2014      4.5     FlowTracker to FlowMonitor rename
79#
80#$Author$
81#$Date$
82#$Header$
83#
84###########################################################################
85#
86#               BEGIN EXECUTABLE STATEMENTS
87#
88
89use FlowViewer_Configuration;
90use FlowViewer_Utilities;
91use FlowViewer_UI;
92use File::stat;
93
94if ($debug_monitor eq "Y") { open (DEBUG,">>$work_directory/DEBUG_MONITOR"); }
95
96# Retrieve parameters
97
98($active_dashboard,$action,$monitor_label,$device_revision) = split(/\^/,$ENV{'QUERY_STRING'});
99if ($action eq "Revise")  { $action = "Revise Monitor"; }
100if ($device_revision ne "") { ($device_revision,$device_name_revision) = split(/=/,$device_revision); } chop($device_name_revision);
101$monitor_label =~ s/~/ /g;
102
103if ($debug_monitor eq "Y") { print DEBUG "In FlowMonitor_main.cgi action: $action\n"; }
104if ($debug_monitor eq "Y") { print DEBUG "monitor_label: $monitor_label  device_revision: $device_revision\n"; }
105
106read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
107@pairs = split(/&/, $buffer);
108foreach $pair (@pairs) {
109    ($name, $value) = split(/=/, $pair);
110    $value =~ tr/+/ /;
111    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
112    $FORM{$name} = $value;
113}
114
115# Clean up input
116
117($ft_link,$FORM{device_name}) = split(/DDD/,$FORM{device_name});
118($ft_link,$FORM{exporter})    = split(/EEE/,$FORM{exporter});
119
120$FORM{start_date}     =~ s/\s+//g; $FORM{start_date}     =~ s/,/, /g;
121$FORM{start_time}     =~ s/\s+//g; $FORM{start_time}     =~ s/,/, /g;
122$FORM{source_address} =~ s/\s+//g; $FORM{source_address} =~ s/,/, /g;
123$FORM{source_port}    =~ s/\s+//g; $FORM{source_port}    =~ s/,/, /g;
124$FORM{source_if}      =~ s/\s+//g; $FORM{source_if}      =~ s/,/, /g;
125$FORM{source_as}      =~ s/\s+//g; $FORM{source_as}      =~ s/,/, /g;
126$FORM{dest_address}   =~ s/\s+//g; $FORM{dest_address}   =~ s/,/, /g;
127$FORM{dest_port}      =~ s/\s+//g; $FORM{dest_port}      =~ s/,/, /g;
128$FORM{dest_if}        =~ s/\s+//g; $FORM{dest_if}        =~ s/,/, /g;
129$FORM{dest_as}        =~ s/\s+//g; $FORM{dest_as}        =~ s/,/, /g;
130$FORM{protocols}      =~ s/\s+//g; $FORM{protocols}      =~ s/,/, /g;
131$FORM{tos_fields}     =~ s/\s+//g; $FORM{tos_fields}     =~ s/,/, /g;
132$FORM{tcp_flags}      =~ s/\s+//g; $FORM{tcp_flags}      =~ s/,/, /g;
133$FORM{nexthop_ip}     =~ s/\s+//g; $FORM{nexthop_ip}     =~ s/,/, /g;
134$FORM{sif_name}       =~ s/,/, /g;
135$FORM{dif_name}       =~ s/,/, /g;
136$FORM{flow_select}    = 1;
137
138# Determine if user is providing a start time to request a FlowMonitor_Recreate
139
140if ($action ne "Revise Monitor") {
141
142	if ($time_zone eq "") {
143	        open(DATE,"date 2>&1|");
144	        while (<DATE>) {
145	                ($d_tz,$m_tz,$dt_tz,$t_tz,$time_zone,$y_tz) = split(/\s+/,$_);
146	        }
147	}
148
149	# Convert into US date format for internal processing
150
151	if    ($date_format eq "DMY")  { ($temp_day_s,$temp_mnth_s,$temp_yr_s) = split(/\//,$FORM{start_date}); }
152	elsif ($date_format eq "DMY2") { ($temp_day_s,$temp_mnth_s,$temp_yr_s) = split(/\./,$FORM{start_date}); }
153	elsif ($date_format eq "YMD")  { ($temp_yr_s,$temp_mnth_s,$temp_day_s) = split(/\-/,$FORM{start_date}); }
154	else                           { ($temp_mnth_s,$temp_day_s,$temp_yr_s) = split(/\//,$FORM{start_date}); }
155
156	$recreate_start = $temp_mnth_s ."/". $temp_day_s ."/". $temp_yr_s;
157
158	if ($debug_monitor 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"; }
159
160	$start_epoch   = date_to_epoch($recreate_start,$FORM{start_time},$time_zone);
161	$current_epoch = time - $start_offset;
162	$delta_epoch   = $current_epoch - $start_epoch;
163
164	if ($delta_epoch < 7200) {
165		$FORM{'start_date'}   = "01/01/2000";
166		$FORM{'start_time'}   = "00:00:00";
167		$FORM{'end_date'}     = "01/01/2000";
168		$FORM{'end_time'}     = "00:00:00";
169	} else {
170		$recreate = 1;
171	}
172} else {
173	$FORM{'start_date'}   = "01/01/2000";
174	$FORM{'start_time'}   = "00:00:00";
175	$FORM{'end_date'}     = "01/01/2000";
176	$FORM{'end_time'}     = "00:00:00";
177}
178
179# Parameters for generating a FlowMonitor report
180
181$active_dashboard    = $FORM{'active_dashboard'};
182$device_name         = $FORM{'device_name'};
183$flow_select         = $FORM{'flow_select'};
184$start_date          = $FORM{'start_date'};
185$start_time          = $FORM{'start_time'};
186$end_date            = $FORM{'end_date'};
187$end_time            = $FORM{'end_time'};
188$source_addresses    = $FORM{'source_address'};
189$source_ports        = $FORM{'source_port'};
190$source_ifs          = $FORM{'source_if'};
191$sif_names           = $FORM{'sif_name'};
192$source_ases         = $FORM{'source_as'};
193$dest_addresses      = $FORM{'dest_address'};
194$dest_ports          = $FORM{'dest_port'};
195$dest_ifs            = $FORM{'dest_if'};
196$dif_names           = $FORM{'dif_name'};
197$dest_ases           = $FORM{'dest_as'};
198$protocols           = $FORM{'protocols'};
199$tcp_flags           = $FORM{'tcp_flags'};
200$tos_fields          = $FORM{'tos_fields'};
201$exporter            = $FORM{'exporter'};
202$nexthop_ips         = $FORM{'nexthop_ip'};
203$sampling_multiplier = $FORM{'sampling_multiplier'};
204$monitor_label      = $FORM{'monitor_label'};
205$monitor_type       = $FORM{'monitor_type'};
206$general_comment     = $FORM{'general_comment'};
207$alert_threshold     = $FORM{'alert_threshold'};
208$alert_frequency     = $FORM{'alert_frequency'};
209$alert_destination   = $FORM{'alert_destination'};
210$revision_comment    = $FORM{'revision_comment'};
211$notate_graphs       = $FORM{'notate_graphs'};
212$silk_rootdir        = $FORM{'silk_rootdir'};
213$silk_class          = $FORM{'silk_class'};
214$silk_flowtype       = $FORM{'silk_flowtype'};
215$silk_type           = $FORM{'silk_type'};
216$silk_sensors        = $FORM{'silk_sensors'};
217$silk_switches       = $FORM{'silk_switches'};
218
219# Convert into US date format for internal processing
220
221if    ($date_format eq "DMY")  { ($temp_day_s,$temp_mnth_s,$temp_yr_s) = split(/\//,$FORM{start_date}); }
222elsif ($date_format eq "DMY2") { ($temp_day_s,$temp_mnth_s,$temp_yr_s) = split(/\./,$FORM{start_date}); }
223elsif ($date_format eq "YMD")  { ($temp_yr_s,$temp_mnth_s,$temp_day_s) = split(/\-/,$FORM{start_date}); }
224else                           { ($temp_mnth_s,$temp_day_s,$temp_yr_s) = split(/\//,$FORM{start_date}); }
225
226$start_date = $temp_mnth_s ."/". $temp_day_s ."/". $temp_yr_s;
227
228if ($debug_monitor 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"; }
229
230$monitor_file = $monitor_label;
231$monitor_file =~ s/^\s+//;
232$monitor_file =~ s/\s+$//;
233$monitor_file =~ s/\&/-/g;
234$monitor_file =~ s/\//-/g;
235$monitor_file =~ s/\(/-/g;
236$monitor_file =~ s/\)/-/g;
237$monitor_file =~ s/\./-/g;
238$monitor_file =~ s/\s+/_/g;
239$monitor_file =~ tr/[A-Z]/[a-z]/;
240
241$filter_file    = $filter_directory  ."/". $monitor_file .".fil";
242$group_file     = $filter_directory  ."/". $monitor_file .".grp";
243$rrdtool_file   = $rrdtool_directory ."/". $monitor_file .".rrd";
244
245$html_directory = $monitor_directory ."/". $monitor_file;
246$html_file      = $html_directory ."/index.html";
247
248if ($debug_monitor eq "Y") {
249	print DEBUG " monitor_file: $monitor_file\n";
250	print DEBUG " monitor_type: $monitor_type\n";
251	print DEBUG "   filter_file: $filter_file\n";
252	print DEBUG "    group_file: $group_file\n";
253	print DEBUG "  rrdtool_file: $rrdtool_file\n";
254	print DEBUG "html_directory: $html_directory\n";
255	print DEBUG "     html_file: $html_file\n";
256}
257
258# Make the Filter directory if it doesn't exist
259
260if (!-e $filter_directory) {
261
262        mkdir $filter_directory, $filter_dir_perms || die "Cannot mkdir Monitor Filter Directory: $filter_directory: $!";
263        chmod $filter_dir_perms, $filter_directory;
264
265	&create_UI_top($active_dashboard);
266	&create_UI_service("FlowMonitor_Main","service_top",$active_dashboard,$filter_hash);
267	&create_UI_sides($active_dashboard);
268	print " <div id=content>\n";
269	print " <br>\n";
270	print " <table>\n";
271	print " <tr><td>The directory for storing Monitor Filter files has been created:</td></tr>\n";
272	print " <tr><td></td></tr>\n";
273	print " <tr><td><i>$filter_directory</i></td></tr>\n";
274	print " <tr><td></td></tr>\n";
275	print " <tr><td>Please ensure this directory has adequate permissions for your</td></tr>\n";
276	print " <tr><td>web server process owner (e.g., 'apache') to write into it.</td></tr>\n";
277	print " </table>\n";
278	print " </div>\n";
279
280	&create_UI_service("FlowMonitor_Main","service_bottom",$active_dashboard,$filter_hash);
281	&finish_the_page("FlowMonitor_Main");
282	exit;
283}
284
285# Make the RRDtool directory if it doesn't exist
286
287if (!-e $rrdtool_directory) {
288
289        mkdir $rrdtool_directory, $rrd_dir_perms || die "Cannot mkdir Monitor RRDtool directory: $rrdtool_directory: $!";
290        chmod $rrd_dir_perms, $rrdtool_directory;
291
292	&create_UI_top($active_dashboard);
293	&create_UI_service("FlowMonitor_Main","service_top",$active_dashboard,$filter_hash);
294	&create_UI_sides($active_dashboard);
295	print " <div id=content>\n";
296	print " <br>\n";
297	print " <table>\n";
298	print " <tr><td>The directory for storing Monitor RRDtool files has been created:</td></tr>\n";
299	print " <tr><td></td></tr>\n";
300	print " <tr><td><i>$rrdtool_directory</i></td></tr>\n";
301	print " <tr><td></td></tr>\n";
302	print " <tr><td>Please ensure this directory has adequate permissions for your</td></tr>\n";
303	print " <tr><td>web server process owner (e.g., 'apache') to write into it.</td></tr>\n";
304	print " </table>\n";
305	print " </div>\n";
306
307	&create_UI_service("FlowMonitor_Main","service_bottom",$active_dashboard,$filter_hash);
308	&finish_the_page("FlowMonitor_Main");
309}
310
311if (($monitor_type ne "Group") && (($no_devices_or_exporters eq "N") && (($device_name eq "") && ($exporter eq "")))) {
312
313	&create_UI_top($active_dashboard);
314	&create_UI_service("FlowMonitor_Main","service_top",$active_dashboard,$filter_hash);
315	&create_UI_sides($active_dashboard);
316	print " <div id=content>\n";
317	print " <span class=text16>FlowMonitor: $monitor_label</span>\n";
318	print " <center>\n";
319	print " <br><br>\n";
320	print " <table>\n";
321        print "  <tr><td colspan=2>Must select a device or an exporter. <p>Use the \"Back\" button to preserve inputs</td></tr>\n";
322	print " </table>\n";
323	print " </div>\n";
324
325	&create_UI_service("FlowMonitor_Main","service_bottom",$active_dashboard,$filter_hash);
326	&finish_the_page("FlowMonitor_Main");
327	exit;
328}
329
330# Determine if we are looking at an IPFIX device
331
332$IPFIX = 0;
333foreach $ipfix_device (@ipfix_devices) {
334        if ($device_name eq $ipfix_device) { $IPFIX = 1; if ($debug_monitor eq "Y") { print DEBUG "This device is exporting IPFIX\n";} }
335}
336
337if ($action eq "Revise Monitor") {
338
339	&create_UI_top($active_dashboard);
340	&create_UI_service("FlowMonitor_Main","service_top",$active_dashboard,$filter_hash);
341	&create_UI_sides($active_dashboard);
342	print " <div id=content_scroll>\n";
343	print "  <span class=text16>FlowMonitor: $monitor_label</span>\n";
344	print "  <table>\n";
345	print "  <tr><td>&nbsp</td></tr>\n";
346        print "  <tr><td width=500 align=left><font color=#CF7C29><b>Old Filtering Criteria:</b></font></td></tr>\n";
347	print "  <tr><td>&nbsp</td></tr>\n";
348
349        open  (OLD_FILTER,"<$filter_file");
350        while (<OLD_FILTER>) {
351                chop;
352                $key = substr($_,0,8);
353                if ($key eq " input: ") {
354                        ($input,$field,$field_value) = split(/: /);
355                        if ($field eq "revision") {
356                                push (@revisions,$field_value);
357                                ($old_notate_graphs,$old_revision_date,$old_revision_comment) = split(/\|/,$field_value);
358				$revision_date_out = epoch_to_date($old_revision_date,"LOCAL");
359                                $revision_date_out =~ s/\^/:/g;
360                                print "  <tr><td align=left>revision: $old_notate_graphs | $revision_date_out | $old_revision_comment</td></tr>\n";
361                        } else {
362				s/input: //;
363                                print "  <tr><td align=left>$_</td></tr>\n";
364                        }
365                }
366        }
367        close (OLD_FILTER);
368
369        if ($IPFIX) {
370                open (NEW_FILTER,">$filter_file") || die "cannot open Filter file for write: $filter_file";
371        } else {
372                create_filter_file (%FORM, $filter_file);
373        }
374
375        open (NEW_FILTER,">>$filter_file");
376        print NEW_FILTER "\n\n";
377        print NEW_FILTER " input: monitor_type: $monitor_type\n";
378        print NEW_FILTER " input: device_name: $device_name\n";
379        print NEW_FILTER " input: monitor_label: $monitor_label\n";
380        print NEW_FILTER " input: general_comment: $general_comment\n";
381        print NEW_FILTER " input: source_addresses: $source_addresses\n";
382        print NEW_FILTER " input: source_ports: $source_ports\n";
383        print NEW_FILTER " input: source_ifs: $source_ifs\n";
384        print NEW_FILTER " input: sif_names: $sif_names\n";
385        print NEW_FILTER " input: source_ases: $source_ases\n";
386        print NEW_FILTER " input: dest_addresses: $dest_addresses\n";
387        print NEW_FILTER " input: dest_ports: $dest_ports\n";
388        print NEW_FILTER " input: dest_ifs: $dest_ifs\n";
389        print NEW_FILTER " input: dif_names: $dif_names\n";
390        print NEW_FILTER " input: dest_ases: $dest_ases\n";
391        print NEW_FILTER " input: protocols: $protocols\n";
392        print NEW_FILTER " input: tos_fields: $tos_fields\n";
393        print NEW_FILTER " input: tcp_flags: $tcp_flags\n";
394        print NEW_FILTER " input: exporter: $exporter\n";
395        print NEW_FILTER " input: nexthop_ips: $nexthop_ips\n";
396        print NEW_FILTER " input: sampling_multiplier: $sampling_multiplier\n";
397        print NEW_FILTER " input: alert_threshold: $alert_threshold\n";
398        print NEW_FILTER " input: alert_frequency: $alert_frequency\n";
399        print NEW_FILTER " input: alert_destination: $alert_destination\n";
400        print NEW_FILTER " input: alert_last_notified: \n";
401        print NEW_FILTER " input: alert_consecutive: \n";
402        print NEW_FILTER " input: IPFIX: $IPFIX\n";
403        print NEW_FILTER " input: silk_rootdir: $silk_rootdir\n";
404        print NEW_FILTER " input: silk_class: $silk_class\n";
405        print NEW_FILTER " input: silk_flowtype: $silk_flowtype\n";
406        print NEW_FILTER " input: silk_type: $silk_type\n";
407        print NEW_FILTER " input: silk_sensors: $silk_sensors\n";
408        print NEW_FILTER " input: silk_switches: $silk_switches\n";
409
410        foreach $revision (@revisions) {
411                print NEW_FILTER " input: revision: $revision\n";
412        }
413
414        # Need to determine revision date/time as it will apply to next collection
415
416        open (INFO,">$work_directory/FlowMonitor_Management_info");
417        $rrd_info_command = "$rrdtool_bin_directory/rrdtool info $rrdtool_file > $work_directory/FlowMonitor_Management_info";
418        system($rrd_info_command);
419
420        open (INFO,"<$work_directory/FlowMonitor_Management_info");
421        while (<INFO>) {
422                chop;
423                $lead = substr($_,0,11);
424                if ($lead eq "last_update") {
425                        ($lead,$last_update) = split(/ = /);
426                }
427        }
428        close (INFO);
429
430        print NEW_FILTER " input: revision: $notate_graphs|$last_update|$revision_comment\n";
431        close (NEW_FILTER);
432
433	print "  <tr><td>&nbsp</td></tr>\n";
434        print "  <tr><td align=left><font color=#CF7C29><b>New Filtering Criteria:</b></font></td></tr>\n";
435	print "  <tr><td>&nbsp</td></tr>\n";
436
437        open  (NEW_FILTER,"<$filter_file");
438        while (<NEW_FILTER>) {
439                $key = substr($_,0,8);
440                if ($key eq " input: ") {
441                        ($input,$field,$field_value) = split(/: /);
442                        if ($field eq "revision") {
443                                ($new_notate_graphs,$revision_date,$new_revision_comment) = split(/\|/,$field_value);
444                                ($notate_graphs,$revision_date,$revision_comment) = split(/\|/,$field_value);
445                                $revision_date_out = epoch_to_date($revision_date,"LOCAL");
446                                $revision_date_out =~ s/\^/:/g;
447                                print "  <tr><td align=left>revision: $new_notate_graphs | $revision_date_out | $new_revision_comment</td></tr>\n";
448                        } else {
449				s/input: //;
450                                print "  <tr><td align=left>$_</td></tr>\n";
451                        }
452                }
453        }
454        close (NEW_FILTER);
455
456	print "  <tr><td>&nbsp</td></tr>\n";
457	print "  </table>";
458
459        print "  <table>\n";
460        print "  <tr><td>&nbsp</td></tr>\n";
461        print "  <tr><td><form method=post action=\"$cgi_bin_short/FlowMonitor_Management.cgi?$active_dashboard^List\">\n";
462        print "  <button class=links type=submit>Return</button></form></td></tr>\n";
463        print "  </table>\n";
464        print "  </div>\n";
465
466	&create_UI_service("FlowMonitor_Main","service_bottom",$active_dashboard,$filter_hash);
467	&finish_the_page("FlowMonitor_Main");
468
469	exit;
470}
471
472if ($monitor_label eq "") {
473
474	&create_UI_top($active_dashboard);
475	&create_UI_service("FlowMonitor_Main","service_top",$active_dashboard,$filter_hash);
476	&create_UI_sides($active_dashboard);
477	print " <div id=content>\n";
478	print " <span class=text16>FlowMonitor: $monitor_label</span>\n";
479	print " <center>\n";
480	print " <br>\n";
481	print " <table>\n";
482        print "  <tr><td colspan=2>You must provide a Monitor Label which will be the title of your monitor.</td></tr>\n";
483	print " </table>\n";
484	print " </div>\n";
485
486	&create_UI_service("FlowMonitor_Main","service_bottom",$active_dashboard,$filter_hash);
487	&finish_the_page("FlowMonitor_Main");
488	exit;
489}
490
491if ($recreate) {
492
493	# Cannot Recreate a Group
494
495	if ($monitor_type eq "Group") {
496
497		&create_UI_top($active_dashboard);
498		&create_UI_service("FlowMonitor_Main","service_top",$active_dashboard,$filter_hash);
499		&create_UI_sides($active_dashboard);
500		print " <div id=content>\n";
501		print " <span class=text16>FlowMonitor: $monitor_label</span>\n";
502		print " <center>\n";
503		print " <br>\n";
504		print " <table>\n";
505        	print "  <tr><td>&nbsp</td></tr>\n";
506                print "  <tr><td>Recreates are permitted for Individual FlowMonitors only. New Groups will extend\n";
507                print "back in time as far back as the existing component Individual FlowMonitors already go. They\n";
508                print "will appear fully with the next run of FlowGrapher. If you wish to Recreate a Group from new\n";
509		print "FlowMonitors, Recreate the Individual FlowMonitors first.\n";
510		print " </td></tr>\n";
511		print " </table>\n";
512
513        	print "  <table>\n";
514        	print "  <tr><td>&nbsp</td></tr>\n";
515        	print "  <tr><td><form method=post action=\"$cgi_bin_short/FlowMonitor.cgi?$active_dashboard\">\n";
516        	print "  <button class=links type=submit>Return</button></form></td></tr>\n";
517        	print "  </table>\n";
518
519		print " </div>\n";
520		&create_UI_service("FlowMonitor_Main","service_bottom",$active_dashboard,$filter_hash);
521		&finish_the_page("FlowMonitor_Main");
522
523                exit;
524	}
525
526	# Make sure this is not a duplicate of an existing FlowMonitor
527
528	while ($existing_filter = <$filter_directory/*>) {
529
530	        if ($filter_file eq $existing_filter) {
531
532	                $match = 1;
533
534			&create_UI_top($active_dashboard);
535			&create_UI_service("FlowMonitor_Main","service_top",$active_dashboard,$filter_hash);
536			&create_UI_sides($active_dashboard);
537			print " <div id=content>\n";
538			print " <span class=text16>FlowMonitor: $monitor_label</span>\n";
539			print " <center>\n";
540			print " <br>\n";
541			print " <table>\n";
542	        	print "  <tr><td>&nbsp</td></tr>\n";
543	                print "  <tr><td colspan=2>An existing Filter file has been found with the same Monitor label.</td></tr>\n";
544	        	print "  <tr><td>&nbsp</td></tr>\n";
545	                print "  <tr><td width=140 align=right><b>Monitor Label: &nbsp&nbsp</b></td><td align=left><font color=$filename_color><b><i>$monitor_label</i></b></font></td></tr>\n";
546	        	print "  <tr><td>&nbsp</td></tr>\n";
547	                print "  <tr><td width=140 align=right><b>Monitor Filter File: &nbsp&nbsp</b></td><td align=left><font color=$filename_color><b><i>$filter_file</i></b></font></td></tr>\n";
548	        	print "  <tr><td>&nbsp</td></tr>\n";
549			print " </table>\n";
550			print " <table>\n";
551	                print "  <tr><td>If you wish to replace the existing Monitor, please remove the existing one\n";
552	                print "first, and resubmit the FlowMonitor form. Or, if you wish to continue an existing\n";
553	                print "Monitor, but with new filtering criteria, visit the Manage All FlowMonitors page\n";
554	                print "and select the \'Revise\' option from the entry in the list of FlowMonitors.\n";
555			print " </td></tr>\n";
556			print " </table>\n";
557			print " </div>\n";
558
559			&create_UI_service("FlowMonitor_Main","service_bottom",$active_dashboard,$filter_hash);
560			&finish_the_page("FlowMonitor_Main");
561
562	                exit;
563	        }
564	}
565
566	$saved_suffix = &get_suffix;
567	$save_file = "$work_directory/FlowMonitor_Recreate_saved_$saved_suffix";
568	$filter_hash = "FM_FlowMonitor_Recreate_saved_$saved_suffix";
569	start_saved_file($save_file);
570
571	$recreate_command = "$cgi_bin_directory/FlowMonitor_Recreate $save_file &";
572	system($recreate_command);
573
574	&create_UI_top($active_dashboard);
575	&create_UI_service("FlowMonitor_Main","service_top",$active_dashboard,$filter_hash);
576	print " <div id=content_wide>\n";
577	&create_filter_output("FlowMonitor_Main",$filter_hash);
578	print " <center>\n";
579	print " <br>\n";
580	print " <table>\n";
581	print "  <br>\n";
582        print "  <tr><td colspan=3>You have successfully started a <b><i>FlowMonitor Recreate</i></b>. The graphs for this new FlowMonitor will appear after the first</td></tr>\n";
583        print "  <tr><td colspan=3>FlowMonitor_Grapher run after the Recreate completes. The Recreate is running in the background and you may continue</td></tr>\n";
584        print "  <tr><td colspan=3>using FlowViewer. Longer Recreate timeframes will result in longer runs and the FlowMonitor will be available somewhat later.</td></tr>\n";
585       	print "  <tr><td>&nbsp</td></tr>\n";
586       	print "  <tr><td>&nbsp</td></tr>\n";
587        print "  <tr><td width=140 align=right><b>Monitor Label: &nbsp&nbsp</td><td align=left><b><font color=$filename_color><b><i>$monitor_label</i></b></font></td></tr>\n";
588        print "  <tr><td width=140 align=right><b>Filter File: &nbsp&nbsp</td><td align=left><b><font color=$filename_color><b><i>$filter_file</i></b></font></td></tr>\n";
589        print "  <tr><td width=140 align=right><b>RRDtool Database: &nbsp&nbsp<b></td><td align=left><font color=$filename_color><b><i>$rrdtool_file</i></b></font></td></tr>\n";
590        print "  <tr><td width=140 align=right><b>HTML Directory: &nbsp&nbsp<b></td><td align=left><font color=$filename_color><b><i>$html_directory</i></b></font></td></tr>\n\n";
591	print " </table>\n";
592	print " </div>\n";
593
594	&create_UI_service("FlowMonitor_Main","service_bottom",$active_dashboard,$filter_hash);
595	&finish_the_page("FlowMonitor_Main");
596	exit;
597}
598
599# Start up the Saved file
600
601$saved_suffix = &get_suffix;
602$saved_hash   = "FlowMonitor_save_$saved_suffix";
603$filter_hash  = "FM_$saved_hash";
604$saved_html   = "$work_directory/$saved_hash";
605&start_saved_file($saved_html);
606
607# Start the FlowMonitor Report web page output
608
609&create_UI_top($active_dashboard);
610&create_UI_service("FlowMonitor_Main","service_top",$active_dashboard,$filter_hash);
611
612# If this is a group monitor, bring up Group Monitor input page
613
614if ($monitor_type eq "Group") {
615
616        # Compare Monitor Label to existing Monitors
617
618        while ($existing_filter = <$filter_directory/*>) {
619
620                if ($filter_file eq $existing_filter) {
621
622			&create_UI_sides($active_dashboard);
623			print " <div id=content>\n";
624			print " <span class=text16>FlowMonitor: $monitor_label</span>\n";
625			print " <center>\n";
626			print " <br>\n";
627			print " <table>\n";
628	      	  	print "  <tr><td>&nbsp</td></tr>\n";
629	                print "  <tr><td colspan=2>An existing Filter file has been found with the same Monitor label.</td></tr>\n";
630	        	print "  <tr><td>&nbsp</td></tr>\n";
631	                print "  <tr><td align=right>Monitor Label: &nbsp&nbsp</td><td align=left><font color=#CF7C29><b><i>$monitor_label</i></b></font></td></tr>\n";
632	        	print "  <tr><td>&nbsp</td></tr>\n";
633	                print "  <tr><td align=right>Monitor Filter File: &nbsp&nbsp</td><td align=left><font color=#CF7C29><b><i>$filter_file</i></b></font></td></tr>\n";
634	        	print "  <tr><td>&nbsp</td></tr>\n";
635			print " </table>\n";
636			print " <table>\n";
637                	print "  <tr><td>If you wish to replace the existing Monitor with this Group, please \n";
638                	print "remove the existing one first, and resubmit the FlowMonitor form. Note that Group \n";
639                	print "and Individual monitors cannot have the same name. Or, if you wish to continue an \n";
640			print "existing Monitor, but with new filtering criteria, vistit the Manage All FlowMonitors\n";
641                	print "page (a pulldown) and select the \'Revise\' option from the entry in the list of Monitors\n";
642			print " </td></tr>\n";
643			print " </table>\n";
644			print " </div>\n";
645
646                        exit;
647                }
648        }
649
650        # Create the web page to hold the RRDtool graphs
651
652        if (!-e $html_directory) {
653                mkdir $html_directory, $html_dir_perms || die "cannot mkdir $html_directory: $!";
654                chmod $html_dir_perms, $html_directory;
655        }
656
657        # Initialize the filter group file
658
659        open (GROUP,">$group_file");
660        print GROUP " input: monitor_label: $monitor_label\n";
661        print GROUP " input: monitor_type: $monitor_type\n";
662        print GROUP " input: general_comment: $general_comment\n";
663        close (GROUP);
664
665        # Invoke the FlowMonitor_Group.cgi to collect group inputs
666
667        $action = "From FlowMonitor_Main";
668        $command_list = "$active_dashboard^$action+$monitor_label+$general_comment";
669        $command_list =~ s/ /~/g;
670        $invoke_command = "$cgi_bin_directory/FlowMonitor_Group.cgi $command_list";
671
672        system($invoke_command);
673
674        exit;
675}
676
677# For Individual monitors
678
679while ($existing_filter = <$filter_directory/*>) {
680
681        if ($filter_file eq $existing_filter) {
682
683                $match = 1;
684
685		&create_UI_sides($active_dashboard);
686		print " <div id=content>\n";
687		print " <span class=text16>FlowMonitor: $monitor_label</span>\n";
688		print " <center>\n";
689		print " <br>\n";
690		print " <table>\n";
691        	print "  <tr><td>&nbsp</td></tr>\n";
692                print "  <tr><td colspan=2>An existing Filter file has been found with the same Monitor label.</td></tr>\n";
693        	print "  <tr><td>&nbsp</td></tr>\n";
694                print "  <tr><td align=right>Monitor Label: &nbsp&nbsp</td><td align=left><font color=#CF7C29><b><i>$monitor_label</i></b></font></td></tr>\n";
695        	print "  <tr><td>&nbsp</td></tr>\n";
696                print "  <tr><td align=right>Monitor Filter File: &nbsp&nbsp</td><td align=left><font color=#CF7C29><b><i>$filter_file</i></b></font></td></tr>\n";
697        	print "  <tr><td>&nbsp</td></tr>\n";
698		print " </table>\n";
699		print " <table>\n";
700                print "  <tr><td>If you wish to replace the existing Monitor, please remove the existing one\n";
701                print "first, and resubmit the FlowMonitor form. Or, if you wish to continue an existing\n";
702                print "Monitor, but with new filtering criteria, visit the Manage All FlowMonitors page\n";
703                print "and select the \'Revise\' option from the entry in the list of FlowMonitors.\n";
704		print " </td></tr>\n";
705		print " </table>\n";
706		print " </div>\n";
707
708		&create_UI_service("FlowMonitor_Main","service_bottom",$active_dashboard,$filter_hash);
709		&finish_the_page("FlowMonitor_Main");
710
711                exit;
712        }
713}
714
715print " <div id=content_wide>\n";
716&create_filter_output("FlowMonitor_Main",$filter_hash);
717print " <center>\n";
718print " <br>\n";
719print " <table>\n";
720
721if (!$match) {
722
723        # Create the filter to match the input specifications
724
725	if ($IPFIX) {
726		open (FILTER,">$filter_file") || die "cannot open Filter file for write: $filter_file";
727		create_ipfix_filter;
728	} else {
729		create_filter_file (%FORM, $filter_file);
730	}
731
732        open (FILTER,">>$filter_file");
733        print FILTER "\n\n";
734        print FILTER " input: monitor_type: $monitor_type\n";
735        print FILTER " input: device_name: $device_name\n";
736        print FILTER " input: monitor_label: $monitor_label\n";
737        print FILTER " input: general_comment: $general_comment\n";
738        print FILTER " input: source_addresses: $source_addresses\n";
739        print FILTER " input: source_ports: $source_ports\n";
740        print FILTER " input: source_ifs: $source_ifs\n";
741        print FILTER " input: sif_names: $sif_names\n";
742        print FILTER " input: source_ases: $source_ases\n";
743        print FILTER " input: dest_addresses: $dest_addresses\n";
744        print FILTER " input: dest_ports: $dest_ports\n";
745        print FILTER " input: dest_ifs: $dest_ifs\n";
746        print FILTER " input: dif_names: $dif_names\n";
747        print FILTER " input: dest_ases: $dest_ases\n";
748        print FILTER " input: protocols: $protocols\n";
749        print FILTER " input: tos_fields: $tos_fields\n";
750        print FILTER " input: tcp_flags: $tcp_flags\n";
751        print FILTER " input: exporter: $exporter\n";
752        print FILTER " input: nexthop_ips: $nexthop_ips\n";
753        print FILTER " input: sampling_multiplier: $sampling_multiplier\n";
754        print FILTER " input: alert_threshold: $alert_threshold\n";
755        print FILTER " input: alert_frequency: $alert_frequency\n";
756        print FILTER " input: alert_destination: $alert_destination\n";
757        print FILTER " input: alert_last_notified: \n";
758        print FILTER " input: alert_consecutive: \n";
759        print FILTER " input: IPFIX: $IPFIX\n";
760        print FILTER " input: silk_rootdir: $silk_rootdir\n";
761        print FILTER " input: silk_class: $silk_class\n";
762        print FILTER " input: silk_flowtype: $silk_flowtype\n";
763        print FILTER " input: silk_type: $silk_type\n";
764        print FILTER " input: silk_sensors: $silk_sensors\n";
765        print FILTER " input: silk_switches: $silk_switches\n";
766
767        chmod $filter_file_perms, $filter_file;
768
769        # Create the RRDtool database for this Monitor
770
771        $start_rrd = time - (40 * 60);
772
773        $rrdtool_command =     "$rrdtool_bin_directory/rrdtool create $rrdtool_file ".
774                                "--step 300 ".
775                                "--start $start_rrd ".
776                                "DS:flowbits:GAUGE:600:U:U ".
777                                "RRA:AVERAGE:0.5:1:600 ".
778                                "RRA:AVERAGE:0.5:6:700 ".
779                                "RRA:AVERAGE:0.5:24:775 ".
780                                "RRA:AVERAGE:0.5:288:1100 ".
781                                "RRA:MAX:0.5:1:600 ".
782                                "RRA:MAX:0.5:6:700 ".
783                                "RRA:MAX:0.5:24:775 ".
784                                "RRA:MAX:0.5:288:1100";
785
786        system($rrdtool_command);
787        chmod $rrd_file_perms, $rrdtool_file;
788
789        # Create the Directory to hold the RRDtool graphs
790
791        if (!-e $html_directory) {
792                mkdir $html_directory, $html_dir_perms || die "cannot mkdir $html_directory: $!";
793                chmod $html_dir_perms, $html_directory;
794        }
795
796	print "  <br>\n";
797        print "  <tr><td>&nbsp</td><td colspan=2>You have successfully setup a new FlowMonitor. The graphs for this new</td></tr>\n";
798        print "  <tr><td>&nbsp</td><td colspan=2>FlowMonitor will appear after the next FlowGrapher run (e.g., < 5 minutes.)</td></tr>\n";
799       	print "  <tr><td>&nbsp</td></tr>\n";
800        print "  <tr><td align=right>Monitor Label: &nbsp&nbsp</td><td align=left><font color=#CF7C29><b><i>$monitor_label</i></b></font></td></tr>\n";
801        print "  <tr><td align=right>Filter File: &nbsp&nbsp</td><td align=left><font color=#CF7C29><b><i>$filter_file</i></b></font></td></tr>\n";
802        print "  <tr><td align=right>RRDtool Database: &nbsp&nbsp</td><td align=left><font color=#CF7C29><b><i>$rrdtool_file</i></b></font></td></tr>\n";
803        print "  <tr><td align=right>HTML Directory: &nbsp&nbsp</td><td align=left><font color=#CF7C29><b><i>$html_directory</i></b></font></td></tr>\n\n";
804}
805
806chmod $filter_file_perms, $filter_file;
807
808print " </table>\n";
809print " </div>\n";
810
811&create_UI_service("FlowMonitor_Main","service_bottom",$active_dashboard,$filter_hash);
812&finish_the_page("FlowMonitor_Main");
813