Calculating IP range reversals with Python 3's ipaddress
In a random Slack, far far away, somebody asked "has anyone seen a tool that will give you the complement set of CIDR ip address range that you give it? e.g. I have an allow-list :arrow_right: magic tool :arrow_right: I now have a deny-list"
.
I replied hrrm.. that's going to get a bit messy, but you could use the ipaddress module in python3 to do this.
.
Then:
>>> from ipaddress import ip_network
>>> n1 = ip_network('0.0.0.0/0')
>>> n2 = ip_network('192.168.0.0/24')
>>> list(n1.address_exclude(n2))
[IPv4Network('0.0.0.0/1'), IPv4Network('128.0.0.0/2'), IPv4Network('224.0.0.0/3'), IPv4Network('208.0.0.0/4'), IPv4Network('200.0.0.0/5'), IPv4Network('196.0.0.0/6'), IPv4Network('194.0.0.0/7'), IPv4Network('193.0.0.0/8'), IPv4Network('192.0.0.0/9'), IPv4Network('192.192.0.0/10'), IPv4Network('192.128.0.0/11'), IPv4Network('192.176.0.0/12'), IPv4Network('192.160.0.0/13'), IPv4Network('192.172.0.0/14'), IPv4Network('192.170.0.0/15'), IPv4Network('192.169.0.0/16'), IPv4Network('192.168.128.0/17'), IPv4Network('192.168.64.0/18'), IPv4Network('192.168.32.0/19'), IPv4Network('192.168.16.0/20'), IPv4Network('192.168.8.0/21'), IPv4Network('192.168.4.0/22'), IPv4Network('192.168.2.0/23'), IPv4Network('192.168.1.0/24')]
And after some further thought:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
... which looks like this when run:
$ ./complement-my-nets.py 1.0.0.0/8,2.0.0.0/8,10.0.0.0/8,192.168.0.0/24
=> 0.0.0.0/8,3.0.0.0/8,4.0.0.0/6,8.0.0.0/7,11.0.0.0/8,12.0.0.0/6,16.0.0.0/4,32.0.0.0/3,64.0.0.0/2,128.0.0.0/2,192.0.0.0/9,192.128.0.0/11,192.160.0.0/13,192.168.1.0/24,192.168.2.0/23,192.168.4.0/22,192.168.8.0/21,192.168.16.0/20,192.168.32.0/19,192.168.64.0/18,192.168.128.0/17,192.169.0.0/16,192.170.0.0/15,192.172.0.0/14,192.176.0.0/12,192.192.0.0/10,193.0.0.0/8,194.0.0.0/7,196.0.0.0/6,200.0.0.0/5,208.0.0.0/4,224.0.0.0/3
$ ./complement-my-nets.py 0.0.0.0/8,3.0.0.0/8,4.0.0.0/6,8.0.0.0/7,11.0.0.0/8,12.0.0.0/6,16.0.0.0/4,32.0.0.0/3,64.0.0.0/2,128.0.0.0/2,192.0.0.0/9,192.128.0.0/11,192.160.0.0/13,192.168.1.0/24,192.168.2.0/23,192.168.4.0/22,192.168.8.0/21,192.168.16.0/20,192.168.32.0/19,192.168.64.0/18,192.168.128.0/17,192.169.0.0/16,192.170.0.0/15,192.172.0.0/14,192.176.0.0/12,192.192.0.0/10,193.0.0.0/8,194.0.0.0/7,196.0.0.0/6,200.0.0.0/5,208.0.0.0/4,224.0.0.0/3
=> 1.0.0.0/8,2.0.0.0/8,10.0.0.0/8,192.168.0.0/24
The final message in that thread? "nice nets"
.
For more on Python 3's ipaddress, see https://docs.python.org/3/library/ipaddress.html.