Beispiel #1
0
    def __init__(self, payload):
        BGPPathAttribute.__init__(self, payload)
        self.type = BGPStatics.UPDATE_ATTRIBUTE_ORIGIN

        self.origin_value = None

        self.__parse()
Beispiel #2
0
    def __init__(self, payload):
        BGPPathAttribute.__init__(self, payload)
        self.type = BGPStatics.UPDATE_ATTRIBUTE_NEXT_HOP

        # Path attribute specific variable
        self.next_hop = None

        self.__parse()
Beispiel #3
0
    def __init__(self, payload):
        BGPPathAttribute.__init__(self, payload)
        self.type = BGPStatics.UPDATE_ATTRIBUTE_COMMUNITIES

        # Path attribute specific variable
        self.communities = []

        self.__parse()
Beispiel #4
0
    def __init__(self, payload, attribute_flags):
        BGPPathAttribute.__init__(self, payload)
        self.type = BGPStatics.UPDATE_ATTRIBUTE_EXTENDED_COMMUNITIES

        # We need the attribute flags for that path attribute
        self.attribute_flags = attribute_flags
        self.extended_communities = []

        self.__parse()
Beispiel #5
0
    def __init__(self, payload):
        BGPPathAttribute.__init__(self, payload)
        self.type = BGPStatics.UPDATE_ATTRIBUTE_AS_PATH

        # Path attribute specific variables
        self.asn_byte_length = None
        self.path_segments = []

        self.__parse()
    def __init__(self, payload):
        BGPPathAttribute.__init__(self, payload)
        self.type = BGPStatics.UPDATE_ATTRIBUTE_BGP_ENTROPY_LABEL_CAPABILITY

        self.__parse()
Beispiel #7
0
    def __parse(self):
        self.parsed = True

        try:
            # Check last two bytes of byte payload - if they are set to zero we don't have any path attributes
            if struct.unpack("!H", self.payload[-2:])[0] == 0:
                self.path_attributes_length = 0

            # Unpack the length of withdrawn routes field and add 2 bytes to the current byte marker position
            self.withdrawn_routes_length = struct.unpack(
                "!H", self.payload[:2])[0]
            current_byte_position = 2

            # Start parsing withdrawn routes
            if self.withdrawn_routes_length is not 0:
                continue_loop = True

                # Loop through withdrawals
                while continue_loop:
                    # First of all we need to parse the length of the withdrawn prefix. Depending on the prefix length
                    # we can determine the length following prefix itself
                    prefix_length_bytes = self.payload[
                        current_byte_position:current_byte_position + 1]
                    prefix_length = struct.unpack("!B", prefix_length_bytes)[0]
                    current_byte_position += 1

                    if 0 <= prefix_length <= 8:
                        # Length of prefix field: 1 Byte
                        prefix_bytes = self.payload[
                            current_byte_position:current_byte_position + 1]
                        current_byte_position += 1

                    elif 9 <= prefix_length <= 16:
                        # Length of prefix field: 2 Bytes
                        prefix_bytes = self.payload[
                            current_byte_position:current_byte_position + 2]
                        current_byte_position += 2

                    elif 17 <= prefix_length <= 24:
                        # Length of prefix field: 3 Bytes
                        prefix_bytes = self.payload[
                            current_byte_position:current_byte_position + 3]
                        current_byte_position += 3

                    elif 25 <= prefix_length:
                        # Length of prefix field: 4 Bytes
                        prefix_bytes = self.payload[
                            current_byte_position:current_byte_position + 4]
                        current_byte_position += 4

                    else:
                        self.error = True
                        raise BGPWithdrawnPrefixError(
                            "can't match prefix length.")

                    # Add BGPRoute object with information about the withdrawn route to list
                    self.withdrawn_routes.append(
                        BGPRoute.from_binary(prefix_bytes,
                                             prefix_length_bytes))

                    # Check if we are at the end of the payload
                    if self.withdrawn_routes_length <= current_byte_position:
                        # If yes we need to stop the iteration
                        continue_loop = False

            # Second step: Continue with the path attributes
            if self.path_attributes_length is None:
                # First of all get the attributes length field and update the current byte position
                self.path_attributes_length = struct.unpack(
                    "!H",
                    self.payload[current_byte_position:current_byte_position +
                                 2])[0]
                current_byte_position += 2

            # Now we have a correct path_attributes_length stored. If this length is zero we don't need to do anything
            if self.path_attributes_length is not 0:
                continue_loop = True

                # Loop through path attributes
                while continue_loop:
                    # Now comes a tricky part of UPDATE message parsing. Each path attribute has a flag bitfield.
                    # One of those flags is called 'extended length'. If it's set to 1 the following attribute fields
                    # are 2 bytes long. But if it's set to zero it's just 1 byte long ...

                    # So first of all: Flag parsing!
                    attribute_flags = BGPUpdateFlags(
                        struct.unpack(
                            "!B", self.payload[
                                current_byte_position:current_byte_position +
                                1])[0])
                    current_byte_position += 1

                    if attribute_flags.length:
                        # We got an extended length flag
                        attribute_fields = struct.unpack(
                            "!BH", self.payload[
                                current_byte_position:current_byte_position +
                                3])
                        current_byte_position += 3
                    else:
                        # We got a normal length flag
                        attribute_fields = struct.unpack(
                            "!BB", self.payload[
                                current_byte_position:current_byte_position +
                                2])
                        current_byte_position += 2

                    # Finally assign the variables
                    attribute_type = attribute_fields[0]
                    attribute_length = attribute_fields[1]

                    # Now we are using the factory pattern again to determine
                    # which kind of attribute we have to add the list
                    self.path_attributes.append(
                        BGPPathAttribute.factory(
                            attribute_type, self.payload[
                                current_byte_position:current_byte_position +
                                attribute_length], attribute_flags))

                    # Add length of attribute to position pointer
                    current_byte_position += attribute_length

                    # Check if there are further path attributes to parse
                    if current_byte_position >= self.path_attributes_length:
                        continue_loop = False

            # Third step: NLRIs
            if len(self.payload) > (self.path_attributes_length + 4 +
                                    self.withdrawn_routes_length):

                continue_loop = True

                # The four bytes that get added to the attributes and routes length are the two two-byte fields
                # for path attribute length and withdrawn routes length
                current_byte_position = self.path_attributes_length + 4 + self.withdrawn_routes_length

                while continue_loop:
                    # First of all we have to check the prefix length as byte-length of the following
                    # prefix depends on its prefix length (This is a 1-byte-field)
                    prefix_length_bytes = self.payload[
                        current_byte_position:current_byte_position + 1]
                    prefix_length = struct.unpack("!B", prefix_length_bytes)[0]
                    current_byte_position += 1

                    if 0 <= prefix_length <= 8:
                        # Length of prefix field: 1 Byte
                        prefix_bytes = self.payload[
                            current_byte_position:current_byte_position + 1]
                        current_byte_position += 1
                    elif 9 <= prefix_length <= 16:
                        # Length of prefix field: 2 Bytes
                        prefix_bytes = self.payload[
                            current_byte_position:current_byte_position + 2]
                        current_byte_position += 2
                    elif 17 <= prefix_length <= 24:
                        # Length of prefix field: 3 Bytes
                        prefix_bytes = self.payload[
                            current_byte_position:current_byte_position + 3]
                        current_byte_position += 3
                    elif 25 <= prefix_length:
                        # Length of prefix field: 4 Bytes
                        prefix_bytes = self.payload[
                            current_byte_position:current_byte_position + 4]
                        current_byte_position += 4
                    else:
                        self.error = True
                        raise BGPWithdrawnPrefixError(
                            "can't match prefix length.")

                    try:
                        self.nlri.append(
                            BGPRoute.from_binary(prefix_bytes,
                                                 prefix_length_bytes))
                    except BGPError as e:
                        raise BGPNLRIError(
                            "can't append NLRI to message (error: " + str(e) +
                            ")")

                    if (current_byte_position + 19) >= len(self.payload):
                        # 19 Byte = Marker (16 bytes) + Message Length (2 bytes) + Message Type (1 byte)
                        continue_loop = False

            # Determine sub-type for filtering
            # Using bit flags for easier assignment
            if len(self.nlri) > 0:
                self.subtype = (self.subtype | BGPStatics.UPDATE_TYPE_ANNOUNCE)

            if len(self.withdrawn_routes) > 0:
                self.subtype = (self.subtype
                                | BGPStatics.UPDATE_TYPE_WITHDRAWAL)

        except BGPWithdrawnPrefixError as p:
            self.error = True
            logging.info(p)
        except Exception as e:
            self.error = True

        self.error = False
    def __init__(self, payload):
        BGPPathAttribute.__init__(self, payload)
        self.type = BGPStatics.UPDATE_ATTRIBUTE_TUNNEL_ENCAPSULATION

        self.__parse()
Beispiel #9
0
    def __init__(self, payload):
        BGPPathAttribute.__init__(self, payload)
        self.type = BGPStatics.UPDATE_ATTRIBUTE_MP_REACH_NLRI

        self.__parse()
Beispiel #10
0
    def __init__(self, payload):
        BGPPathAttribute.__init__(self, payload)
        self.type = BGPStatics.UPDATE_ATTRIBUTE_AS4_AGGREGATOR

        self.__parse()
Beispiel #11
0
    def __init__(self, payload):
        BGPPathAttribute.__init__(self, payload)
        self.type = BGPStatics.UPDATE_ATTRIBUTE_ORIGINATOR_ID

        self.__parse()
Beispiel #12
0
    def __init__(self, payload):
        BGPPathAttribute.__init__(self, payload)
        self.type = BGPStatics.UPDATE_ATTRIBUTE_PMSI_TUNNEL

        self.__parse()
Beispiel #13
0
    def __init__(self, payload):
        BGPPathAttribute.__init__(self, payload)
        self.type = BGPStatics.UPDATE_ATTRIBUTE_TRAFFIC_ENGINEERING

        self.__parse()
Beispiel #14
0
    def __init__(self, payload):
        BGPPathAttribute.__init__(self, payload)
        self.type = BGPStatics.UPDATE_ATTRIBUTE_CONNECTOR_ATTRIBUTE

        self.__parse()
Beispiel #15
0
    def __init__(self, payload):
        BGPPathAttribute.__init__(self, payload)
        self.type = BGPStatics.UPDATE_ATTRIBUTE_MULTI_EXIT_DISC

        self.__parse()
Beispiel #16
0
    def __init__(self, payload):
        BGPPathAttribute.__init__(self, payload)
        self.type = BGPStatics.UPDATE_ATTRIBUTE_RESERVED

        self.__parse()
Beispiel #17
0
    def __init__(self, payload):
        BGPPathAttribute.__init__(self, payload)
        self.type = BGPStatics.UPDATE_ATTRIBUTE_CLUSTER_LIST

        self.__parse()
    def __init__(self, payload):
        BGPPathAttribute.__init__(self, payload)
        self.type = BGPStatics.UPDATE_ATTRIBUTE_IPV6_ADDRESS_SPECIFIC_EXTENDED_COMMUNITY

        self.__parse()
Beispiel #19
0
    def __init__(self, payload):
        BGPPathAttribute.__init__(self, payload)
        self.type = None

        self.__parse()
Beispiel #20
0
    def __init__(self, payload):
        BGPPathAttribute.__init__(self, payload)
        self.type = BGPStatics.UPDATE_ATTRIBUTE_AS_PATHLIMIT

        self.__parse()
    def __init__(self, payload):
        BGPPathAttribute.__init__(self, payload)
        self.type = BGPStatics.UPDATE_ATTRIBUTE_PE_DISTINGUISHER_LABLES

        self.__parse()