Browse Source

- Adds the ability to plot statistics diagrams by providing the parameter '-p/--plot' and an optional file format, e.g., '-p format=pdf'

Patrick Jattke 7 years ago
parent
commit
0b05608efc
3 changed files with 52 additions and 7 deletions
  1. 13 5
      code/CLI.py
  2. 10 0
      code/ID2TLib/Controller.py
  3. 29 2
      code/ID2TLib/Statistics.py

+ 13 - 5
code/CLI.py

@@ -34,6 +34,10 @@ class CLI(object):
         # Load PCAP statistics
         controller.load_pcap_statistics(self.args.export, self.args.recalculate, self.args.statistics)
 
+        # Create statistics plots
+        if self.args.plot is not None:
+            controller.create_statistics_plot(self.args.plot)
+
         # Process attack(s) with given attack params
         if self.args.attack is not None:
             # If attack is present, load attack with params
@@ -72,6 +76,8 @@ class CLI(object):
                             action='store_true', default=False)
         parser.add_argument('-s', '--statistics', help='print general file statistics to stdout.', action='store_true',
                             default=False)
+        parser.add_argument('-p', '--plot', help='creates a plot of common dataset statistics', action='append',
+                            nargs='?')
         parser.add_argument('-q', '--query', metavar="QUERY",
                             action='append', nargs='?',
                             help='queries the statistics database. If no query is provided, the application enters into query mode.')
@@ -93,25 +99,27 @@ def main(args):
     cli.parse_arguments(args)
 
 
-# Uncomment to enable calling by terminal
+# # Uncomment to enable calling by terminal
 if __name__ == '__main__':
     main(sys.argv[1:])
 
 # if __name__ == '__main__':
 #     FILE = ['-i', '/mnt/hgfs/datasets/95M.pcap']
 #     FILE2 = ['-i', '/mnt/hgfs/datasets/95M_20161103-185151.pcap']
-#
+#     FILE3 = ['-i', '/home/pjattke/temp/test_me_short.pcap']
+#     ATTACK_NO_PARAM = ['-a', 'DDoSAttack', 'attackers.count=10']
 #
 #     ATTACK = ['-a', 'PortscanAttack', 'ip.src=10.2.2.4', 'mac.dst=05:AB:47:B5:19:11',
 #               'inject.at-timestamp=1449038705.316721', 'attack.note=Portscan2']
-#     ATTACK2 = ['-a', 'PortscanAttack', 'ip.dst=193.133.122.23, ip.src=192.124.34.12', 'inject.after-pkt=34']
+#     ATTACK2 = ['-a', 'PortscanAttack', 'ip.dst=193.133.122.23', 'ip.src=192.124.34.12', 'inject.after-pkt=34']
 #
 #     STATS_RECALC = ['-r']
 #     STATS_PRINT = ['-s']
+#     STATS_PLOT = ['-p', 'format=pdf']
 #
 #     QUERY_MODE_LOOP = ['-q']
-#     QUERY_DB = ['-q', 'most_used(ttlValue)']
+#     QUERY_DB = ['-q', 'ipAddress(pktsSent > 1000, kbytesSent >= 20)']
 #
-#     main(FILE2 + ATTACK)
+#     main(FILE + STATS_PLOT)
 
     # main(['-c', '/home/pjattke/Thesis/development/code/config'])

+ 10 - 0
code/ID2TLib/Controller.py

@@ -98,3 +98,13 @@ class Controller:
                 except sqlite3.Error as e:
                     print("An error occurred:", e.args[0])
                 buffer = ""
+
+    def create_statistics_plot(self, params: str):
+        """
+        Plots the statistics to a file by using the given customization parameters.
+        """
+        if params is not None and params[0] is not None:
+            params_dict = dict([z.split("=") for z in params])
+            self.statistics.plot_statistics(format=params_dict['format'])
+        else:
+            self.statistics.plot_statistics()

+ 29 - 2
code/ID2TLib/Statistics.py

@@ -1,8 +1,7 @@
 import os
 import time
-
 import ID2TLib.libpcapreader as pr
-
+import matplotlib.pyplot as plt
 from ID2TLib.PcapFile import PcapFile
 from ID2TLib.StatsDatabase import StatsDatabase
 
@@ -280,3 +279,31 @@ class Statistics:
         else:
             return (any(x in value.lower().strip() for x in self.stats_db.get_all_named_query_keywords()) or
                     any(x in value.lower().strip() for x in self.stats_db.get_all_sql_query_keywords()))
+
+    def plot_statistics(self, format: str = 'png'):
+        """
+        Plots the statistics associated with the dataset prior attack injection.
+        :param format: The format to be used to save the statistics diagrams.
+        """
+
+        def plot_ttl(file_ending: str):
+            result = self.stats_db._process_user_defined_query(
+                "SELECT ttlValue, SUM(ttlCount) FROM ip_ttl GROUP BY ttlValue")
+            graphx, graphy = [], []
+            for row in result:
+                graphx.append(row[0])
+                graphy.append(row[1])
+            plt.autoscale(enable=True, axis='both')
+            plt.title("TTL Distribution")
+            plt.xlabel('TTL Value')
+            plt.ylabel('Number of Packets')
+            width = 0.5
+            plt.xlim([0, max(graphx)])
+            plt.grid(True)
+            plt.bar(graphx, graphy, width, align='center', linewidth=2, color='red', edgecolor='red')
+            out = self.pcap_filepath.replace('.pcap', '_plot-ttl' + file_ending)
+            plt.savefig(out)
+            return out
+
+        out_path = plot_ttl('.' + format)
+        print("Saved TTL distribution plot at: ", out_path)