示例#1
0
    def parse(cls, 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 [
                    cls.AS_SET, cls.AS_SEQUENCE, cls.AS_CONFED_SEQUENCE,
                    cls.AS_CONFED_SET
            ]:
                raise excep.UpdateMessageError(
                    sub_error=bgp_cons.ERR_MSG_UPDATE_MALFORMED_ASPATH,
                    data=repr(value))
            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
示例#2
0
    def construct(cls, value):
        try:
            if netaddr.IPAddress(value).version == 4:
                ip_addr_raw = netaddr.IPAddress(value).packed
                return struct.pack(
                    '!B', cls.FLAG) + struct.pack('!B', cls.ID) + struct.pack(
                        '!B', len(ip_addr_raw)) + ip_addr_raw

            else:
                raise excep.UpdateMessageError(
                    sub_error=bgp_cons.ERR_MSG_UPDATE_INVALID_NEXTHOP,
                    data=value)
        except Exception:
            raise excep.UpdateMessageError(
                sub_error=bgp_cons.ERR_MSG_UPDATE_INVALID_NEXTHOP, data=value)
示例#3
0
 def parse(cls, value):
     if len(value) % 4 == 0:
         next_hop = str(socket.inet_ntoa(struct.unpack("!I", value[0:4])))
         return next_hop
     else:
         # Error process
         raise excep.UpdateMessageError(
             sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN, data=value)
示例#4
0
 def construct(cls, value):
     if value not in [cls.IGP, cls.EGP, cls.INCOMPLETE]:
         raise excep.UpdateMessageError(
             sub_error=bgp_cons.ERR_MSG_UPDATE_INVALID_ORIGIN, data='')
     length = 1
     return struct.pack('!B', cls.FLAG) + struct.pack(
         '!B', cls.ID) + struct.pack('!B', length) + struct.pack(
             '!B', value)
示例#5
0
 def construct(cls, value):
     cluster_raw = b''
     try:
         for cluster in value:
             cluster_raw += netaddr.IPAddress(cluster).packed
         return struct.pack("!B", cls.FLAG) + struct.pack('!B', cls.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', cls.FLAG))
示例#6
0
 def parse(cls, value):
     cluster_list = []
     if len(value) % 4 != 0:
            raise excep.UpdateMessageError(sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN,data=repr(value))
     while value:
         cluster_list.append(str(netaddr.IPAddress(struct.unpack('!I', value[0:4])[0])))
         value = value[4:]
     return cluster_list
 def construct(cls, value):
     try:
         return struct.pack('!B', cls.FLAG) + struct.pack(
             '!B', cls.ID) + struct.pack('!B', 4) + struct.pack(
                 '!I', int(netaddr.IPAddress(ip)))
     except Exception:
         raise excep.UpdateMessageError(
             sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN, data=value)
示例#8
0
 def parse(cls, value):
     """
     parse bgp local preference attribute
     :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)
示例#9
0
 def construct(cls, value):
     """
     encode bgp local preference attribute
     :param value: interger value
     """
     try:
         return struct.pack('!B', cls.FLAG) + struct.pack('!B', cls.ID) + struct.pack('!B', 4) + struct.pack('!I', value)
     except Exception:
         raise excep.UpdateMessageError( sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN,data='')
示例#10
0
    def parse(cls, value, asn4=False):

        if not asn4:
            try:
                asn = struct.unpack('!H', value[:2])[0]
                aggregator = str(netaddr.IPAddress(struct.unpack('!I', value[2:])[0]))
            except Exception:
                raise excep.UpdateMessageError(sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN,data=value)

        else:
            # 4 bytes ASN
            try:
                asn = struct.unpack('!I', value[:4])[0]
                aggregator = str(netaddr.IPAddress(struct.unpack('!I', value[4:])[0]))
            except Exception:
                raise excep.UpdateMessageError(sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN,data=value)

        return asn, aggregator
示例#11
0
    def construct(cls, value, asn4=False):
        try:
            if asn4:
                agg_raw = struct.pack('!I', value[0]) + netaddr.IPAddress(value[1]).packed
            else:
                agg_raw = struct.pack('!H', value[0]) + netaddr.IPAddress(value[1]).packed

            return struct.pack('!B', cls.FLAG) + struct.pack('!B', cls.ID) + struct.pack('!B', len(agg_raw)) + agg_raw
        except Exception:
            raise excep.UpdateMessageError(sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN,data=value)
 def parse(cls, 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)
    def construct(cls, value):
        """construct a ATOMIC_AGGREGATE path attribute
        :param value:
        """

        if value:
            raise excep.UpdateMessageError(
                sub_error=bgp_cons.ERR_MSG_UPDATE_OPTIONAL_ATTR, data='')
        else:
            value = 0
        return struct.pack('!B', cls.FLAG) + struct.pack(
            '!B', cls.ID) + struct.pack('!B', value)
示例#14
0
    def construct(cls, value, asn4=False):
        """
        Construct AS PATH.
        :param asn4: 4byte asn
        :param value:
        """
        # value example
        # [(2, [3257, 31027, 34848, 21465])], or [(3, [64606]), (2, [64624, 65515])]
        flags = cls.FLAG
        as_path_raw = b''
        if value != 0:
            for segment in value:
                as_seg_raw = b''
                seg_type = segment[0]
                as_path_list = segment[1]
                if seg_type not in [
                        cls.AS_SET, cls.AS_SEQUENCE, cls.AS_CONFED_SET,
                        cls.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 len(as_path_raw) > 255:
                flags += AttributeFlag.EXTENDED_LENGTH
                return struct.pack(
                    '!B', flags) + struct.pack('!B', cls.ID) + struct.pack(
                        '!H', len(as_path_raw)) + as_path_raw
            else:
                return struct.pack(
                    '!B', flags) + struct.pack('!B', cls.ID) + struct.pack(
                        '!B', len(as_path_raw)) + as_path_raw
        else:
            length = 0
            return struct.pack('!B', flags) + struct.pack(
                '!B', cls.ID) + struct.pack('!B', length)
示例#15
0
    def parse_prefix_list(data, addpath=False):
        """
        Parses an RFC4271 encoded blob of BGP prefixes into a list

        :param data: hex data
        :param addpath: support addpath or not
        :return: prefix_list
        """
        prefixes = []
        postfix = data
        while len(postfix) > 0:
            # for python2 and python3
            if addpath:
                path_id = struct.unpack('!I', postfix[0:4])[0]
                postfix = postfix[4:]
            if isinstance(postfix[0], int):
                prefix_len = postfix[0]
            else:
                prefix_len = ord(postfix[0])
            if prefix_len > 32:
                LOG.warning('Prefix Length larger than 32')
                raise excep.UpdateMessageError(
                    sub_error=bgp_cons.ERR_MSG_UPDATE_INVALID_NETWORK_FIELD,
                    data=repr(data))
            octet_len, remainder = int(prefix_len / 8), prefix_len % 8
            if remainder > 0:
                # prefix length doesn't fall on octet boundary
                octet_len += 1
            tmp = postfix[1:octet_len + 1]
            # for python2 and python3
            if isinstance(postfix[0], int):
                prefix_data = [i for i in tmp]
            else:
                prefix_data = [ord(i) for i in tmp]
            # Zero the remaining bits in the last octet if it didn't fall
            # on an octet boundary
            if remainder > 0:
                prefix_data[-1] &= 255 << (8 - remainder)
            prefix_data = prefix_data + list(str(0)) * 4
            prefix = "%s.%s.%s.%s" % (tuple(
                prefix_data[0:4])) + '/' + str(prefix_len)
            if not addpath:
                prefixes.append(prefix)
            else:
                prefixes.append({'prefix': prefix, 'path_id': path_id})
            # Next prefix
            postfix = postfix[octet_len + 1:]

        return prefixes
示例#16
0
    def parse(cls, value):

        if len(value) != 4:
            raise excep.UpdateMessageError(
                sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN, data=value)
        return str(socket.inet_ntoa(struct.unpack("!I", value[0:4])))
示例#17
0
    def parse(cls, value):
        if len(value) % 8 != 0:
            raise excep.UpdateMessageError(sub_error=bgp_cons.ERR_MSG_UPDATE_ATTR_LEN,data=value)

        ext_community = []
        while value:
            comm_type, subtype = struct.unpack('!BB', value[0:2])
            value_tmp = value[2:8]

            comm_code = comm_type * 256 + subtype

            if comm_code == bgp_cons.BGP_EXT_COM_RT_0:
                # Route Target, Format AS(2bytes):AN(4bytes)
                asn, an = struct.unpack('!HI', value_tmp)
                ext_community.append([bgp_cons.BGP_EXT_COM_RT_0, '%s:%s' % (asn, an)])

            elif comm_code == bgp_cons.BGP_EXT_COM_RT_1:
                # Route Target,Format IPv4 address(4bytes):AN(2bytes)
                ipv4 = str(netaddr.IPAddress(struct.unpack('!I', value_tmp[0:4])[0]))
                an = struct.unpack('!H', value_tmp[4:])[0]
                ext_community.append([bgp_cons.BGP_EXT_COM_RT_1, '%s:%s' % (ipv4, an)])

            elif comm_code == bgp_cons.BGP_EXT_COM_RT_2:
                # Route Target,Format AS(4bytes):AN(2bytes)
                asn, an = struct.unpack('!IH', value_tmp)
                ext_community.append([bgp_cons.BGP_EXT_COM_RT_2, '%s:%s' % (asn, an)])

            elif comm_code == bgp_cons.BGP_EXT_COM_RO_0:
                # Route Origin,Format AS(2bytes):AN(4bytes)
                asn, an = struct.unpack('!HI', value_tmp)
                ext_community.append([bgp_cons.BGP_EXT_COM_RO_0, '%s:%s' % (asn, an)])

            elif comm_code == bgp_cons.BGP_EXT_COM_RO_1:
                # Route Origin,Format IP address:AN(2bytes)
                ipv4 = str(netaddr.IPAddress(struct.unpack('!I', value_tmp[0:4])[0]))
                an = struct.unpack('!H', value_tmp[4:])[0]
                ext_community.append([bgp_cons.BGP_EXT_COM_RO_1, '%s:%s' % (ipv4, an)])

            elif comm_code == bgp_cons.BGP_EXT_COM_RO_2:
                # Route Origin,Format AS(2bytes):AN(4bytes)
                asn, an = struct.unpack('!IH', value_tmp)
                ext_community.append([bgp_cons.BGP_EXT_COM_RO_2, '%s:%s' % (asn, an)])

            elif comm_code == bgp_cons.BGP_EXT_REDIRECT_NH:
                ipv4 = str(netaddr.IPAddress(int(binascii.b2a_hex(value_tmp[0:4]), 16)))
                copy_flag = struct.unpack('!H', value_tmp[4:])[0]
                ext_community.append([bgp_cons.BGP_EXT_REDIRECT_NH, ipv4, copy_flag])
            elif comm_code == bgp_cons.BGP_EXT_TRA_RATE:
                asn, rate = struct.unpack('!Hf', value_tmp)
                ext_community.append([bgp_cons.BGP_EXT_TRA_RATE, '%s:%s' % (asn, int(rate))])


            """
             # BGP Flow spec
            elif comm_code == bgp_cons.BGP_EXT_REDIRECT_NH:
                ipv4 = str(netaddr.IPAddress(int(binascii.b2a_hex(value_tmp[0:4]), 16)))
                copy_flag = struct.unpack('!H', value_tmp[4:])[0]
                ext_community.append([bgp_cons.BGP_EXT_REDIRECT_NH, ipv4, copy_flag])
            elif comm_code == bgp_cons.BGP_EXT_TRA_RATE:
                asn, rate = struct.unpack('!Hf', value_tmp)
                ext_community.append([bgp_cons.BGP_EXT_TRA_RATE, '%s:%s' % (asn, int(rate))])

            elif comm_code == bgp_cons.BGP_EXT_TRA_ACTION:
                bit_value = parse_bit(value_tmp[-1])
                ext_community.append([bgp_cons.BGP_EXT_TRA_ACTION, {'S': bit_value['6'], 'T': bit_value['7']}])
            elif comm_code == bgp_cons.BGP_EXT_REDIRECT_VRF:
                asn, an = struct.unpack('!HI', value_tmp)
                ext_community.append([bgp_cons.BGP_EXT_REDIRECT_VRF, '%s:%s' % (asn, an)])
            elif comm_code == bgp_cons.BGP_EXT_TRA_MARK:
                mark = struct.unpack('!B', value_tmp[-1])[0]
                ext_community.append([bgp_cons.BGP_EXT_TRA_MARK, mark])

            else:
                ext_community.append([bgp_cons.BGP_EXT_COM_UNKNOW, repr(value_tmp)])
                LOG.warn('unknow bgp extended community, type=%s, value=%s', comm_code, repr(value_tmp))

            """
            value = value[8:]

        return ext_community
示例#18
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
                    if isinstance(postfix[2], int):
                        attr_len = postfix[2]
                    else:
                        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)

            elif type_code == bgp_cons.BGPTYPE_MP_REACH_NLRI:
                decode_value = MpReachNLRI.parse(value=attr_value)

            elif type_code == bgp_cons.BGPTYPE_MP_UNREACH_NLRI:
                decode_value = MpUnReachNLRI.parse(value=attr_value)

            elif type_code == bgp_cons.BGPTYPE_EXTENDED_COMMUNITY:
                decode_value = ExtCommunity.parse(value=attr_value)
            else:
                decode_value = repr(attr_value)
            attributes[type_code] = decode_value

        return attributes
示例#19
0
 def parse(cls, value):
     origin = struct.unpack('!B', value)[0]
     if orgin not in [cls.IGP, cls.EGP, cls.INCOMPLETE]:
         raise excep.UpdateMessageError(
             sub_error=bgp_cons.ERR_MSG_UPDATE_INVALID_ORIGIN, data=value)
     return origin