Skip to content

Instantly share code, notes, and snippets.

@Dlat
Created March 22, 2023 04:02
Show Gist options
  • Save Dlat/86d7caa68fe6490b2d3dae52b3ab38ff to your computer and use it in GitHub Desktop.
Save Dlat/86d7caa68fe6490b2d3dae52b3ab38ff to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
##
## netblock.py
## https://rmccurdy.com/.scripts/downloaded/
## Author: Michal Ludvig <michal@logix.cz>
## http://www.logix.cz/michal
##
## Simple tool to compute an IPv4 netblock covering
## all IP addresses given on the command line.
##
## For example:
## ~$ netblock 1.2.3.4 1.2.3.255
## 1.2.3.0/24
##
## ~$ netblock 192.168.131.12 192.168.137.1 192.168.144.9
## 192.168.128.0/19
##
import sys
import socket
import struct
# functions dottedQuadToNum(), numToDottedQuad() and makeMask() taken
# from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66517
# and made endian-agnostic
def dottedQuadToNum(ip):
"convert decimal dotted quad string to long integer"
return struct.unpack('>L',socket.inet_aton(ip))[0]
def numToDottedQuad(n):
"convert long int to dotted quad string"
return socket.inet_ntoa(struct.pack('>L',n))
def makeMask(n):
"return a mask of n bits as a long integer"
return ~((2L<<n-1)-1)
def commonSubnet(ips):
"compute a netblock covering all IPs in list 'ips'"
ipn = [dottedQuadToNum(ips.pop(0)), dottedQuadToNum(ips.pop(0))]
ipnum = ipn[0] ^ ipn[1]
for i in range(31, 0, -1):
if ipnum & (1L<<i) != 0:
i += 1
break
mask = makeMask(i)
net = numToDottedQuad(ipn[0] & mask)
if ips:
return commonSubnet([net] + ips)
return net, 32-i
if __name__ == "__main__":
try:
print "%s/%d" % commonSubnet(sys.argv[1:])
except:
print "Usage: %s <ip1> <ip2> ... <ipN>"
sys.exit(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment