#!/usr/bin/env python

## 
## netblock.py
## 
## 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)