1 # Written by John Hoffman
2 # see LICENSE.txt for license information
4 from bisect import bisect, insort
11 bool = lambda x: not not x
17 raise ValueError, "bad address"
27 raise ValueError, "bad address"
28 if ip == '::': # boundary handling
33 raise ValueError, "bad address"
37 raise ValueError, "bad address"
41 for n in ip.split(':'):
42 if n == '': # double-colon
44 raise ValueError, "bad address"
48 if n.find('.') >= 0: # IPv4
51 raise ValueError, "bad address"
55 n = ('0'*(4-len(n))) + n
56 b.append(int(n[:2], 16))
57 b.append(int(n[2:], 16))
61 for i in xrange(17-len(b)):
68 ipv4addrmask = 65535L*256*256*256*256
72 self.ipv4list = [] # starts of ranges
73 self.ipv4dict = {} # start: end of ranges
74 self.ipv6list = [] # "
75 self.ipv6dict = {} # "
77 def __nonzero__(self):
78 return bool(self.ipv4list or self.ipv6list)
81 def append(self, ip_beg, ip_end = None):
85 assert ip_beg <= ip_end
86 if ip_beg.find(':') < 0: # IPv4
87 ip_beg = to_long_ipv4(ip_beg)
88 ip_end = to_long_ipv4(ip_end)
92 ip_beg = to_long_ipv6(ip_beg)
93 ip_end = to_long_ipv6(ip_end)
94 bb = ip_beg % (256*256*256*256)
95 if bb == ipv4addrmask:
104 pos = bisect(l, ip_beg)-1
110 if range_beg > ip_end+1:
113 range_end = d[range_beg]
114 if range_end < ip_beg-1:
120 # if neither of the above conditions is true, the ranges overlap
121 ip_beg = min(ip_beg, range_beg)
122 ip_end = max(ip_end, range_end)
131 def includes(self, ip):
132 if not (self.ipv4list or self.ipv6list):
134 if ip.find(':') < 0: # IPv4
135 ip = to_long_ipv4(ip)
139 ip = to_long_ipv6(ip)
140 bb = ip % (256*256*256*256)
141 if bb == ipv4addrmask:
148 for ip_beg in l[bisect(l, ip)-1:]:
152 if ip > ip_beg and ip <= ip_end:
157 # reads a list from a file in the format 'whatever:whatever:ip-ip'
158 # (not IPv6 compatible at all)
159 def read_rangelist(self, file):
166 if not line or line[0] == '#':
168 line = line.split(':')[-1]
170 ip1, ip2 = line.split('-')
175 self.append(ip1.strip(), ip2.strip())
177 print '*** WARNING *** could not parse IP range: '+line
181 return ip.find(':') < 0