Check if two CIDR addresses intersect?
Asked Answered
U

5

25

Given two CIDR addresses say 192.168.2.0/14 and 192.168.2.0/32

How do I check if two ip addresses overlap in "python2.6"??

I have gone through netaddr and it allows to check if 192.168.2.0 is in CIDR address 192.168.2.0/14 by

from netaddr import IPNetwork, IPAddress
bool = IPAddress("192.168.2.0") in IPNetwork("192.168.2.0/14"):

But how to check for two CIDR address??

I found a reference :: How can I check if an ip is in a network in python

Unclassical answered 20/6, 2013 at 6:28 Comment(4)
FYI, 192.168.2.0/32 is a single IP address (192.168.2.0), not a subnet.Swen
Would you accept an answer that is not python specific?Swen
Thnx for the info. I need it in python but your explanation might be useful.Unclassical
My explanation would have been the same as rob's.Swen
A
42

Using ipaddr:

>>> import ipaddr
>>> n1 = ipaddr.IPNetwork('192.168.1.0/24')
>>> n2 = ipaddr.IPNetwork('192.168.2.0/24')
>>> n3 = ipaddr.IPNetwork('192.168.2.0/25')
>>> n1.overlaps(n2)
False
>>> n1.overlaps(n3)
False
>>> n2.overlaps(n3)
True
>>> n2.overlaps(n1)
False
Apothem answered 20/6, 2013 at 6:46 Comment(6)
Thanks the library does exactly what I want.Unclassical
Does the same code work for IPv6 as well or it supports IPv4 only?Unclassical
Work for IPv6. ipaddr.IPNetwork('::192.168.0.0/120').overlaps(ipaddr.IPNetwork('::192.168.0.0/121')) returns True and ipaddr.IPNetwork('::192.168.4.0/120').overlaps(ipaddr.IPNetwork('::192.168.0.0/121')) returns FalseApothem
Is there any solution in Powershell?Trombidiasis
Is there an online tool for this?Goda
It's now included in the standard library (ipaddress), see stackoverflow.com/a/77105792Carcanet
L
7

I'll assume you actually want both CIDRs to represent ranges, even though in your example, 192.168.2.0/32 represents only one address. Also note that in 192.168.2.0/14, the .2. is meaningless, because the 14-bit prefix doesn't reach the third octet.

Anyway, there are a several ways to do this. You could notice that for them to overlap, one must always be a subset of the other:

def cidrsOverlap(cidr0, cidr1):
    return cidr0 in cidr1 or cidr1 in cidr0

Or you could notice that for the ranges to overlap, the first range's lowest address must be less than or equal to the second range's highest address, and vice versa. Thus:

def cidrsOverlap(cidr0, cidr1):
    return cidr0.first <= cidr1.last and cidr1.first <= cidr0.last

print cidrsOverlap(IPNetwork('192.168.2.0/24'), IPNetwork('192.168.3.0/24'))
# prints False

print cidrsOverlap(IPNetwork('192.168.2.0/23'), IPNetwork('192.168.3.0/24'))
# prints True
Luger answered 20/6, 2013 at 6:42 Comment(3)
Thanks the range comparison works. One more thing, could you find out the ip addresses that are overlapped??Unclassical
The ip addresses that are overlapped is the subnet with the smaller range: that is, the higher number after the /. Therefore, between 192.168.2.0/23 and 192.168.2.0/24 the addresses that are overlapped are 192.168.2.0/24. Remember, CIDR subnet cannot "overlap". They can only contain a smaller CIDR subnet or not.Swen
@AJRedDevil Since one is always a subset of the other, the overlap is just the smaller range. The first address in the overlap (smaller range) is max(cidr0.first, cidr1.first). The last address is min(cidr0.last, cidr1.last).Luger
R
5

I wrote this simple command line tool, based on the netaddr lib.

pip install ipconflict

Example:

ipconflict 10.0.0.0/22 10.0.1.0/24

Output:

conflict found: 10.0.1.0/24 <-> 10.0.1.0/22
Ralleigh answered 4/6, 2019 at 13:33 Comment(0)
R
1

If don't have netaddr at hand for testing, but I think you could check if the first and last address of the first network are both contained in the second:

net_1 = IPNetwork("192.168.2.0/14")
net_2 = IPNetwork("192.168.2.0/32")
if net_1.first in net_2 and net_1.last in net_2:
    # do something

BTW, IPNetwork line 1102 defines a __contains__ method. But I'm not certain the line 1127 isn't broken ? You should test and report a bug if it is.

Romaine answered 20/6, 2013 at 6:41 Comment(0)
C
1

ipaddress was added in the in Python 3.3 standard library and is intended to replace what is explained in this answer.

from ipaddress import IPv4Network

n1 = IPv4Network('192.168.1.0/24')
n2 = IPv4Network('192.168.2.0/24')
n3 = IPv4Network('192.168.2.0/25')

n1.overlaps(n2)
# False
n1.overlaps(n3)
# False
n2.overlaps(n3)
# True
n2.overlaps(n1)
# False
Carcanet answered 14/9, 2023 at 14:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.