Esempio n. 1
0
 def json(self):
     return {
         "origin": self.origin_value,
         "origin_string": BGPTranslation.origin(self.origin_value),
         "type": self.type,
         "type_string": BGPTranslation.path_attribute(self.type),
         "error": self.error,
     }
Esempio n. 2
0
 def json(self):
     return {
         "multiple_exit_discriminator": self.multiple_exit_discriminator,
         "type": self.type,
         "type_string": BGPTranslation.path_attribute(self.type),
         "error": self.error,
     }
Esempio n. 3
0
 def json(self):
     return {
         "type": self.type,
         "type_string": BGPTranslation.path_attribute(self.type),
         "error": self.error,
         "next_hop": str(BGPRoute.decimal_ip_to_string(self.next_hop))
     }
Esempio n. 4
0
    def __str__(self):
        if isinstance(self.global_administrator, int) and isinstance(
                self.local_administrator, int) and isinstance(
                    self.type, int) and isinstance(self.sub_type, int):
            type = self.type
            sub_type = self.sub_type
            global_administrator = self.global_administrator
            local_administrator = self.local_administrator

        elif isinstance(self.global_administrator, bytes) and isinstance(
                self.local_administrator, bytes) and isinstance(
                    self.type, bytes) and isinstance(self.sub_type, bytes):
            type = struct.unpack("!B", self.type)[0]
            sub_type = struct.unpack("!B", self.sub_type)[0]
            global_administrator = struct.unpack("!H",
                                                 self.global_administrator)[0]
            local_administrator = struct.unpack("!I",
                                                self.local_administrator)[0]

        else:
            return ""

        type_string = BGPTranslation.extended_community(type, sub_type)

        return type_string + " (" + str(self.global_administrator) + ":" + str(
            self.local_administrator) + ")"
Esempio n. 5
0
    def __str__(self):
        # Return the string identifier of the BGP message
        # Example return: <BGPMessage type=UPDATE length=128>
        message_type_string = BGPTranslation.message_type(self.type)
        message_length_string = self.length
        message_parsed_string = BGPTranslation.boolean(self.parsed)
        message_error_string = BGPTranslation.boolean(self.error)

        # Assemble first part of message
        return_string = "<BGPMessage type="

        # Assemble message type
        if message_type_string is not None:
            return_string += message_type_string
        else:
            return_string += "UNKNOWN"

        # Assemble length
        return_string += " " + "length="

        if message_length_string is not None:
            return_string += str(message_length_string)
        else:
            return_string += "UNKNOWN"

        # Assemble parsed
        return_string += " " + "parsed="

        if message_parsed_string is not None:
            return_string += message_parsed_string
        else:
            return_string += "UNKNOWN"

        # Assemble error
        return_string += " " + "error="

        if message_error_string is not None:
            return_string += message_error_string
        else:
            return_string += "UNKNOWN"

        # Close message
        return_string += ">"

        # Return fully assembled message
        return return_string
Esempio n. 6
0
    def json(self):
        r = {
            "type":
            self.type,
            "type_string":
            BGPTranslation.extended_community_type(self.type),
            "sub_type":
            self.sub_type,
            "sub_type_string":
            BGPTranslation.extended_community_subtype(self.type,
                                                      self.sub_type),
            "global_administrator":
            self.global_administrator,
            "local_administrator":
            self.local_administrator
        }

        return r
Esempio n. 7
0
    def json(self):
        capabilities = []

        for c in self.capability_list:
            capabilities.append(c.json())

        return {
            "type": self.type,
            "type_string": BGPTranslation.open_parameter(self.type),
            "capabilities": capabilities
        }
    def json(self):
        r = {
            "type": self.type,
            "type_string": BGPTranslation.path_attribute(self.type),
            "error": self.error,
            "extended_communities": []
        }

        for e in self.extended_communities:
            r["extended_communities"].append(e.json())

        return r
Esempio n. 9
0
    def json(self):
        r = {
            "type": self.type,
            "type_string": BGPTranslation.path_attribute(self.type),
            "error": self.error,
            "large_communities": []
        }

        for community in self.large_communities:
            r["large_communities"].append(community.json())

        return r
Esempio n. 10
0
    def json(self):
        r = {
            "segment_type":
            self.segment_type,
            "segment_type_string":
            BGPTranslation.path_segment_type(self.segment_type),
            "segments": []
        }

        for s in self.segments:
            r["segments"].append(s)

        return r
Esempio n. 11
0
    def json(self):
        r = {
            "asn_byte_length": self.asn_byte_length,
            "type": self.type,
            "type_string": BGPTranslation.path_attribute(self.type),
            "path_segments": [],
            "error": self.error,
        }

        for segment in self.path_segments:
            r["path_segments"].append(segment.json())

        return r
Esempio n. 12
0
    def apply(self, message):
        r = ""

        for f in self.fields:
            if f == self.FIELD_MESSAGE_TIMESTAMP:
                r += self.separator + str(
                    message.pcap_information.get_timestamp()[0]) + "." + str(
                        message.pcap_information.get_timestamp()[1])
            elif f == self.FIELD_MESSAGE_IP_SOURCE:
                r += self.separator + message.pcap_information.get_ip(
                ).get_source_string()
            elif f == self.FIELD_MESSAGE_IP_DESTINATION:
                r += self.separator + message.pcap_information.get_ip(
                ).get_destination_string()
            elif f == self.FIELD_MESSAGE_MAC_SOURCE:
                r += self.separator + message.pcap_information.get_mac(
                ).get_source_string()
            elif f == self.FIELD_MESSAGE_MAC_DESTINATION:
                r += self.separator + message.pcap_information.get_mac(
                ).get_destination_string()
            elif f == self.FIELD_MESSAGE_LENGTH:
                r += self.separator + str(message.length)
            elif f == self.FIELD_MESSAGE_TYPE:
                r += self.separator + BGPTranslation.message_type(message.type)
            elif f == self.FIELD_UPDATE_SUBTYPE:
                # We can only display this information if we are handling an UPDATE message
                if message.type == BGPStatics.MESSAGE_TYPE_UPDATE:
                    r += self.separator + BGPTranslation.update_subtype(
                        message.subtype)
                else:
                    r += self.separator
            elif f == self.FIELD_UPDATE_PATH_ATTRIBUTES_LENGTH:
                # We can only display this information if we are handling an UPDATE message
                if message.type == BGPStatics.MESSAGE_TYPE_UPDATE:
                    r += self.separator + str(message.path_attributes_length)
                else:
                    r += self.separator
            elif f == self.FIELD_UPDATE_WITHDRAWN_ROUTES_LENGTH:
                # We can only display this information if we are handling an UPDATE message
                if message.type == BGPStatics.MESSAGE_TYPE_UPDATE:
                    r += self.separator + str(message.withdrawn_routes_length)
                else:
                    r += self.separator
            elif f == self.FIELD_UPDATE_WITHDRAWN_ROUTES:
                # We can only display this information if we are handling an UPDATE message
                if message.type == BGPStatics.MESSAGE_TYPE_UPDATE:
                    if len(message.withdrawn_routes) > 0:
                        add = ""

                        for route in message.withdrawn_routes:
                            add += ";" + str(route)

                        # Skip first separator character
                        r += self.separator + add[1:]
                    else:
                        r += self.separator
                else:
                    r += self.separator
            elif f == self.FIELD_UPDATE_NLRI:
                # We can only display this information if we are handling an UPDATE message
                if message.type == BGPStatics.MESSAGE_TYPE_UPDATE:
                    if len(message.nlri) > 0:
                        add = ""

                        for route in message.nlri:
                            add += ";" + str(route)

                        # Skip first separator character
                        r += self.separator + add[1:]
                    else:
                        r += self.separator
                else:
                    r += self.separator
            elif f == self.FIELD_UPDATE_ATTRIBUTE_ORIGIN:
                # We can only display this information if we are handling an UPDATE message
                if message.type == BGPStatics.MESSAGE_TYPE_UPDATE:
                    if len(message.path_attributes) > 0:
                        for attribute in message.path_attributes:
                            # We found the correct path attribute
                            if isinstance(attribute, PathAttributeOrigin):
                                r += self.separator + str(attribute)
                                break
                    else:
                        r += self.separator
                else:
                    r += self.separator
            elif f == self.FIELD_UPDATE_ATTRIBUTE_AS_PATH:
                # We can only display this information if we are handling an UPDATE message
                if message.type == BGPStatics.MESSAGE_TYPE_UPDATE:
                    if len(message.path_attributes) > 0:
                        for attribute in message.path_attributes:
                            # We found the correct path attribute
                            if isinstance(attribute, PathAttributeASPath):
                                if len(attribute.path_segments) > 0:
                                    add = ""

                                    for segment in attribute.path_segments:
                                        add += ";" + str(segment)

                                    # Skip first separator
                                    r += self.separator + add[1:]
                                    break
                                else:
                                    r += self.separator
                                    break

                    else:
                        r += self.separator
                else:
                    r += self.separator
            elif f == self.FIELD_UPDATE_ATTRIBUTE_NEXT_HOP:
                # We can only display this information if we are handling an UPDATE message
                if message.type == BGPStatics.MESSAGE_TYPE_UPDATE:
                    if len(message.path_attributes) > 0:
                        for attribute in message.path_attributes:
                            # We found the correct path attribute
                            if isinstance(attribute, PathAttributeNextHop):
                                r += self.separator + str(attribute)
                                break
                    else:
                        r += self.separator
                else:
                    r += self.separator
            elif f == self.FIELD_UPDATE_ATTRIBUTE_COMMUNITIES or f == self.FIELD_UPDATE_ATTRIBUTE_LARGE_COMMUNITIES:
                # We can only display this information if we are handling an UPDATE message
                if message.type == BGPStatics.MESSAGE_TYPE_UPDATE:
                    if len(message.path_attributes) > 0:
                        for attribute in message.path_attributes:
                            # We found the correct path attribute
                            communities = None
                            if isinstance(attribute, PathAttributeCommunities):
                                communities = attribute.communities
                            elif isinstance(attribute,
                                            PathAttributeLargeCommunities):
                                communities = attribute.large_communities

                            if communities:
                                if len(communities) > 0:
                                    add = ""
                                    for community in communities:
                                        add += ";" + str(community)

                                    r += self.separator + add[1:]
                                    break
                                else:
                                    r += self.separator
                    else:
                        r += self.separator
                else:
                    r += self.separator
            elif f == self.FIELD_UPDATE_ATTRIBUTE_EXTENDED_COMMUNITIES:
                # @todo Find a good way to display extended communities in just one line
                r += self.separator
            else:
                # No field match
                pass

        # Delete first tab
        return r[1:]
Esempio n. 13
0
 def json(self):
     return {
         "capability": self.type,
         "capability_string": BGPTranslation.capability(self.type)
     }
Esempio n. 14
0
    def apply(self, message):

        # Basic data for every message type
        data = {
            "timestamp":
            str(message.pcap_information.get_timestamp()[0]) + "." +
            str(message.pcap_information.get_timestamp()[1]),
            "message_type":
            message.type,
            "message_type_string":
            BGPTranslation.message_type(message.type),
            "length":
            message.length,
            "source_mac":
            message.pcap_information.get_mac().get_source_string(),
            "destination_mac":
            message.pcap_information.get_mac().get_destination_string(),
            "source_ip":
            message.pcap_information.get_ip().get_source_string(),
            "destination_ip":
            message.pcap_information.get_ip().get_destination_string(),
            "customer_vlan":
            message.pcap_information.get_customer_vlan(),
            "service_vlan":
            message.pcap_information.get_service_vlan(),
            "message_data":
            None
        }

        # Handle specific message types that contain more information than added above
        # Currently we just need to add information to OPEN- and UPDATE-messages
        if message.type == BGPStatics.MESSAGE_TYPE_OPEN:
            message_data = {
                "asn": message.asn,
                "hold_time": message.hold_time,
                "identifier": message.identifier,
                "optional_parameter_length": message.optional_parameter_length,
                "optional_parameters": None
            }

            # Add optional parameters
            optional_parameters = []

            if len(message.optional_parameter) > 0:
                for o in message.optional_parameter:
                    optional_parameters.append(o.json())

            # Assign to message data
            message_data["optional_parameters"] = optional_parameters

            # Assign message data to return data
            data["message_data"] = message_data

        elif message.type == BGPStatics.MESSAGE_TYPE_UPDATE:
            message_data = {
                "sub_type_string":
                BGPTranslation.update_subtype(message.subtype),
                "withdrawn_routes_length": message.withdrawn_routes_length,
                "path_attributes_length": message.path_attributes_length,
                "path_attributes": None,
                "withdrawn_routes": None,
                "pathId": None,
                "nlri": None
            }

            path_attributes = []
            withdrawn_routes = []
            nlri = []

            # Add path attributes
            if len(message.path_attributes) > 0:
                for a in message.path_attributes:
                    path_attributes.append(a.json())

            # Add withdrawn routes
            if len(message.withdrawn_routes) > 0:
                for w in message.withdrawn_routes:
                    withdrawn_routes.append(str(w))

            # Add NLRI
            if len(message.nlri) > 0:
                for n in message.nlri:
                    nlri.append(str(n))

            # Assign to message data
            message_data["path_attributes"] = path_attributes
            if message.add_path:
                message_data["pathId"] = message.path_id
            message_data["withdrawn_routes"] = withdrawn_routes
            message_data["nlri"] = nlri

            # Assign message data to return data
            data["message_data"] = message_data

        return json.dumps(data)
Esempio n. 15
0
    def apply(self, message):
        # Example return:
        #
        # [BGPMessage UPDATE] - [123.123.123.123 -> 123.123.123.123]
        # |- IP: 123.123.123.123 -> 123.123.123.123
        # |- MAC: 11:11:11:11:11:11 -> 11:11:11:11:11
        # |- Unix Time: 1412416346.123245123
        # |
        # |- Withdrawn Routes Length: 0
        # |- Total Path Attribute Length: 55
        # |- Path Attributes
        # |--- ORIGIN: IGP
        # |--- AS_PATH: (9498 9430)
        # |--- NEXT_HOP: 80.81.194.250
        # |--- COMMUNITIES: 9498:1 9498:11 9498:91
        # |- NLRI
        # |--- 203.190.42.0/24
        ##

        # Initialize basic return string and PCAP information
        string = "[BGPMessage " + BGPTranslation.message_type(
            message.type) + "] - " + str(message.length) + " Bytes\n"
        string += self.prefix(0) + "MAC: " + message.pcap_information.get_mac(
        ).get_source_string(
            separated=True) + " -> " + message.pcap_information.get_mac(
            ).get_destination_string(separated=True) + "\n"
        string += self.prefix(0) + "IP: " + message.pcap_information.get_ip(
        ).get_source_string() + ":" + message.pcap_information.get_ports(
        ).get_source_string() + " -> " + message.pcap_information.get_ip(
        ).get_destination_string() + ":" + message.pcap_information.get_ports(
        ).get_destination_string() + "\n"
        string += self.prefix(
            0) + "Timestamp: " + message.pcap_information.get_timestmap_utc(
            ) + " (" + str(
                message.pcap_information.get_timestamp()[0]) + "." + str(
                    message.pcap_information.get_timestamp()[1]) + ")\n"

        # Display additional information
        if BGPStatics.MESSAGE_TYPE_KEEPALIVE == message.type:
            pass

        if BGPStatics.MESSAGE_TYPE_OPEN == message.type:
            # --- Divider for PCAP information
            string += self.prefix(-1) + "\n"

            string += self.prefix(0) + "Version: " + str(
                message.version) + "\n"
            string += self.prefix(0) + "My ASN: " + str(message.asn) + "\n"
            string += self.prefix(0) + "Hold Time: " + str(
                message.hold_time) + "\n"
            string += self.prefix(0) + "BGP Identifier: " + str(
                BGPRoute.decimal_ip_to_string(message.identifier)) + "\n"

            # --- Optional Parameters
            string += self.prefix(0) + "Optional Parameters Length: " + str(
                message.optional_parameter_length) + " Bytes" + "\n"

            # Process optional parameters
            if message.optional_parameter_length > 0:
                string += self.prefix(0) + "Optional Parameters:" + "\n"

                for parameter in message.optional_parameter:
                    if parameter.type == BGPStatics.OPEN_CAPABILITY:
                        string += self.prefix(
                            1) + "Parameter: Capability" + "\n"

                        # Process capabilities
                        for capability in parameter.capability_list:
                            if capability.type is not BGPStatics.CAPABILITY_UNKNOWN:
                                string += self.prefix(
                                    2) + BGPTranslation.capability(
                                        capability.type) + " (" + str(
                                            capability.type) + ")\n"
                            else:
                                string += self.prefix(2) + str(
                                    capability) + "\n"

                    elif parameter.type == BGPStatics.OPEN_AUTHENTICATION:
                        string += self.prefix(
                            1) + "Parameter: Authentication" + "\n"
                    elif parameter.type == BGPStatics.OPEN_RESERVED:
                        string += self.prefix(1) + "Parameter: Reserved" + "\n"

        if BGPStatics.MESSAGE_TYPE_UPDATE == message.type:
            # --- Divider for PCAP information
            string += self.prefix(-1) + "\n"

            # --- Update Message Sub-Type
            string += self.prefix(
                0
            ) + "Update Message Sub-Type: " + BGPTranslation.update_subtype(
                message.subtype) + "\n"

            # --- Lengths
            string += self.prefix(0) + "Withdrawn Routes Length: " + str(
                message.withdrawn_routes_length) + " Bytes\n"
            string += self.prefix(0) + "Total Path Attribute Length: " + str(
                message.path_attributes_length) + " Bytes\n"

            # --- NLRI
            if len(message.nlri) > 0:
                string += self.prefix(0) + "Prefix (NLRI):"
                if message.add_path:
                    string += " (AddPath)\n" + self.prefix(
                        0) + "Path Identifier: " + str(message.path_id)
                string += "\n"

                # Process NLRI
                for route in message.nlri:
                    string += self.prefix(1) + str(route) + "\n"

            # --- Path Attributes
            if message.path_attributes_length > 0:

                # Process path attributes
                for attribute in message.path_attributes:
                    string += self.prefix(0) + "Path Attributes:" + "\n"

                    if attribute.type == BGPStatics.UPDATE_ATTRIBUTE_EXTENDED_COMMUNITIES:
                        # Extended Communities must be displayed in another way than other attributes
                        string += self.prefix(
                            1) + BGPTranslation.path_attribute(
                                attribute.type) + ":\n"

                        for community in attribute.extended_communities:
                            string += self.prefix(2) + str(community) + "\n"
                    else:
                        # We got a "normal" path attribute
                        string += self.prefix(
                            1) + BGPTranslation.path_attribute(
                                attribute.type) + ": " + str(attribute) + "\n"

            # --- Withdrawn Routes
            if message.withdrawn_routes_length > 0:
                string += self.prefix(0) + "Withdrawn Routes:"
                if message.add_path:
                    string += " (AddPath)\n" + self.prefix(
                        0) + "Path Identifier: " + str(message.path_id)
                string += "\n"

                # Process withdrawn routes
                for route in message.withdrawn_routes:
                    string += self.prefix(1) + str(route) + "\n"

        if BGPStatics.MESSAGE_TYPE_NOTIFICATION == message.type:
            pass

        if BGPStatics.MESSAGE_TYPE_ROUTE_REFRESH == message.type:
            pass

        if BGPStatics.MESSAGE_TYPE_RESERVED == message.type:
            pass

        # Return assembled string plus final line break
        return string + "\n"
Esempio n. 16
0
 def json(self):
     return {
         "type": self.type,
         "type_string": BGPTranslation.path_attribute(self.type),
         "error": self.error,
     }
Esempio n. 17
0
 def json(self):
     return {
         "type": self.type,
         "type_string": BGPTranslation.open_parameter(self.type)
     }
Esempio n. 18
0
    def get_field_value(self, f, message):
        # Timestamp
        if f in self.FIELD_MESSAGE_TIMESTAMP:
            return str(
                message.pcap_information.get_timestamp()[0]) + "." + str(
                    message.pcap_information.get_timestamp()[1])

        # Source IP
        if f in self.FIELD_MESSAGE_IP_SOURCE:
            return message.pcap_information.get_ip().get_source_string()

        # Destination IP
        if f in self.FIELD_MESSAGE_IP_DESTINATION:
            return message.pcap_information.get_ip().get_destination_string()

        # Source MAC
        if f in self.FIELD_MESSAGE_MAC_SOURCE:
            return message.pcap_information.get_mac().get_source_string()

        # Destination MAC
        if f in self.FIELD_MESSAGE_MAC_DESTINATION:
            return message.pcap_information.get_mac().get_destination_string()

        # ASN
        if f in self.FIELD_OPEN_MYASN:
            asn = getattr(message, "asn", False)
            if asn:
                return str(asn)
            return None

        # Hold time
        if f in self.FIELD_OPEN_HOLD_TIME:
            hold_time = getattr(message, "hold_time", False)
            if hold_time:
                return str(hold_time)
            return None

        # BGP Version
        if f in self.FIELD_OPEN_VERSION:
            version = getattr(message, "version", False)
            if version:
                return str(version)
            return None

        # BGP Identifier
        if f in self.FIELD_OPEN_BGP_IDENTIFIER:
            bgp_identifier = getattr(message, "identifier", False)
            if bgp_identifier:
                return str(bgp_identifier)
            return None

        # Message length
        if f in self.FIELD_MESSAGE_LENGTH:
            return str(message.length)

        # Path attributes length
        if f in self.FIELD_UPDATE_PATH_ATTRIBUTES_LENGTH:
            path_attributes_length = getattr(message, "path_attributes_length",
                                             False)
            if path_attributes_length:
                return str(path_attributes_length)
            return None

        # Withdrawn routes length
        if f in self.FIELD_UPDATE_WITHDRAWN_ROUTES_LENGTH:
            withdrawn_routes_length = getattr(message,
                                              "withdrawn_routes_length", False)
            if withdrawn_routes_length:
                return str(withdrawn_routes_length)
            return None

        # Message type
        if f in self.FIELD_MESSAGE_TYPE:
            return BGPTranslation.message_type(message.type)

        # Message sub type
        if f in self.FIELD_UPDATE_SUBTYPE:
            subtype = getattr(message, "subtype", False)
            if subtype:
                return BGPTranslation.update_subtype(subtype)
            return None

        # Withdrawn routes
        if f in self.FIELD_UPDATE_WITHDRAWN_ROUTES:
            w_routes = getattr(message, "withdrawn_routes", False)
            if w_routes:
                return [str(r) for r in w_routes]
            return None

        # Path Identifier
        if f in self.FIELD_UPDATE_PATH_IDENTIFIER:
            add_path = getattr(message, "add_path", False)
            if add_path:
                return [message.path_id]
            return None

        # NLRI (announced prefixes)
        if f in self.FIELD_UPDATE_NLRI:
            prefixes = getattr(message, "nlri", False)
            if prefixes:
                return [str(r) for r in prefixes]
            return None

        # NLRI length
        if f in self.FIELD_UPDATE_NLRI_LENGTH:
            prefixes = getattr(message, "nlri", False)
            if prefixes:
                return [r.prefix_length_string for r in prefixes]
            return None

        # Attribute: Origin
        if f in self.FIELD_UPDATE_ATTRIBUTE_ORIGIN:
            path_attributes = getattr(message, "path_attributes", False)
            if path_attributes:
                return [
                    str(a) for a in path_attributes
                    if isinstance(a, PathAttributeOrigin)
                ]
            return None

        # Next hop
        if f in self.FIELD_UPDATE_ATTRIBUTE_NEXT_HOP:
            path_attributes = getattr(message, "path_attributes", False)
            if path_attributes:
                return [
                    str(a) for a in path_attributes
                    if isinstance(a, PathAttributeNextHop)
                ]
            return None

        # Communities
        if f in self.FIELD_UPDATE_ATTRIBUTE_COMMUNITIES:
            path_attributes = getattr(message, "path_attributes", False)
            if path_attributes:  # The split is necessary because communities are not returned as a list?
                communities = [
                    str(pa).split(" ") for pa in path_attributes
                    if isinstance(pa, PathAttributeCommunities)
                ]
                return list(chain.from_iterable(
                    communities))  # Flattens the resulting list
            return None

        # Large Communities
        if f in self.FIELD_UPDATE_ATTRIBUTE_LARGE_COMMUNITIES:
            path_attributes = getattr(message, "path_attributes", False)
            if path_attributes:  # The split is necessary because communities are not returned as a list?
                communities = [
                    str(pa).split(" ") for pa in path_attributes
                    if isinstance(pa, PathAttributeLargeCommunities)
                ]
                return list(chain.from_iterable(
                    communities))  # Flattens the resulting list
            return None

        # AS path (AS Sets remain unhandled?)
        if f in self.FIELD_UPDATE_ATTRIBUTE_AS_PATH:
            path_attributes = getattr(message, "path_attributes", False)
            if path_attributes:  # The split is necessary because segments are not returned as a list?
                segments = [
                    str(seg).split(" ") for seg in path_attributes
                    if isinstance(seg, PathAttributeASPath)
                ]
                return list(chain.from_iterable(
                    segments))  # Flattens the resulting list
            return None
Esempio n. 19
0
 def __str__(self):
     return BGPTranslation.origin(self.origin_value)