network-finder
network_finder
is a Python module for determining whether an IP address or
IP subnet is contained within another IP subnet. For example, 192.0.2.1
is
contained by 192.0.2.0/24
, and 192.0.2.0/24
is contained by 192.0.2.0/16
.
IPv6 addresses are supported.
CPython 3.4 and above, CPython 2.7, and PyPy are supported.
network-finder
is similar to
py-radix, but uses binary search
instead of prefix matching. It is slower than py-radix
, but can use less
memory.
Installation
To install automatically with pip
: pip install network-finder
To install manually, clone the repository and run: python setup.py install
When installing manually, by default a C extension (generated by Cython) will be built. Set the environment variable NO_CYTHON=true
to skip building the module. The C extension will not be built when using PyPy.
Usage
network-finder
's API is intentionally similar to py-radix
's. These examples
show how to build a list of subnets and then use them for matching.
from network_finder import NetworkFinder
network_finder = NetworkFinder()
cidr_data = {
'192.0.2.0/24': 'Local network',
'192.0.2.0/25': 'Trusted zone',
'192.0.2.128/25': 'Untrusted zone',
'192.0.2.254': 'Mainframe',
}
# You can set the `data` attribute on subnets when adding them
for key, value in cidr_data.items():
subnet = network_finder.add(key)
subnet.data = value
# search_exact requires the specific search term to be present
local_network = network_finder.search_exact('192.0.2.0/24')
assert network_finder.search_exact('192.0.2.0/32') is None
# search_best returns the smallest subnet that contains the search term
# (longest prefix match)
trusted_zone = network_finder.search_best('192.0.2.10')
assert network_finder.search_best('198.51.100.1') is None
# search_worst returns the largest subnet that contains the search term
# (shortest prefix match)
local_network = network_finder.search_worst('192.0.2.254')
assert network_finder.search_worst('198.51.100.1') is None
# search_covered returns a list of subnets that are contained within the search
# term.
local_ranges = network_finder.search_covered('192.0.2.0/24')
all_ranges = network_finder.search_covered('0.0.0.0/0')
assert local_ranges == all_ranges
# search_covering returns a list of subnets that contain the search term,.
names = [x.data for x in network_finder.search_covering('192.0.2.254')]
assert sorted(names) == ['Local network', 'Mainframe', 'Untrusted zone']