#
# old_revision [39c9f012ce8b82b4f02cb9b3e8a1cc5775b00f4f]
#
# patch "pf/conf/ui.conf"
#  from [754db03e72d1019e16845c586f054e35187dd7a0]
#    to [0c9b4100fe0d4ae4097bfe79b53a2444f8945cde]
# 
# patch "pf/html/admin/status/grapher.php"
#  from [18dfe328514b21827c4df9823d3ba5f4bd55765c]
#    to [b5ec51a45b52ee29d39f7ae70e02e626ca153c2c]
# 
# patch "pf/html/admin/status/reports.php"
#  from [309cdd669c4d812d7c838399ca1757caf86ace4e]
#    to [2483d4c5bdf2356f4d8d2c325c6efbcd2a191cdc]
# 
# patch "pf/lib/pf/pfcmd/help.pm"
#  from [b7dc1a244925947cb1373019a079d5728f5351ee]
#    to [117de21d6e855f50163582d9c73598cf4beea7f5]
# 
# patch "pf/lib/pf/pfcmd/report.pm"
#  from [bf061b52bc7bd0bbdb4fad9326607268836b96df]
#    to [981e74e03f9d2cd29c61ae7e1de8b642884c1709]
# 
# patch "pf/lib/pf/pfcmd.pm"
#  from [a6fc36f5ea1e6021125213ae8dbaa3ef59b9a2a3]
#    to [9d509164702942249355ac4f73f1cd272ba71381]
#
============================================================
--- pf/conf/ui.conf	754db03e72d1019e16845c586f054e35187dd7a0
+++ pf/conf/ui.conf	0c9b4100fe0d4ae4097bfe79b53a2444f8945cde
@@ -44,7 +44,7 @@ networks=Networks
 networks=Networks
 
 [ui.status.reports]
-display=ipmachistory,locationhistoryswitch,locationhistorymac,ifoctetshistoryswitch,ifoctetshistorymac,ifoctetshistoryuser,active,inactive,registered,unregistered,os,osclass,unknownprints,openviolations,statics
+display=ipmachistory,locationhistoryswitch,locationhistorymac,ifoctetshistoryswitch,ifoctetshistorymac,ifoctetshistoryuser,active,inactive,registered,unregistered,os,osclass,unknownprints,openviolations,statics,conn,connreg
 ipmachistory=IP - MAC History
 locationhistoryswitch=Location History (switch)
 locationhistorymac=Location History (MAC)
@@ -60,6 +60,8 @@ statics=Probable Static IPs
 unknownprints=Unknown Fingerprints
 openviolations=Open Violations
 statics=Probable Static IPs
+conn=Connection Types for All Nodes
+connreg=Connection Types for Registered Nodes
 
 [ui.scan]
 display=scan, results
@@ -612,6 +614,20 @@ command=report statics
 connection_type=Type of connection
 command=report statics
 
+[ui.status.reports.conn]
+display=connection_type,percent,connections
+connection_type=Connection Type
+percent=Percent
+connections=Connections
+command=report conn
+
+[ui.status.reports.connreg]
+display=connection_type,percent,connections
+connection_type=Connection Type
+percent=Percent
+connections=Connections
+command=report connreg
+
 [ui.scan.scan]
 display=id,date,hosts,tid
 id=Scan ID
============================================================
--- pf/html/admin/status/grapher.php	18dfe328514b21827c4df9823d3ba5f4bd55765c
+++ pf/html/admin/status/grapher.php	b5ec51a45b52ee29d39f7ae70e02e626ca153c2c
@@ -55,7 +55,13 @@
     'bar' => 'bar',
     'ifoctetshistorymac' => 'stacked_without_fill',
     'ifoctetshistoryswitch' => 'stacked_without_fill',
-    'ifoctetshistoryuser' => 'stacked_without_fill');
+    'ifoctetshistoryuser' => 'stacked_without_fill',
+    'conn' => 'pie',
+    'conn active' => 'pie',
+    'conn all' => 'pie',
+    'connreg' => 'pie',
+    'connreg active' => 'pie',
+    'connreg all' => 'pie');
 
   if (($type == 'ifoctetshistoryuser')||($type == 'ifoctetshistorymac')) {
     $chart_data = get_chart_data("graph $type {$_GET['pid']} start_time={$_GET['start_time']},end_time=${_GET['end_time']}");
@@ -81,11 +87,14 @@
     
   } else {
 
-    $span == 'report' ? $chart_data = get_pie_chart_data("report $type") : $chart_data = get_chart_data("graph $type $span");
-    
-    # For graphs with one data point, make them bar graphs
-    if(count($chart_data['x_labels']) == 1){
-          $single_point = 'bar';
+    if ($span == 'report') {
+        $chart_data = get_pie_chart_data("report $type");
+    } else {
+        $chart_data = get_chart_data("graph $type $span");
+        # For graphs with one data point, make them bar graphs
+        if(count($chart_data['x_labels']) == 1){
+            $single_point = 'bar';
+        }
     }
 
     jpgraph($chart_data['chart_data'], $chart_data['x_labels'], set_default(set_default($single_point, $types[$type]), 'line'), $size, pretty_header('status-graphs', $type), "Per ".ucfirst($span));
@@ -134,10 +143,15 @@
 
         if($type == 'pie'){
                 $graph = new PieGraph($width, $height, "auto");
-                $title=pretty_header('status-reports', 'osclass').' distribution';
 
+                # we extract the first portion of the graph type to go and fetch it's pretty header for the graph's title
+                if (preg_match("/^(\w+).*$/", $_GET['type'], $match)) {
+                    $title=pretty_header('status-reports', $match[1]) .' distribution';
+                } else {
+                    $title=pretty_header('status-reports', $_GET['type']).' distribution';
+                }
         }
-
+        
         $graph->title->Set(ucwords($title));
         if($subtitle != 'Per Report'){
                 $graph->subtitle->Set($subtitle);
============================================================
--- pf/html/admin/status/reports.php	309cdd669c4d812d7c838399ca1757caf86ace4e
+++ pf/html/admin/status/reports.php	2483d4c5bdf2356f4d8d2c325c6efbcd2a191cdc
@@ -31,7 +31,7 @@
 
   include_once('../header.php');
 
-  $active_available = array('registered', 'unregistered', 'os', 'osclass', 'unknownprints', 'openviolations', 'statics');
+  $active_available = array('registered', 'unregistered', 'os', 'osclass', 'unknownprints', 'openviolations', 'statics', 'conn', 'connreg');
   $type = set_default($_REQUEST['type'], 'ipmachistory');
   $subtype = set_default($_GET['subtype'], '');
 
============================================================
--- pf/lib/pf/pfcmd/help.pm	b7dc1a244925947cb1373019a079d5728f5351ee
+++ pf/lib/pf/pfcmd/help.pm	117de21d6e855f50163582d9c73598cf4beea7f5
@@ -296,7 +296,7 @@ sub help_report {
 
 sub help_report {
     print STDERR << "EOT";
-Usage: pfcmd report <active|inactive> | <registered|unregistered|os|osclass|unknownprints|openviolations|statics> [all|active]
+Usage: pfcmd report <active|inactive> | <registered|unregistered|os|osclass|unknownprints|openviolations|statics|conn|connreg> [all|active]
 
 display canned reports - "active" modifier shows only nodes with open iplog entries
 
@@ -309,6 +309,8 @@ statics        | show probable static IP
 unknownprints  | show DHCP fingerprints without a known OS mapping
 openviolations | show all open violations
 statics        | show probable static IPs
+conn           | show connections by type for all nodes
+connreg        | show connections by type for registered nodes only
 EOT
     return 1;
 }
============================================================
--- pf/lib/pf/pfcmd/report.pm	bf061b52bc7bd0bbdb4fad9326607268836b96df
+++ pf/lib/pf/pfcmd/report.pm	981e74e03f9d2cd29c61ae7e1de8b642884c1709
@@ -42,6 +42,10 @@ BEGIN {
         report_registered_active
         report_openviolations_all
         report_openviolations_active
+        report_conn_all
+        report_conn_active
+        report_connreg_all
+        report_connreg_active
         report_statics_all
         report_statics_active
         report_unknownprints_all
@@ -54,6 +58,7 @@ use pf::util;
 use pf::config;
 use pf::db;
 use pf::util;
+use pf::node;
 
 # The next two variables and the _prepare sub are required for database handling magic (see pf::db)
 our $report_db_prepared = 0;
@@ -119,6 +124,18 @@ sub report_db_prepare {
     $report_statements->{'report_openviolations_active_sql'} = get_db_handle()->prepare(
         qq [SELECT n.pid as owner, n.mac as mac, v.status as status, v.start_date as start_date, c.description as violation from (violation v, iplog i) LEFT JOIN node n ON v.mac=n.mac LEFT JOIN class c on c.vid=v.vid WHERE v.status="open" and n.mac=i.mac and (i.end_time=0 or i.end_time > now()) order by n.pid ]);
 
+    $report_statements->{'report_conn_all_sql'} = get_db_handle()->prepare(
+        qq [SELECT connection_type,count(*) as connections,ROUND(COUNT(*)/(SELECT COUNT(*) from locationlog INNER JOIN node ON node.mac=locationlog.mac)*100,1) AS percent from locationlog INNER JOIN node ON node.mac=locationlog.mac GROUP BY connection_type]);
+
+    $report_statements->{'report_conn_active_sql'} = get_db_handle()->prepare(
+        qq [SELECT connection_type,count(*) as connections,ROUND(COUNT(*)/(SELECT COUNT(*) from locationlog INNER JOIN node ON node.mac=locationlog.mac INNER JOIN iplog ON node.mac=iplog.mac WHERE iplog.end_time = 0 OR iplog.end_time > now() AND locationlog.end_time IS NULL)*100,1) AS percent from locationlog INNER JOIN node ON node.mac=locationlog.mac INNER JOIN iplog ON node.mac=iplog.mac WHERE iplog.end_time = 0 OR iplog.end_time > now() AND locationlog.end_time IS NULL GROUP BY connection_type]);
+   
+    $report_statements->{'report_connreg_all_sql'} = get_db_handle()->prepare(
+        qq [SELECT connection_type,count(*) as connections,ROUND(COUNT(*)/(SELECT COUNT(*) from locationlog INNER JOIN node ON node.mac=locationlog.mac WHERE node.status = "reg")*100,1) AS percent from locationlog INNER JOIN node ON node.mac=locationlog.mac WHERE node.status = "reg" GROUP BY connection_type]);
+
+    $report_statements->{'report_connreg_active_sql'} = get_db_handle()->prepare(
+        qq [SELECT connection_type,count(*) as connections,ROUND(COUNT(*)/(SELECT COUNT(*) from locationlog INNER JOIN node ON node.mac=locationlog.mac INNER JOIN iplog ON node.mac=iplog.mac WHERE node.status = "reg" AND (iplog.end_time =0 OR iplog.end_time > now()) AND locationlog.end_time IS NULL)*100,1) AS percent from locationlog INNER JOIN node ON node.mac=locationlog.mac INNER JOIN iplog ON node.mac=iplog.mac WHERE node.status = "reg" AND (iplog.end_time = 0 OR iplog.end_time > now()) AND locationlog.end_time IS NULL GROUP BY connection_type ]);
+
     $report_db_prepared = 1;
     return 1;
 }
@@ -327,6 +344,98 @@ sub report_unknownprints_active {
     return (@data);
 }
 
+=item * report_conn_all
+
+Reporting - Connections by connection type and user status for all nodes
+
+=cut
+sub report_conn_all {
+    my @data    = db_data(REPORT, $report_statements, 'report_conn_all_sql');
+    my $total   = 0;
+    my @return_data;
+
+    foreach my $record (@data) {
+        $total += $record->{'connections'};
+ 
+        if ( $record->{'connections'} > 0 ) {
+            push @return_data, $record;
+        }
+
+    }
+    @return_data = translate_connection_type(@return_data);
+    push @return_data, { connection_type => "Total", percent => "100", connections => $total };
+    return (@return_data);
+}
+
+=item * report_conn_active
+
+Reporting - Connections by connection type and user status for all active nodes
+
+=cut
+sub report_conn_active {
+    my @data    = db_data(REPORT, $report_statements, 'report_conn_active_sql');
+    my $total   = 0;
+    my @return_data;
+
+    foreach my $record (@data) {
+        $total += $record->{'connections'};
+
+        if ( $record->{'connections'} > 0 ) {
+            push @return_data, $record;
+        }
+
+    }
+    @return_data = translate_connection_type(@return_data);
+    push @return_data, { connection_type => "Total", percent => "100", connections => $total };
+    return (@return_data);
+}
+
+=item * report_connreg_all
+
+Reporting - Connections by connection type and user status for all nodes (registered users)
+
+=cut
+sub report_connreg_all {
+    my @data    = db_data(REPORT, $report_statements, 'report_connreg_all_sql');
+    my $total   = 0;
+    my @return_data;
+
+    foreach my $record (@data) {
+        $total += $record->{'connections'};
+
+        if ( $record->{'connections'} > 0 ) {
+            push @return_data, $record;
+        }
+
+    }
+    @return_data = translate_connection_type(@return_data);
+    push @return_data, { connection_type => "Total", percent => "100", connections => $total };
+    return (@return_data);
+}
+
+=item * report_connreg_active
+
+Reporting - Connections by connection type and user status for all active nodes (registered users)
+
+=cut
+sub report_connreg_active {
+    my @data    = db_data(REPORT, $report_statements, 'report_connreg_active_sql');
+    my $total   = 0;
+    my @return_data;
+
+    foreach my $record (@data) {
+        $total += $record->{'connections'};
+
+        if ( $record->{'connections'} > 0 ) {
+            push @return_data, $record;
+        }
+
+    }
+    @return_data = translate_connection_type(@return_data);
+    push @return_data, { connection_type => "Total", percent => "100", connections => $total };
+    return (@return_data);
+}
+
 =item * translate_connection_type
 
 Translates connection_type database string into a human-understandable string
@@ -369,13 +478,15 @@ Olivier Bilodeau <obilodeau@inverse.ca>
 
 Olivier Bilodeau <obilodeau@inverse.ca>
 
+Francois Gaudreault <fgaudreault@inverse.ca>
+
 =head1 COPYRIGHT
 
 Copyright (C) 2005 David LaPorte
 
 Copyright (C) 2005 Kevin Amorin
 
-Copyright (C) 2010 Inverse inc.
+Copyright (C) 2010 - 2011 Inverse inc.
 
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
============================================================
--- pf/lib/pf/pfcmd.pm	a6fc36f5ea1e6021125213ae8dbaa3ef59b9a2a3
+++ pf/lib/pf/pfcmd.pm	9d509164702942249355ac4f73f1cd272ba71381
@@ -252,12 +252,12 @@ sub parseCommandLine {
         'report'          => qr{ ^ (?: #for grouping only
                                      ( active | inactive | openviolations 
                                        | os | osclass | registered | statics 
-                                       | unknownprints | unregistered )
+                                       | unknownprints | unregistered | conn | connreg )
                                      |
                                      (?: #for grouping only
                                        ( openviolations | os | osclass 
                                          | registered | statics
-                                         | unknownprints | unregistered 
+                                         | unknownprints | unregistered | conn | connreg
                                        )
                                        \s+
                                        ( all | active )
