Esempio n. 1
0
    def parse(self, value, asn4=False):
        """
        Parse AS PATH attributes.
        :param asn4: 4 bytes asn or not
        :param value: raw binary balue
        """
        # Loop over all path segments
        aspath = []
        while len(value) > 0:
            seg_type, length = struct.unpack('!BB', value[:2])
            if seg_type not in [
                    self.AS_SET, self.AS_SEQUENCE, self.AS_CONFED_SEQUENCE,
                    self.AS_CONFED_SET
            ]:
                raise excep.UpdateMessageError(
                    sub_error=bgp_cons.ERR_MSG_UPDATE_MALFORMED_ASPATH,
                    data=value[0])
            try:
                if asn4:
                    segment = list(
                        struct.unpack('!%dI' % length,
                                      value[2:2 + length * 4]))
                    value = value[2 + length * 4:]

                else:
                    segment = list(
                        struct.unpack('!%dH' % length,
                                      value[2:2 + length * 2]))
                    value = value[2 + length * 2:]
            except Exception:
                raise excep.UpdateMessageError(
                    sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN, data='')
            aspath.append((seg_type, segment))
        return aspath
Esempio n. 2
0
    def parse(value):
        """
        Parse originator id
        :param value:
        """
        if len(value) > 4:
            raise excep.UpdateMessageError(
                sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN, data=value)
        try:
            return IPv4Address(int(binascii.b2a_hex(value[0:4]), 16)).__str__()

        except Exception:
            raise excep.UpdateMessageError(
                sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN, data=value)
Esempio n. 3
0
 def parse(value):
     """
     Parse culster list
     :param value
     """
     cluster_list = []
     if len(value) % 4 != 0:
         raise excep.UpdateMessageError(
             sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN, data=repr(value))
     try:
         while value:
             cluster_list.append(
                 IPv4Address(struct.unpack('!I', value[0:4])[0]).__str__())
             value = value[4:]
     except Exception:
         raise excep.UpdateMessageError(
             sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN, data=repr(value))
     return cluster_list
Esempio n. 4
0
 def parse(value):
     """
     parse bgp ATOMIC_AGGREGATE attribute
     :param value:
     """
     if not value:
         return value
     else:
         raise excep.UpdateMessageError(
             sub_error=bgp_cons.ERR_MSG_UPDATE_OPTIONAL_ATTR, data=value)
Esempio n. 5
0
 def parse(value):
     """
     parse BGP med attributes
     :param value: raw binary value
     """
     try:
         return struct.unpack('!I', value)[0]
     except:
         raise excep.UpdateMessageError(
             sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN, data=value)
Esempio n. 6
0
    def parse(message):
        """
        parse notification message

        :param message: input raw binary message data
        """
        try:
            error, suberror = struct.unpack('!BB', message[:2])
            data = message[2:]
        except:
            raise excep.UpdateMessageError(
                sub_error=bgp_cons.ERR_MSG_HDR_BAD_MSG_LEN, data=repr(message))
        return error, suberror, data
Esempio n. 7
0
    def construct(self, value, flags=None):

        """
        construct a origin attribute
        """
        if value not in [self.IGP, self.EGP, self.INCOMPLETE]:
            raise excep.UpdateMessageError(
                sub_error=bgp_cons.ERR_MSG_UPDATE_INVALID_ORIGIN,
                data='')
        length = 1
        if not flags:
            flags = self.FLAG
        return struct.pack('!B', flags) + struct.pack('!B', self.ID) \
            + struct.pack('!B', length) + struct.pack('!B', value)
Esempio n. 8
0
 def construct(self, value, flags=None):
     """
     encode BGP nexthop attribute.
     """
     try:
         ipv4_addr = IPv4Address(value)
     except:
         raise excep.UpdateMessageError(
             sub_error=bgp_cons.ERR_MSG_UPDATE_INVALID_NEXTHOP, data=value)
     ip_addr_raw = ipv4_addr.packed
     if not flags:
         flags = self.FLAG
     return struct.pack('!B', flags) + struct.pack('!B', self.ID) \
         + struct.pack('!B', len(ip_addr_raw)) + ip_addr_raw
Esempio n. 9
0
    def parse(value):
        """
        Parse BGP nexthop.
        :param value: raw binary value
        """
        next_hop = '0.0.0.0'
        if len(value) % 4 == 0:

            while value:
                try:
                    next_hop = IPv4Address(
                        int(binascii.b2a_hex(value[0:4]), 16)).__str__()
                except Exception:
                    # Error process
                    raise excep.UpdateMessageError(
                        sub_error=bgp_cons.ERR_MSG_UPDATE_INVALID_NEXTHOP,
                        data=value[0:4])
                value = value[4:]
        else:
            # Error process
            raise excep.UpdateMessageError(
                sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN, data=value)
        return next_hop
Esempio n. 10
0
 def construct(self, value, flags=None):
     """
     encode BGP med attributes
     :param value:
     :param flags: bgp attribute flags
     """
     if not flags:
         flags = self.FLAG
     try:
         return struct.pack('!B', flags) + struct.pack('!B', self.ID) \
             + struct.pack('!B', 4) + struct.pack('!I', value)
     except Exception:
         raise excep.UpdateMessageError(
             sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN, data='')
Esempio n. 11
0
 def construct(self, value, flags=None):
     """
     construct a ORIGINATOR_ID path attribute
     :param value:
     :param flags:
     """
     if not flags:
         flags = self.FLAG
     try:
         return struct.pack('!B', flags) + struct.pack('!B', self.ID) \
             + struct.pack('!B', 4) + IPv4Address(value).packed
     except Exception:
         raise excep.UpdateMessageError(
             sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN, data=value)
Esempio n. 12
0
    def construct(self, value, flags=None):
        """construct a ATOMIC_AGGREGATE path attribute
        :param value:
        :param flags:
        """

        if not flags:
            flags = self.FLAG
        if value:
            raise excep.UpdateMessageError(
                sub_error=bgp_cons.ERR_MSG_UPDATE_OPTIONAL_ATTR, data='')
        else:
            value = 0
        return struct.pack('!B', flags) + struct.pack('!B', self.ID) \
            + struct.pack('!B', value)
Esempio n. 13
0
 def parse(self, value):
     """
     Error process:
     (1) the falgs of the ORIGIN attribute must be "well-know,transitive"
     (2) If the ORIGIN attribute has an undefined value, then the Error Sub-code 
     MUST be set to Invalid Origin Attribute. The Data field MUST contain the
     unrecognized attribute (type,length, and vlaue)
     :param value: raw binary value
     """
     orgin = struct.unpack('!B', value)[0]
     if orgin not in [self.IGP, self.EGP, self.INCOMPLETE]:
         raise excep.UpdateMessageError(
             sub_error=bgp_cons.ERR_MSG_UPDATE_INVALID_ORIGIN,
             data=value)
     return orgin
Esempio n. 14
0
    def construct(self, value, flags=None, asn4=False):
        """
        Construct AS PATH.
        :param asn4: 4byte asn
        :param value:
        :param flags:
        """
        # value example
        # [(2, [3257, 31027, 34848, 21465])], or [(3, [64606]), (2, [64624, 65515])]

        as_path_raw = ''
        for segment in value:
            as_seg_raw = ''
            seg_type = segment[0]
            as_path_list = segment[1]
            if seg_type not in [
                    self.AS_SET, self.AS_SEQUENCE, self.AS_CONFED_SET,
                    self.AS_CONFED_SEQUENCE
            ]:
                assert excep.UpdateMessageError(
                    sub_error=bgp_cons.ERR_MSG_UPDATE_MALFORMED_ASPATH,
                    data='')

            if asn4:
                #  4 bytes asn encode
                as_count = 0
                for asn in as_path_list:
                    as_count += 1
                    as_seg_raw += struct.pack('!I', asn)
            else:
                # 2 bytes asn encode
                as_count = 0
                for asn in as_path_list:
                    as_count += 1
                    as_seg_raw += struct.pack('!H', asn)

            as_path_raw += struct.pack('!B', seg_type) + struct.pack(
                '!B', as_count) + as_seg_raw

        if not flags:
            flags = self.FLAG
        if len(as_path_raw) > 255:
            flags += AttributeFlag.EXTENDED_LENGTH
            return struct.pack('!B', flags) + struct.pack('!B', self.ID) \
                + struct.pack('!H', len(as_path_raw)) + as_path_raw
        else:
            return struct.pack('!B', flags) + struct.pack('!B', self.ID) \
                + struct.pack('!B', len(as_path_raw)) + as_path_raw
Esempio n. 15
0
 def construct(self, value, flags=None):
     """
     construct a CLUSTER_LIST path attribute
     :param value:
     :param flags:
     """
     cluster_raw = ''
     if not flags:
         flags = self.FLAG
     try:
         for cluster in value:
             cluster_raw += IPv4Address(cluster).packed
         return struct.pack("!B", flags) + struct.pack('!B', self.ID) \
             + struct.pack("!B", len(cluster_raw)) + cluster_raw
     except Exception:
         raise excep.UpdateMessageError(
             sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN,
             data=struct.pack('B', flags))
Esempio n. 16
0
 def parse(self, value):
     """
     parse BGP community.
     :param value:
     """
     community = []
     if value:
         try:
             length = len(value) / 2
             value_list = list(struct.unpack('!%dH' % length, value))
             while value_list:
                 value_type = value_list[0] * 16 * 16 * 16 * 16 + value_list[1]
                 if 'UNKNOW' != self.to_string(value_type):
                     community.append(self.to_string(value_type))
                 else:
                     community.append("%s:%s" % (value_list[0], value_list[1]))
                 value_list = value_list[2:]
         except Exception:
             raise excep.UpdateMessageError(
                 sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN,
                 data=value)
     return community
Esempio n. 17
0
    def parse_attributes(data, asn4=False):
        """
        Parses an RFC4271 encoded blob of BGP attributes into a list

        :param data:
        :param asn4: support 4 bytes asn or not
        :return:
        """
        attributes = {}
        postfix = data
        while len(postfix) > 0:

            try:
                flags, type_code = struct.unpack('!BB', postfix[:2])

                if flags & AttributeFlag.EXTENDED_LENGTH:
                    attr_len = struct.unpack('!H', postfix[2:4])[0]
                    attr_value = postfix[4:4 + attr_len]
                    postfix = postfix[4 + attr_len:]  # Next attribute
                else:  # standard 1-octet length
                    attr_len = ord(postfix[2])
                    attr_value = postfix[3:3 + attr_len]
                    postfix = postfix[3 + attr_len:]  # Next attribute
            except Exception as e:
                LOG.error(e)
                error_str = traceback.format_exc()
                LOG.debug(error_str)
                raise excep.UpdateMessageError(
                    sub_error=bgp_cons.ERR_MSG_UPDATE_MALFORMED_ATTR_LIST,
                    data='')

            if type_code == bgp_cons.BGPTYPE_ORIGIN:

                decode_value = Origin().parse(value=attr_value)

            elif type_code == bgp_cons.BGPTYPE_AS_PATH:

                decode_value = ASPath().parse(value=attr_value, asn4=asn4)

            elif type_code == bgp_cons.BGPTYPE_NEXT_HOP:

                decode_value = NextHop().parse(value=attr_value)

            elif type_code == bgp_cons.BGPTYPE_MULTI_EXIT_DISC:

                decode_value = MED().parse(value=attr_value)

            elif type_code == bgp_cons.BGPTYPE_LOCAL_PREF:

                decode_value = LocalPreference().parse(value=attr_value)

            elif type_code == bgp_cons.BGPTYPE_ATOMIC_AGGREGATE:

                decode_value = AtomicAggregate().parse(value=attr_value)

            elif type_code == bgp_cons.BGPTYPE_AGGREGATOR:

                decode_value = Aggregator().parse(value=attr_value, asn4=asn4)

            elif type_code == bgp_cons.BGPTYPE_COMMUNITIES:

                decode_value = Community().parse(value=attr_value)

            elif type_code == bgp_cons.BGPTYPE_ORIGINATOR_ID:

                decode_value = OriginatorID().parse(value=attr_value)

            elif type_code == bgp_cons.BGPTYPE_CLUSTER_LIST:

                decode_value = ClusterList().parse(value=attr_value)

            elif type_code == bgp_cons.BGPTYPE_NEW_AS_PATH:

                decode_value = ASPath().parse(value=attr_value, asn4=True)

            elif type_code == bgp_cons.BGPTYPE_NEW_AGGREGATOR:

                decode_value = Aggregator().parse(value=attr_value, asn4=True)
            else:
                decode_value = repr(attr_value)
            attributes[type_code] = decode_value

        return attributes