def __init__(self, payload): BGPPathAttribute.__init__(self, payload) self.type = BGPStatics.UPDATE_ATTRIBUTE_ORIGIN self.origin_value = None self.__parse()
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()
def __init__(self, payload): BGPPathAttribute.__init__(self, payload) self.type = BGPStatics.UPDATE_ATTRIBUTE_COMMUNITIES # Path attribute specific variable self.communities = [] self.__parse()
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()
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()
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()
def __init__(self, payload): BGPPathAttribute.__init__(self, payload) self.type = BGPStatics.UPDATE_ATTRIBUTE_MP_REACH_NLRI self.__parse()
def __init__(self, payload): BGPPathAttribute.__init__(self, payload) self.type = BGPStatics.UPDATE_ATTRIBUTE_AS4_AGGREGATOR self.__parse()
def __init__(self, payload): BGPPathAttribute.__init__(self, payload) self.type = BGPStatics.UPDATE_ATTRIBUTE_ORIGINATOR_ID self.__parse()
def __init__(self, payload): BGPPathAttribute.__init__(self, payload) self.type = BGPStatics.UPDATE_ATTRIBUTE_PMSI_TUNNEL self.__parse()
def __init__(self, payload): BGPPathAttribute.__init__(self, payload) self.type = BGPStatics.UPDATE_ATTRIBUTE_TRAFFIC_ENGINEERING self.__parse()
def __init__(self, payload): BGPPathAttribute.__init__(self, payload) self.type = BGPStatics.UPDATE_ATTRIBUTE_CONNECTOR_ATTRIBUTE self.__parse()
def __init__(self, payload): BGPPathAttribute.__init__(self, payload) self.type = BGPStatics.UPDATE_ATTRIBUTE_MULTI_EXIT_DISC self.__parse()
def __init__(self, payload): BGPPathAttribute.__init__(self, payload) self.type = BGPStatics.UPDATE_ATTRIBUTE_RESERVED self.__parse()
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()
def __init__(self, payload): BGPPathAttribute.__init__(self, payload) self.type = None self.__parse()
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()