Exemplo n.º 1
0
def _extended_community(value):
    if value[:2].lower() == '0x':
        # we could raise if the length is not 8 bytes (16 chars)
        if len(value) % 2:
            raise ValueError('invalid extended community %s' % value)
        raw = concat_bytes_i(
            character(int(value[_:_ + 2], 16))
            for _ in range(2, len(value), 2))
        return ExtendedCommunity.unpack(raw)
    elif value.count(':'):
        components = value.split(':')
        command = 'target' if len(components) == 2 else components.pop(0)

        if command not in _HEADER:
            raise ValueError(
                'invalid extended community %s (only origin,target or l2info are supported) '
                % command)

        if len(components) != _SIZE[command]:
            raise ValueError(
                'invalid extended community %s, expecting %d fields ' %
                (command, len(components)))

        header = _HEADER.get(command, None)

        if header is None:
            raise ValueError('unknown extended community %s' % command)

        if command == 'l2info':
            # encaps, control, mtu, site
            return ExtendedCommunity.unpack(
                header + pack('!BBHH', *[int(_) for _ in components]))

        _ga, _la = components
        ga, la = _ga.upper(), _la.upper()

        if command in ('target', 'origin'):
            # global admin, local admin
            if '.' in ga or '.' in la:
                gc = ga.count('.')
                lc = la.count('.')
                if gc == 0 and lc == 3:
                    # ASN first, IP second
                    return ExtendedCommunity.unpack(header + pack(
                        '!HBBBB', int(ga), *[int(_) for _ in la.split('.')]))
                if gc == 3 and lc == 0:
                    # IP first, ASN second
                    return ExtendedCommunity.unpack(
                        header +
                        pack('!BBBBH', *[int(_)
                                         for _ in ga.split('.')] + [int(la)]))

        iga = int(ga[:-1]) if 'L' in ga else int(ga)
        ila = int(la[:-1]) if 'L' in la else int(la)

        if command == 'target':
            if ga.endswith('L') or iga > _SIZE_H:
                return ExtendedCommunity.unpack(
                    _HEADER['target4'] + pack('!LH', iga, ila), None)
            else:
                return ExtendedCommunity.unpack(header + pack('!HI', iga, ila),
                                                None)
        if command == 'origin':
            if ga.endswith('L') or iga > _SIZE_H:
                return ExtendedCommunity.unpack(
                    _HEADER['origin4'] + pack('!LH', iga, ila), None)
            else:
                return ExtendedCommunity.unpack(header + pack('!HI', iga, ila),
                                                None)

        if command == 'target4':
            return ExtendedCommunity.unpack(
                _HEADER['target4'] + pack('!LH', iga, ila), None)

        if command == 'origin4':
            return ExtendedCommunity.unpack(
                _HEADER['origin4'] + pack('!LH', iga, ila), None)

        if command == 'redirect':
            return ExtendedCommunity.unpack(header + pack('!HL', iga, ila),
                                            None)

        if command == 'bandwidth':
            return ExtendedCommunity.unpack(
                _HEADER['bandwidth'] + pack('!Hf', iga, ila), None)

        raise ValueError('invalid extended community %s' % command)
    elif value == 'redirect-to-nexthop':
        header = _HEADER[value]
        return ExtendedCommunity.unpack(header + pack('!HL', 0, 0), None)
    else:
        raise ValueError('invalid extended community %s - lc+gc' % value)
Exemplo n.º 2
0
def _extended_community (value):
	if value[:2].lower() == '0x':
		# we could raise if the length is not 8 bytes (16 chars)
		if len(value) % 2:
			raise ValueError('invalid extended community %s' % value)
		raw = ''.join([chr(int(value[_:_+2],16)) for _ in range(2,len(value),2)])
		return ExtendedCommunity.unpack(raw)
	elif value.count(':'):
		components = value.split(':')
		command = 'target' if len(components) == 2 else components.pop(0)

		if command not in _HEADER:
			raise ValueError('invalid extended community %s (only origin,target or l2info are supported) ' % command)

		if len(components) != _SIZE[command]:
			raise ValueError('invalid extended community %s, expecting %d fields ' % (command,len(components)))

		header = _HEADER.get(command,None)

		if header is None:
			raise ValueError('unknown extended community %s' % command)

		if command == 'l2info':
			# encaps, control, mtu, site
			return ExtendedCommunity.unpack(header+pack('!BBHH',*[int(_) for _ in components]))

		_ga,_la = components
		ga,la = _ga.upper(),_la.upper()

		if command in ('target','origin'):
			# global admin, local admin
			if '.' in ga or '.' in la:
				gc = ga.count('.')
				lc = la.count('.')
				if gc == 0 and lc == 3:
					# ASN first, IP second
					return ExtendedCommunity.unpack(header+pack('!HBBBB',int(ga),*[int(_) for _ in la.split('.')]))
				if gc == 3 and lc == 0:
					# IP first, ASN second
					return ExtendedCommunity.unpack(header+pack('!BBBBH',*[int(_) for _ in ga.split('.')]+[int(la)]))

		iga = int(ga[:-1]) if 'L' in ga else int(ga)
		ila = int(la[:-1]) if 'L' in la else int(la)

		if command == 'target':
			if ga.endswith('L') or iga > _SIZE_H:
				return ExtendedCommunity.unpack(_HEADER['target4']+pack('!LH',iga,ila),None)
			else:
				return ExtendedCommunity.unpack(header+pack('!HI',iga,ila),None)
		if command == 'origin':
			if ga.endswith('L') or iga > _SIZE_H:
				return ExtendedCommunity.unpack(_HEADER['origin4']+pack('!LH',iga,ila),None)
			else:
				return ExtendedCommunity.unpack(header+pack('!HI',iga,ila),None)

		if command == 'target4':
			return ExtendedCommunity.unpack(_HEADER['target4']+pack('!LH',iga,ila),None)

		if command == 'orgin4':
			return ExtendedCommunity.unpack(_HEADER['origin4']+pack('!LH',iga,ila),None)

		if command in ('redirect',):
			return ExtendedCommunity.unpack(header+pack('!HL',iga,ila),None)

		raise ValueError('invalid extended community %s' % command)
	elif value == 'redirect-to-nexthop':
		header = _HEADER[value]
		return ExtendedCommunity.unpack(header+pack('!HL',0,0),None)
	else:
		raise ValueError('invalid extended community %s - lc+gc' % value)