def __init__(self, addr, version=None, flags=0, rd=0): if not _is_int(addr): m = re.match('(?P<addr>[a-f\d\.:]+)%?(?P<rd>\d+)?', str(addr)) if not m: raise ValueError(addr) self.rd = int(m.group('rd') or rd) addr = m.group('addr') else: self.rd = rd super(IPAddressRd, self).__init__(addr, version, flags)
def __setitem__(self, idx, value): """Set the value of the word referenced by index in this address""" if isinstance(idx, slice): # TODO - settable slices. raise NotImplementedError("settable slices are not supported!") if not _is_int(idx): raise TypeError("index not an integer!") if not 0 <= idx <= (self._dialect.num_words - 1): raise IndexError("index %d outside address type boundary!" % idx) if not _is_int(value): raise TypeError("value not an integer!") if not 0 <= value <= self._dialect.max_word: raise IndexError("value %d outside word size maximum of %d bits!" % (value, self._dialect.word_size)) words = list(self._module.int_to_words(self._value, self._dialect)) words[idx] = value self._value = self._module.words_to_int(words)
def __init__(self, iab, strict=False): """ Constructor :param iab: an IAB string ``00-50-C2-XX-X0-00`` or an unsigned \ integer. This address looks like an EUI-48 but it should not \ have any non-zero bits in the last 3 bytes. :param strict: If True, raises a ValueError if the last 12 bits \ of IAB MAC/EUI-48 address are non-zero, ignores them otherwise. \ (Default: False) """ super(IAB, self).__init__() # Lazy loading of IEEE data structures. from netaddr.eui import ieee self.record = { 'idx': 0, 'iab': '', 'org': '', 'address' : [], 'offset': 0, 'size': 0, } if isinstance(iab, str): #TODO: Improve string parsing here. #TODO: '00-50-C2' is actually invalid. #TODO: Should be '00-50-C2-00-00-00' (i.e. a full MAC/EUI-48) int_val = int(iab.replace('-', ''), 16) iab_int, user_int = self.split_iab_mac(int_val, strict=strict) self._value = iab_int elif _is_int(iab): iab_int, user_int = self.split_iab_mac(iab, strict=strict) self._value = iab_int else: raise TypeError('unexpected IAB format: %r!' % iab) # Discover offsets. if self._value in ieee.IAB_INDEX: fh = open(ieee.IAB_REGISTRY) (offset, size) = ieee.IAB_INDEX[self._value][0] self.record['offset'] = offset self.record['size'] = size fh.seek(offset) data = fh.read(size) self._parse_data(data, offset, size) fh.close() else: raise NotRegisteredError('IAB %r not unregistered!' % iab)
def __setitem__(self, idx, value): """Sets the value of the word referenced by index in this address""" if isinstance(idx, slice): # TODO - settable slices. raise NotImplementedError('settable slices are not supported!') if not _is_int(idx): raise TypeError('index not an integer!') if not 0 <= idx <= (self._dialect.num_words - 1): raise IndexError('index %d outside address type boundary!' % idx) if not _is_int(value): raise TypeError('value not an integer!') if not 0 <= value <= self._dialect.max_word: raise IndexError('value %d outside word size maximum of %d bits!' % (value, self._dialect.word_size)) words = list(self._module.int_to_words(self._value, self._dialect)) words[idx] = value self._value = self._module.words_to_int(words)
def __init__(self, addr, implicit_prefix=False, version=None, flags=0, rd=0): if not _is_int(addr): m = re.match('(?P<addr>[a-f\d\.:]+)%?(?P<rd>\d+)?/?(?P<prefix>\d+)?', str(addr)) if not m: raise ValueError(addr) self.rd = int(m.group('rd') or rd) if m.group('prefix'): addr = '{addr}/{prefix}'.format(**m.groupdict()) else: addr = m.group('addr') else: self.rd = rd super(IPNetworkRd, self).__init__(addr, implicit_prefix, version, flags)
def __init__(self, addr, version=None, dialect=None): """ Constructor. :param addr: an EUI-48 (MAC) or EUI-64 address in string format or \ an unsigned integer. May also be another EUI object (copy \ construction). :param version: (optional) the explict EUI address version. Mainly \ used to distinguish between EUI-48 and EUI-64 identifiers \ specified as integers which may be numerically equivalent. :param dialect: (optional) the mac_* dialect to be used to configure \ the formatting of EUI-48 (MAC) addresses. """ super(EUI, self).__init__() self._module = None if isinstance(addr, EUI): # Copy constructor. if version is not None and version != addr._module.version: raise ValueError('cannot switch EUI versions using ' 'copy constructor!') self._module = addr._module self._value = addr._value self.dialect = addr.dialect return if version is not None: if version == 48: self._module = _eui48 elif version == 64: self._module = _eui64 else: raise ValueError('unsupported EUI version %r' % version) else: # Choose a default version when addr is an integer and version is # not specified. if _is_int(addr): if 0 <= addr <= 0xffffffffffff: self._module = _eui48 elif 0xffffffffffff < addr <= 0xffffffffffffffff: self._module = _eui64 self.value = addr # Choose a dialect for MAC formatting. self.dialect = dialect
def __getitem__(self, idx): """ :return: The integer value of the word referenced by index (both \ positive and negative). Raises ``IndexError`` if index is out \ of bounds. Also supports Python list slices for accessing \ word groups. """ if _is_int(idx): # Indexing, including negative indexing goodness. num_words = self._dialect.num_words if not (-num_words) <= idx <= (num_words - 1): raise IndexError("index out range for address type!") return self._module.int_to_words(self._value, self._dialect)[idx] elif isinstance(idx, slice): words = self._module.int_to_words(self._value, self._dialect) return [words[i] for i in range(*idx.indices(len(words)))] else: raise TypeError("unsupported type %r!" % idx)
def __getitem__(self, idx): """ :return: The integer value of the word referenced by index (both \ positive and negative). Raises ``IndexError`` if index is out \ of bounds. Also supports Python list slices for accessing \ word groups. """ if _is_int(idx): # Indexing, including negative indexing goodness. num_words = self._dialect.num_words if not (-num_words) <= idx <= (num_words - 1): raise IndexError('index out range for address type!') return self._module.int_to_words(self._value, self._dialect)[idx] elif isinstance(idx, slice): words = self._module.int_to_words(self._value, self._dialect) return [words[i] for i in range(*idx.indices(len(words)))] else: raise TypeError('unsupported type %r!' % idx)
def __init__(self, oui, oui_index=None, oui_registry=None): """ Constructor :param oui: an OUI string ``XX-XX-XX`` or an unsigned integer. \ Also accepts and parses full MAC/EUI-48 address strings (but not \ MAC/EUI-48 integers)! :param oui_index: An index generated by `netaddr.eui.ieee`. """ super(OUI, self).__init__() self.records = [] ieee = _maybe_import_netaddr_eui_ieee() if oui_index is None: oui_index = ieee.OUI_INDEX if oui_registry is None: oui_registry = ieee.OUI_REGISTRY if isinstance(oui, str): #TODO: Improve string parsing here. #TODO: Accept full MAC/EUI-48 addressses as well as XX-XX-XX #TODO: and just take /16 (see IAB for details) self._value = int(oui.replace('-', ''), 16) elif _is_int(oui): if 0 <= oui <= 0xffffff: self._value = oui else: raise ValueError('OUI int outside expected range: %r' % oui) else: raise TypeError('unexpected OUI format: %r' % oui) # Discover offsets. if self._value in oui_index: fh = open(oui_registry) for (offset, size) in oui_index[self._value]: fh.seek(offset) data = fh.read(size) self._parse_data(data, offset, size) fh.close() else: raise NotRegisteredError('OUI %r not registered!' % oui)
def __init__(self, oui): """ Constructor :param oui: an OUI string ``XX-XX-XX`` or an unsigned integer. \ Also accepts and parses full MAC/EUI-48 address strings (but not \ MAC/EUI-48 integers)! """ super(OUI, self).__init__() # Lazy loading of IEEE data structures. from netaddr.eui import ieee self.records = [] if isinstance(oui, str): #TODO: Improve string parsing here. #TODO: Accept full MAC/EUI-48 addressses as well as XX-XX-XX #TODO: and just take /16 (see IAB for details) self._value = int(oui.replace('-', ''), 16) elif _is_int(oui): if 0 <= oui <= 0xffffff: self._value = oui else: raise ValueError('OUI int outside expected range: %r' % (oui, )) else: raise TypeError('unexpected OUI format: %r' % (oui, )) # Discover offsets. if self._value in ieee.OUI_INDEX: fh = _importlib_resources.open_binary(__package__, 'oui.txt') for (offset, size) in ieee.OUI_INDEX[self._value]: fh.seek(offset) data = fh.read(size).decode('UTF-8') self._parse_data(data, offset, size) fh.close() else: raise NotRegisteredError('OUI %r not registered!' % (oui, ))
def __init__(self, oui): """ Constructor :param oui: an OUI string ``XX-XX-XX`` or an unsigned integer. \ Also accepts and parses full MAC/EUI-48 address strings (but not \ MAC/EUI-48 integers)! """ super(OUI, self).__init__() # Lazy loading of IEEE data structures. from netaddr.eui import ieee self.records = [] if isinstance(oui, str): # TODO: Improve string parsing here. # TODO: Accept full MAC/EUI-48 addressses as well as XX-XX-XX # TODO: and just take /16 (see IAB for details) self._value = int(oui.replace("-", ""), 16) elif _is_int(oui): if 0 <= oui <= 0xFFFFFF: self._value = oui else: raise ValueError("OUI int outside expected range: %r" % oui) else: raise TypeError("unexpected OUI format: %r" % oui) # Discover offsets. if self._value in ieee.OUI_INDEX: fh = open(ieee.OUI_REGISTRY) for (offset, size) in ieee.OUI_INDEX[self._value]: fh.seek(offset) data = fh.read(size) self._parse_data(data, offset, size) fh.close() else: raise NotRegisteredError("OUI %r not registered!" % oui)
def test_compat_string_and_int_detection(): assert _is_int(_sys_maxint) assert not _is_str(_sys_maxint) assert _is_str('') assert _is_str(''.encode())