Created
February 25, 2021 08:33
-
-
Save tnibert/f7e13547d4702d43065b2f99ed0d1626 to your computer and use it in GitHub Desktop.
Check if an address is in a given subnet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env python3 | |
split_fields = lambda addr: [int(f) for f in addr.split(".")] | |
def check_subnet(prefix_addr: str, prefix_length: int, to_check: str): | |
""" | |
Determine if the IPv4 address to_check is within the given subnet | |
:param prefix_addr: address prefix as shown in CIDR notation | |
:param prefix_length: the number of bits in the network section | |
of the IP (subnet mask, as per CIDR notation) | |
:param to_check: the IP address to check if within the given subnet | |
:return: True if to_check is in the subnet specified by prefix_addr and prefix_length, else False | |
""" | |
# split apart the bytes making up the IPv4 address | |
pref_fields = split_fields(prefix_addr) | |
check_addr_fields = split_fields(to_check) | |
# assert valid IPs - each field limited to 8 bits | |
for field in pref_fields + check_addr_fields: | |
assert field < 256 | |
# identify the first varying field and the number of bits that are the same | |
bits_to_check = prefix_length % 8 | |
field_to_check = int(prefix_length / 8) | |
# confirm fully matching bytes do in fact match | |
if pref_fields[:field_to_check] != check_addr_fields[:field_to_check]: | |
return False | |
# check that the network bits in the first varying field match | |
shift = 8 - bits_to_check | |
return (pref_fields[field_to_check] >> shift) == (check_addr_fields[field_to_check] >> shift) | |
if __name__ == '__main__': | |
# is 10.0.65.13 in subnet 10.0.64.0/18? | |
assert check_subnet("10.0.64.0", 18, "10.0.65.13") | |
assert check_subnet("192.168.1.0", 24, "192.168.1.112") | |
assert not check_subnet("192.168.1.0", 24, "192.168.2.2") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment