Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
@param strict: (optional) If True and non-zero bits are found to the
right of the subnet mask/prefix a ValueError is raised. If False,
CIDR returned has these bits automatically truncated.
(default: True)
@param expand_abbrev: (optional) If True, enables the abbreviated CIDR
expansion routine. If False, abbreviated CIDRs will be considered
invalid addresses, raising an AddrFormatError exception.
(default: True)
"""
cidr_arg = cidr # Keep a copy of original argument.
if expand_abbrev:
# Replace an abbreviation with a verbose CIDR.
verbose_cidr = CIDR.abbrev_to_verbose(cidr)
if verbose_cidr is not None:
cidr = verbose_cidr
if not isinstance(cidr, (str, unicode)):
raise TypeError('%r is not a valid CIDR!' % cidr)
# Check for prefix in address and extract it.
try:
(network, mask) = cidr.split('/', 1)
except ValueError:
network = cidr
mask = None
#FIXME: Are IP objects for first and last really necessary?
#FIXME: Should surely just be integer values.
first = IP(network)
def compact(self):
"""
Compact/summarize internal list of IP addresses and CIDRs.
"""
if self._dirty:
self._cidrs = CIDR.summarize(self._cidrs)
self._dirty = False
def cidrs(self):
"""
@return: A list of a copy of this L{CIDR} object. This method is here
mainly for compatibility with IPRange interface.
"""
cidr_copy = CIDR('%s/%d' % (self.strategy.int_to_str(self.first),
self.prefixlen))
# Respect formatting.
if self.fmt in (str, unicode):
return [self.fmt(cidr_copy)]
return [cidr_copy]
def is_reserved(self):
"""
@return: C{True} if this IP is in IANA reserved range, C{False}
otherwise. Reference: RFCs 3330 and 3171.
"""
if self.addr_type == AT_INET:
# Use of ipglobs here much more concise than CIDR...
for cidr in (CIDR('240/4'), CIDR('234/7'), CIDR('236/7'),
IPGlob('225-231.*.*.*'), IPGlob('234-238.*.*.*')):
if self in cidr:
return True
if self.addr_type == AT_INET6:
for cidr in (CIDR('ff00::/12'),CIDR('::/8'), CIDR('0100::/8'),
CIDR('0200::/7'), CIDR('0400::/6'), CIDR('0800::/5'),
CIDR('1000::/4'), CIDR('4000::/3'), CIDR('6000::/3'),
CIDR('8000::/3'), CIDR('A000::/3'), CIDR('C000::/3'),
CIDR('E000::/4'), CIDR('F000::/5'), CIDR('F800::/6'),
CIDR('FE00::/9')):
if self in cidr:
return True
return False
def is_multicast(self):
"""@return: C{True} if this IP is multicast, C{False} otherwise"""
if self.addr_type == AT_INET:
return self in CIDR('224/4')
elif self.addr_type == AT_INET6:
return self in CIDR('ff00::/8')
def is_private(self):
"""
@return: C{True} if this IP is for internal/private use only
(i.e. non-public), C{False} otherwise. Reference: RFCs 1918,
3330, 4193, 3879 and 2365.
"""
if self.addr_type == AT_INET:
for cidr in (CIDR('192.168/16'), CIDR('10/8'),CIDR('172.16/12'),
CIDR('192.0.2.0/24'), CIDR('239.192/14')):
if self in cidr:
return True
elif self.addr_type == AT_INET6:
# Please Note: FEC0::/10 has been deprecated! See RFC 3879.
return self in CIDR('fc00::/7') # ULAs - Unique Local Addresses
if self.is_link_local():
return True
return False
if count is None:
count = max_count
if not 1 <= count <= max_count:
raise ValueError('count not within current CIDR boundaries!')
base_address = self.strategy.int_to_str(self.first)
# Respect self.fmt value if one wasn't passed to the method.
if fmt is None and self.fmt in (str, unicode):
fmt = self.fmt
if fmt is None:
# Create new CIDR instances for each subnet returned.
for i in xrange(count):
cidr = CIDR('%s/%d' % (base_address, prefixlen))
cidr.first += cidr.size() * i
cidr.prefixlen = prefixlen
yield cidr
elif fmt in (str, unicode):
# Keep the same CIDR and just modify it.
for i in xrange(count):
cidr = CIDR('%s/%d' % (base_address, prefixlen))
cidr.first += cidr.size() * i
cidr.prefixlen = prefixlen
yield fmt(cidr)
else:
raise TypeError('unsupported fmt callable %r' % fmt)
def is_reserved(self):
"""
@return: C{True} if this IP is in IANA reserved range, C{False}
otherwise. Reference: RFCs 3330 and 3171.
"""
if self.addr_type == AT_INET:
# Use of ipglobs here much more concise than CIDR...
for cidr in (CIDR('240/4'), CIDR('234/7'), CIDR('236/7'),
IPGlob('225-231.*.*.*'), IPGlob('234-238.*.*.*')):
if self in cidr:
return True
if self.addr_type == AT_INET6:
for cidr in (CIDR('ff00::/12'),CIDR('::/8'), CIDR('0100::/8'),
CIDR('0200::/7'), CIDR('0400::/6'), CIDR('0800::/5'),
CIDR('1000::/4'), CIDR('4000::/3'), CIDR('6000::/3'),
CIDR('8000::/3'), CIDR('A000::/3'), CIDR('C000::/3'),
CIDR('E000::/4'), CIDR('F000::/5'), CIDR('F800::/6'),
CIDR('FE00::/9')):
if self in cidr:
return True
return False
def add(self, cidr):
"""
Adds a CIDR or IP address to this group.
@param cidr: the CIDR/IP address to be added.
"""
if hasattr(cidr, 'value'):
# An IP object.
cidr = cidr.cidr()
elif not hasattr(cidr, 'first'):
# Anything that isn't a CIDR object or IP object.
cidr = CIDR(cidr, strict=False, expand_abbrev=False)
self._cidrs.append(cidr)
self._dirty = True
def cidr_to_bits(cidr):
"""
@param cidr: a CIDR object or CIDR string value (acceptable by CIDR class
constructor).
@return: a tuple containing CIDR in binary string format and addr_type.
"""
if not hasattr(cidr, 'network'):
cidr = CIDR(cidr, strict=False)
bits = cidr.network.bits(word_sep='')
return (bits[0:cidr.prefixlen], cidr.addr_type)