mirror of https://github.com/fail2ban/fail2ban
allow using of IPv6 address style mask (analog to the IPv4), for example: `2606:28ff::/ffff:ff80::` -> `2606:2880::/25`
fast calculating of maskplen using map table MAP_ADDR2MASKPLEN, with pre-calculated addr->maskplen values; test cases extended;pull/1415/head
parent
0c2eeee8c7
commit
4b5b16cd9f
|
@ -171,7 +171,7 @@ class IPAddr(object):
|
|||
# IP address without CIDR mask
|
||||
if len(s) > 2:
|
||||
raise ValueError("invalid ipstr %r, too many plen representation" % (ipstr,))
|
||||
if "." in s[1]: # 255.255.255.0 style mask
|
||||
if "." in s[1] or ":" in s[1]: # 255.255.255.0 resp. ffff:: style mask
|
||||
s[1] = IPAddr.masktoplen(s[1])
|
||||
s[1] = long(s[1])
|
||||
return s
|
||||
|
@ -235,7 +235,7 @@ class IPAddr(object):
|
|||
return self.ntoa
|
||||
|
||||
def __reduce__(self):
|
||||
"""IPAddr pickle-handler, that simple wrap IPAddr to the str
|
||||
"""IPAddr pickle-handler, that simply wraps IPAddr to the str
|
||||
|
||||
Returns a string as instance to be pickled, because fail2ban-client can't
|
||||
unserialize IPAddr objects
|
||||
|
@ -392,17 +392,29 @@ class IPAddr(object):
|
|||
|
||||
return (self.addr & mask) == net.addr
|
||||
|
||||
# Pre-calculated map: addr to maskplen
|
||||
def __getMaskMap():
|
||||
m6 = (1 << 128)-1
|
||||
m4 = (1 << 32)-1
|
||||
mmap = {m6: 128, m4: 32, 0: 0}
|
||||
m = 0
|
||||
for i in xrange(0, 128):
|
||||
m |= 1 << i
|
||||
if i < 32:
|
||||
mmap[m ^ m4] = 32-1-i
|
||||
mmap[m ^ m6] = 128-1-i
|
||||
return mmap
|
||||
|
||||
MAP_ADDR2MASKPLEN = __getMaskMap()
|
||||
|
||||
@property
|
||||
def maskplen(self):
|
||||
mplen = 0
|
||||
if self._maskplen is not None:
|
||||
return self._maskplen
|
||||
maddr = self._addr
|
||||
while maddr:
|
||||
if not (maddr & 0x80000000):
|
||||
raise ValueError("invalid mask %r, no plen representation" % (str(self),))
|
||||
maddr = (maddr << 1) & 0xFFFFFFFFL
|
||||
mplen += 1
|
||||
mplen = IPAddr.MAP_ADDR2MASKPLEN.get(self._addr)
|
||||
if mplen is None:
|
||||
raise ValueError("invalid mask %r, no plen representation" % (str(self),))
|
||||
self._maskplen = mplen
|
||||
return mplen
|
||||
|
||||
|
|
|
@ -1452,11 +1452,24 @@ class DNSUtilsNetworkTests(unittest.TestCase):
|
|||
self.assertEqual(IPAddr('93.184.0.1', 24).ntoa, '93.184.0.0/24')
|
||||
self.assertEqual(IPAddr('192.168.1.0/255.255.255.128').ntoa, '192.168.1.0/25')
|
||||
|
||||
self.assertEqual(IPAddr('93.184.0.1/32').ntoa, '93.184.0.1')
|
||||
self.assertEqual(IPAddr('93.184.0.1/255.255.255.255').ntoa, '93.184.0.1')
|
||||
|
||||
self.assertEqual(str(IPAddr('2606:2800:220:1:248:1893:25c8::', 120)), '2606:2800:220:1:248:1893:25c8:0/120')
|
||||
self.assertEqual(IPAddr('2606:2800:220:1:248:1893:25c8::', 120).ntoa, '2606:2800:220:1:248:1893:25c8:0/120')
|
||||
self.assertEqual(str(IPAddr('2606:2800:220:1:248:1893:25c8:0/120')), '2606:2800:220:1:248:1893:25c8:0/120')
|
||||
self.assertEqual(IPAddr('2606:2800:220:1:248:1893:25c8:0/120').ntoa, '2606:2800:220:1:248:1893:25c8:0/120')
|
||||
|
||||
self.assertEqual(str(IPAddr('2606:28ff:220:1:248:1893:25c8::', 25)), '2606:2880::/25')
|
||||
self.assertEqual(str(IPAddr('2606:28ff:220:1:248:1893:25c8::/ffff:ff80::')), '2606:2880::/25')
|
||||
self.assertEqual(str(IPAddr('2606:28ff:220:1:248:1893:25c8::/ffff:ffff:ffff:ffff:ffff:ffff:ffff::')),
|
||||
'2606:28ff:220:1:248:1893:25c8:0/112')
|
||||
|
||||
self.assertEqual(str(IPAddr('2606:28ff:220:1:248:1893:25c8::/128')),
|
||||
'2606:28ff:220:1:248:1893:25c8:0')
|
||||
self.assertEqual(str(IPAddr('2606:28ff:220:1:248:1893:25c8::/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')),
|
||||
'2606:28ff:220:1:248:1893:25c8:0')
|
||||
|
||||
def testIPAddr_CIDR_Repr(self):
|
||||
self.assertEqual(["127.0.0.0/8", "::/32", "2001:db8::/32"],
|
||||
[IPAddr("127.0.0.0", 8), IPAddr("::1", 32), IPAddr("2001:db8::", 32)]
|
||||
|
|
Loading…
Reference in New Issue