Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Author: Robin Gohmert
- # Date: 25.07.2014
- # =============================================================================
- # >> IMPORTS
- # =============================================================================
- # Python
- import ctypes
- import socket
- import struct
- import threading
- import time
- import Queue
- # =============================================================================
- # >> CLASSES
- # =============================================================================
- class ScanNetwork(threading.Thread):
- '''
- Scans a network for IP addresses and their MAC addresses.
- '''
- def __init__(self, queue):
- '''
- Initializes the thread.
- @<queue>:
- A Queue.Queue object filled with IP addresses to scan.
- '''
- super(ScanNetwork, self).__init__()
- self.queue = queue
- self.results = set()
- def run(self):
- '''
- Runs until <self.queue> is empty.
- All results are stored in <self.results>.
- '''
- # Run until the queue is empty
- while not self.queue.empty():
- # Get the next IP address
- ip = self.queue.get()
- try:
- # Try to resolve the MAC address using ARP
- mac = get_macaddress(ip)
- except WindowsError:
- # Do nothing if it failed.
- pass
- else:
- # Else add the result to the result set
- self.results.add((ip, mac))
- finally:
- # Tell the queue that an IP address has been proceeded
- self.queue.task_done()
- # =============================================================================
- # >> FUNCTIONS
- # =============================================================================
- def get_macaddress(host):
- '''
- Returns the MAC address of a network host, requires >= WIN2K.
- http://code.activestate.com/recipes/347812-get-the-mac-address-of-a-remote-computer/
- '''
- # Check for api availability
- try:
- SendARP = ctypes.windll.Iphlpapi.SendARP
- except:
- raise NotImplementedError('Usage only on Windows 2000 and above')
- # Doesn't work with loopbacks, but let's try and help.
- if host == '127.0.0.1' or host.lower() == 'localhost':
- host = socket.gethostname()
- # gethostbyname blocks, so use it wisely.
- try:
- inetaddr = ctypes.windll.wsock32.inet_addr(host)
- if inetaddr in (0, -1):
- raise Exception
- except:
- hostip = socket.gethostbyname(host)
- inetaddr = ctypes.windll.wsock32.inet_addr(hostip)
- buffer = ctypes.c_buffer(6)
- addlen = ctypes.c_ulong(ctypes.sizeof(buffer))
- if SendARP(inetaddr, 0, ctypes.byref(buffer), ctypes.byref(addlen)) != 0:
- raise WindowsError('Retreival of mac address(%s) - failed' % host)
- # Convert binary data into a string.
- macaddr = ''
- for intval in struct.unpack('BBBBBB', buffer):
- if intval > 15:
- replacestr = '0x'
- else:
- replacestr = 'x'
- macaddr = ''.join([macaddr, hex(intval).replace(replacestr, '')])
- return ':'.join(macaddr[x:x+2] for x in xrange(0, len(macaddr), 2)).upper()
- def scan_network(range1=range(0, 256), range2=range(0, 256),
- range3=range(0, 256), range4=range(0, 256), thread_count=64):
- '''
- Scans a network for IP adresses and their MAC addresses.
- The <rangeX> parameters specify the search ranges. <thread_count> is used
- to define how many threads should be used to finish the task.
- EXAMPLE:
- scan_network([172], [25], [30], thread_count=256)
- This will do a scan from 172.25.30.0 to 172.25.30.255 with 256 threads
- running.
- '''
- # Validate the thread count
- if thread_count <= 0:
- raise ValueError('There must be at least one thread.')
- # Validate the search range
- for scan_range in (range1, range2, range3, range4):
- if any(map(lambda x: not 0 <= x <= 255, scan_range)):
- raise ValueError('Every search range must be between 0 and 255.')
- print 'Start scanning...'
- start_time = time.time()
- # Create queue and fill it with tasks
- queue = Queue.Queue()
- ip_count = 0
- for part1 in range1:
- for part2 in range2:
- for part3 in range3:
- for part4 in range4:
- ip_count += 1
- queue.put('%s.%s.%s.%s'% (part1, part2, part3, part4))
- # Start the threads
- threads = set()
- for i in xrange(thread_count):
- thread = ScanNetwork(queue)
- threads.add(thread)
- thread.start()
- # Wait until all tasks are done
- queue.join()
- # Get all results
- results = set()
- for thread in threads:
- results.update(thread.results)
- # Print out all results sorted by the IP
- for ip, mac in sorted(results, key=lambda result: result[0]):
- print 'IP: %s | MAC: %s'% (ip.ljust(15), mac)
- # Print some general information
- print 'Scan finished.'
- print 'Time elapsed: %s seconds.'% (time.time() - start_time)
- print 'Scanned %s different IP addresses.'% ip_count
- print 'Found %s MAC adresses.'% len(results)
- print 'Thread count: %s'% thread_count
- # Also return the results
- return results
- # =============================================================================
- # >> MAIN
- # =============================================================================
- def main():
- scan_network([172], [25], [30], thread_count=256)
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment