Skip to content

Instantly share code, notes, and snippets.

@isofew
Created September 18, 2020 03:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save isofew/90eb1e421527ac12e2586edde28f4c6b to your computer and use it in GitHub Desktop.
Save isofew/90eb1e421527ac12e2586edde28f4c6b to your computer and use it in GitHub Desktop.
useful utils to help manipulate ip networks (e.g. get routes excluding a certain country)
#!/usr/bin/env python
import re
from math import log
from urllib.request import urlopen
from ipaddress import *
from intervaltree import *
from copy import deepcopy
# the default info url is only for ip addresses assigned from apnic (asia-pacific)
def ipv4_networks_by_country(country_code, info_url='https://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest'):
return list(collapse_addresses( [
IPv4Network( '{}/{}'.format( start_ip, 32 - int(log(int(num_ip), 2)) ) )
for start_ip, num_ip in \
re.findall(
r'apnic\|{}\|ipv4\|([0-9\.]+)\|([0-9]+)\|[0-9]+\|a.*'.format( country_code ),
urlopen(info_url).read().decode('utf8'),
re.IGNORECASE
)
] ))
def nets_to_tree(nets):
t = IntervalTree()
for net in nets:
t[ net[0] : net[-1] ] = True
return t
def tree_to_nets(tree):
return list(collapse_addresses( sum([
list( summarize_address_range(itvl.begin, itvl.end) )
for itvl in tree
], []) ))
def chop_from(tree1, tree2):
tree1 = deepcopy(tree1)
for itvl in tree2:
tree1.chop(itvl.begin - 1, itvl.end + 1)
return tree1
def get_nets_noncn():
nets_cn = ipv4_networks_by_country('cn') + [
IPv4Network('10.0.0.0/8'),
IPv4Network('172.16.0.0/12'),
IPv4Network('192.168.0.0/16')
]
tree_cn = nets_to_tree(nets_cn)
tree_all = nets_to_tree([ IPv4Network('0.0.0.0/0') ])
tree_noncn = chop_from(tree_all, tree_cn)
nets_non_cn = tree_to_nets(tree_noncn)
return nets_non_cn
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment