Browse Source

add temporal benchmark param

Jens Keim 6 years ago
parent
commit
c2d1a4a9fe

+ 22 - 4
code/Attack/BaseAttack.py

@@ -5,6 +5,7 @@ import os
 import random
 import re
 import tempfile
+import time
 import numpy as np
 
 from abc import abstractmethod, ABCMeta
@@ -44,6 +45,10 @@ class BaseAttack(metaclass=ABCMeta):
         self.supported_params = {}
         self.attack_start_utime = 0
         self.attack_end_utime = 0
+        self.start_time = 0
+        self.finish_time = 0
+        self.packets = []
+        self.path_attack_pcap = ""
 
     def set_statistics(self, statistics):
         """
@@ -64,6 +69,13 @@ class BaseAttack(metaclass=ABCMeta):
         """
         pass
 
+    @abstractmethod
+    def generate_attack_packets(self):
+        """
+        Creates the attack packets.
+        """
+        pass
+
     @abstractmethod
     def generate_attack_pcap(self):
         """
@@ -260,6 +272,15 @@ class BaseAttack(metaclass=ABCMeta):
         if isinstance(seed, int):
             random.seed(seed)
 
+    def set_start_time(self):
+        self.start_time = time.time()
+
+    def set_finish_time(self):
+        self.finish_time = time.time()
+
+    def get_packet_generation_time(self):
+        return self.finish_time - self.start_time
+
     def add_param_value(self, param, value):
         """
         Adds the pair param : value to the dictionary of attack parameters. Prints and error message and skips the
@@ -420,7 +441,7 @@ class BaseAttack(metaclass=ABCMeta):
         maxDelay = int(maxDelay) * 10 ** -6
         return minDelay, maxDelay
 
-    def packetsToConvs(self,exploit_raw_packets):
+    def packets_to_convs(self,exploit_raw_packets):
         """
            Classifies a bunch of packets to conversations groups. A conversation is a set of packets go between host A (IP,port)
            to host B (IP,port)
@@ -460,7 +481,6 @@ class BaseAttack(metaclass=ABCMeta):
                     conversations[conv_rep] = pktList
         return (conversations, orderList_conversations)
 
-
     def is_valid_ip_address(self,addr):
         """
         Checks if the IP address family is supported.
@@ -492,7 +512,6 @@ class BaseAttack(metaclass=ABCMeta):
             print("\nERROR: Invalid IP addresses; source IP is the same as destination IP: " + ip_destination + ".")
             sys.exit(0)
 
-
     def get_inter_arrival_time(self, packets, distribution:bool=False):
         """
         Gets the inter-arrival times array and its distribution of a set of packets.
@@ -525,7 +544,6 @@ class BaseAttack(metaclass=ABCMeta):
         else:
             return inter_arrival_times
 
-
     def clean_white_spaces(self, str):
         """
         Delete extra backslash from white spaces. This function is used to process the payload of packets.

+ 23 - 19
code/Attack/DDoSAttack.py

@@ -27,6 +27,9 @@ class DDoSAttack(BaseAttack.BaseAttack):
         super(DDoSAttack, self).__init__("DDoS Attack", "Injects a DDoS attack'",
                                         "Resource Exhaustion")
 
+        self.last_packet = None
+        self.total_pkt_num = 0
+
         # Define allowed parameters and their type
         self.supported_params.update({
             Param.IP_SOURCE: ParameterTypes.TYPE_IP_ADDRESS,
@@ -74,7 +77,7 @@ class DDoSAttack(BaseAttack.BaseAttack):
         self.add_param_value(Param.MAC_DESTINATION, destination_mac)
         self.add_param_value(Param.VICTIM_BUFFER, randint(1000,10000))
 
-    def generate_attack_pcap(self):
+    def generate_attack_packets(self):
         BUFFER_SIZE = 1000
 
         # Determine source IP and MAC address
@@ -93,7 +96,7 @@ class DDoSAttack(BaseAttack.BaseAttack):
             num_attackers = len(ip_source_list)
 
         # Initialize parameters
-        packets = deque(maxlen=BUFFER_SIZE)
+        self.packets = deque(maxlen=BUFFER_SIZE)
         port_source_list = self.get_param_value(Param.PORT_SOURCE)
         mac_destination = self.get_param_value(Param.MAC_DESTINATION)
         ip_destination = self.get_param_value(Param.IP_DESTINATION)
@@ -134,7 +137,7 @@ class DDoSAttack(BaseAttack.BaseAttack):
         alpha, loc, beta = (2.3261710235, -0.188306914406, 44.4853123884)
         gd = gamma.rvs(alpha, loc=loc, scale=beta, size=len(ip_source_list))
 
-        path_attack_pcap = None
+        self.path_attack_pcap = None
 
         timestamp_prv_reply, timestamp_confirm = 0, 0
         minDelay, maxDelay = self.get_reply_delay(ip_destination)
@@ -162,7 +165,7 @@ class DDoSAttack(BaseAttack.BaseAttack):
         mss_dst = handle_most_used_outputs(mss_dst)
 
         replies_count = 0
-        total_pkt_num = 0
+        self.total_pkt_num = 0
         # For each attacker, generate his own packets, then merge all packets
         for attacker in range(num_attackers):
             # Timestamp
@@ -188,8 +191,8 @@ class DDoSAttack(BaseAttack.BaseAttack):
                 request = (request_ether / request_ip / request_tcp)
                 request.time = timestamp_next_pkt
                 # Append request
-                packets.append(request)
-                total_pkt_num +=1
+                self.packets.append(request)
+                self.total_pkt_num +=1
 
                 # Build reply package
                 if replies_count <= victim_buffer:
@@ -204,29 +207,30 @@ class DDoSAttack(BaseAttack.BaseAttack):
                     timestamp_prv_reply = timestamp_reply
 
                     reply.time = timestamp_reply
-                    packets.append(reply)
+                    self.packets.append(reply)
                     replies_count+=1
-                    total_pkt_num += 1
+                    self.total_pkt_num += 1
 
                 attacker_pps = max(get_interval_pps(complement_interval_attacker_pps, timestamp_next_pkt), (pps / num_attackers) / 2)
                 timestamp_next_pkt = update_timestamp(timestamp_next_pkt, attacker_pps)
 
                 # Store timestamp of first packet (for attack label)
-                if total_pkt_num <= 2 :
-                    self.attack_start_utime = packets[0].time
+                if self.total_pkt_num <= 2 :
+                    self.attack_start_utime = self.packets[0].time
                 elif pkt_num % BUFFER_SIZE == 0: # every 1000 packets write them to the pcap file (append)
-                    last_packet = packets[-1]
-                    packets = sorted(packets, key=lambda pkt: pkt.time)
-                    path_attack_pcap = self.write_attack_pcap(packets, True, path_attack_pcap)
-                    packets = []
+                    self.last_packet = self.packets[-1]
+                    self.packets = sorted(self.packets, key=lambda pkt: pkt.time)
+                    self.path_attack_pcap = self.write_attack_pcap(self.packets, True, self.path_attack_pcap)
+                    self.packets = []
 
-        if len(packets) > 0:
-            packets = sorted(packets, key=lambda pkt: pkt.time)
-            path_attack_pcap = self.write_attack_pcap(packets, True, path_attack_pcap)
+    def generate_attack_pcap(self):
+        if len(self.packets) > 0:
+            self.packets = sorted(self.packets, key=lambda pkt: pkt.time)
+            self.path_attack_pcap = self.write_attack_pcap(self.packets, True, self.path_attack_pcap)
 
         # Store timestamp of last packet
-        self.attack_end_utime = last_packet.time
+        self.attack_end_utime = self.last_packet.time
 
         # Return packets sorted by packet time_sec_start
         # pkt_num+1: because pkt_num starts at 0
-        return total_pkt_num , path_attack_pcap
+        return self.total_pkt_num, self.path_attack_pcap

+ 22 - 22
code/Attack/EternalBlueExploit.py

@@ -78,8 +78,7 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                               self.statistics.get_pps_received(most_used_ip_address)) / 2)
         self.add_param_value(Param.INJECT_AFTER_PACKET, randint(0, self.statistics.get_packet_count()))
 
-    def generate_attack_pcap(self):
-
+    def generate_attack_packets(self):
 
         # Timestamp
         timestamp_next_pkt = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
@@ -89,7 +88,7 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
         complement_interval_pps = self.statistics.calculate_complement_packet_rates(pps)
 
         # Initialize parameters
-        packets = []
+        self.packets = []
         mac_source = self.get_param_value(Param.MAC_SOURCE)
         ip_source = self.get_param_value(Param.IP_SOURCE)
         port_source = self.get_param_value(Param.PORT_SOURCE)
@@ -100,7 +99,7 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
         # Check ip.src == ip.dst
         self.ip_src_dst_equal_check(ip_source, ip_destination)
 
-        path_attack_pcap = None
+        self.path_attack_pcap = None
 
         # Set TTL based on TTL distribution of IP address
         source_ttl_dist = self.statistics.get_ttl_distribution(ip_source)
@@ -144,7 +143,7 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
 
         port_source = randint(self.minDefaultPort,self.maxDefaultPort) # experiments show this range of ports
         # conversations = {(ip.src, ip.dst, port.src, port.dst): packets}
-        conversations, orderList_conversations = self.packetsToConvs(exploit_raw_packets)
+        conversations, orderList_conversations = self.packets_to_convs(exploit_raw_packets)
         exploit_raw_packets.close()
 
         conv_start_timesamp = timestamp_next_pkt
@@ -156,16 +155,16 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
             inter_arrival_times = self.get_inter_arrival_time(conv_pkts)
 
             if conv_index == len(orderList_conversations) - 2:  # Not the last conversation
-                timestamp_next_pkt = packets[-1].time + uniform(0.001,0.01)
+                timestamp_next_pkt = self.packets[-1].time + uniform(0.001,0.01)
 
             if conv_index != len(orderList_conversations)-1: # Not the last conversation
                 port_source += 2
-                for pkt_num, pkt in enumerate(conv_pkts):
+                for self.pkt_num, pkt in enumerate(conv_pkts):
                     eth_frame = Ether(pkt[0])
                     ip_pkt = eth_frame.payload
                     tcp_pkt = ip_pkt.payload
 
-                    if pkt_num == 0:
+                    if self.pkt_num == 0:
                         if tcp_pkt.getfieldval("dport") == smb_port:
                             orig_ip_dst = ip_pkt.getfieldval("dst")
 
@@ -198,7 +197,7 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                         new_pkt.time = timestamp_next_pkt
 
                         pps = max(Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10)
-                        timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + inter_arrival_times[pkt_num] #float(timeSteps.random())
+                        timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + inter_arrival_times[self.pkt_num] #float(timeSteps.random())
 
                     # Reply
                     else:
@@ -228,16 +227,16 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                         new_pkt = (eth_frame / ip_pkt / tcp_pkt)
 
                         pps = max(Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10)
-                        timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + inter_arrival_times[pkt_num]#float(timeSteps.random())
+                        timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + inter_arrival_times[self.pkt_num]#float(timeSteps.random())
 
                         new_pkt.time = timestamp_next_pkt
 
-                    packets.append(new_pkt)
+                    self.packets.append(new_pkt)
 
             else: # Last conversation where the victim start a connection with the attacker
-                timestamp_next_pkt = packets[-1].time + uniform(0.001, 0.01)
+                timestamp_next_pkt = self.packets[-1].time + uniform(0.001, 0.01)
                 port_source = randint(self.minDefaultPort,self.maxDefaultPort)
-                for pkt_num, pkt in enumerate(conv_pkts):
+                for self.pkt_num, pkt in enumerate(conv_pkts):
                     eth_frame = Ether(pkt[0])
                     ip_pkt = eth_frame.payload
                     tcp_pkt = ip_pkt.payload
@@ -271,7 +270,7 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                         new_pkt.time = timestamp_next_pkt
 
                         pps = max(Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10)
-                        timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + inter_arrival_times[pkt_num]# float(timeSteps.random())
+                        timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + inter_arrival_times[self.pkt_num]# float(timeSteps.random())
 
                     # Reply
                     else:
@@ -301,20 +300,21 @@ class EternalBlueExploit(BaseAttack.BaseAttack):
                         new_pkt = (eth_frame / ip_pkt / tcp_pkt)
 
                         pps = max(Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10)
-                        timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + inter_arrival_times[pkt_num]# float(timeSteps.random())
+                        timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + inter_arrival_times[self.pkt_num]# float(timeSteps.random())
 
                         new_pkt.time = timestamp_next_pkt
 
-                    packets.append(new_pkt)
+                    self.packets.append(new_pkt)
 
+    def generate_attack_pcap(self):
         # Store timestamp of first packet (for attack label)
-        self.attack_start_utime = packets[0].time
-        self.attack_end_utime = packets[-1].time
+        self.attack_start_utime = self.packets[0].time
+        self.attack_end_utime = self.packets[-1].time
 
-        if len(packets) > 0:
-            packets = sorted(packets, key=lambda pkt: pkt.time)
-            path_attack_pcap = self.write_attack_pcap(packets, True, path_attack_pcap)
+        if len(self.packets) > 0:
+            self.packets = sorted(self.packets, key=lambda pkt: pkt.time)
+            self.path_attack_pcap = self.write_attack_pcap(self.packets, True, self.path_attack_pcap)
 
         # return packets sorted by packet time_sec_start
         # pkt_num+1: because pkt_num starts at 0
-        return pkt_num + 1, path_attack_pcap
+        return self.pkt_num + 1, self.path_attack_pcap

+ 13 - 12
code/Attack/FTPWinaXeExploit.py

@@ -77,7 +77,7 @@ class FTPWinaXeExploit(BaseAttack.BaseAttack):
         self.add_param_value(Param.CUSTOM_PAYLOAD, '')
         self.add_param_value(Param.CUSTOM_PAYLOAD_FILE, '')
 
-    def generate_attack_pcap(self):
+    def generate_attack_packets(self):
 
         pps = self.get_param_value(Param.PACKETS_PER_SECOND)
 
@@ -97,7 +97,7 @@ class FTPWinaXeExploit(BaseAttack.BaseAttack):
         custom_payload_limit = 1000
         check_payload_len(custom_payload_len, custom_payload_limit)
 
-        packets = []
+        self.packets = []
 
         # Create random victim if specified
         if self.get_param_value(Param.IP_SOURCE_RANDOMIZE):
@@ -126,7 +126,7 @@ class FTPWinaXeExploit(BaseAttack.BaseAttack):
         syn = (victim_ether / victim_ip / request_tcp)
         syn.time = timestamp_next_pkt
         timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, minDelay)
-        packets.append(syn)
+        self.packets.append(syn)
 
         # response from attacker (server)
         attacker_ether = Ether(src=mac_attacker, dst=mac_victim)
@@ -137,7 +137,7 @@ class FTPWinaXeExploit(BaseAttack.BaseAttack):
         synack = (attacker_ether / attacker_ip / reply_tcp)
         synack.time = timestamp_next_pkt
         timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, minDelay)
-        packets.append(synack)
+        self.packets.append(synack)
 
         # acknowledgement from victim (client)
         ack_tcp = TCP(sport=sport, dport=ftp_port, seq=victim_seq, ack=attacker_seq, flags='A',
@@ -145,7 +145,7 @@ class FTPWinaXeExploit(BaseAttack.BaseAttack):
         ack = (victim_ether / victim_ip / ack_tcp)
         ack.time = timestamp_next_pkt
         timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps)
-        packets.append(ack)
+        self.packets.append(ack)
 
         # FTP exploit packet
         ftp_tcp = TCP(sport=ftp_port, dport=sport, seq=attacker_seq, ack=victim_seq, flags='PA',
@@ -179,7 +179,7 @@ class FTPWinaXeExploit(BaseAttack.BaseAttack):
         ftp_buff = (attacker_ether / attacker_ip / ftp_tcp)
         ftp_buff.time = timestamp_next_pkt
         timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps)
-        packets.append(ftp_buff)
+        self.packets.append(ftp_buff)
         attacker_seq += len(ftp_tcp.payload)
 
         # Fin Ack from attacker
@@ -189,7 +189,7 @@ class FTPWinaXeExploit(BaseAttack.BaseAttack):
         fin_ack = (attacker_ether / attacker_ip / fin_ack_tcp)
         fin_ack.time = timestamp_next_pkt
         timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, minDelay)
-        packets.append(fin_ack)
+        self.packets.append(fin_ack)
 
         # Ack from victim on FTP packet
         ftp_ack_tcp = TCP(sport=sport, dport=ftp_port, seq=victim_seq, ack=attacker_seq, flags='A',
@@ -197,20 +197,21 @@ class FTPWinaXeExploit(BaseAttack.BaseAttack):
         ftp_ack = (victim_ether / victim_ip / ftp_ack_tcp)
         ftp_ack.time = timestamp_next_pkt
         timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps)
-        packets.append(ftp_ack)
+        self.packets.append(ftp_ack)
 
         # Ack from victim on Fin/Ack of attacker
         fin_ack_ack_tcp = TCP(sport=sport, dport=ftp_port, seq=victim_seq, ack=attacker_seq+1, flags='A',
                       window=victim_win_value, options=[('MSS', victim_mss_value)])
         fin_ack_ack = (victim_ether / victim_ip / fin_ack_ack_tcp)
         fin_ack_ack.time = timestamp_next_pkt
-        packets.append(fin_ack_ack)
+        self.packets.append(fin_ack_ack)
 
+    def generate_attack_pcap(self):
         # store end time of attack
-        self.attack_end_utime = packets[-1].time
+        self.attack_end_utime = self.packets[-1].time
 
         # write attack packets to pcap
-        pcap_path = self.write_attack_pcap(sorted(packets, key=lambda pkt: pkt.time))
+        pcap_path = self.write_attack_pcap(sorted(self.packets, key=lambda pkt: pkt.time))
 
         # return packets sorted by packet time_sec_start
-        return len(packets), pcap_path
+        return len(self.packets), pcap_path

+ 15 - 13
code/Attack/JoomlaRegPrivExploit.py

@@ -77,8 +77,7 @@ class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
                              (self.statistics.get_pps_sent(most_used_ip_address) +
                               self.statistics.get_pps_received(most_used_ip_address)) / 2)
 
-    def generate_attack_pcap(self):
-
+    def generate_attack_packets(self):
         # Timestamp
         timestamp_next_pkt = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
 
@@ -88,7 +87,7 @@ class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
         complement_interval_pps = self.statistics.calculate_complement_packet_rates(pps)
 
         # Initialize parameters
-        packets = []
+        self.packets = []
         mac_source = self.get_param_value(Param.MAC_SOURCE)
         ip_source = self.get_param_value(Param.IP_SOURCE)
         port_source = randint(self.minDefaultPort, self.maxDefaultPort)
@@ -102,7 +101,7 @@ class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
         # Check ip.src == ip.dst
         self.ip_src_dst_equal_check(ip_source, ip_destination)
 
-        path_attack_pcap = None
+        self.path_attack_pcap = None
 
         # Set TTL based on TTL distribution of IP address
         source_ttl_dist = self.statistics.get_ttl_distribution(ip_source)
@@ -134,7 +133,7 @@ class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
         global victim_seq
         victim_seq = randint(1000,50000)
 
-        for pkt_num, pkt in enumerate(exploit_raw_packets):
+        for self.pkt_num, pkt in enumerate(exploit_raw_packets):
             eth_frame = Ether(pkt[0])
             ip_pkt = eth_frame.payload
             tcp_pkt = ip_pkt.payload
@@ -145,7 +144,7 @@ class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
             ip_pkt.payload = b''
             tcp_pkt.payload = b''
 
-            if pkt_num == 0:
+            if self.pkt_num == 0:
                 prev_orig_port_source = tcp_pkt.getfieldval("sport")
                 if tcp_pkt.getfieldval("dport") == self.http_port:
                     orig_ip_dst = ip_pkt.getfieldval("dst") # victim IP
@@ -215,17 +214,20 @@ class JoomlaRegPrivExploit(BaseAttack.BaseAttack):
                 timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + float(timeSteps.random())
                 new_pkt.time = timestamp_next_pkt
 
-            packets.append(new_pkt)
+            self.packets.append(new_pkt)
 
         exploit_raw_packets.close()
+
+    def generate_attack_pcap(self):
+
         # Store timestamp of first packet (for attack label)
-        self.attack_start_utime = packets[0].time
-        self.attack_end_utime = packets[-1].time
+        self.attack_start_utime = self.packets[0].time
+        self.attack_end_utime = self.packets[-1].time
 
-        if len(packets) > 0:
-            packets = sorted(packets, key=lambda pkt: pkt.time)
-            path_attack_pcap = self.write_attack_pcap(packets, True, path_attack_pcap)
+        if len(self.packets) > 0:
+            self.packets = sorted(self.packets, key=lambda pkt: pkt.time)
+            self.path_attack_pcap = self.write_attack_pcap(self.packets, True, self.path_attack_pcap)
 
         # return packets sorted by packet time_sec_start
         # pkt_num+1: because pkt_num starts at 0
-        return pkt_num + 1, path_attack_pcap
+        return self.pkt_num + 1, self.path_attack_pcap

+ 15 - 14
code/Attack/MS17ScanAttack.py

@@ -77,7 +77,7 @@ class MS17ScanAttack(BaseAttack.BaseAttack):
                               self.statistics.get_pps_received(most_used_ip_address)) / 2)
         self.add_param_value(Param.INJECT_AFTER_PACKET, randint(0, self.statistics.get_packet_count()))
 
-    def generate_attack_pcap(self):
+    def generate_attack_packets(self):
 
         # Timestamp
         timestamp_next_pkt = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
@@ -87,7 +87,7 @@ class MS17ScanAttack(BaseAttack.BaseAttack):
         complement_interval_pps = self.statistics.calculate_complement_packet_rates(pps)
 
         # Initialize parameters
-        packets = []
+        self.packets = []
         mac_source = self.get_param_value(Param.MAC_SOURCE)
         ip_source = self.get_param_value(Param.IP_SOURCE)
         port_source = self.get_param_value(Param.PORT_SOURCE)
@@ -98,7 +98,7 @@ class MS17ScanAttack(BaseAttack.BaseAttack):
         # Check ip.src == ip.dst
         self.ip_src_dst_equal_check(ip_source, ip_destination)
 
-        path_attack_pcap = None
+        self.path_attack_pcap = None
 
         # Set TTL based on TTL distribution of IP address
         source_ttl_dist = self.statistics.get_ttl_distribution(ip_source)
@@ -146,12 +146,12 @@ class MS17ScanAttack(BaseAttack.BaseAttack):
 
         source_origin_wins, destination_origin_wins = {}, {}
 
-        for pkt_num, pkt in enumerate(exploit_raw_packets):
+        for self.pkt_num, pkt in enumerate(exploit_raw_packets):
             eth_frame = Ether(pkt[0])
             ip_pkt = eth_frame.payload
             tcp_pkt = ip_pkt.payload
 
-            if pkt_num == 0:
+            if self.pkt_num == 0:
                 if tcp_pkt.getfieldval("dport") == smb_port:
                     orig_ip_dst = ip_pkt.getfieldval("dst")  # victim IP
 
@@ -185,7 +185,7 @@ class MS17ScanAttack(BaseAttack.BaseAttack):
 
                 pps = max(Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10)
                 timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + inter_arrival_times[
-                    pkt_num]  # float(timeSteps.random())
+                    self.pkt_num]  # float(timeSteps.random())
             # Reply
             else:
                 # Ether
@@ -213,21 +213,22 @@ class MS17ScanAttack(BaseAttack.BaseAttack):
 
                 new_pkt = (eth_frame / ip_pkt / tcp_pkt)
                 timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + inter_arrival_times[
-                    pkt_num]  # + float(timeSteps.random())
+                    self.pkt_num]  # + float(timeSteps.random())
                 new_pkt.time = timestamp_next_pkt
 
-            packets.append(new_pkt)
+            self.packets.append(new_pkt)
 
         exploit_raw_packets.close()
 
+    def generate_attack_pcap(self):
         # Store timestamp of first packet (for attack label)
-        self.attack_start_utime = packets[0].time
-        self.attack_end_utime = packets[-1].time
+        self.attack_start_utime = self.packets[0].time
+        self.attack_end_utime = self.packets[-1].time
 
-        if len(packets) > 0:
-            packets = sorted(packets, key=lambda pkt: pkt.time)
-            path_attack_pcap = self.write_attack_pcap(packets, True, path_attack_pcap)
+        if len(self.packets) > 0:
+            self.packets = sorted(self.packets, key=lambda pkt: pkt.time)
+            self.path_attack_pcap = self.write_attack_pcap(self.packets, True, self.path_attack_pcap)
 
         # return packets sorted by packet time_sec_start
         # pkt_num+1: because pkt_num starts at 0
-        return pkt_num + 1, path_attack_pcap
+        return self.pkt_num + 1, self.path_attack_pcap

+ 9 - 8
code/Attack/PortscanAttack.py

@@ -108,7 +108,7 @@ class PortscanAttack(BaseAttack.BaseAttack):
             port_dst_shuffled = ports_dst
         return port_dst_shuffled
 
-    def generate_attack_pcap(self):
+    def generate_attack_packets(self):
         mac_source = self.get_param_value(Param.MAC_SOURCE)
         mac_destination = self.get_param_value(Param.MAC_DESTINATION)
         pps = self.get_param_value(Param.PACKETS_PER_SECOND)
@@ -134,7 +134,7 @@ class PortscanAttack(BaseAttack.BaseAttack):
         timestamp_prv_reply, timestamp_confirm = 0,0
 
         # Initialize parameters
-        packets = []
+        self.packets = []
         ip_source = self.get_param_value(Param.IP_SOURCE)
         ip_destination = self.get_param_value(Param.IP_DESTINATION)
 
@@ -222,7 +222,7 @@ class PortscanAttack(BaseAttack.BaseAttack):
 
             request.time = timestamp_next_pkt
             # Append request
-            packets.append(request)
+            self.packets.append(request)
 
             # 2) Build reply (for open ports) package
             if dport in ports_open:  # destination port is OPEN
@@ -238,7 +238,7 @@ class PortscanAttack(BaseAttack.BaseAttack):
                 timestamp_prv_reply = timestamp_reply
 
                 reply.time = timestamp_reply
-                packets.append(reply)
+                self.packets.append(reply)
 
                 # requester confirms
                 confirm_ether = request_ether
@@ -247,18 +247,19 @@ class PortscanAttack(BaseAttack.BaseAttack):
                 confirm = (confirm_ether / confirm_ip / confirm_tcp)
                 timestamp_confirm = Util.update_timestamp(timestamp_reply,pps,minDelay)
                 confirm.time = timestamp_confirm
-                packets.append(confirm)
+                self.packets.append(confirm)
 
                 # else: destination port is NOT OPEN -> no reply is sent by target
 
             pps = max(Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10)
             timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps)
 
+    def generate_attack_pcap(self):
         # store end time of attack
-        self.attack_end_utime = packets[-1].time
+        self.attack_end_utime = self.packets[-1].time
 
         # write attack packets to pcap
-        pcap_path = self.write_attack_pcap(sorted(packets, key=lambda pkt: pkt.time))
+        pcap_path = self.write_attack_pcap(sorted(self.packets, key=lambda pkt: pkt.time))
 
         # return packets sorted by packet time_sec_start
-        return len(packets), pcap_path
+        return len(self.packets), pcap_path

+ 13 - 13
code/Attack/SMBLorisAttack.py

@@ -74,8 +74,7 @@ class SMBLorisAttack(BaseAttack.BaseAttack):
         self.add_param_value(Param.INJECT_AFTER_PACKET, random.randint(0, self.statistics.get_packet_count()))
         self.add_param_value(Param.ATTACK_DURATION, 30)
 
-    def generate_attack_pcap(self):
-
+    def generate_attack_packets(self):
         pps = self.get_param_value(Param.PACKETS_PER_SECOND)
 
         # Timestamp
@@ -84,7 +83,7 @@ class SMBLorisAttack(BaseAttack.BaseAttack):
         self.attack_start_utime = first_timestamp
 
         # Initialize parameters
-        packets = []
+        self.packets = []
         ip_destination = self.get_param_value(Param.IP_DESTINATION)
         mac_destination = self.get_param_value(Param.MAC_DESTINATION)
 
@@ -140,7 +139,7 @@ class SMBLorisAttack(BaseAttack.BaseAttack):
 
             sport = 1025
 
-            # Timestamps of first packets shouldn't be exactly the same to look more realistic
+            # Timestamps of first self.packets shouldn't be exactly the same to look more realistic
             timestamp_next_pkt = random.uniform(first_timestamp, update_timestamp(first_timestamp, pps))
 
             while timestamp_next_pkt <= attack_ends_time:
@@ -161,7 +160,7 @@ class SMBLorisAttack(BaseAttack.BaseAttack):
                 syn = (attacker_ether / attacker_ip / syn_tcp)
                 syn.time = timestamp_next_pkt
                 timestamp_next_pkt = update_timestamp(timestamp_next_pkt, victim_pps, minDelay)
-                packets.append(syn)
+                self.packets.append(syn)
 
                 # response from victim (server)
                 synack_tcp = TCP(sport=smb_port, dport=sport, seq=victim_seq, ack=attacker_seq, flags='SA',
@@ -170,7 +169,7 @@ class SMBLorisAttack(BaseAttack.BaseAttack):
                 synack = (victim_ether / victim_ip / synack_tcp)
                 synack.time = timestamp_next_pkt
                 timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, minDelay)
-                packets.append(synack)
+                self.packets.append(synack)
 
                 # acknowledgement from attacker (client)
                 ack_tcp = TCP(sport=sport, dport=smb_port, seq=attacker_seq, ack=victim_seq, flags='A',
@@ -178,7 +177,7 @@ class SMBLorisAttack(BaseAttack.BaseAttack):
                 ack = (attacker_ether / attacker_ip / ack_tcp)
                 ack.time = timestamp_next_pkt
                 timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps)
-                packets.append(ack)
+                self.packets.append(ack)
 
                 # send NBT session header paket with maximum LENGTH-field
                 req_tcp = TCP(sport=sport, dport=smb_port, seq=attacker_seq, ack=victim_seq, flags='AP',
@@ -189,7 +188,7 @@ class SMBLorisAttack(BaseAttack.BaseAttack):
                 req = (attacker_ether / attacker_ip / req_tcp / req_payload)
                 req.time = timestamp_next_pkt
                 timestamp_next_pkt = update_timestamp(timestamp_next_pkt, victim_pps, minDelay)
-                packets.append(req)
+                self.packets.append(req)
 
                 # final ack from victim (server)
                 last_ack_tcp = TCP(sport=smb_port, dport=sport, seq=victim_seq, ack=attacker_seq, flags='A',
@@ -197,15 +196,16 @@ class SMBLorisAttack(BaseAttack.BaseAttack):
                 last_ack = (victim_ether / victim_ip / last_ack_tcp)
                 last_ack.time = timestamp_next_pkt
                 timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps, minDelay)
-                packets.append(last_ack)
+                self.packets.append(last_ack)
 
                 sport += 1
 
+    def generate_attack_pcap(self):
         # store end time of attack
-        self.attack_end_utime = packets[-1].time
+        self.attack_end_utime = self.packets[-1].time
 
-        # write attack packets to pcap
-        pcap_path = self.write_attack_pcap(sorted(packets, key=lambda pkt: pkt.time))
+        # write attack self.packets to pcap
+        pcap_path = self.write_attack_pcap(sorted(self.packets, key=lambda pkt: pkt.time))
 
         # return packets sorted by packet time_sec_start
-        return len(packets), pcap_path
+        return len(self.packets), pcap_path

+ 19 - 17
code/Attack/SMBScanAttack.py

@@ -93,7 +93,7 @@ class SMBScanAttack(BaseAttack.BaseAttack):
         self.add_param_value(Param.PROTOCOL_VERSION, "1")
         self.add_param_value(Param.IP_DESTINATION_END, "0.0.0.0")
 
-    def generate_attack_pcap(self):
+    def generate_attack_packets(self):
 
         pps = self.get_param_value(Param.PACKETS_PER_SECOND)
 
@@ -124,7 +124,7 @@ class SMBScanAttack(BaseAttack.BaseAttack):
             invalid_smb_version(hosting_version)
         # Check source platform
         src_platform = self.get_param_value(Param.SOURCE_PLATFORM).lower()
-        packets = []
+        self.packets = []
 
         # randomize source ports according to platform, if specified
         if self.get_param_value(Param.PORT_SOURCE_RANDOMIZE):
@@ -203,7 +203,7 @@ class SMBScanAttack(BaseAttack.BaseAttack):
                 request.time = timestamp_next_pkt
 
                 # Append request
-                packets.append(request)
+                self.packets.append(request)
 
                 # Update timestamp for next package
                 timestamp_reply = update_timestamp(timestamp_next_pkt, pps, minDelay)
@@ -223,7 +223,7 @@ class SMBScanAttack(BaseAttack.BaseAttack):
                     victim_seq += 1
                     reply = (reply_ether / reply_ip / reply_tcp)
                     reply.time = timestamp_reply
-                    packets.append(reply)
+                    self.packets.append(reply)
 
                     # requester confirms, ACK
                     confirm_ether = request_ether
@@ -233,7 +233,7 @@ class SMBScanAttack(BaseAttack.BaseAttack):
                     confirm = (confirm_ether / confirm_ip / confirm_tcp)
                     timestamp_confirm = update_timestamp(timestamp_reply, pps, minDelay)
                     confirm.time = timestamp_confirm
-                    packets.append(confirm)
+                    self.packets.append(confirm)
 
                     smb_MID = randint(1, 65535)
                     smb_PID = randint(1, 65535)
@@ -269,7 +269,7 @@ class SMBScanAttack(BaseAttack.BaseAttack):
 
                     timestamp_smb_req = update_timestamp(timestamp_confirm, pps, minDelay)
                     smb_req_combined.time = timestamp_smb_req
-                    packets.append(smb_req_combined)
+                    self.packets.append(smb_req_combined)
 
                     # destination confirms SMB request package
                     reply_tcp = TCP(sport=smb_port, dport=sport, seq=victim_seq, ack=attacker_seq,
@@ -277,7 +277,7 @@ class SMBScanAttack(BaseAttack.BaseAttack):
                     confirm_smb_req = (reply_ether / reply_ip / reply_tcp)
                     timestamp_reply = update_timestamp(timestamp_smb_req, pps, minDelay)
                     confirm_smb_req.time = timestamp_reply
-                    packets.append(confirm_smb_req)
+                    self.packets.append(confirm_smb_req)
 
                     # smb response package
                     first_timestamp = time.mktime(time.strptime(self.statistics.get_pcap_timestamp_start()[:19],
@@ -316,7 +316,7 @@ class SMBScanAttack(BaseAttack.BaseAttack):
                         smb_rsp_combined = (smb_rsp_combined / smb_rsp_negotiate_body)
 
                     smb_rsp_combined.time = timestamp_smb_rsp
-                    packets.append(smb_rsp_combined)
+                    self.packets.append(smb_rsp_combined)
 
 
                     # source confirms SMB response package
@@ -325,7 +325,7 @@ class SMBScanAttack(BaseAttack.BaseAttack):
                     confirm_smb_res = (confirm_ether / confirm_ip / confirm_tcp)
                     timestamp_confirm = update_timestamp(timestamp_smb_rsp, pps, minDelay)
                     confirm_smb_res.time = timestamp_confirm
-                    packets.append(confirm_smb_res)
+                    self.packets.append(confirm_smb_res)
 
                     # attacker sends FIN ACK
                     confirm_tcp = TCP(sport=sport, dport=smb_port, seq=attacker_seq, ack=victim_seq,
@@ -334,7 +334,7 @@ class SMBScanAttack(BaseAttack.BaseAttack):
                     timestamp_src_fin_ack = update_timestamp(timestamp_confirm, pps, minDelay)
                     source_fin_ack.time = timestamp_src_fin_ack
                     attacker_seq += 1
-                    packets.append(source_fin_ack)
+                    self.packets.append(source_fin_ack)
 
                     # victim sends FIN ACK
                     reply_tcp = TCP(sport=smb_port, dport=sport, seq=victim_seq, ack=attacker_seq,
@@ -343,7 +343,7 @@ class SMBScanAttack(BaseAttack.BaseAttack):
                     timestamp_dest_fin_ack = update_timestamp(timestamp_src_fin_ack, pps, minDelay)
                     victim_seq += 1
                     destination_fin_ack.time = timestamp_dest_fin_ack
-                    packets.append(destination_fin_ack)
+                    self.packets.append(destination_fin_ack)
 
                     # source sends final ACK
                     confirm_tcp = TCP(sport=sport, dport=smb_port, seq=attacker_seq, ack=victim_seq,
@@ -351,7 +351,7 @@ class SMBScanAttack(BaseAttack.BaseAttack):
                     final_ack = (confirm_ether / confirm_ip / confirm_tcp)
                     timestamp_final_ack = update_timestamp(timestamp_dest_fin_ack, pps, minDelay)
                     final_ack.time = timestamp_final_ack
-                    packets.append(final_ack)
+                    self.packets.append(final_ack)
 
                 else:
                     # Build RST package
@@ -361,16 +361,18 @@ class SMBScanAttack(BaseAttack.BaseAttack):
                                     window=destination_win_value, options=[('MSS', destination_mss_value)])
                     reply = (reply_ether / reply_ip / reply_tcp)
                     reply.time = timestamp_reply
-                    packets.append(reply)
+                    self.packets.append(reply)
 
             pps = max(get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10)
             timestamp_next_pkt = update_timestamp(timestamp_next_pkt, pps)
 
+    def generate_attack_pcap(self):
+
         # store end time of attack
-        self.attack_end_utime = packets[-1].time
+        self.attack_end_utime = self.packets[-1].time
 
-        # write attack packets to pcap
-        pcap_path = self.write_attack_pcap(sorted(packets, key=lambda pkt: pkt.time))
+        # write attack self.packets to pcap
+        pcap_path = self.write_attack_pcap(sorted(self.packets, key=lambda pkt: pkt.time))
 
         # return packets sorted by packet time_sec_start
-        return len(packets), pcap_path
+        return len(self.packets), pcap_path

+ 16 - 13
code/Attack/SQLiAttack.py

@@ -77,7 +77,7 @@ class SQLiAttack(BaseAttack.BaseAttack):
                              (self.statistics.get_pps_sent(most_used_ip_address) +
                               self.statistics.get_pps_received(most_used_ip_address)) / 2)
 
-    def generate_attack_pcap(self):
+    def generate_attack_packets(self):
         # Timestamp
         timestamp_next_pkt = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
         pps = self.get_param_value(Param.PACKETS_PER_SECOND)
@@ -86,7 +86,7 @@ class SQLiAttack(BaseAttack.BaseAttack):
         complement_interval_pps = self.statistics.calculate_complement_packet_rates(pps)
 
         # Initialize parameters
-        packets = []
+        self.packets = []
         mac_source = self.get_param_value(Param.MAC_SOURCE)
         ip_source = self.get_param_value(Param.IP_SOURCE)
         mac_destination = self.get_param_value(Param.MAC_DESTINATION)
@@ -99,7 +99,7 @@ class SQLiAttack(BaseAttack.BaseAttack):
         # Check ip.src == ip.dst
         self.ip_src_dst_equal_check(ip_source, ip_destination)
 
-        path_attack_pcap = None
+        self.path_attack_pcap = None
 
         # Set TTL based on TTL distribution of IP address
         source_ttl_dist = self.statistics.get_ttl_distribution(ip_source)
@@ -133,7 +133,7 @@ class SQLiAttack(BaseAttack.BaseAttack):
         global victim_seq
         victim_seq = random.randint(1000, 50000)
 
-        for pkt_num, pkt in enumerate(exploit_raw_packets):
+        for self.pkt_num, pkt in enumerate(exploit_raw_packets):
             eth_frame = Ether(pkt[0])
             ip_pkt = eth_frame.payload
             tcp_pkt = ip_pkt.payload
@@ -144,7 +144,7 @@ class SQLiAttack(BaseAttack.BaseAttack):
             ip_pkt.payload = b''
             tcp_pkt.payload = b''
 
-            if pkt_num == 0:
+            if self.pkt_num == 0:
                 prev_orig_port_source = tcp_pkt.getfieldval("sport")
                 orig_ip_dst = ip_pkt.getfieldval("dst")  # victim IP
 
@@ -231,17 +231,20 @@ class SQLiAttack(BaseAttack.BaseAttack):
                 timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps) + float(timeSteps.random())
                 new_pkt.time = timestamp_next_pkt
 
-            packets.append(new_pkt)
+            self.packets.append(new_pkt)
 
         exploit_raw_packets.close()
+
+    def generate_attack_pcap(self):
+
         # Store timestamp of first packet (for attack label)
-        self.attack_start_utime = packets[0].time
-        self.attack_end_utime = packets[-1].time
+        self.attack_start_utime = self.packets[0].time
+        self.attack_end_utime = self.packets[-1].time
 
-        if len(packets) > 0:
-            packets = sorted(packets, key=lambda pkt: pkt.time)
-            path_attack_pcap = self.write_attack_pcap(packets, True, path_attack_pcap)
+        if len(self.packets) > 0:
+            self.packets = sorted(self.packets, key=lambda pkt: pkt.time)
+            self.path_attack_pcap = self.write_attack_pcap(self.packets, True, self.path_attack_pcap)
 
-        # return packets sorted by packet time_sec_start
+        # return self.packets sorted by packet time_sec_start
         # pkt_num+1: because pkt_num starts at 0
-        return pkt_num + 1, path_attack_pcap
+        return self.pkt_num + 1, self.path_attack_pcap

+ 13 - 11
code/Attack/SalityBotnet.py

@@ -55,7 +55,7 @@ class SalityBotnet(BaseAttack.BaseAttack):
                              (self.statistics.get_pps_sent(most_used_ip_address) +
                               self.statistics.get_pps_received(most_used_ip_address)) / 2)
 
-    def generate_attack_pcap(self):
+    def generate_attack_packets(self):
 
         # Timestamp
         timestamp_next_pkt = self.get_param_value(Param.INJECT_AT_TIMESTAMP)
@@ -66,7 +66,7 @@ class SalityBotnet(BaseAttack.BaseAttack):
         complement_interval_pps = self.statistics.calculate_complement_packet_rates(pps)
 
         # Initialize parameters
-        packets = []
+        self.packets = []
         mac_source = self.get_param_value(Param.MAC_SOURCE)
         ip_source = self.get_param_value(Param.IP_SOURCE)
 
@@ -89,13 +89,13 @@ class SalityBotnet(BaseAttack.BaseAttack):
         ip_map = {origin_ip_src : ip_source, origin_ip_dns_server: ip_dns_server}
         mac_map = {origin_mac_src : mac_source, origin_mac_dns_server: mac_dns_server}
 
-        path_attack_pcap = None
+        self.path_attack_pcap = None
 
         # Inject Sality botnet
         # Read sality_botnet pcap file
         exploit_raw_packets = RawPcapReader(self.template_attack_pcap_path)
 
-        for pkt_num, pkt in enumerate(exploit_raw_packets):
+        for self.pkt_num, pkt in enumerate(exploit_raw_packets):
             eth_frame = Ether(pkt[0])
             ip_pkt = eth_frame.payload
 
@@ -127,17 +127,19 @@ class SalityBotnet(BaseAttack.BaseAttack):
             pps = max(Util.get_interval_pps(complement_interval_pps, timestamp_next_pkt), 10)
             timestamp_next_pkt = Util.update_timestamp(timestamp_next_pkt, pps)
 
-            packets.append(new_pkt)
+            self.packets.append(new_pkt)
 
         exploit_raw_packets.close()
+
+    def generate_attack_pcap(self):
         # Store timestamp of first packet (for attack label)
-        self.attack_start_utime = packets[0].time
-        self.attack_end_utime = packets[-1].time
+        self.attack_start_utime = self.packets[0].time
+        self.attack_end_utime = self.packets[-1].time
 
-        if len(packets) > 0:
-            packets = sorted(packets, key=lambda pkt: pkt.time)
-            path_attack_pcap = self.write_attack_pcap(packets, True, path_attack_pcap)
+        if len(self.packets) > 0:
+            self.packets = sorted(self.packets, key=lambda pkt: pkt.time)
+            self.path_attack_pcap = self.write_attack_pcap(self.packets, True, self.path_attack_pcap)
 
         # return packets sorted by packet time_sec_start
         # pkt_num+1: because pkt_num starts at 0
-        return pkt_num + 1, path_attack_pcap
+        return self.pkt_num + 1, self.path_attack_pcap

+ 2 - 1
code/CLI.py

@@ -63,6 +63,7 @@ class CLI(object):
                                                        'in interval-wise, TCP checksum, and checking payload availability.', action='store_true')
         parser.add_argument('-S', '--randomSeed', action='append', help='sets random seed for testing or benchmarking',
                             nargs='+', default=[])
+        parser.add_argument('-T', '--time', help='measures packet generation time', action='store_true', default=False)
 
         # Attack arguments
         parser.add_argument('-a', '--attack', metavar="ATTACK", action='append',
@@ -151,7 +152,7 @@ class CLI(object):
         # Process attack(s) with given attack params
         if self.args.attack is not None:
             # If attack is present, load attack with params
-            controller.process_attacks(self.args.attack, self.args.randomSeed)
+            controller.process_attacks(self.args.attack, self.args.randomSeed, self.args.time)
 
         # Parameter -q without arguments was given -> go into query loop
         if self.args.query == [None]:

+ 13 - 4
code/ID2TLib/AttackController.py

@@ -52,7 +52,7 @@ class AttackController:
         # Record the attack
         self.added_attacks.append(self.current_attack)
 
-    def process_attack(self, attack: str, params: str):
+    def process_attack(self, attack: str, params: str, time=False):
         """
         Takes as input the name of an attack (classname) and the attack parameters as string. Parses the string of
         attack parameters, creates the attack by writing the attack packets and returns the path of the written pcap.
@@ -94,15 +94,24 @@ class AttackController:
         # Write attack into pcap file
         print("Generating attack packets...", end=" ")
         sys.stdout.flush()  # force python to print text immediately
+        if time:
+            self.current_attack.set_start_time()
+        self.current_attack.generate_attack_packets()
+        if time:
+            self.current_attack.set_finish_time()
+        duration = self.current_attack.get_packet_generation_time()
         total_packets, temp_attack_pcap_path = self.current_attack.generate_attack_pcap()
-        print("done. (total: " + str(total_packets) + " pkts.)")
+        print("done. (total: " + str(total_packets) + " pkts", end="")
+        if time:
+            print(" in ", duration, " seconds", end="")
+        print(".)")
 
         # Store label into LabelManager
         l = Label(attack, self.get_attack_start_utime(),
                   self.get_attack_end_utime(), attack_note)
         self.label_mgr.add_labels(l)
 
-        return temp_attack_pcap_path
+        return temp_attack_pcap_path, duration
 
     def get_attack_start_utime(self):
         """
@@ -123,4 +132,4 @@ class AttackController:
         :return: None
         """
         for param_key, param_value in params.items():
-            self.current_attack.add_param_value(param_key, param_value)
+            self.current_attack.add_param_value(param_key, param_value)

+ 7 - 2
code/ID2TLib/Controller.py

@@ -41,21 +41,26 @@ class Controller:
         """
         self.statistics.load_pcap_statistics(flag_write_file, flag_recalculate_stats, flag_print_statistics)
 
-    def process_attacks(self, attacks_config: list, seeds=[]):
+    def process_attacks(self, attacks_config: list, seeds=[], time=False):
         """
         Creates the attack based on the attack name and the attack parameters given in the attacks_config. The
         attacks_config is a list of attacks, e.g.
         [['PortscanAttack', 'ip.src="192.168.178.2",'dst.port=80'],['PortscanAttack', 'ip.src="10.10.10.2"]].
         Merges the individual temporary attack pcaps into one single pcap and merges this single pcap with the
         input dataset.
+
         :param attacks_config: A list of attacks with their attack parameters.
+        :param seeds: A list of random seeds for the given attacks.
+        :param time: Measure time for packet generation.
         """
         # load attacks sequentially
+        self.durations = []
         i = 0
         for attack in attacks_config:
             if len(seeds) > i:
                 self.attack_controller.set_seed(seed=seeds[i][0])
-            temp_attack_pcap = self.attack_controller.process_attack(attack[0], attack[1:])
+            temp_attack_pcap, duration = self.attack_controller.process_attack(attack[0], attack[1:], time)
+            self.durations.append(duration)
             self.written_pcaps.append(temp_attack_pcap)
             i += 1
 

+ 1 - 0
code/Test/ID2TAttackTest.py

@@ -27,6 +27,7 @@ class ID2TAttackTest(unittest.TestCase):
         :param flag_print_statistics: Prints the statistics on the terminal.
         :param attack_sub_dir: create sub-directory for each attack-class if True
         :param test_sub_dir: create sub-directory for each test-function/case if True
+        :param time: Measure time for packet generation.
         """
 
         controller = Ctrl.Controller(pcap_file_path=pcap, do_extra_tests=False)