示例#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.ID(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:]
        next = 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 ''),
                od, 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(next, 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.ID.names.get(aid, 'unset'), flag, aid))
            return self.parse(next, 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(next, 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(next, negotiated)
示例#2
0
    def flag_attribute_content(data):
        flag = Attribute.Flag(ord(data[0]))
        attr = Attribute.ID(ord(data[1]))

        if flag & Attribute.Flag.EXTENDED_LENGTH:
            length = unpack('!H', data[2:4])[0]
            return flag, attr, data[4:length + 4]
        else:
            length = ord(data[2])
            return flag, attr, data[3:length + 3]
示例#3
0
    def add(self, attribute, data=None):
        # we return None as attribute if the unpack code must not generate them
        if attribute is None:
            return

        self._str = ''
        self._json = ''

        if attribute.MULTIPLE:
            if self.has(attribute.ID):
                self[attribute.ID].append(attribute)
            else:
                self[attribute.ID] = MultiAttributes(attribute)
        else:
            if attribute.ID in self:
                raise Notify(
                    3, 0, 'multiple attribute for %s' %
                    str(Attribute.ID(attribute.ID)))
            self[attribute.ID] = attribute