Ejemplo n.º 1
0
    def parse(self, data, negotiated):
        if not data:
            return self

        # We do not care if the attribute are transitive or not as we do not redistribute
        flag = Attribute.Flag(ord(data[0]))
        aid = Attribute.CODE(ord(data[1]))

        if flag & Attribute.Flag.EXTENDED_LENGTH:
            length = unpack('!H', data[2:4])[0]
            offset = 4
        else:
            length = ord(data[2])
            offset = 3

        data = data[offset:]
        left = data[length:]
        attribute = data[:length]

        logger = Logger()
        logger.parser(
            LazyFormat(
                "parsing flag %x type %02x (%s) len %02x %s" %
                (flag, int(aid), aid, length, 'payload ' if length else ''),
                data[:length]))

        # remove the PARTIAL bit before comparaison if the attribute is optional
        if aid in Attribute.attributes_optional:
            aid &= Attribute.Flag.MASK_PARTIAL & 0xFF
            # aid &= ~Attribute.Flag.PARTIAL & 0xFF  # cleaner than above (python use signed integer for ~)

        # handle the attribute if we know it
        if Attribute.registered(aid, flag):
            self.add(Attribute.unpack(aid, flag, attribute, negotiated))
            return self.parse(left, negotiated)
        # XXX: FIXME: we could use a fallback function here like capability

        # if we know the attribute but the flag is not what the RFC says. ignore it.
        if aid in Attribute.attributes_known:
            logger.parser(
                'invalid flag for attribute %s (flag 0x%02X, aid 0x%02X)' %
                (Attribute.CODE.names.get(aid, 'unset'), flag, aid))
            return self.parse(left, negotiated)

        # it is an unknown transitive attribute we need to pass on
        if flag & Attribute.Flag.TRANSITIVE:
            logger.parser(
                'unknown transitive attribute (flag 0x%02X, aid 0x%02X)' %
                (flag, aid))
            self.add(
                GenericAttribute(aid, flag | Attribute.Flag.PARTIAL,
                                 attribute), attribute)
            return self.parse(left, negotiated)

        # it is an unknown non-transitive attribute we can ignore.
        logger.parser(
            'ignoring unknown non-transitive attribute (flag 0x%02X, aid 0x%02X)'
            % (flag, aid))
        return self.parse(left, negotiated)
Ejemplo n.º 2
0
	def parse (self, data, negotiated):
		if not data:
			return self

		# We do not care if the attribute are transitive or not as we do not redistribute
		flag = Attribute.Flag(ord(data[0]))
		aid = Attribute.CODE(ord(data[1]))

		if flag & Attribute.Flag.EXTENDED_LENGTH:
			length = unpack('!H',data[2:4])[0]
			offset = 4
		else:
			length = ord(data[2])
			offset = 3

		data = data[offset:]
		left = data[length:]
		attribute = data[:length]

		logger = Logger()
		logger.parser(LazyFormat("parsing flag %x type %02x (%s) len %02x %s" % (flag,int(aid),aid,length,'payload ' if length else ''),data[:length]))

		# remove the PARTIAL bit before comparaison if the attribute is optional
		if aid in Attribute.attributes_optional:
			flag &= Attribute.Flag.MASK_PARTIAL & 0xFF
			# flag &= ~Attribute.Flag.PARTIAL & 0xFF  # cleaner than above (python use signed integer for ~)

		# handle the attribute if we know it
		if Attribute.registered(aid,flag):
			self.add(Attribute.unpack(aid,flag,attribute,negotiated))
			return self.parse(left,negotiated)
		# XXX: FIXME: we could use a fallback function here like capability

		# if we know the attribute but the flag is not what the RFC says. ignore it.
		if aid in Attribute.attributes_known:
			logger.parser('invalid flag for attribute %s (flag 0x%02X, aid 0x%02X)' % (Attribute.CODE.names.get(aid,'unset'),flag,aid))
			return self.parse(left,negotiated)

		# it is an unknown transitive attribute we need to pass on
		if flag & Attribute.Flag.TRANSITIVE:
			logger.parser('unknown transitive attribute (flag 0x%02X, aid 0x%02X)' % (flag,aid))
			self.add(GenericAttribute(aid,flag | Attribute.Flag.PARTIAL,attribute),attribute)
			return self.parse(left,negotiated)

		# it is an unknown non-transitive attribute we can ignore.
		logger.parser('ignoring unknown non-transitive attribute (flag 0x%02X, aid 0x%02X)' % (flag,aid))
		return self.parse(left,negotiated)
Ejemplo n.º 3
0
    def parse(self, data, negotiated):
        if not data:
            return self

        try:
            # We do not care if the attribute are transitive or not as we do not redistribute
            flag = Attribute.Flag(ord(data[0]))
            aid = Attribute.CODE(ord(data[1]))
        except IndexError:
            self.add(TreatAsWithdraw())
            return self

        try:
            offset = 3
            length = ord(data[2])

            if flag & Attribute.Flag.EXTENDED_LENGTH:
                offset = 4
                length = (length << 8) + ord(data[3])
        except IndexError:
            self.add(TreatAsWithdraw(aid))
            return self

        data = data[offset:]
        left = data[length:]
        attribute = data[:length]

        logger = Logger()
        logger.parser(LazyAttribute(flag, aid, length, data[:length]))

        # remove the PARTIAL bit before comparaison if the attribute is optional
        if aid in Attribute.attributes_optional:
            flag &= Attribute.Flag.MASK_PARTIAL & 0xFF
            # flag &= ~Attribute.Flag.PARTIAL & 0xFF  # cleaner than above (python use signed integer for ~)

        if aid in self:
            if aid in self.NO_DUPLICATE:
                raise Notify(
                    3, 1, 'multiple attribute for %s' %
                    str(Attribute.CODE(attribute.ID)))

            logger.parser(
                'duplicate attribute %s (flag 0x%02X, aid 0x%02X) skipping' %
                (Attribute.CODE.names.get(aid, 'unset'), flag, aid))
            return self.parse(left, negotiated)

        # handle the attribute if we know it
        if Attribute.registered(aid, flag):
            if length == 0 and aid not in self.VALID_ZERO:
                self.add(TreatAsWithdraw(aid))
                return self.parse(left, negotiated)

            try:
                decoded = Attribute.unpack(aid, flag, attribute, negotiated)
            except IndexError, exc:
                if aid in self.TREAT_AS_WITHDRAW:
                    decoded = TreatAsWithdraw(aid)
                else:
                    raise exc
            except Notify, exc:
                if aid in self.TREAT_AS_WITHDRAW:
                    decoded = TreatAsWithdraw()
                elif aid in self.DISCARD:
                    decoded = Discard()
                else:
                    raise exc
Ejemplo n.º 4
0
    def parse(self, data, direction, negotiated):
        if not data:
            return self

        try:
            # We do not care if the attribute are transitive or not as we do not redistribute
            flag = Attribute.Flag(data[0])
            aid = Attribute.CODE(data[1])
        except IndexError:
            self.add(TreatAsWithdraw())
            return self

        try:
            offset = 3
            length = data[2]

            if flag & Attribute.Flag.EXTENDED_LENGTH:
                offset = 4
                length = (length << 8) + data[3]
        except IndexError:
            self.add(TreatAsWithdraw(aid))
            return self

        data = data[offset:]
        left = data[length:]
        attribute = data[:length]

        logfunc.debug(lazyattribute(flag, aid, length, data[:length]), 'parser')

        # remove the PARTIAL bit before comparaison if the attribute is optional
        if aid in Attribute.attributes_optional:
            flag &= Attribute.Flag.MASK_PARTIAL & 0xFF
            # flag &= ~Attribute.Flag.PARTIAL & 0xFF  # cleaner than above (python use signed integer for ~)

        if aid in self:
            if aid in self.NO_DUPLICATE:
                raise Notify(3, 1, 'multiple attribute for %s' % str(Attribute.CODE(attribute.ID)))

            log.debug(
                'duplicate attribute %s (flag 0x%02X, aid 0x%02X) skipping'
                % (Attribute.CODE.names.get(aid, 'unset'), flag, aid),
                'parser',
            )
            return self.parse(left, direction, negotiated)

        # handle the attribute if we know it
        if Attribute.registered(aid, flag):
            if length == 0 and aid not in self.VALID_ZERO:
                self.add(TreatAsWithdraw(aid))
                return self.parse(left, direction, negotiated)

            try:
                decoded = Attribute.unpack(aid, flag, attribute, direction, negotiated)
            except IndexError as exc:
                if aid in self.TREAT_AS_WITHDRAW:
                    decoded = TreatAsWithdraw(aid)
                else:
                    raise exc
            except Notify as exc:
                if aid in self.TREAT_AS_WITHDRAW:
                    decoded = TreatAsWithdraw()
                elif aid in self.DISCARD:
                    decoded = Discard()
                else:
                    raise exc
            self.add(decoded)
            return self.parse(left, direction, negotiated)

        # XXX: FIXME: we could use a fallback function here like capability

        # if we know the attribute but the flag is not what the RFC says.
        if aid in Attribute.attributes_known:
            if aid in self.TREAT_AS_WITHDRAW:
                log.debug(
                    'invalid flag for attribute %s (flag 0x%02X, aid 0x%02X) treat as withdraw'
                    % (Attribute.CODE.names.get(aid, 'unset'), flag, aid),
                    'parser',
                )
                self.add(TreatAsWithdraw())
            if aid in self.DISCARD:
                log.debug(
                    'invalid flag for attribute %s (flag 0x%02X, aid 0x%02X) discard'
                    % (Attribute.CODE.names.get(aid, 'unset'), flag, aid),
                    'parser',
                )
                return self.parse(left, direction, negotiated)
            # XXX: Check if we are missing any
            log.debug(
                'invalid flag for attribute %s (flag 0x%02X, aid 0x%02X) unspecified (should not happen)'
                % (Attribute.CODE.names.get(aid, 'unset'), flag, aid),
                'parser',
            )
            return self.parse(left, direction, negotiated)

        # it is an unknown transitive attribute we need to pass on
        if flag & Attribute.Flag.TRANSITIVE:
            log.debug('unknown transitive attribute (flag 0x%02X, aid 0x%02X)' % (flag, aid), 'parser')
            try:
                decoded = GenericAttribute(aid, flag | Attribute.Flag.PARTIAL, attribute)
            except IndexError:
                decoded = TreatAsWithdraw(aid)
            self.add(decoded, attribute)
            return self.parse(left, direction, negotiated)

        # it is an unknown non-transitive attribute we can ignore.
        log.debug('ignoring unknown non-transitive attribute (flag 0x%02X, aid 0x%02X)' % (flag, aid), 'parser')
        return self.parse(left, direction, negotiated)
Ejemplo n.º 5
0
	def parse (self, data, negotiated):
		if not data:
			return self

		try:
			# We do not care if the attribute are transitive or not as we do not redistribute
			flag = Attribute.Flag(ordinal(data[0]))
			aid = Attribute.CODE(ordinal(data[1]))
		except IndexError:
			self.add(TreatAsWithdraw())
			return self

		try:
			offset = 3
			length = ordinal(data[2])

			if flag & Attribute.Flag.EXTENDED_LENGTH:
				offset = 4
				length = (length << 8) + ordinal(data[3])
		except IndexError:
			self.add(TreatAsWithdraw(aid))
			return self

		data = data[offset:]
		left = data[length:]
		attribute = data[:length]

		logger = Logger()
		logger.debug(LazyAttribute(flag,aid,length,data[:length]),'parser')

		# remove the PARTIAL bit before comparaison if the attribute is optional
		if aid in Attribute.attributes_optional:
			flag &= Attribute.Flag.MASK_PARTIAL & 0xFF
			# flag &= ~Attribute.Flag.PARTIAL & 0xFF  # cleaner than above (python use signed integer for ~)

		if aid in self:
			if aid in self.NO_DUPLICATE:
				raise Notify(3,1,'multiple attribute for %s' % str(Attribute.CODE(attribute.ID)))

			logger.debug('duplicate attribute %s (flag 0x%02X, aid 0x%02X) skipping' % (Attribute.CODE.names.get(aid,'unset'),flag,aid),'parser')
			return self.parse(left,negotiated)

		# handle the attribute if we know it
		if Attribute.registered(aid,flag):
			if length == 0 and aid not in self.VALID_ZERO:
				self.add(TreatAsWithdraw(aid))
				return self.parse(left,negotiated)

			try:
				decoded = Attribute.unpack(aid,flag,attribute,negotiated)
			except IndexError as exc:
				if aid in self.TREAT_AS_WITHDRAW:
					decoded = TreatAsWithdraw(aid)
				else:
					raise exc
			except Notify as exc:
				if aid in self.TREAT_AS_WITHDRAW:
					decoded = TreatAsWithdraw()
				elif aid in self.DISCARD:
					decoded = Discard()
				else:
					raise exc
			self.add(decoded)
			return self.parse(left,negotiated)

		# XXX: FIXME: we could use a fallback function here like capability

		# if we know the attribute but the flag is not what the RFC says.
		if aid in Attribute.attributes_known:
			if aid in self.TREAT_AS_WITHDRAW:
				logger.debug('invalid flag for attribute %s (flag 0x%02X, aid 0x%02X) treat as withdraw' % (Attribute.CODE.names.get(aid,'unset'),flag,aid),'parser')
				self.add(TreatAsWithdraw())
			if aid in self.DISCARD:
				logger.debug('invalid flag for attribute %s (flag 0x%02X, aid 0x%02X) discard' % (Attribute.CODE.names.get(aid,'unset'),flag,aid),'parser')
				return self.parse(left,negotiated)
			# XXX: Check if we are missing any
			logger.debug('invalid flag for attribute %s (flag 0x%02X, aid 0x%02X) unspecified (should not happen)' % (Attribute.CODE.names.get(aid,'unset'),flag,aid),'parser')
			return self.parse(left,negotiated)

		# it is an unknown transitive attribute we need to pass on
		if flag & Attribute.Flag.TRANSITIVE:
			logger.debug('unknown transitive attribute (flag 0x%02X, aid 0x%02X)' % (flag,aid),'parser')
			try:
				decoded = GenericAttribute(aid,flag | Attribute.Flag.PARTIAL,attribute)
			except IndexError:
				decoded = TreatAsWithdraw(aid)
			self.add(decoded,attribute)
			return self.parse(left,negotiated)

		# it is an unknown non-transitive attribute we can ignore.
		logger.debug('ignoring unknown non-transitive attribute (flag 0x%02X, aid 0x%02X)' % (flag,aid),'parser')
		return self.parse(left,negotiated)
Ejemplo n.º 6
0
	def parse (self, data, negotiated):
		if not data:
			return self

		try:
			# We do not care if the attribute are transitive or not as we do not redistribute
			flag = Attribute.Flag(ord(data[0]))
			aid = Attribute.CODE(ord(data[1]))
		except IndexError:
			self.add(TreatAsWithdraw())
			return self

		try:
			offset = 3
			length = ord(data[2])

			if flag & Attribute.Flag.EXTENDED_LENGTH:
				offset = 4
				length = (length << 8) + ord(data[3])
		except IndexError:
			self.add(TreatAsWithdraw(aid))
			return self

		data = data[offset:]
		left = data[length:]
		attribute = data[:length]

		logger = Logger()
		logger.parser(LazyAttribute(flag,aid,length,data[:length]))

		# remove the PARTIAL bit before comparaison if the attribute is optional
		if aid in Attribute.attributes_optional:
			flag &= Attribute.Flag.MASK_PARTIAL & 0xFF
			# flag &= ~Attribute.Flag.PARTIAL & 0xFF  # cleaner than above (python use signed integer for ~)

		if aid in self:
			if aid in self.NO_DUPLICATE:
				raise Notify(3,1,'multiple attribute for %s' % str(Attribute.CODE(attribute.ID)))

			logger.parser('duplicate attribute %s (flag 0x%02X, aid 0x%02X) skipping' % (Attribute.CODE.names.get(aid,'unset'),flag,aid))
			return self.parse(left,negotiated)

		# handle the attribute if we know it
		if Attribute.registered(aid,flag):
			if length == 0 and aid not in self.VALID_ZERO:
				self.add(TreatAsWithdraw(aid))
				return self.parse(left,negotiated)

			try:
				decoded = Attribute.unpack(aid,flag,attribute,negotiated)
			except IndexError, exc:
				if aid in self.TREAT_AS_WITHDRAW:
					decoded = TreatAsWithdraw(aid)
				else:
					raise exc
			except Notify, exc:
				if aid in self.TREAT_AS_WITHDRAW:
					decoded = TreatAsWithdraw()
				elif aid in self.DISCARD:
					decoded = Discard()
				else:
					raise exc