fix vendor
This commit is contained in:
273
vendor/netaddr/strategy/__init__.py
vendored
Normal file
273
vendor/netaddr/strategy/__init__.py
vendored
Normal file
@@ -0,0 +1,273 @@
|
||||
#-----------------------------------------------------------------------------
|
||||
# Copyright (c) 2008 by David P. D. Moss. All rights reserved.
|
||||
#
|
||||
# Released under the BSD license. See the LICENSE file for details.
|
||||
#-----------------------------------------------------------------------------
|
||||
"""
|
||||
Shared logic for various address types.
|
||||
"""
|
||||
import re as _re
|
||||
|
||||
from netaddr.compat import _range, _is_str
|
||||
|
||||
|
||||
def bytes_to_bits():
|
||||
"""
|
||||
:return: A 256 element list containing 8-bit binary digit strings. The
|
||||
list index value is equivalent to its bit string value.
|
||||
"""
|
||||
lookup = []
|
||||
bits_per_byte = _range(7, -1, -1)
|
||||
for num in range(256):
|
||||
bits = 8 * [None]
|
||||
for i in bits_per_byte:
|
||||
bits[i] = '01'[num & 1]
|
||||
num >>= 1
|
||||
lookup.append(''.join(bits))
|
||||
return lookup
|
||||
|
||||
#: A lookup table of 8-bit integer values to their binary digit bit strings.
|
||||
BYTES_TO_BITS = bytes_to_bits()
|
||||
|
||||
|
||||
def valid_words(words, word_size, num_words):
|
||||
"""
|
||||
:param words: A sequence of unsigned integer word values.
|
||||
|
||||
:param word_size: Width (in bits) of each unsigned integer word value.
|
||||
|
||||
:param num_words: Number of unsigned integer words expected.
|
||||
|
||||
:return: ``True`` if word sequence is valid for this address type,
|
||||
``False`` otherwise.
|
||||
"""
|
||||
if not hasattr(words, '__iter__'):
|
||||
return False
|
||||
|
||||
if len(words) != num_words:
|
||||
return False
|
||||
|
||||
max_word = 2 ** word_size - 1
|
||||
|
||||
for i in words:
|
||||
if not 0 <= i <= max_word:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def int_to_words(int_val, word_size, num_words):
|
||||
"""
|
||||
:param int_val: Unsigned integer to be divided into words of equal size.
|
||||
|
||||
:param word_size: Width (in bits) of each unsigned integer word value.
|
||||
|
||||
:param num_words: Number of unsigned integer words expected.
|
||||
|
||||
:return: A tuple contain unsigned integer word values split according
|
||||
to provided arguments.
|
||||
"""
|
||||
max_int = 2 ** (num_words * word_size) - 1
|
||||
|
||||
if not 0 <= int_val <= max_int:
|
||||
raise IndexError('integer out of bounds: %r!' % hex(int_val))
|
||||
|
||||
max_word = 2 ** word_size - 1
|
||||
|
||||
words = []
|
||||
for _ in range(num_words):
|
||||
word = int_val & max_word
|
||||
words.append(int(word))
|
||||
int_val >>= word_size
|
||||
|
||||
return tuple(reversed(words))
|
||||
|
||||
|
||||
def words_to_int(words, word_size, num_words):
|
||||
"""
|
||||
:param words: A sequence of unsigned integer word values.
|
||||
|
||||
:param word_size: Width (in bits) of each unsigned integer word value.
|
||||
|
||||
:param num_words: Number of unsigned integer words expected.
|
||||
|
||||
:return: An unsigned integer that is equivalent to value represented
|
||||
by word sequence.
|
||||
"""
|
||||
if not valid_words(words, word_size, num_words):
|
||||
raise ValueError('invalid integer word sequence: %r!' % (words,))
|
||||
|
||||
int_val = 0
|
||||
for i, num in enumerate(reversed(words)):
|
||||
word = num
|
||||
word = word << word_size * i
|
||||
int_val = int_val | word
|
||||
|
||||
return int_val
|
||||
|
||||
|
||||
def valid_bits(bits, width, word_sep=''):
|
||||
"""
|
||||
:param bits: A network address in a delimited binary string format.
|
||||
|
||||
:param width: Maximum width (in bits) of a network address (excluding
|
||||
delimiters).
|
||||
|
||||
:param word_sep: (optional) character or string used to delimit word
|
||||
groups (default: '', no separator).
|
||||
|
||||
:return: ``True`` if network address is valid, ``False`` otherwise.
|
||||
"""
|
||||
if not _is_str(bits):
|
||||
return False
|
||||
|
||||
if word_sep != '':
|
||||
bits = bits.replace(word_sep, '')
|
||||
|
||||
if len(bits) != width:
|
||||
return False
|
||||
|
||||
max_int = 2 ** width - 1
|
||||
|
||||
try:
|
||||
if 0 <= int(bits, 2) <= max_int:
|
||||
return True
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def bits_to_int(bits, width, word_sep=''):
|
||||
"""
|
||||
:param bits: A network address in a delimited binary string format.
|
||||
|
||||
:param width: Maximum width (in bits) of a network address (excluding
|
||||
delimiters).
|
||||
|
||||
:param word_sep: (optional) character or string used to delimit word
|
||||
groups (default: '', no separator).
|
||||
|
||||
:return: An unsigned integer that is equivalent to value represented
|
||||
by network address in readable binary form.
|
||||
"""
|
||||
if not valid_bits(bits, width, word_sep):
|
||||
raise ValueError('invalid readable binary string: %r!' % (bits,))
|
||||
|
||||
if word_sep != '':
|
||||
bits = bits.replace(word_sep, '')
|
||||
|
||||
return int(bits, 2)
|
||||
|
||||
|
||||
def int_to_bits(int_val, word_size, num_words, word_sep=''):
|
||||
"""
|
||||
:param int_val: An unsigned integer.
|
||||
|
||||
:param word_size: Width (in bits) of each unsigned integer word value.
|
||||
|
||||
:param num_words: Number of unsigned integer words expected.
|
||||
|
||||
:param word_sep: (optional) character or string used to delimit word
|
||||
groups (default: '', no separator).
|
||||
|
||||
:return: A network address in a delimited binary string format that is
|
||||
equivalent in value to unsigned integer.
|
||||
"""
|
||||
bit_words = []
|
||||
|
||||
for word in int_to_words(int_val, word_size, num_words):
|
||||
bits = []
|
||||
while word:
|
||||
bits.append(BYTES_TO_BITS[word & 255])
|
||||
word >>= 8
|
||||
bits.reverse()
|
||||
bit_str = ''.join(bits) or '0' * word_size
|
||||
bits = ('0' * word_size + bit_str)[-word_size:]
|
||||
bit_words.append(bits)
|
||||
|
||||
if word_sep != '':
|
||||
# Check custom separator.
|
||||
if not _is_str(word_sep):
|
||||
raise ValueError('word separator is not a string: %r!' % (word_sep,))
|
||||
|
||||
return word_sep.join(bit_words)
|
||||
|
||||
|
||||
def valid_bin(bin_val, width):
|
||||
"""
|
||||
:param bin_val: A network address in Python's binary representation format
|
||||
('0bxxx').
|
||||
|
||||
:param width: Maximum width (in bits) of a network address (excluding
|
||||
delimiters).
|
||||
|
||||
:return: ``True`` if network address is valid, ``False`` otherwise.
|
||||
"""
|
||||
if not _is_str(bin_val):
|
||||
return False
|
||||
|
||||
if not bin_val.startswith('0b'):
|
||||
return False
|
||||
|
||||
bin_val = bin_val.replace('0b', '')
|
||||
|
||||
if len(bin_val) > width:
|
||||
return False
|
||||
|
||||
max_int = 2 ** width - 1
|
||||
|
||||
try:
|
||||
if 0 <= int(bin_val, 2) <= max_int:
|
||||
return True
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def int_to_bin(int_val, width):
|
||||
"""
|
||||
:param int_val: An unsigned integer.
|
||||
|
||||
:param width: Maximum allowed width (in bits) of a unsigned integer.
|
||||
|
||||
:return: Equivalent string value in Python's binary representation format
|
||||
('0bxxx').
|
||||
"""
|
||||
bin_tokens = []
|
||||
|
||||
try:
|
||||
# Python 2.6.x and upwards.
|
||||
bin_val = bin(int_val)
|
||||
except NameError:
|
||||
# Python 2.4.x and 2.5.x
|
||||
i = int_val
|
||||
while i > 0:
|
||||
word = i & 0xff
|
||||
bin_tokens.append(BYTES_TO_BITS[word])
|
||||
i >>= 8
|
||||
|
||||
bin_tokens.reverse()
|
||||
bin_val = '0b' + _re.sub(r'^[0]+([01]+)$', r'\1', ''.join(bin_tokens))
|
||||
|
||||
if len(bin_val[2:]) > width:
|
||||
raise IndexError('binary string out of bounds: %s!' % (bin_val,))
|
||||
|
||||
return bin_val
|
||||
|
||||
|
||||
def bin_to_int(bin_val, width):
|
||||
"""
|
||||
:param bin_val: A string containing an unsigned integer in Python's binary
|
||||
representation format ('0bxxx').
|
||||
|
||||
:param width: Maximum allowed width (in bits) of a unsigned integer.
|
||||
|
||||
:return: An unsigned integer that is equivalent to value represented
|
||||
by Python binary string format.
|
||||
"""
|
||||
if not valid_bin(bin_val, width):
|
||||
raise ValueError('not a valid Python binary string: %r!' % (bin_val,))
|
||||
|
||||
return int(bin_val.replace('0b', ''), 2)
|
296
vendor/netaddr/strategy/eui48.py
vendored
Normal file
296
vendor/netaddr/strategy/eui48.py
vendored
Normal file
@@ -0,0 +1,296 @@
|
||||
#-----------------------------------------------------------------------------
|
||||
# Copyright (c) 2008 by David P. D. Moss. All rights reserved.
|
||||
#
|
||||
# Released under the BSD license. See the LICENSE file for details.
|
||||
#-----------------------------------------------------------------------------
|
||||
"""
|
||||
IEEE 48-bit EUI (MAC address) logic.
|
||||
|
||||
Supports numerous MAC string formats including Cisco's triple hextet as well
|
||||
as bare MACs containing no delimiters.
|
||||
"""
|
||||
import struct as _struct
|
||||
import re as _re
|
||||
|
||||
# Check whether we need to use fallback code or not.
|
||||
try:
|
||||
from socket import AF_LINK
|
||||
except ImportError:
|
||||
AF_LINK = 48
|
||||
|
||||
from netaddr.core import AddrFormatError
|
||||
from netaddr.compat import _is_str
|
||||
from netaddr.strategy import (
|
||||
valid_words as _valid_words, int_to_words as _int_to_words,
|
||||
words_to_int as _words_to_int, valid_bits as _valid_bits,
|
||||
bits_to_int as _bits_to_int, int_to_bits as _int_to_bits,
|
||||
valid_bin as _valid_bin, int_to_bin as _int_to_bin,
|
||||
bin_to_int as _bin_to_int)
|
||||
|
||||
#: The width (in bits) of this address type.
|
||||
width = 48
|
||||
|
||||
#: The AF_* constant value of this address type.
|
||||
family = AF_LINK
|
||||
|
||||
#: A friendly string name address type.
|
||||
family_name = 'MAC'
|
||||
|
||||
#: The version of this address type.
|
||||
version = 48
|
||||
|
||||
#: The maximum integer value that can be represented by this address type.
|
||||
max_int = 2 ** width - 1
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Dialect classes.
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
class mac_eui48(object):
|
||||
"""A standard IEEE EUI-48 dialect class."""
|
||||
#: The individual word size (in bits) of this address type.
|
||||
word_size = 8
|
||||
|
||||
#: The number of words in this address type.
|
||||
num_words = width // word_size
|
||||
|
||||
#: The maximum integer value for an individual word in this address type.
|
||||
max_word = 2 ** word_size - 1
|
||||
|
||||
#: The separator character used between each word.
|
||||
word_sep = '-'
|
||||
|
||||
#: The format string to be used when converting words to string values.
|
||||
word_fmt = '%.2X'
|
||||
|
||||
#: The number base to be used when interpreting word values as integers.
|
||||
word_base = 16
|
||||
|
||||
|
||||
class mac_unix(mac_eui48):
|
||||
"""A UNIX-style MAC address dialect class."""
|
||||
word_size = 8
|
||||
num_words = width // word_size
|
||||
word_sep = ':'
|
||||
word_fmt = '%x'
|
||||
word_base = 16
|
||||
|
||||
|
||||
class mac_unix_expanded(mac_unix):
|
||||
"""A UNIX-style MAC address dialect class with leading zeroes."""
|
||||
word_fmt = '%.2x'
|
||||
|
||||
|
||||
class mac_cisco(mac_eui48):
|
||||
"""A Cisco 'triple hextet' MAC address dialect class."""
|
||||
word_size = 16
|
||||
num_words = width // word_size
|
||||
word_sep = '.'
|
||||
word_fmt = '%.4x'
|
||||
word_base = 16
|
||||
|
||||
|
||||
class mac_bare(mac_eui48):
|
||||
"""A bare (no delimiters) MAC address dialect class."""
|
||||
word_size = 48
|
||||
num_words = width // word_size
|
||||
word_sep = ''
|
||||
word_fmt = '%.12X'
|
||||
word_base = 16
|
||||
|
||||
|
||||
class mac_pgsql(mac_eui48):
|
||||
"""A PostgreSQL style (2 x 24-bit words) MAC address dialect class."""
|
||||
word_size = 24
|
||||
num_words = width // word_size
|
||||
word_sep = ':'
|
||||
word_fmt = '%.6x'
|
||||
word_base = 16
|
||||
|
||||
#: The default dialect to be used when not specified by the user.
|
||||
DEFAULT_DIALECT = mac_eui48
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
#: Regular expressions to match all supported MAC address formats.
|
||||
RE_MAC_FORMATS = (
|
||||
# 2 bytes x 6 (UNIX, Windows, EUI-48)
|
||||
'^' + ':'.join(['([0-9A-F]{1,2})'] * 6) + '$',
|
||||
'^' + '-'.join(['([0-9A-F]{1,2})'] * 6) + '$',
|
||||
|
||||
# 4 bytes x 3 (Cisco)
|
||||
'^' + ':'.join(['([0-9A-F]{1,4})'] * 3) + '$',
|
||||
'^' + '-'.join(['([0-9A-F]{1,4})'] * 3) + '$',
|
||||
'^' + r'\.'.join(['([0-9A-F]{1,4})'] * 3) + '$',
|
||||
|
||||
# 6 bytes x 2 (PostgreSQL)
|
||||
'^' + '-'.join(['([0-9A-F]{5,6})'] * 2) + '$',
|
||||
'^' + ':'.join(['([0-9A-F]{5,6})'] * 2) + '$',
|
||||
|
||||
# 12 bytes (bare, no delimiters)
|
||||
'^(' + ''.join(['[0-9A-F]'] * 12) + ')$',
|
||||
'^(' + ''.join(['[0-9A-F]'] * 11) + ')$',
|
||||
)
|
||||
# For efficiency, each string regexp converted in place to its compiled
|
||||
# counterpart.
|
||||
RE_MAC_FORMATS = [_re.compile(_, _re.IGNORECASE) for _ in RE_MAC_FORMATS]
|
||||
|
||||
|
||||
def valid_str(addr):
|
||||
"""
|
||||
:param addr: An IEEE EUI-48 (MAC) address in string form.
|
||||
|
||||
:return: ``True`` if MAC address string is valid, ``False`` otherwise.
|
||||
"""
|
||||
for regexp in RE_MAC_FORMATS:
|
||||
try:
|
||||
match_result = regexp.findall(addr)
|
||||
if len(match_result) != 0:
|
||||
return True
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def str_to_int(addr):
|
||||
"""
|
||||
:param addr: An IEEE EUI-48 (MAC) address in string form.
|
||||
|
||||
:return: An unsigned integer that is equivalent to value represented
|
||||
by EUI-48/MAC string address formatted according to the dialect
|
||||
settings.
|
||||
"""
|
||||
words = []
|
||||
if _is_str(addr):
|
||||
found_match = False
|
||||
for regexp in RE_MAC_FORMATS:
|
||||
match_result = regexp.findall(addr)
|
||||
if len(match_result) != 0:
|
||||
found_match = True
|
||||
if isinstance(match_result[0], tuple):
|
||||
words = match_result[0]
|
||||
else:
|
||||
words = (match_result[0],)
|
||||
break
|
||||
if not found_match:
|
||||
raise AddrFormatError('%r is not a supported MAC format!' % (addr,))
|
||||
else:
|
||||
raise TypeError('%r is not str() or unicode()!' % (addr,))
|
||||
|
||||
int_val = None
|
||||
|
||||
if len(words) == 6:
|
||||
# 2 bytes x 6 (UNIX, Windows, EUI-48)
|
||||
int_val = int(''.join(['%.2x' % int(w, 16) for w in words]), 16)
|
||||
elif len(words) == 3:
|
||||
# 4 bytes x 3 (Cisco)
|
||||
int_val = int(''.join(['%.4x' % int(w, 16) for w in words]), 16)
|
||||
elif len(words) == 2:
|
||||
# 6 bytes x 2 (PostgreSQL)
|
||||
int_val = int(''.join(['%.6x' % int(w, 16) for w in words]), 16)
|
||||
elif len(words) == 1:
|
||||
# 12 bytes (bare, no delimiters)
|
||||
int_val = int('%012x' % int(words[0], 16), 16)
|
||||
else:
|
||||
raise AddrFormatError('unexpected word count in MAC address %r!' % (addr,))
|
||||
|
||||
return int_val
|
||||
|
||||
|
||||
def int_to_str(int_val, dialect=None):
|
||||
"""
|
||||
:param int_val: An unsigned integer.
|
||||
|
||||
:param dialect: (optional) a Python class defining formatting options.
|
||||
|
||||
:return: An IEEE EUI-48 (MAC) address string that is equivalent to
|
||||
unsigned integer formatted according to the dialect settings.
|
||||
"""
|
||||
if dialect is None:
|
||||
dialect = mac_eui48
|
||||
|
||||
words = int_to_words(int_val, dialect)
|
||||
tokens = [dialect.word_fmt % i for i in words]
|
||||
addr = dialect.word_sep.join(tokens)
|
||||
|
||||
return addr
|
||||
|
||||
|
||||
def int_to_packed(int_val):
|
||||
"""
|
||||
:param int_val: the integer to be packed.
|
||||
|
||||
:return: a packed string that is equivalent to value represented by an
|
||||
unsigned integer.
|
||||
"""
|
||||
return _struct.pack(">HI", int_val >> 32, int_val & 0xffffffff)
|
||||
|
||||
|
||||
def packed_to_int(packed_int):
|
||||
"""
|
||||
:param packed_int: a packed string containing an unsigned integer.
|
||||
It is assumed that string is packed in network byte order.
|
||||
|
||||
:return: An unsigned integer equivalent to value of network address
|
||||
represented by packed binary string.
|
||||
"""
|
||||
words = list(_struct.unpack('>6B', packed_int))
|
||||
|
||||
int_val = 0
|
||||
for i, num in enumerate(reversed(words)):
|
||||
word = num
|
||||
word = word << 8 * i
|
||||
int_val = int_val | word
|
||||
|
||||
return int_val
|
||||
|
||||
|
||||
def valid_words(words, dialect=None):
|
||||
if dialect is None:
|
||||
dialect = DEFAULT_DIALECT
|
||||
return _valid_words(words, dialect.word_size, dialect.num_words)
|
||||
|
||||
|
||||
def int_to_words(int_val, dialect=None):
|
||||
if dialect is None:
|
||||
dialect = DEFAULT_DIALECT
|
||||
return _int_to_words(int_val, dialect.word_size, dialect.num_words)
|
||||
|
||||
|
||||
def words_to_int(words, dialect=None):
|
||||
if dialect is None:
|
||||
dialect = DEFAULT_DIALECT
|
||||
return _words_to_int(words, dialect.word_size, dialect.num_words)
|
||||
|
||||
|
||||
def valid_bits(bits, dialect=None):
|
||||
if dialect is None:
|
||||
dialect = DEFAULT_DIALECT
|
||||
return _valid_bits(bits, width, dialect.word_sep)
|
||||
|
||||
|
||||
def bits_to_int(bits, dialect=None):
|
||||
if dialect is None:
|
||||
dialect = DEFAULT_DIALECT
|
||||
return _bits_to_int(bits, width, dialect.word_sep)
|
||||
|
||||
|
||||
def int_to_bits(int_val, dialect=None):
|
||||
if dialect is None:
|
||||
dialect = DEFAULT_DIALECT
|
||||
return _int_to_bits(
|
||||
int_val, dialect.word_size, dialect.num_words, dialect.word_sep)
|
||||
|
||||
|
||||
def valid_bin(bin_val, dialect=None):
|
||||
if dialect is None:
|
||||
dialect = DEFAULT_DIALECT
|
||||
return _valid_bin(bin_val, width)
|
||||
|
||||
|
||||
def int_to_bin(int_val):
|
||||
return _int_to_bin(int_val, width)
|
||||
|
||||
|
||||
def bin_to_int(bin_val):
|
||||
return _bin_to_int(bin_val, width)
|
273
vendor/netaddr/strategy/eui64.py
vendored
Normal file
273
vendor/netaddr/strategy/eui64.py
vendored
Normal file
@@ -0,0 +1,273 @@
|
||||
#-----------------------------------------------------------------------------
|
||||
# Copyright (c) 2008 by David P. D. Moss. All rights reserved.
|
||||
#
|
||||
# Released under the BSD license. See the LICENSE file for details.
|
||||
#-----------------------------------------------------------------------------
|
||||
"""
|
||||
IEEE 64-bit EUI (Extended Unique Indentifier) logic.
|
||||
"""
|
||||
import struct as _struct
|
||||
import re as _re
|
||||
|
||||
from netaddr.core import AddrFormatError
|
||||
from netaddr.strategy import (
|
||||
valid_words as _valid_words, int_to_words as _int_to_words,
|
||||
words_to_int as _words_to_int, valid_bits as _valid_bits,
|
||||
bits_to_int as _bits_to_int, int_to_bits as _int_to_bits,
|
||||
valid_bin as _valid_bin, int_to_bin as _int_to_bin,
|
||||
bin_to_int as _bin_to_int)
|
||||
|
||||
|
||||
# This is a fake constant that doesn't really exist. Here for completeness.
|
||||
AF_EUI64 = 64
|
||||
|
||||
#: The width (in bits) of this address type.
|
||||
width = 64
|
||||
|
||||
#: The AF_* constant value of this address type.
|
||||
family = AF_EUI64
|
||||
|
||||
#: A friendly string name address type.
|
||||
family_name = 'EUI-64'
|
||||
|
||||
#: The version of this address type.
|
||||
version = 64
|
||||
|
||||
#: The maximum integer value that can be represented by this address type.
|
||||
max_int = 2 ** width - 1
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Dialect classes.
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
class eui64_base(object):
|
||||
"""A standard IEEE EUI-64 dialect class."""
|
||||
#: The individual word size (in bits) of this address type.
|
||||
word_size = 8
|
||||
|
||||
#: The number of words in this address type.
|
||||
num_words = width // word_size
|
||||
|
||||
#: The maximum integer value for an individual word in this address type.
|
||||
max_word = 2 ** word_size - 1
|
||||
|
||||
#: The separator character used between each word.
|
||||
word_sep = '-'
|
||||
|
||||
#: The format string to be used when converting words to string values.
|
||||
word_fmt = '%.2X'
|
||||
|
||||
#: The number base to be used when interpreting word values as integers.
|
||||
word_base = 16
|
||||
|
||||
|
||||
class eui64_unix(eui64_base):
|
||||
"""A UNIX-style MAC address dialect class."""
|
||||
word_size = 8
|
||||
num_words = width // word_size
|
||||
word_sep = ':'
|
||||
word_fmt = '%x'
|
||||
word_base = 16
|
||||
|
||||
|
||||
class eui64_unix_expanded(eui64_unix):
|
||||
"""A UNIX-style MAC address dialect class with leading zeroes."""
|
||||
word_fmt = '%.2x'
|
||||
|
||||
|
||||
class eui64_cisco(eui64_base):
|
||||
"""A Cisco 'triple hextet' MAC address dialect class."""
|
||||
word_size = 16
|
||||
num_words = width // word_size
|
||||
word_sep = '.'
|
||||
word_fmt = '%.4x'
|
||||
word_base = 16
|
||||
|
||||
|
||||
class eui64_bare(eui64_base):
|
||||
"""A bare (no delimiters) MAC address dialect class."""
|
||||
word_size = 64
|
||||
num_words = width // word_size
|
||||
word_sep = ''
|
||||
word_fmt = '%.16X'
|
||||
word_base = 16
|
||||
|
||||
|
||||
#: The default dialect to be used when not specified by the user.
|
||||
|
||||
DEFAULT_EUI64_DIALECT = eui64_base
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
#: Regular expressions to match all supported MAC address formats.
|
||||
RE_EUI64_FORMATS = (
|
||||
# 2 bytes x 8 (UNIX, Windows, EUI-64)
|
||||
'^' + ':'.join(['([0-9A-F]{1,2})'] * 8) + '$',
|
||||
'^' + '-'.join(['([0-9A-F]{1,2})'] * 8) + '$',
|
||||
|
||||
# 4 bytes x 4 (Cisco like)
|
||||
'^' + ':'.join(['([0-9A-F]{1,4})'] * 4) + '$',
|
||||
'^' + '-'.join(['([0-9A-F]{1,4})'] * 4) + '$',
|
||||
'^' + r'\.'.join(['([0-9A-F]{1,4})'] * 4) + '$',
|
||||
|
||||
# 16 bytes (bare, no delimiters)
|
||||
'^(' + ''.join(['[0-9A-F]'] * 16) + ')$',
|
||||
)
|
||||
# For efficiency, each string regexp converted in place to its compiled
|
||||
# counterpart.
|
||||
RE_EUI64_FORMATS = [_re.compile(_, _re.IGNORECASE) for _ in RE_EUI64_FORMATS]
|
||||
|
||||
|
||||
def _get_match_result(address, formats):
|
||||
for regexp in formats:
|
||||
match = regexp.findall(address)
|
||||
if match:
|
||||
return match[0]
|
||||
|
||||
|
||||
def valid_str(addr):
|
||||
"""
|
||||
:param addr: An IEEE EUI-64 indentifier in string form.
|
||||
|
||||
:return: ``True`` if EUI-64 indentifier is valid, ``False`` otherwise.
|
||||
"""
|
||||
try:
|
||||
if _get_match_result(addr, RE_EUI64_FORMATS):
|
||||
return True
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def str_to_int(addr):
|
||||
"""
|
||||
:param addr: An IEEE EUI-64 indentifier in string form.
|
||||
|
||||
:return: An unsigned integer that is equivalent to value represented
|
||||
by EUI-64 string address formatted according to the dialect
|
||||
"""
|
||||
words = []
|
||||
|
||||
try:
|
||||
words = _get_match_result(addr, RE_EUI64_FORMATS)
|
||||
if not words:
|
||||
raise TypeError
|
||||
except TypeError:
|
||||
raise AddrFormatError('invalid IEEE EUI-64 identifier: %r!' % (addr,))
|
||||
|
||||
if isinstance(words, tuple):
|
||||
pass
|
||||
else:
|
||||
words = (words,)
|
||||
|
||||
if len(words) == 8:
|
||||
# 2 bytes x 8 (UNIX, Windows, EUI-48)
|
||||
int_val = int(''.join(['%.2x' % int(w, 16) for w in words]), 16)
|
||||
elif len(words) == 4:
|
||||
# 4 bytes x 4 (Cisco like)
|
||||
int_val = int(''.join(['%.4x' % int(w, 16) for w in words]), 16)
|
||||
elif len(words) == 1:
|
||||
# 16 bytes (bare, no delimiters)
|
||||
int_val = int('%016x' % int(words[0], 16), 16)
|
||||
else:
|
||||
raise AddrFormatError(
|
||||
'bad word count for EUI-64 identifier: %r!' % addr)
|
||||
|
||||
return int_val
|
||||
|
||||
|
||||
def int_to_str(int_val, dialect=None):
|
||||
"""
|
||||
:param int_val: An unsigned integer.
|
||||
|
||||
:param dialect: (optional) a Python class defining formatting options
|
||||
|
||||
:return: An IEEE EUI-64 identifier that is equivalent to unsigned integer.
|
||||
"""
|
||||
if dialect is None:
|
||||
dialect = eui64_base
|
||||
words = int_to_words(int_val, dialect)
|
||||
tokens = [dialect.word_fmt % i for i in words]
|
||||
addr = dialect.word_sep.join(tokens)
|
||||
return addr
|
||||
|
||||
|
||||
def int_to_packed(int_val):
|
||||
"""
|
||||
:param int_val: the integer to be packed.
|
||||
|
||||
:return: a packed string that is equivalent to value represented by an
|
||||
unsigned integer.
|
||||
"""
|
||||
words = int_to_words(int_val)
|
||||
return _struct.pack('>8B', *words)
|
||||
|
||||
|
||||
def packed_to_int(packed_int):
|
||||
"""
|
||||
:param packed_int: a packed string containing an unsigned integer.
|
||||
It is assumed that string is packed in network byte order.
|
||||
|
||||
:return: An unsigned integer equivalent to value of network address
|
||||
represented by packed binary string.
|
||||
"""
|
||||
words = list(_struct.unpack('>8B', packed_int))
|
||||
|
||||
int_val = 0
|
||||
for i, num in enumerate(reversed(words)):
|
||||
word = num
|
||||
word = word << 8 * i
|
||||
int_val = int_val | word
|
||||
|
||||
return int_val
|
||||
|
||||
|
||||
def valid_words(words, dialect=None):
|
||||
if dialect is None:
|
||||
dialect = DEFAULT_EUI64_DIALECT
|
||||
return _valid_words(words, dialect.word_size, dialect.num_words)
|
||||
|
||||
|
||||
def int_to_words(int_val, dialect=None):
|
||||
if dialect is None:
|
||||
dialect = DEFAULT_EUI64_DIALECT
|
||||
return _int_to_words(int_val, dialect.word_size, dialect.num_words)
|
||||
|
||||
|
||||
def words_to_int(words, dialect=None):
|
||||
if dialect is None:
|
||||
dialect = DEFAULT_EUI64_DIALECT
|
||||
return _words_to_int(words, dialect.word_size, dialect.num_words)
|
||||
|
||||
|
||||
def valid_bits(bits, dialect=None):
|
||||
if dialect is None:
|
||||
dialect = DEFAULT_EUI64_DIALECT
|
||||
return _valid_bits(bits, width, dialect.word_sep)
|
||||
|
||||
|
||||
def bits_to_int(bits, dialect=None):
|
||||
if dialect is None:
|
||||
dialect = DEFAULT_EUI64_DIALECT
|
||||
return _bits_to_int(bits, width, dialect.word_sep)
|
||||
|
||||
|
||||
def int_to_bits(int_val, dialect=None):
|
||||
if dialect is None:
|
||||
dialect = DEFAULT_EUI64_DIALECT
|
||||
return _int_to_bits(
|
||||
int_val, dialect.word_size, dialect.num_words, dialect.word_sep)
|
||||
|
||||
|
||||
def valid_bin(bin_val, dialect=None):
|
||||
if dialect is None:
|
||||
dialect = DEFAULT_EUI64_DIALECT
|
||||
return _valid_bin(bin_val, width)
|
||||
|
||||
|
||||
def int_to_bin(int_val):
|
||||
return _int_to_bin(int_val, width)
|
||||
|
||||
|
||||
def bin_to_int(bin_val):
|
||||
return _bin_to_int(bin_val, width)
|
279
vendor/netaddr/strategy/ipv4.py
vendored
Normal file
279
vendor/netaddr/strategy/ipv4.py
vendored
Normal file
@@ -0,0 +1,279 @@
|
||||
#-----------------------------------------------------------------------------
|
||||
# Copyright (c) 2008 by David P. D. Moss. All rights reserved.
|
||||
#
|
||||
# Released under the BSD license. See the LICENSE file for details.
|
||||
#-----------------------------------------------------------------------------
|
||||
"""IPv4 address logic."""
|
||||
|
||||
import sys as _sys
|
||||
import struct as _struct
|
||||
|
||||
from socket import inet_aton as _inet_aton
|
||||
# Check whether we need to use fallback code or not.
|
||||
if _sys.platform in ('win32', 'cygwin'):
|
||||
# inet_pton() not available on Windows. inet_pton() under cygwin
|
||||
# behaves exactly like inet_aton() and is therefore highly unreliable.
|
||||
from netaddr.fbsocket import inet_pton as _inet_pton, AF_INET
|
||||
else:
|
||||
# All other cases, use all functions from the socket module.
|
||||
from socket import inet_pton as _inet_pton, AF_INET
|
||||
|
||||
from netaddr.core import AddrFormatError, ZEROFILL, INET_PTON
|
||||
|
||||
from netaddr.strategy import (
|
||||
valid_words as _valid_words, valid_bits as _valid_bits,
|
||||
bits_to_int as _bits_to_int, int_to_bits as _int_to_bits,
|
||||
valid_bin as _valid_bin, int_to_bin as _int_to_bin,
|
||||
bin_to_int as _bin_to_int)
|
||||
|
||||
from netaddr.compat import _str_type
|
||||
|
||||
#: The width (in bits) of this address type.
|
||||
width = 32
|
||||
|
||||
#: The individual word size (in bits) of this address type.
|
||||
word_size = 8
|
||||
|
||||
#: The format string to be used when converting words to string values.
|
||||
word_fmt = '%d'
|
||||
|
||||
#: The separator character used between each word.
|
||||
word_sep = '.'
|
||||
|
||||
#: The AF_* constant value of this address type.
|
||||
family = AF_INET
|
||||
|
||||
#: A friendly string name address type.
|
||||
family_name = 'IPv4'
|
||||
|
||||
#: The version of this address type.
|
||||
version = 4
|
||||
|
||||
#: The number base to be used when interpreting word values as integers.
|
||||
word_base = 10
|
||||
|
||||
#: The maximum integer value that can be represented by this address type.
|
||||
max_int = 2 ** width - 1
|
||||
|
||||
#: The number of words in this address type.
|
||||
num_words = width // word_size
|
||||
|
||||
#: The maximum integer value for an individual word in this address type.
|
||||
max_word = 2 ** word_size - 1
|
||||
|
||||
#: A dictionary mapping IPv4 CIDR prefixes to the equivalent netmasks.
|
||||
prefix_to_netmask = dict(
|
||||
[(i, max_int ^ (2 ** (width - i) - 1)) for i in range(0, width + 1)])
|
||||
|
||||
#: A dictionary mapping IPv4 netmasks to their equivalent CIDR prefixes.
|
||||
netmask_to_prefix = dict(
|
||||
[(max_int ^ (2 ** (width - i) - 1), i) for i in range(0, width + 1)])
|
||||
|
||||
#: A dictionary mapping IPv4 CIDR prefixes to the equivalent hostmasks.
|
||||
prefix_to_hostmask = dict(
|
||||
[(i, (2 ** (width - i) - 1)) for i in range(0, width + 1)])
|
||||
|
||||
#: A dictionary mapping IPv4 hostmasks to their equivalent CIDR prefixes.
|
||||
hostmask_to_prefix = dict(
|
||||
[((2 ** (width - i) - 1), i) for i in range(0, width + 1)])
|
||||
|
||||
|
||||
def valid_str(addr, flags=0):
|
||||
"""
|
||||
:param addr: An IPv4 address in presentation (string) format.
|
||||
|
||||
:param flags: decides which rules are applied to the interpretation of the
|
||||
addr value. Supported constants are INET_PTON and ZEROFILL. See the
|
||||
netaddr.core docs for details.
|
||||
|
||||
:return: ``True`` if IPv4 address is valid, ``False`` otherwise.
|
||||
"""
|
||||
if addr == '':
|
||||
raise AddrFormatError('Empty strings are not supported!')
|
||||
|
||||
validity = True
|
||||
|
||||
if flags & ZEROFILL:
|
||||
addr = '.'.join(['%d' % int(i) for i in addr.split('.')])
|
||||
|
||||
try:
|
||||
if flags & INET_PTON:
|
||||
_inet_pton(AF_INET, addr)
|
||||
else:
|
||||
_inet_aton(addr)
|
||||
except Exception:
|
||||
validity = False
|
||||
|
||||
return validity
|
||||
|
||||
|
||||
def str_to_int(addr, flags=0):
|
||||
"""
|
||||
:param addr: An IPv4 dotted decimal address in string form.
|
||||
|
||||
:param flags: decides which rules are applied to the interpretation of the
|
||||
addr value. Supported constants are INET_PTON and ZEROFILL. See the
|
||||
netaddr.core docs for details.
|
||||
|
||||
:return: The equivalent unsigned integer for a given IPv4 address.
|
||||
"""
|
||||
if flags & ZEROFILL:
|
||||
addr = '.'.join(['%d' % int(i) for i in addr.split('.')])
|
||||
|
||||
try:
|
||||
if flags & INET_PTON:
|
||||
return _struct.unpack('>I', _inet_pton(AF_INET, addr))[0]
|
||||
else:
|
||||
return _struct.unpack('>I', _inet_aton(addr))[0]
|
||||
except Exception:
|
||||
raise AddrFormatError('%r is not a valid IPv4 address string!' % (addr,))
|
||||
|
||||
|
||||
def int_to_str(int_val, dialect=None):
|
||||
"""
|
||||
:param int_val: An unsigned integer.
|
||||
|
||||
:param dialect: (unused) Any value passed in is ignored.
|
||||
|
||||
:return: The IPv4 presentation (string) format address equivalent to the
|
||||
unsigned integer provided.
|
||||
"""
|
||||
if 0 <= int_val <= max_int:
|
||||
return '%d.%d.%d.%d' % (
|
||||
int_val >> 24,
|
||||
(int_val >> 16) & 0xff,
|
||||
(int_val >> 8) & 0xff,
|
||||
int_val & 0xff)
|
||||
else:
|
||||
raise ValueError('%r is not a valid 32-bit unsigned integer!' % (int_val,))
|
||||
|
||||
|
||||
def int_to_arpa(int_val):
|
||||
"""
|
||||
:param int_val: An unsigned integer.
|
||||
|
||||
:return: The reverse DNS lookup for an IPv4 address in network byte
|
||||
order integer form.
|
||||
"""
|
||||
words = ["%d" % i for i in int_to_words(int_val)]
|
||||
words.reverse()
|
||||
words.extend(['in-addr', 'arpa', ''])
|
||||
return '.'.join(words)
|
||||
|
||||
|
||||
def int_to_packed(int_val):
|
||||
"""
|
||||
:param int_val: the integer to be packed.
|
||||
|
||||
:return: a packed string that is equivalent to value represented by an
|
||||
unsigned integer.
|
||||
"""
|
||||
return _struct.pack('>I', int_val)
|
||||
|
||||
|
||||
def packed_to_int(packed_int):
|
||||
"""
|
||||
:param packed_int: a packed string containing an unsigned integer.
|
||||
It is assumed that string is packed in network byte order.
|
||||
|
||||
:return: An unsigned integer equivalent to value of network address
|
||||
represented by packed binary string.
|
||||
"""
|
||||
return _struct.unpack('>I', packed_int)[0]
|
||||
|
||||
|
||||
def valid_words(words):
|
||||
return _valid_words(words, word_size, num_words)
|
||||
|
||||
|
||||
def int_to_words(int_val):
|
||||
"""
|
||||
:param int_val: An unsigned integer.
|
||||
|
||||
:return: An integer word (octet) sequence that is equivalent to value
|
||||
represented by an unsigned integer.
|
||||
"""
|
||||
if not 0 <= int_val <= max_int:
|
||||
raise ValueError('%r is not a valid integer value supported by'
|
||||
'this address type!' % (int_val,))
|
||||
return ( int_val >> 24,
|
||||
(int_val >> 16) & 0xff,
|
||||
(int_val >> 8) & 0xff,
|
||||
int_val & 0xff)
|
||||
|
||||
|
||||
def words_to_int(words):
|
||||
"""
|
||||
:param words: A list or tuple containing integer octets.
|
||||
|
||||
:return: An unsigned integer that is equivalent to value represented
|
||||
by word (octet) sequence.
|
||||
"""
|
||||
if not valid_words(words):
|
||||
raise ValueError('%r is not a valid octet list for an IPv4 address!' % (words,))
|
||||
return _struct.unpack('>I', _struct.pack('4B', *words))[0]
|
||||
|
||||
|
||||
def valid_bits(bits):
|
||||
return _valid_bits(bits, width, word_sep)
|
||||
|
||||
|
||||
def bits_to_int(bits):
|
||||
return _bits_to_int(bits, width, word_sep)
|
||||
|
||||
|
||||
def int_to_bits(int_val, word_sep=None):
|
||||
if word_sep is None:
|
||||
word_sep = globals()['word_sep']
|
||||
return _int_to_bits(int_val, word_size, num_words, word_sep)
|
||||
|
||||
|
||||
def valid_bin(bin_val):
|
||||
return _valid_bin(bin_val, width)
|
||||
|
||||
|
||||
def int_to_bin(int_val):
|
||||
return _int_to_bin(int_val, width)
|
||||
|
||||
|
||||
def bin_to_int(bin_val):
|
||||
return _bin_to_int(bin_val, width)
|
||||
|
||||
|
||||
def expand_partial_address(addr):
|
||||
"""
|
||||
Expands a partial IPv4 address into a full 4-octet version.
|
||||
|
||||
:param addr: an partial or abbreviated IPv4 address
|
||||
|
||||
:return: an expanded IP address in presentation format (x.x.x.x)
|
||||
|
||||
"""
|
||||
tokens = []
|
||||
|
||||
error = AddrFormatError('invalid partial IPv4 address: %r!' % addr)
|
||||
|
||||
if isinstance(addr, _str_type):
|
||||
if ':' in addr:
|
||||
# Ignore IPv6 ...
|
||||
raise error
|
||||
|
||||
try:
|
||||
if '.' in addr:
|
||||
tokens = ['%d' % int(o) for o in addr.split('.')]
|
||||
else:
|
||||
tokens = ['%d' % int(addr)]
|
||||
except ValueError:
|
||||
raise error
|
||||
|
||||
if 1 <= len(tokens) <= 4:
|
||||
for i in range(4 - len(tokens)):
|
||||
tokens.append('0')
|
||||
else:
|
||||
raise error
|
||||
|
||||
if not tokens:
|
||||
raise error
|
||||
|
||||
return '%s.%s.%s.%s' % tuple(tokens)
|
||||
|
259
vendor/netaddr/strategy/ipv6.py
vendored
Normal file
259
vendor/netaddr/strategy/ipv6.py
vendored
Normal file
@@ -0,0 +1,259 @@
|
||||
#-----------------------------------------------------------------------------
|
||||
# Copyright (c) 2008 by David P. D. Moss. All rights reserved.
|
||||
#
|
||||
# Released under the BSD license. See the LICENSE file for details.
|
||||
#-----------------------------------------------------------------------------
|
||||
"""
|
||||
IPv6 address logic.
|
||||
"""
|
||||
import struct as _struct
|
||||
|
||||
OPT_IMPORTS = False
|
||||
|
||||
# Check whether we need to use fallback code or not.
|
||||
try:
|
||||
import socket as _socket
|
||||
# These might all generate exceptions on different platforms.
|
||||
if not _socket.has_ipv6:
|
||||
raise Exception('IPv6 disabled')
|
||||
_socket.inet_pton
|
||||
_socket.AF_INET6
|
||||
from _socket import (inet_pton as _inet_pton, inet_ntop as _inet_ntop,
|
||||
AF_INET6)
|
||||
OPT_IMPORTS = True
|
||||
except Exception:
|
||||
from netaddr.fbsocket import (inet_pton as _inet_pton, inet_ntop as _inet_ntop,
|
||||
AF_INET6)
|
||||
|
||||
from netaddr.core import AddrFormatError
|
||||
from netaddr.strategy import (
|
||||
valid_words as _valid_words, int_to_words as _int_to_words,
|
||||
words_to_int as _words_to_int, valid_bits as _valid_bits,
|
||||
bits_to_int as _bits_to_int, int_to_bits as _int_to_bits,
|
||||
valid_bin as _valid_bin, int_to_bin as _int_to_bin,
|
||||
bin_to_int as _bin_to_int)
|
||||
|
||||
#: The width (in bits) of this address type.
|
||||
width = 128
|
||||
|
||||
#: The individual word size (in bits) of this address type.
|
||||
word_size = 16
|
||||
|
||||
#: The separator character used between each word.
|
||||
word_sep = ':'
|
||||
|
||||
#: The AF_* constant value of this address type.
|
||||
family = AF_INET6
|
||||
|
||||
#: A friendly string name address type.
|
||||
family_name = 'IPv6'
|
||||
|
||||
#: The version of this address type.
|
||||
version = 6
|
||||
|
||||
#: The number base to be used when interpreting word values as integers.
|
||||
word_base = 16
|
||||
|
||||
#: The maximum integer value that can be represented by this address type.
|
||||
max_int = 2 ** width - 1
|
||||
|
||||
#: The number of words in this address type.
|
||||
num_words = width // word_size
|
||||
|
||||
#: The maximum integer value for an individual word in this address type.
|
||||
max_word = 2 ** word_size - 1
|
||||
|
||||
#: A dictionary mapping IPv6 CIDR prefixes to the equivalent netmasks.
|
||||
prefix_to_netmask = dict(
|
||||
[(i, max_int ^ (2 ** (width - i) - 1)) for i in range(0, width+1)])
|
||||
|
||||
#: A dictionary mapping IPv6 netmasks to their equivalent CIDR prefixes.
|
||||
netmask_to_prefix = dict(
|
||||
[(max_int ^ (2 ** (width - i) - 1), i) for i in range(0, width+1)])
|
||||
|
||||
#: A dictionary mapping IPv6 CIDR prefixes to the equivalent hostmasks.
|
||||
prefix_to_hostmask = dict(
|
||||
[(i, (2 ** (width - i) - 1)) for i in range(0, width+1)])
|
||||
|
||||
#: A dictionary mapping IPv6 hostmasks to their equivalent CIDR prefixes.
|
||||
hostmask_to_prefix = dict(
|
||||
[((2 ** (width - i) - 1), i) for i in range(0, width+1)])
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Dialect classes.
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
class ipv6_compact(object):
|
||||
"""An IPv6 dialect class - compact form."""
|
||||
#: The format string used to converting words into string values.
|
||||
word_fmt = '%x'
|
||||
|
||||
#: Boolean flag indicating if IPv6 compaction algorithm should be used.
|
||||
compact = True
|
||||
|
||||
class ipv6_full(ipv6_compact):
|
||||
"""An IPv6 dialect class - 'all zeroes' form."""
|
||||
|
||||
#: Boolean flag indicating if IPv6 compaction algorithm should be used.
|
||||
compact = False
|
||||
|
||||
class ipv6_verbose(ipv6_compact):
|
||||
"""An IPv6 dialect class - extra wide 'all zeroes' form."""
|
||||
|
||||
#: The format string used to converting words into string values.
|
||||
word_fmt = '%.4x'
|
||||
|
||||
#: Boolean flag indicating if IPv6 compaction algorithm should be used.
|
||||
compact = False
|
||||
|
||||
|
||||
def valid_str(addr, flags=0):
|
||||
"""
|
||||
:param addr: An IPv6 address in presentation (string) format.
|
||||
|
||||
:param flags: decides which rules are applied to the interpretation of the
|
||||
addr value. Future use - currently has no effect.
|
||||
|
||||
:return: ``True`` if IPv6 address is valid, ``False`` otherwise.
|
||||
"""
|
||||
if addr == '':
|
||||
raise AddrFormatError('Empty strings are not supported!')
|
||||
|
||||
try:
|
||||
_inet_pton(AF_INET6, addr)
|
||||
except:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def str_to_int(addr, flags=0):
|
||||
"""
|
||||
:param addr: An IPv6 address in string form.
|
||||
|
||||
:param flags: decides which rules are applied to the interpretation of the
|
||||
addr value. Future use - currently has no effect.
|
||||
|
||||
:return: The equivalent unsigned integer for a given IPv6 address.
|
||||
"""
|
||||
try:
|
||||
packed_int = _inet_pton(AF_INET6, addr)
|
||||
return packed_to_int(packed_int)
|
||||
except Exception:
|
||||
raise AddrFormatError('%r is not a valid IPv6 address string!' % (addr,))
|
||||
|
||||
|
||||
def int_to_str(int_val, dialect=None):
|
||||
"""
|
||||
:param int_val: An unsigned integer.
|
||||
|
||||
:param dialect: (optional) a Python class defining formatting options.
|
||||
|
||||
:return: The IPv6 presentation (string) format address equivalent to the
|
||||
unsigned integer provided.
|
||||
"""
|
||||
if dialect is None:
|
||||
dialect = ipv6_compact
|
||||
|
||||
addr = None
|
||||
|
||||
try:
|
||||
packed_int = int_to_packed(int_val)
|
||||
if dialect.compact:
|
||||
# Default return value.
|
||||
addr = _inet_ntop(AF_INET6, packed_int)
|
||||
else:
|
||||
# Custom return value.
|
||||
words = list(_struct.unpack('>8H', packed_int))
|
||||
tokens = [dialect.word_fmt % word for word in words]
|
||||
addr = word_sep.join(tokens)
|
||||
except Exception:
|
||||
raise ValueError('%r is not a valid 128-bit unsigned integer!' % (int_val,))
|
||||
|
||||
return addr
|
||||
|
||||
|
||||
def int_to_arpa(int_val):
|
||||
"""
|
||||
:param int_val: An unsigned integer.
|
||||
|
||||
:return: The reverse DNS lookup for an IPv6 address in network byte
|
||||
order integer form.
|
||||
"""
|
||||
addr = int_to_str(int_val, ipv6_verbose)
|
||||
tokens = list(addr.replace(':', ''))
|
||||
tokens.reverse()
|
||||
# We won't support ip6.int here - see RFC 3152 for details.
|
||||
tokens = tokens + ['ip6', 'arpa', '']
|
||||
return '.'.join(tokens)
|
||||
|
||||
|
||||
def int_to_packed(int_val):
|
||||
"""
|
||||
:param int_val: the integer to be packed.
|
||||
|
||||
:return: a packed string that is equivalent to value represented by an
|
||||
unsigned integer.
|
||||
"""
|
||||
words = int_to_words(int_val, 4, 32)
|
||||
return _struct.pack('>4I', *words)
|
||||
|
||||
|
||||
def packed_to_int(packed_int):
|
||||
"""
|
||||
:param packed_int: a packed string containing an unsigned integer.
|
||||
It is assumed that string is packed in network byte order.
|
||||
|
||||
:return: An unsigned integer equivalent to value of network address
|
||||
represented by packed binary string.
|
||||
"""
|
||||
words = list(_struct.unpack('>4I', packed_int))
|
||||
|
||||
int_val = 0
|
||||
for i, num in enumerate(reversed(words)):
|
||||
word = num
|
||||
word = word << 32 * i
|
||||
int_val = int_val | word
|
||||
|
||||
return int_val
|
||||
|
||||
|
||||
def valid_words(words):
|
||||
return _valid_words(words, word_size, num_words)
|
||||
|
||||
|
||||
def int_to_words(int_val, num_words=None, word_size=None):
|
||||
if num_words is None:
|
||||
num_words = globals()['num_words']
|
||||
if word_size is None:
|
||||
word_size = globals()['word_size']
|
||||
return _int_to_words(int_val, word_size, num_words)
|
||||
|
||||
|
||||
def words_to_int(words):
|
||||
return _words_to_int(words, word_size, num_words)
|
||||
|
||||
|
||||
def valid_bits(bits):
|
||||
return _valid_bits(bits, width, word_sep)
|
||||
|
||||
|
||||
def bits_to_int(bits):
|
||||
return _bits_to_int(bits, width, word_sep)
|
||||
|
||||
|
||||
def int_to_bits(int_val, word_sep=None):
|
||||
if word_sep is None:
|
||||
word_sep = globals()['word_sep']
|
||||
return _int_to_bits(int_val, word_size, num_words, word_sep)
|
||||
|
||||
|
||||
def valid_bin(bin_val):
|
||||
return _valid_bin(bin_val, width)
|
||||
|
||||
|
||||
def int_to_bin(int_val):
|
||||
return _int_to_bin(int_val, width)
|
||||
|
||||
|
||||
def bin_to_int(bin_val):
|
||||
return _bin_to_int(bin_val, width)
|
Reference in New Issue
Block a user