How can I get a list of the IP addresses or host names from a local network easily in Python?
It would be best if it was multi-platform, but it needs to work on Mac OS X first, then others follow.
Edit: By local I mean all active addresses within a local network, such as 192.168.xxx.xxx
.
So, if the IP address of my computer (within the local network) is 192.168.1.1
, and I have three other connected computers, I would want it to return the IP addresses 192.168.1.2
, 192.168.1.3
, 192.168.1.4
, and possibly their hostnames.
This question is related to
python
networking
If you know the names of your computers you can use:
import socket
IP1 = socket.gethostbyname(socket.gethostname()) # local IP adress of your computer
IP2 = socket.gethostbyname('name_of_your_computer') # IP adress of remote computer
Otherwise you will have to scan for all the IP addresses that follow the same mask as your local computer (IP1), as stated in another answer.
Update: The script is now located on github.
I wrote a small python script, that leverages scapy's arping()
.
Here is a small tool scanip that will help you to get all ip addresses and their corresponding mac addresses in the network (Works on Linux).
Here is a small tool scanip that will help you to get all ip addresses and their corresponding mac addresses in the network (Works on Linux).
One of the answers in this question might help you. There seems to be a platform agnostic version for python, but I haven't tried it yet.
I found this network scanner in python article and wrote this short code. It does what you want! You do however need to know accessible ports for your devices. Port 22 is ssh standard and what I am using. I suppose you could loop over all ports. Some defaults are:
linux: [20, 21, 22, 23, 25, 80, 111, 443, 445, 631, 993, 995]
windows: [135, 137, 138, 139, 445]
mac: [22, 445, 548, 631]
import socket
def connect(hostname, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.setdefaulttimeout(1)
result = sock.connect_ex((hostname, port))
sock.close()
return result == 0
for i in range(0,255):
res = connect("192.168.1."+str(i), 22)
if res:
print("Device found at: ", "192.168.1."+str(i) + ":"+str(22))
One of the answers in this question might help you. There seems to be a platform agnostic version for python, but I haven't tried it yet.
I have collected the following functionality from some other threads and it works for me in Ubuntu.
import os
import socket
import multiprocessing
import subprocess
import os
def pinger(job_q, results_q):
"""
Do Ping
:param job_q:
:param results_q:
:return:
"""
DEVNULL = open(os.devnull, 'w')
while True:
ip = job_q.get()
if ip is None:
break
try:
subprocess.check_call(['ping', '-c1', ip],
stdout=DEVNULL)
results_q.put(ip)
except:
pass
def get_my_ip():
"""
Find my IP address
:return:
"""
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
ip = s.getsockname()[0]
s.close()
return ip
def map_network(pool_size=255):
"""
Maps the network
:param pool_size: amount of parallel ping processes
:return: list of valid ip addresses
"""
ip_list = list()
# get my IP and compose a base like 192.168.1.xxx
ip_parts = get_my_ip().split('.')
base_ip = ip_parts[0] + '.' + ip_parts[1] + '.' + ip_parts[2] + '.'
# prepare the jobs queue
jobs = multiprocessing.Queue()
results = multiprocessing.Queue()
pool = [multiprocessing.Process(target=pinger, args=(jobs, results)) for i in range(pool_size)]
for p in pool:
p.start()
# cue hte ping processes
for i in range(1, 255):
jobs.put(base_ip + '{0}'.format(i))
for p in pool:
jobs.put(None)
for p in pool:
p.join()
# collect he results
while not results.empty():
ip = results.get()
ip_list.append(ip)
return ip_list
if __name__ == '__main__':
print('Mapping...')
lst = map_network()
print(lst)
I have done following code to get the IP of MAC known device. This can be modified accordingly to obtain all IPs with some string manipulation. Hope this will help you.
#running windows cmd line statement and put output into a string
cmd_out = os.popen("arp -a").read()
line_arr = cmd_out.split('\n')
line_count = len(line_arr)
#search in all lines for ip
for i in range(0, line_count):
y = line_arr[i]
z = y.find(mac_address)
#if mac address is found then get the ip using regex matching
if z > 0:
ip_out= re.search('[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+', y, re.M | re.I)
Try:
import socket
print ([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][:1])
For OSX (and Linux), a simple solution is to use either os.popen or os.system and run the arp -a
command.
For example:
devices = []
for device in os.popen('arp -a'): devices.append(device)
This will give you a list of the devices on your local network.
Update: The script is now located on github.
I wrote a small python script, that leverages scapy's arping()
.
If you know the names of your computers you can use:
import socket
IP1 = socket.gethostbyname(socket.gethostname()) # local IP adress of your computer
IP2 = socket.gethostbyname('name_of_your_computer') # IP adress of remote computer
Otherwise you will have to scan for all the IP addresses that follow the same mask as your local computer (IP1), as stated in another answer.
One of the answers in this question might help you. There seems to be a platform agnostic version for python, but I haven't tried it yet.
I have collected the following functionality from some other threads and it works for me in Ubuntu.
import os
import socket
import multiprocessing
import subprocess
import os
def pinger(job_q, results_q):
"""
Do Ping
:param job_q:
:param results_q:
:return:
"""
DEVNULL = open(os.devnull, 'w')
while True:
ip = job_q.get()
if ip is None:
break
try:
subprocess.check_call(['ping', '-c1', ip],
stdout=DEVNULL)
results_q.put(ip)
except:
pass
def get_my_ip():
"""
Find my IP address
:return:
"""
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
ip = s.getsockname()[0]
s.close()
return ip
def map_network(pool_size=255):
"""
Maps the network
:param pool_size: amount of parallel ping processes
:return: list of valid ip addresses
"""
ip_list = list()
# get my IP and compose a base like 192.168.1.xxx
ip_parts = get_my_ip().split('.')
base_ip = ip_parts[0] + '.' + ip_parts[1] + '.' + ip_parts[2] + '.'
# prepare the jobs queue
jobs = multiprocessing.Queue()
results = multiprocessing.Queue()
pool = [multiprocessing.Process(target=pinger, args=(jobs, results)) for i in range(pool_size)]
for p in pool:
p.start()
# cue hte ping processes
for i in range(1, 255):
jobs.put(base_ip + '{0}'.format(i))
for p in pool:
jobs.put(None)
for p in pool:
p.join()
# collect he results
while not results.empty():
ip = results.get()
ip_list.append(ip)
return ip_list
if __name__ == '__main__':
print('Mapping...')
lst = map_network()
print(lst)
I have done following code to get the IP of MAC known device. This can be modified accordingly to obtain all IPs with some string manipulation. Hope this will help you.
#running windows cmd line statement and put output into a string
cmd_out = os.popen("arp -a").read()
line_arr = cmd_out.split('\n')
line_count = len(line_arr)
#search in all lines for ip
for i in range(0, line_count):
y = line_arr[i]
z = y.find(mac_address)
#if mac address is found then get the ip using regex matching
if z > 0:
ip_out= re.search('[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+', y, re.M | re.I)
If you know the names of your computers you can use:
import socket
IP1 = socket.gethostbyname(socket.gethostname()) # local IP adress of your computer
IP2 = socket.gethostbyname('name_of_your_computer') # IP adress of remote computer
Otherwise you will have to scan for all the IP addresses that follow the same mask as your local computer (IP1), as stated in another answer.
I found this network scanner in python article and wrote this short code. It does what you want! You do however need to know accessible ports for your devices. Port 22 is ssh standard and what I am using. I suppose you could loop over all ports. Some defaults are:
linux: [20, 21, 22, 23, 25, 80, 111, 443, 445, 631, 993, 995]
windows: [135, 137, 138, 139, 445]
mac: [22, 445, 548, 631]
import socket
def connect(hostname, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.setdefaulttimeout(1)
result = sock.connect_ex((hostname, port))
sock.close()
return result == 0
for i in range(0,255):
res = connect("192.168.1."+str(i), 22)
if res:
print("Device found at: ", "192.168.1."+str(i) + ":"+str(22))
Try:
import socket
print ([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][:1])
If you know the names of your computers you can use:
import socket
IP1 = socket.gethostbyname(socket.gethostname()) # local IP adress of your computer
IP2 = socket.gethostbyname('name_of_your_computer') # IP adress of remote computer
Otherwise you will have to scan for all the IP addresses that follow the same mask as your local computer (IP1), as stated in another answer.
For OSX (and Linux), a simple solution is to use either os.popen or os.system and run the arp -a
command.
For example:
devices = []
for device in os.popen('arp -a'): devices.append(device)
This will give you a list of the devices on your local network.
Source: Stackoverflow.com