Reputation: 186
Using python I need to find the next IP address given a range of IP addresses I've already used. So if I have a list of IP address like...
IPs = ['10.220.1.1','10.220.1.2','10.220.1.3','10.220.1.5']
When I ask for the next IP address I need it to return '10.220.1.4'. The next request would return '10.220.1.6' and so on.
Upvotes: 2
Views: 6183
Reputation: 2014
If you're using Python 3.3 (or newer), you can use the ipaddress
module. Example for all hosts in the subnet 10.220.1.0/24
except for those in reserved
:
from ipaddress import IPv4Network
network = IPv4Network('10.220.1.0/24')
reserved = {'10.220.1.1', '10.220.1.2', '10.220.1.3', '10.220.1.5'}
hosts_iterator = (host for host in network.hosts() if str(host) not in reserved)
# Using hosts_iterator:
print(next(hosts_iterator)) # prints 10.220.1.4
print(next(hosts_iterator)) # prints 10.220.1.6
print(next(hosts_iterator)) # prints 10.220.1.7
# Or you can iterate over hosts_iterator:
for host in hosts_iterator:
print(host)
So basically this can be done in a single line (+ imports and definition of network and reserved addresses).
Upvotes: 10
Reputation: 2665
Create a basic ip object to hold a record of your current ip and to get the next ip
class IPObj(object):
def __init__(self, list_of_ips):
self.position = 0
self.ips = list_of_ips
self.current_ip = self.ips[self.position]
def next_ip(self, stop_iteration=False):
'''
return the next ip in the list
'''
if self.position >= len(self.ips)-1:
self.position = 0 # By default next_ip will do nothing when it reaches the end but it will throw an exception if stop_iteration==True
if stop_iteration:
raise StopIteration
self.position += 1
self.current_ip = self.ips[self.position]
return self.current_ip
def __repr__(self):
return repr(self.current_ip)
#Testing
ips = IPObj(['10.220.1.1','10.220.1.2','10.220.1.3','10.220.1.5'])
print ips
while True:
print ips.next_ip(True),
Output: 10.220.1.1, 10.220.1.2, 10.220.1.3, 10.220.1.5,
Traceback (most recent call last):
File "C:\Users\J10ey\workspace\SO_Help\src\ip's.py", line 32, in print ips.next_ip(True) File "C:\Users\J10ey\workspace\SO_Help\src\ip's.py", line 21, in next_ip raise StopIteration StopIteration
Upvotes: 0
Reputation: 15310
Convert your list to a set, for performance:
used_ips = set(IPs)
Now generate your IP#'s however you would like, and check if they are contained in the set:
for next_ip in generate_ip_numbers():
if next_ip in used_ips:
continue
print("Next ip address is:", next_ip)
Upvotes: 0
Reputation: 180481
You can use an generator using the ipaddress module which is a bultin from python >= 3.3 or you can install with pip for earlier versions:
In [20]: from ipaddress import ip_network
In [21]: IPs = {'10.220.1.1','10.220.1.2','10.220.1.3','10.220.1.5'}
In [22]: net = ip_network(u"10.220.1.0/24")
In [23]: avail =(str(ip) for ip in net.hosts() if str(ip) not in IPs
....: )
In [24]: next(avail)
Out[24]: '10.220.1.4'
In [25]: next(avail)
Out[25]: '10.220.1.6'
Upvotes: 0
Reputation: 17263
If you're using Python 3 you could use ipaddress
with generator:
import ipaddress
def gen_ip(start, reserved):
start = int(ipaddress.IPv4Address(start))
for i in range(start + 1, int(2 ** 32) + 1):
ip = str(ipaddress.IPv4Address(i))
if ip not in reserved:
yield ip
IPs = ['10.220.1.1','10.220.1.2','10.220.1.3','10.220.1.5']
j = 0
for ip in gen_ip(min(IPs), set(IPs)):
print(ip)
j += 1
if j == 5:
break
Output:
10.220.1.4
10.220.1.6
10.220.1.7
10.220.1.8
10.220.1.9
Upvotes: 0