You are not logged in Log in Join
You are here: Home » Members » Tino Wildenhain » Authentication supporting CIDR » lib/python/Shared/Tino/IPHelper.py » View File

Log in
Name

Password

 

lib/python/Shared/Tino/IPHelper.py

File details
Size
3 K
File type
text/plain

File contents

import string
class IPv4:
    """ Simple class for IPv4 parsing, used as quick conversion if its really sure we
        get valid and complete 4-tuples. (in our case from REMOTE_ADDR and friends)
        It has much lesser overhead then the IPv4CIDR class below
    """
    def __init__(self,ipstr):
        # ipstr in the form 'a.b.c.d'
        self.maskbits=32L
        self.mask=4294967295L
        # constants since this is a host address
        ipl=map(long,ipstr.split('.',3))
        # sum them up
        self.ip=min(reduce(lambda x,y:(x<<8L)+y,ipl),4294967294L)
    def __str__(self):
        ip=self.ip
        s=[]
        while ip:
            ip,r=divmod(ip,256)
            s.insert(0,str(r))
        s=(['0','0','0','0']+s)[-4:]
        if self.maskbits<32:
            return(string.join(s,'.')+'/'+str(self.maskbits))
        return(string.join(s,'.'))
    def __repr__(self):
        return("IPv4('%s')" % self)
    
    def __getitem__(self,key):
        if key:
            raise IndexError('list index out of range')
        else: return self

    def __eq__(self,other):
        return((other.ip & other.mask) == (self.ip & other.mask))
                    
class IPv4CIDR(IPv4):
    """ Helper class for IPv4 handling. Uses CIDR (classless interdomain routing) notation
        for subnets (or supernets, respectively)
        It should only trow exceptions during instantiation and only if something is completely
        wrong.

        Use:  a=IPv4CIDR('192.168.15.5')
              n1=IPv4CIDR('192.168.15.0/24')
              n2=IPv4CIDR('172.16.0.0/18')

              a == n1 -> returns true (1)
              a == n2 -> returns false (0)
              a in [n1,n2] -> returns true (1) because a is in subnet n1               
    """
    def __init__(self,ipstr):
        # ipstr in CIDR notation: ip/hostbits
        # if /hostbits are ommited, /32 is assumed
        # we have to check for the magic star first
        if ipstr:
            if ipstr[-1]=='*':
                ipstr=(ipstr[:-1]+'0.'*(4-ipstr.count('.')))[:-1]+'/'+str(ipstr.count('.')*8)
            ips,masks=(ipstr.split('/')+['32',])[:2]
            self.maskbits=min(long(masks),32L)
            self.mask=min(4294967296L-(1L<<(32-self.maskbits)),4294967295L)
            ipl=map(long,ips.split('.',3))
            # now a bit magic... 
            self.ip=min(reduce(lambda x,y:(x<<8L)+y,ipl[:-1]+[0L,]*(4-len(ipl))+ipl[-1:]),4294967294L)
            # and voil� - we have ip and mask with simple bound-checking
        else:
            self.mask=0
            self.maskbits=0
            self.ip=0

    def __repr__(self):
        return("IPv4CIDR('%s')" % self)

    def __eq__(self,other):
        # we check which might be the host (or smaller subnet)
        if self.maskbits>other.maskbits:
            return((other.ip & other.mask) == ((self.ip & self.mask) & other.mask))
        else:
            return((self.ip & self.mask) == ((other.ip & other.mask) & self.mask))