use IO::Socket::SSL qw(SSL_VERIFY_NONE); use strict; use warnings; use LWP::UserAgent; use JSON; use Data::Dumper; my $start_timer = time(); ################################################################# # CHANGE HERE ################################################################# my $authToken = ""; # Remember: You don't need a token if you are running this on # the Scrutinizer server my $scrut_server = 'https://10.1.4.189'; my $hours_back = 1; # Here you can enter in a host filter. Under Host Search Request # You will see two lines that are rem'd out. Turn these on to # Populate this option #my $host_filter = '192.168.1.1'; ################################################################# my ($rpt_options,$data_requested) = host_search_request( start_epoch => $^T - ($hours_back * 60 * 60), end_epoch => $^T, #ip_address => $host_filter, ); my $report_data = get_scrutinizer_data( rpt_options => $rpt_options, data_requested => $data_requested, ); my $formatted_data = format_report_data( report_data => $report_data ); my $end_timer = time(); my $elapse_timer = $end_timer - $start_timer; print $formatted_data; #print "Elapse time: $elapse_timer seconds\n"; # ---------------------------------------------------------------------- sub format_report_data{ my %args = @_; my $report_data = $args{'report_data'}; my $formatted_data = ''; my $row_count = $report_data->{'report'}->{'table'}->{'inbound'}->{'totalRowCount'} || 0; my $columns = $report_data->{'report'}->{'table'}->{'inbound'}->{'columns'} || []; my $rows = $report_data->{'report'}->{'table'}->{'inbound'}->{'rows'} || []; # This lets us reference rows by element name instead of needing to know the index my %indices; my $index_counter = 0; foreach my $c(@{$columns}){ $indices{$c->{'elementName'}} = $index_counter; $index_counter++; } $formatted_data .= "There were $row_count results found\n"; foreach my $row(@{$rows}){ my ( ### Here you need to set up an element variable to call ### this variable will be populated below and will be ### called in $formatted_data $src_ip, $dst_ip, $bytes, $first_flow_ts, $last_flow_ts ) = ( ## Here is where we populate the hash with the flow elements ## $row->[$indices{'sourceipaddress'}]->{'label'}, $row->[$indices{'destinationipaddress'}]->{'label'}, $row->[$indices{'sum_octetdeltacount'}]->{'label'}, # Here is where we populate the hash with an EPOCH timestamp $row->[$indices{'first_flow_epoch'}]->{'label'}, $row->[$indices{'last_flow_epoch'}]->{'label'}, # This is an example of how you can format it in local readable time #scalar(localtime($row->[$indices{'first_flow_epoch'}]->{'label'})), #scalar(localtime($row->[$indices{'last_flow_epoch'}]->{'label'})), ); ### Here is where we format the line data. This is what is what will be sent to the ### screen. You can pipe it to a csv file EXAMPLE: perl [SCRIPT NAME] > "[CSV FILENAME]_$(date '+%y-%m-%d').csv" $formatted_data .= qq{$first_flow_ts,$last_flow_ts,$src_ip, $dst_ip, $bytes\n}; } return $formatted_data; } sub get_scrutinizer_data{ my %args = @_; my $rpt_options = $args{'rpt_options'}; my $data_requested = $args{'data_requested'}; my $ua = LWP::UserAgent->new( 'agent' => '', timeout => 7200, 'ssl_opts' => { verify_hostname => 0, SSL_verify_mode => SSL_VERIFY_NONE, }, ); $ua->agent("Mozilla/6.0"); $ua->env_proxy(); my $parameters = { rm => 'report_api', authToken => $authToken, action => 'get', rpt_json => encode_json($rpt_options), data_requested => encode_json($data_requested), }; my $response = $ua->post("$scrut_server/fcgi/scrut_fcgi.fcgi", $parameters); my $report_data; if ($response->is_success) { return $report_data = decode_json($response->content); } else { die "Error with request: ".$response->status_line; } } sub host_search_request{ my %args = @_; my $start_epoch = $args{'start_epoch'}; my $end_epoch = $args{'end_epoch'}; my $ip_address = $args{'ip_address'}; ### Here is where you add your json filters. You can find them in any report by clicking on ### the [Report Details] button in the left section of the report screen, right under ### devices used my $rpt_options = { reportTypeLang => "host2host", reportDirections => { selected => "inbound" }, dataGranularity => { selected => 1 }, times => { dateRange => "Custom", start => $start_epoch, end => $end_epoch }, filters => { # There has to be at least one sdfDips filter. sdfDips filters are # used to indicate which exporter/interface we want to use for the report. # sdfDips are defined like this: "in_[IP_OF_EXPORTER_IN_HEX]_[TEMPLATE_ID] # This information is located under the json tab under [Report Details] # sdfDips_0 => "in_408CF386_408CF386-4 sdfDips_0 => "in_GROUP_ALL", # sdfIps_0 => "in_".$ip_address."_Both", # #sdfIPGroups_0 => "in_16800001_both", }, rateTotal => { selected => "total" }, bbp => { selected => "bytes", }, }; my $data_requested = { inbound => { table => { query_limit => { # Here is where we determine the number of rows to return. # This is a required filter but can be a really high number # if need. REMEMBER: The more rows you return the longer # the report is going to take to generate. # The offset is for pagination. If you ask for 1000 rowns # with an offset of 1000 you will get 1000 - 2000 offset => 0, max_num_rows => 1000 } } } }; return ($rpt_options,$data_requested); }