Python TLV unpack

119 views Asked by At

My program should check for tag length and values and structure them in an output file that contains hex numbers. It does nearly everything correct except one TLv.

For example I have this in my input file:

A118A7080606B20207D181008105A107C4B1040605B20200AE040607B20207D1810101

The output I get is:

A1 18
    A7 08
        06 06 B20207D18100     #this tlv doesnt get nested more
    81 05 A107C4B104
    06 05 B20200AE04
06 07
    B2 02 07D1
    81 01 01

The output I want is:

A1 18
    A7 08
        06 06
                    B2 02 07D1
                    81 00
    81 05 A107C4B104
    06 05 B20200AE04
06 07
    B2 02 07D1
    81 01 01

As you see this tlv 06 06 B20207D18100 doesn't get nested, I believe, because it ends with 00, but I am not sure.

This is my code:

def is_valid_tlv(s):
    i = 0
    while i < len(s):
        # Get the tag
        tag = s[i:i+2]
        i += 2
        if i >= len(s):
            return False

        # Get the length
        length = s[i:i+2]
        i += 2
        if i >= len(s):
            return False

        # Calculate the length of the value
        length_value = length
        if length == '81':
            length_value = s[i:i+2]
            i += 2
        elif length == '82':
            length_value = s[i:i+4]
            i += 4
        elif length == '83':
            length_value = s[i:i+6]
            i += 6

        # Get the value
        value = s[i:i+int(length_value, 16)*2]
        i += int(length_value, 16)*2
        

        # Check if the length of the value matches the length specified in the TLV
        if len(value) != int(length_value, 16)*2:
            print(value)
            return False

    return i == len(s)

def parse_tlv(data, indent=0, f=None):
    i = 0
    while i < len(data):
        # Get the tag
        tag = data[i:i+2]
        i += 2

        # Check if the tag is in the list of tags
        if tag not in tags:
            continue

        # Get the length
        length = data[i:i+2]
        i += 2

        # Calculate the length of the value
        length_value = length
        if length == '81':
            length_value = data[i:i+2]
            i += 2
            length = length + length_value
        elif length == '82':
            length_value = data[i:i+4]
            i += 4
            length = length + length_value
        elif length == '83':
            length_value = data[i:i+6]
            i += 6
            length = length + length_value

        # Get the value
        value = data[i:i+int(length_value, 16)*2]
        i += int(length_value, 16)*2

        # Check if the value forms a valid TLV
        if is_valid_tlv(value):
            # If there are more TLVs in the value, parse them
            f.write('\t'*indent + tag + ' ' + length + '\n')
            parse_tlv(value, indent+1, f)
        else:
            # Write the tag, length, and value to the output file
            f.write('\t'*indent + tag + ' ' + length + ' ' + value + '\n')

# The list of tags to search for
tags = ['A1', '81', '06', 'A7', 'B2', 'B0']
# Step 1: Ask for an input file and create an output file
input_file_name = input("Enter the name of the input file: ")
output_file_name = input("Enter the name of the output file: ")

# Read the input file
with open(input_file_name, 'r') as f:
    data = f.read().replace('\n', '')

# Open the output file
with open(output_file_name, 'w') as f:
    # Step 2: Parse the TLV structure
    parse_tlv(data, 0, f)
0

There are 0 answers