+class InetAddress (object):
+ def __init__(me, addrstr, maskstr = None):
+ me.addr = me._addrstr_to_int(addrstr)
+ if maskstr is None:
+ me.mask = -1
+ elif maskstr.isdigit():
+ me.mask = (1 << 32) - (1 << 32 - int(maskstr))
+ else:
+ me.mask = me._addrstr_to_int(maskstr)
+ if me.addr&~me.mask:
+ raise ValueError('network contains bits set beyond mask')
+ def _addrstr_to_int(me, addrstr):
+ return unpack('>L', S.inet_aton(addrstr))[0]
+ def _int_to_addrstr(me, n):
+ return S.inet_ntoa(pack('>L', n))
+ def sockaddr(me, port = 0):
+ if me.mask != -1: raise ValueError('not a simple address')
+ return me._int_to_addrstr(me.addr), port
+ def __str__(me):
+ addrstr = me._int_to_addrstr(me.addr)
+ if me.mask == -1:
+ return addrstr
+ else:
+ inv = me.mask ^ ((1 << 32) - 1)
+ if (inv&(inv + 1)) == 0:
+ return '%s/%d' % (addrstr, 32 - inv.bit_length())
+ else:
+ return '%s/%s' % (addrstr, me._int_to_addrstr(me.mask))
+ def withinp(me, net):
+ if (me.mask&net.mask) != net.mask: return False
+ if (me.addr ^ net.addr)&net.mask: return False
+ return True
+ def eq(me, other):
+ if me.mask != other.mask: return False
+ if me.addr != other.addr: return False
+ return True
+ @classmethod
+ def from_sockaddr(cls, sa):
+ addr, port = (lambda a, p: (a, p))(*sa)
+ return cls(addr), port
+
+def parse_address(addrstr, maskstr = None):
+ return InetAddress(addrstr, maskstr)