corradomatt
corradomatt

Reputation: 186

Find next available IP address in python

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

Answers (5)

Manuel Jacob
Manuel Jacob

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

TheLazyScripter
TheLazyScripter

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

aghast
aghast

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

Padraic Cunningham
Padraic Cunningham

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

niemmi
niemmi

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

Related Questions