kemonine
/
lollipopcloud
Archived
1
0
Fork 0
This repository has been archived on 2022-08-05. You can view files and clone it, but cannot push or open issues or pull requests.
lollipopcloud/hardware/rfc7050.py

79 lines
2.3 KiB
Python

#!/usr/bin/env python3
###############
# RFC7050 ipv6 prefix discovery
# Prefixes can have lengths 32, 40, 48, 56, 64, or 96 per RFC6052
# IMPORTANT: THIS DOES NOT HANDLE THE SUFFIX ASPECTS THAT MAY COME INTO PLAY ON SOME NETWORKS
###############
##########
# Dependencies
##########
# pip3 install dnspython
##########
# Sample T-Mobile record
##########
# ipv4only.arpa
# 192.0.0.170
# 192.0.0.171
# 2607:7700:0:26::c000:aa
# 2607:7700:0:26::c000:ab
##########
import ipaddress
import dns.resolver
##########
# Discovery of DNS records
##########
#TODO: Swap this to a well-known address that is ISP independent
# Sub domain with only an A record somewhere?
Update to handle the tweaked approach
resolver = dns.resolver.Resolver()
a_recs = resolver.query("ipv4only.arpa", "A")
aaaa_recs = resolver.query("ipv4only.arpa", "AAAA")
##########
# Process DNS records for prefix discovery process
##########
a_addresses = []
aaaa_addresses = []
for a in a_recs:
print(a)
a_addresses.append(ipaddress.IPv4Address(a.to_text()))
for aaaa in aaaa_recs:
print(aaaa)
aaaa_addresses.append(ipaddress.IPv6Address(aaaa.to_text()))
##########
# Figure out published prefixes
##########
prefixes = []
for aaaa in aaaa_addresses:
ipv6_bytes = aaaa.packed
for a in a_addresses:
ipv4_bytes = a.packed
# Split the bytes so we can find the prefix minus the ipv4 address and following info
partition = ipv6_bytes.partition(ipv4_bytes)
if partition[0] != ipv6_bytes:
# Padded to a full 16 bytes needed by the Python ipaddress module
mask_number_bytes = 16 - len(partition[0])
# Figure out the actual integer mask
mask = 128 - (mask_number_bytes * 8)
# Pad the prefix with 0's
prefix_bytes = partition[0] + bytearray(mask_number_bytes)
# Get the /128 address
address = ipaddress.IPv6Address(prefix_bytes)
# Build the compressed address + mask for output
prefix = '/'.join([str(address), str(mask)])
# De-duplicate the prefixes
# Some ISPs publish multiple records that result in identical prefixes
if prefix not in prefixes:
prefixes.append(prefix)
print(prefixes)