#!/usr/bin/python
# deaggregate.py - deaggregate a network for a specific subnet, yielding the minimum number of subnets
# Add -exclude to only output the surrounding subnets. Subnet is read from stdin, all non matching subnets
# are output untouched. Use as a filter, rinse, repeat.
# Simeon Miteff <simeon@localloop.co.za>
#
#Copyright (c) 2008 Simeon Miteff
#
#Permission is hereby granted, free of charge, to any person obtaining a copy
#of this software and associated documentation files (the "Software"), to 
#deal in the Software without restriction, including without limitation the 
#rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 
#sell copies of the Software, and to permit persons to whom the Software is 
#furnished to do so, subject to the following conditions:
#
#The above copyright notice and this permission notice shall be included in 
#all copies or substantial portions of the Software.
# 
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
#THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
#FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 
#IN THE SOFTWARE.

from IPy import IP
import sys

def split(ip,sub,exclude):
    if ip==sub:
        if not exclude:
            print ip
    else:
        a = IP(str(ip.net())+'/'+str(ip.prefixlen()+1))
        b = IP(str(IP(ip.net().int()|2**(32-(ip.prefixlen()+1))))+'/'+str(ip.prefixlen()+1))
        if a.overlaps(sub):
            print b
            split(a,sub,exclude)
        elif b.overlaps(sub):
            print a
            split(b,sub,exclude)

if __name__=="__main__":
    if len(sys.argv)<2:
        sys.stderr.write("Usage: %s CIDR_prefix [-exclude]\n" % sys.argv[0]) 
        sys.exit(1)
    
    sub = IP(sys.argv[1])
    
    exclude = False
    if len(sys.argv)==3:
        if sys.argv[2]=='-exclude':
            exclude = True
    
    for line in sys.stdin:
        pre = IP(line.strip())
        if not pre.overlaps(sub):
            print line.strip()
        else:
            split(pre,sub,exclude)

