Various small tools
netblock.py source
Project updated · 3 August 2008
#!/usr/bin/env python
##
## netblock.py
##
## Author: Michal Ludvig <michal@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)