Browse Source

Revert "Refactor retrieval of router, i.e. most used, MAC address"

This reverts commit 501d619d988ea213caac0dcfdc19694f53739275.
dustin.born 6 years ago
parent
commit
0dcd2614dd
1 changed files with 72 additions and 19 deletions
  1. 72 19
      code/ID2TLib/PcapAddressOperations.py

+ 72 - 19
code/ID2TLib/PcapAddressOperations.py

@@ -16,13 +16,6 @@ class PcapAddressOperations():
         """
         """
         self.statistics = statistics
         self.statistics = statistics
         self.UNCERTAIN_IPSPACE_MULTIPLIER = uncertain_ip_mult
         self.UNCERTAIN_IPSPACE_MULTIPLIER = uncertain_ip_mult
-
-        stat_result = self.statistics.process_db_query("most_used(macAddress)", print_results=False)
-        if isinstance(stat_result, list):
-            self.probable_router_mac = choice(stat_result)
-        else:
-            self.probable_router_mac = stat_result
-
         self._init_ipaddress_ops()
         self._init_ipaddress_ops()
 
 
     def get_probable_router_mac(self):
     def get_probable_router_mac(self):
@@ -30,7 +23,8 @@ class PcapAddressOperations():
         Returns the most probable router MAC address based on the most used MAC address in the statistics.
         Returns the most probable router MAC address based on the most used MAC address in the statistics.
         :return: the MAC address
         :return: the MAC address
         """
         """
-        return self.probable_router_mac
+        self.probable_router_mac, count = self.statistics.process_db_query("most_used(macAddress)", print_results=False)[0]
+        return self.probable_router_mac     # and count as a measure of certainty?
 
 
     def pcap_contains_priv_ips(self):
     def pcap_contains_priv_ips(self):
         """
         """
@@ -86,6 +80,10 @@ class PcapAddressOperations():
         :return: the newly created local IP addresses
         :return: the newly created local IP addresses
         """
         """
 
 
+        # add more unused local ips to the pool, if needed
+        while len(self.unused_local_ips) < count and self.expand_unused_local_ips() == True:
+            pass
+
         unused_local_ips = self.unused_local_ips
         unused_local_ips = self.unused_local_ips
         uncertain_local_ips = self.uncertain_local_ips
         uncertain_local_ips = self.uncertain_local_ips
         count_certain = min(count, len(unused_local_ips))
         count_certain = min(count, len(unused_local_ips))
@@ -189,21 +187,76 @@ class PcapAddressOperations():
                 elif (not str(ip) == "255.255.255.255") and (not ip.is_localhost()) and (not ip.is_multicast()) and (not ip.is_reserved()) and (not ip.is_zero_conf()):
                 elif (not str(ip) == "255.255.255.255") and (not ip.is_localhost()) and (not ip.is_multicast()) and (not ip.is_reserved()) and (not ip.is_zero_conf()):
                     external_ips.add(ip)
                     external_ips.add(ip)
 
 
-        min_local_ip, max_local_ip = min(local_ips), max(local_ips)
-
         # save the certain unused local IPs of the network
         # save the certain unused local IPs of the network
-        unused_local_ips = set()
-        for i in range(min_local_ip.to_int() + 1, max_local_ip.to_int()):
-            ip = IPAddress.from_int(i)
-            if not ip in local_ips:
-                unused_local_ips.add(ip)
+        # to do that, divide the unused local Addressspace into chunks of (chunks_size) Addresses
+        # initally only the first chunk will be used, but more chunks can be added to the pool of unused_local_ips if needed
+        self.min_local_ip, self.max_local_ip = min(local_ips), max(local_ips)
+        local_ip_range = (self.max_local_ip.to_int()) - (self.min_local_ip.to_int() + 1)
+        if local_ip_range < 0:
+            # for min,max pairs like (1,1), (1,2) there is no free address in between, but for (1,1) local_ip_range may be -1, because 1-(1+1)=-1
+            local_ip_range = 0
+
+        # chunk size can be adjusted if needed
+        self.chunk_size = 200
+
+        self.current_chunk = 1
+        if local_ip_range < self.chunk_size:
+            # there are not more than chunk_size unused IP Addresses to begin with
+            self.chunks = 0
+            self.chunk_remainder = local_ip_range
+        else:
+            # determine how many chunks of (chunk_size) Addresses there are and the save the remainder
+            self.chunks = local_ip_range // self.chunk_size
+            self.chunk_remainder = local_ip_range % self.chunk_size
+
+        # add the first chunk of IP Addresses
+        self.unused_local_ips = set()
+        self.expand_unused_local_ips()
 
 
         # save the gathered information for efficient later use
         # save the gathered information for efficient later use
         self.external_ips = frozenset(external_ips)
         self.external_ips = frozenset(external_ips)
         self.remaining_external_ips = external_ips
         self.remaining_external_ips = external_ips
-        self.min_local_ip, self.max_local_ip = min_local_ip, max_local_ip
-        self.max_uncertain_local_ip = max_local_ip
+        self.max_uncertain_local_ip = self.max_local_ip
         self.local_ips = frozenset(local_ips)
         self.local_ips = frozenset(local_ips)
         self.remaining_local_ips = local_ips
         self.remaining_local_ips = local_ips
-        self.unused_local_ips = unused_local_ips
-        self.uncertain_local_ips = set()
+        self.uncertain_local_ips = set()
+
+    def expand_unused_local_ips(self):
+        """
+        expands the set of unused_local_ips by one chunk_size
+        to illustrate this algorithm: suppose we have a chunksize of 100 and an Address space of 1 to 1000 (1 and 1000 are unused too), we then have 10 chunks
+        every time this method is called, one chunk (100 Addresses) is added, each chunk starts at the base_address + the number of its chunk
+        then, every chunk_amounth'th Address is added. Therefore for 10 chunks, every 10th address is added
+        For the above example for the first, second and last call, we get the following IPs, respectively:
+        first Call:  1+0,  1+10,  1+20,  1+30, ...,  1+990
+        second Call: 2+0,  2+10,  2+20,  2+30, ...,  2+990
+        ten'th Call: 10+0, 10+10, 10+20, 10+30, ..., 10+990
+
+        :return: False if there are no more available unusd local IP Addresses, True otherwise
+        """
+
+        if self.current_chunk == self.chunks+1:
+            # all chunks are used up, therefore add the remainder
+            remainder_base_addr = self.min_local_ip.to_int() + self.chunks*self.chunk_size + 1
+            for i in range(0,self.chunk_remainder):
+                ip = IPAddress.from_int(remainder_base_addr + i)
+                self.unused_local_ips.add(ip)
+
+            self.current_chunk = self.current_chunk + 1
+            return True
+
+        elif self.current_chunk <= self.chunks:
+            # add another chunk
+            # choose IPs from the whole address space, that is available
+            base_address = self.min_local_ip.to_int() + self.current_chunk
+
+            for i in range(0,self.chunk_size):
+                ip = IPAddress.from_int(base_address + i*self.chunks)
+                self.unused_local_ips.add(ip)
+
+            self.current_chunk = self.current_chunk + 1
+            return True
+
+        else:
+            # no free IPs remaining
+            return False