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))