Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
@param addrs: A sequence of IPRange class/subclass instances used to
pre-populate the set. Individual CIDR objects can be added and
removed after instantiation with the usual set methods, add() and
remove().
"""
for addr in addrs:
if isinstance(addr, IP):
self.add(addr.cidr())
if isinstance(addr, str):
try:
self.add(CIDR(addr))
except:
pass
try:
ip = IP(addr)
self.add(ip.cidr())
except:
pass
try:
ipglob = IPGlob(addr)
try:
self.add(ipglob.cidr())
except:
self.add(ipglob)
except:
pass
else:
self.add(addr)
pass
try:
obj = IPGlob(addr)
addrs[i] = obj
continue
except:
pass
# Find lowest and highest IP objects in address list.
addrs.sort()
lowest = addrs[0]
highest = addrs[-1]
if isinstance(lowest, IPRange):
# Create new IP as user may be returning address strings.
lowest = IP(lowest.first, lowest.addr_type)
if isinstance(highest, IPRange):
# Create new IP as user may be returning address strings.
highest = IP(highest.last, highest.addr_type)
if lowest.addr_type != highest.addr_type:
raise TypeError('address types are not the same!')
cidr = highest.cidr()
while cidr.prefixlen > 0:
if highest in cidr and lowest not in cidr:
cidr.prefixlen -= 1
else:
break
C{addr_type} arguments.
"""
if not isinstance(start, IP):
if isinstance(start, (str, unicode)):
start = IP(start)
else:
raise TypeError('start is not recognised address in string ' \
'format or IP class/subclass instance!')
else:
# Use start object's constructor as formatter.
if fmt is None:
fmt = start.__class__
if not isinstance(stop, IP):
if isinstance(stop, (str, unicode)):
stop = IP(stop)
else:
raise TypeError('stop is not recognised address string ' \
'or IP class/subclass instance!')
if not isinstance(step, (int, long)):
raise TypeError('step must be type int|long, not %s!' % type(step))
if start.addr_type != stop.addr_type:
raise TypeError('start and stop are not the same address type!')
if step == 0:
raise ValueError('step argument cannot be zero')
negative_step = False
addr_type = start.addr_type
"""
B{Please Note:} the IPv4-Mapped IPv6 address format is now considered
deprecated. Reference: RFC 4291
@param ipv4_compatible: If C{True} returns an IPv4-Mapped address
(::ffff:x.x.x.x), an IPv4-Compatible (::x.x.x.x) address
otherwise. Default: False (IPv4-Mapped).
@return: A new L{IP} version 6 object that is numerically equivalent
this address. If this object is already IPv6 then a copy of this
object is returned. If this object is IPv4, a new version 6 L{IP}
object is returned.
"""
ip_addr = None
if self.addr_type == AT_INET6:
ip_addr = IP(self.value, AT_INET6)
ip_addr.prefixlen = self.prefixlen - 96
elif self.addr_type == AT_INET:
ip_addr = IP(self.value, AT_INET6)
if ipv4_compatible:
# IPv4-Compatible IPv6 address
ip_addr[5] = 0
else:
# IPv4-Mapped IPv6 address
ip_addr[5] = 0xffff
ip_addr.prefixlen = self.prefixlen + 96
return ip_addr
if not len(addrs) > 1:
raise ValueError('sequence must contain 2 or more elements!')
if fmt not in (None, str, unicode):
raise ValueError('unsupported formatter %r!' % fmt)
# List is required.
if not isinstance(addrs, list):
addrs = list(addrs)
# Detect type of string address or address range and create the
# equivalent instance.
for (i, addr) in enumerate(addrs):
if isinstance(addr, (str, unicode)):
try:
obj = IP(addr)
addrs[i] = obj
continue
except:
pass
try:
obj = CIDR(addr)
addrs[i] = obj
continue
except:
pass
try:
obj = IPGlob(addr)
addrs[i] = obj
continue
except:
pass
def iter_host_addrs(self):
"""
@return: An iterator object providing access to all valid host IP
addresses within the specified CIDR block.
- with IPv4 the network and broadcast addresses are always
excluded. Any smaller than 4 hosts yields an emtpy list.
- with IPv6 only the unspecified address '::' is excluded from
the yielded list.
"""
if self.addr_type == AT_INET:
# IPv4
if self.size() >= 4:
return nrange( IP(self.first+1, self.addr_type),
IP(self.last-1, self.addr_type), fmt=self.fmt)
else:
return iter([])
elif self.addr_type == AT_INET6:
# IPv6
if self.first == 0:
# Don't return '::'.
return nrange(IP(self.first+1, self.addr_type),
IP(self.last, self.addr_type), fmt=self.fmt)
else:
return iter(self)
# This can probably be tidied up a bit but I'm really proud of this
# method. It is one seriously sweet piece of code!!!
cidr_list = []
# Get spanning CIDR covering both addresses.
start = IP(self.first, self.addr_type)
end = IP(self.last, self.addr_type)
cidr_span = CIDR.span_addrs([start, end])
if cidr_span.first == self.first and cidr_span.last == self.last:
# Spanning CIDR matches start and end exactly.
cidr_list = [cidr_span]
elif cidr_span.last == self.last:
# Spanning CIDR matches end exactly.
ip = IP(start)
first_int_val = int(ip)
ip -= 1
cidr_remainder = cidr_span - ip
first_found = False
for cidr in cidr_remainder:
if cidr.first == first_int_val:
first_found = True
if first_found:
cidr_list.append(cidr)
elif cidr_span.first == self.first:
# Spanning CIDR matches start exactly.
ip = IP(end)
last_int_val = int(ip)
ip += 1
cidr_remainder = cidr_span - ip
# Spanning CIDR overlaps start and end.
ip = IP(start)
first_int_val = int(ip)
ip -= 1
cidr_remainder = cidr_span - ip
# Fix start.
first_found = False
for cidr in cidr_remainder:
if cidr.first == first_int_val:
first_found = True
if first_found:
cidr_list.append(cidr)
# Fix end.
ip = IP(end)
last_int_val = int(ip)
ip += 1
cidr_remainder = cidr_list.pop() - ip
last_found = False
for cidr in cidr_remainder:
cidr_list.append(cidr)
if cidr.last == last_int_val:
break
# Return address list in requested format.
if self.fmt in (str, unicode):
cidr_list = [self.fmt(c) for c in cidr_list]
return cidr_list
if self.addr_type == AT_LINK:
# Modify MAC to make it an EUI-64.
suffix = ["%02x" % i for i in self[0:3]] + ['ff', 'fe'] + \
["%02x" % i for i in self[3:6]]
else:
suffix = ["%02x" % i for i in list(self)]
suffix = ["%02x%02x" % (int(x[0], 16), int(x[1], 16)) for x in \
zip(suffix[::2], suffix[1::2])]
# Subtract 2 again to return EUI to its original value.
self[0] -= 2
eui64 = ':'.join(suffix)
addr = prefix + eui64 + '/64'
return IP(addr)
can represent address ranges that do not fall on strict bit mask
boundaries. They are very suitable in configuration files being more
obvious and readable than their CIDR equivalents, especially for admins
and users without much networking knowledge or experience.}
I{All CIDR blocks can always be represented as ipglob ranges but the
reverse is not true. IPGlobs are almost but not quite as flexible
as IPRange objects.}
"""
STRATEGIES = (ST_IPV4,)
ADDR_TYPES = (AT_UNSPEC, AT_INET)
# Descriptor registrations.
strategy = StrategyDescriptor(STRATEGIES)
addr_type = AddrTypeDescriptor(ADDR_TYPES)
fmt = FormatDescriptor(IP)
def is_valid(ipglob):
"""
A static method that validates ipglob address ranges.
@param ipglob: an IPv4 ipglob address.
@return: True if ipglob address is valid, False otherwise.
"""
#TODO: Add support for abbreviated ipglobs
#TODO: e.g. 192.168.*.* == 192.168.*
#TODO: *.*.*.* == *
#TODO: Add strict flag to enable verbose ipglob checking.
seen_hyphen = False
seen_asterisk = False
try: