Ssravankumar Aditya
Ssravankumar Aditya

Reputation: 489

Python IP range to IP range match

Is there any method to check if some IP addresses from a network range are present in the subnets of another IP range?

Example: 10.0.1.0/18 in 123.1.0.0/8 

If it exists, I need it to return True, else False.

Upvotes: 3

Views: 8114

Answers (3)

E. Ducateme
E. Ducateme

Reputation: 4248

from ipaddress import ip_address, ip_network

NOTE: Other answers specifically point at IPv4Address, IPv4Network, but ip_address and ip_network simply call the IPv4 OR IPv6 version when needed.

addr = ip_address('10.0.1.0')

NOTE: the sample network you provided is not a true /8 network, so the ip_network will respond with an error of ValueError: 123.1.0.0/8 has host bits set

To get past this, by forcing the ipaddress library to essentially round down to the nearest network address, you can set strict=False and Python will find the nearest, lower address for a /8 network: 123.0.0.0

netw = ip_network('123.1.0.0/8', strict=False)

print(addr in netw)

Then it is simply a matter of testing using the in keyword.

If you want to test every address in a network range against every address in another network range, then:

net1 = ip_network('10.0.1.0/18', strict=False)
net2 = ip_network('123.1.0.0/8', strict=False)

for addr in net1:
    if addr in net2:
        print(addr, 'True')
    else:
        print(addr, 'False')

In addition, networks can be converted into sets:

n1 = set(net1)
n2 = set(net2)

And Python sets have the ability show any overlap OR inclusion (subset/superset relationships).

n1.isdisjoint(n2)
n1.issubset(n2)
n2.issubset(n1)
n2.issuperset(n1)

etc.

Upvotes: 4

Thierry Lathuille
Thierry Lathuille

Reputation: 24288

Since Python 3.3, you can use the ipaddress module of the standard library:

from ipaddress import IPv4Address, IPv4Network

IPv4Address('192.0.2.6') in IPv4Network('192.0.2.0/28')
# True
IPv4Address('10.0.1.0') in IPv4Network('192.0.2.0/28')
# False

If you mean if the networks overlap, use overlaps:

In [14]: IPv4Network('10.0.1.0/24').overlaps(IPv4Network('192.0.2.0/28'))
Out[14]: False

Note that this module was marked as provisional in Python 3.3, but no longer is in 3.6. So enjoy it!

Upvotes: 9

Eric Godard
Eric Godard

Reputation: 164

I think the accepted answer in this question should help you:

If you can't go for any reason on this link here is the answer:

import socket,struct

def makeMask(n):
    "return a mask of n bits as a long integer"
    return (2L<<n-1) - 1

def dottedQuadToNum(ip):
    "convert decimal dotted quad string to long integer"
    return struct.unpack('L',socket.inet_aton(ip))[0]

def networkMask(ip,bits):
    "Convert a network address to a long integer" 
    return dottedQuadToNum(ip) & makeMask(bits)

def addressInNetwork(ip,net):
   "Is an address in a network"
   return ip & net == net

address = dottedQuadToNum("192.168.1.1")
networka = networkMask("10.0.0.0",24)
networkb = networkMask("192.168.0.0",24)
print (address,networka,networkb)
print addressInNetwork(address,networka)
print addressInNetwork(address,networkb)

Return True or False (in the example first you have False then True).

Or in one function:

import socket,struct

def addressInNetwork(ip,net):
   "Is an address in a network"
   ipaddr = struct.unpack('L',socket.inet_aton(ip))[0]
   netaddr,bits = net.split('/')
   netmask = struct.unpack('L',socket.inet_aton(netaddr))[0] & ((2L<<int(bits)-1) - 1)
   return ipaddr & netmask == netmask

The answer is inspired by the question I linked, give credits to the people if it work for you.

Upvotes: 0

Related Questions