Ayuto

Scan Network

Jul 25th, 2014
230
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.61 KB | None | 0 0
  1. # Author:   Robin Gohmert
  2. # Date:     25.07.2014
  3.  
  4. # =============================================================================
  5. # >> IMPORTS
  6. # =============================================================================
  7. # Python
  8. import ctypes
  9. import socket
  10. import struct
  11. import threading
  12. import time
  13. import Queue
  14.  
  15.  
  16. # =============================================================================
  17. # >> CLASSES
  18. # =============================================================================
  19. class ScanNetwork(threading.Thread):
  20.     '''
  21.    Scans a network for IP addresses and their MAC addresses.
  22.    '''
  23.  
  24.     def __init__(self, queue):
  25.         '''
  26.        Initializes the thread.
  27.  
  28.        @<queue>:
  29.        A Queue.Queue object filled with IP addresses to scan.
  30.        '''
  31.  
  32.         super(ScanNetwork, self).__init__()
  33.         self.queue = queue
  34.         self.results = set()
  35.  
  36.     def run(self):
  37.         '''
  38.        Runs until <self.queue> is empty.
  39.  
  40.        All results are stored in <self.results>.
  41.        '''
  42.  
  43.         # Run until the queue is empty
  44.         while not self.queue.empty():
  45.             # Get the next IP address
  46.             ip = self.queue.get()
  47.  
  48.             try:
  49.                 # Try to resolve the MAC address using ARP
  50.                 mac = get_macaddress(ip)
  51.             except WindowsError:
  52.                 # Do nothing if it failed.
  53.                 pass
  54.             else:
  55.                 # Else add the result to the result set
  56.                 self.results.add((ip, mac))
  57.             finally:
  58.                 # Tell the queue that an IP address has been proceeded
  59.                 self.queue.task_done()
  60.  
  61.  
  62. # =============================================================================
  63. # >> FUNCTIONS
  64. # =============================================================================
  65. def get_macaddress(host):
  66.     '''
  67.    Returns the MAC address of a network host, requires >= WIN2K.
  68.  
  69.    http://code.activestate.com/recipes/347812-get-the-mac-address-of-a-remote-computer/
  70.    '''
  71.  
  72.     # Check for api availability
  73.     try:
  74.         SendARP = ctypes.windll.Iphlpapi.SendARP
  75.     except:
  76.         raise NotImplementedError('Usage only on Windows 2000 and above')
  77.  
  78.     # Doesn't work with loopbacks, but let's try and help.
  79.     if host == '127.0.0.1' or host.lower() == 'localhost':
  80.         host = socket.gethostname()
  81.  
  82.     # gethostbyname blocks, so use it wisely.
  83.     try:
  84.         inetaddr = ctypes.windll.wsock32.inet_addr(host)
  85.         if inetaddr in (0, -1):
  86.             raise Exception
  87.     except:
  88.         hostip = socket.gethostbyname(host)
  89.         inetaddr = ctypes.windll.wsock32.inet_addr(hostip)
  90.  
  91.     buffer = ctypes.c_buffer(6)
  92.     addlen = ctypes.c_ulong(ctypes.sizeof(buffer))
  93.     if SendARP(inetaddr, 0, ctypes.byref(buffer), ctypes.byref(addlen)) != 0:
  94.         raise WindowsError('Retreival of mac address(%s) - failed' % host)
  95.  
  96.     # Convert binary data into a string.
  97.     macaddr = ''
  98.     for intval in struct.unpack('BBBBBB', buffer):
  99.         if intval > 15:
  100.             replacestr = '0x'
  101.         else:
  102.             replacestr = 'x'
  103.         macaddr = ''.join([macaddr, hex(intval).replace(replacestr, '')])
  104.  
  105.     return ':'.join(macaddr[x:x+2] for x in xrange(0, len(macaddr), 2)).upper()
  106.  
  107. def scan_network(range1=range(0, 256), range2=range(0, 256),
  108.         range3=range(0, 256), range4=range(0, 256), thread_count=64):
  109.     '''
  110.    Scans a network for IP adresses and their MAC addresses.
  111.  
  112.    The <rangeX> parameters specify the search ranges. <thread_count> is used
  113.    to define how many threads should be used to finish the task.
  114.  
  115.    EXAMPLE:
  116.    scan_network([172], [25], [30], thread_count=256)
  117.  
  118.    This will do a scan from 172.25.30.0 to 172.25.30.255 with 256 threads
  119.    running.
  120.    '''
  121.  
  122.     # Validate the thread count
  123.     if thread_count <= 0:
  124.         raise ValueError('There must be at least one thread.')
  125.  
  126.     # Validate the search range
  127.     for scan_range in (range1, range2, range3, range4):
  128.         if any(map(lambda x: not 0 <= x <= 255, scan_range)):
  129.             raise ValueError('Every search range must be between 0 and 255.')
  130.  
  131.     print 'Start scanning...'
  132.     start_time = time.time()
  133.  
  134.     # Create queue and fill it with tasks
  135.     queue = Queue.Queue()
  136.     ip_count = 0
  137.     for part1 in range1:
  138.         for part2 in range2:
  139.             for part3 in range3:
  140.                 for part4 in range4:
  141.                     ip_count += 1
  142.                     queue.put('%s.%s.%s.%s'% (part1, part2, part3, part4))
  143.  
  144.     # Start the threads
  145.     threads = set()
  146.     for i in xrange(thread_count):
  147.         thread = ScanNetwork(queue)
  148.         threads.add(thread)
  149.         thread.start()
  150.  
  151.     # Wait until all tasks are done
  152.     queue.join()
  153.  
  154.     # Get all results
  155.     results = set()
  156.     for thread in threads:
  157.         results.update(thread.results)
  158.  
  159.     # Print out all results sorted by the IP
  160.     for ip, mac in sorted(results, key=lambda result: result[0]):
  161.         print 'IP: %s | MAC: %s'% (ip.ljust(15), mac)
  162.  
  163.     # Print some general information
  164.     print 'Scan finished.'
  165.     print 'Time elapsed: %s seconds.'% (time.time() - start_time)
  166.     print 'Scanned %s different IP addresses.'% ip_count
  167.     print 'Found %s MAC adresses.'% len(results)
  168.     print 'Thread count: %s'% thread_count
  169.  
  170.     # Also return the results
  171.     return results
  172.  
  173.  
  174. # =============================================================================
  175. # >> MAIN
  176. # =============================================================================
  177. def main():
  178.     scan_network([172], [25], [30], thread_count=256)
  179.  
  180. if __name__ == '__main__':
  181.     main()
Advertisement
Add Comment
Please, Sign In to add comment