Загрузка данных


import struct

def decode_mikrotik_payload(hex_data):
    # Если данные скопированы как hex-строка из Wireshark
    if isinstance(hex_data, str):
        data = bytes.fromhex(hex_data.replace(":", "").replace(" ", ""))
    else:
        data = hex_data

    offset = 0
    result = {}

    # Маппинг типов из вашего JS кода
    FT_TYPES = {
        0x00000000: "BOOL",
        0x08000000: "U32",
        0x10000000: "U64",
        0x20000000: "STRING",
        0x28000000: "MESSAGE",
        0x30000000: "RAW"
    }

    while offset < len(data):
        try:
            # 1. Читаем заголовок (4 байта, Big Endian)
            header = struct.unpack(">I", data[offset:offset+4])[0]
            offset += 4

            field_type_raw = header & 0xF8000000
            field_id = header & 0x00FFFFFF # Младшие 24 бита - ID поля
            
            type_name = FT_TYPES.get(field_type_raw, f"UNKNOWN({hex(field_type_raw)})")

            # 2. Читаем длину (в этом протоколе длина часто кодируется 1 байтом, 
            # если она < 0x80, или 2 байтами)
            length = data[offset]
            offset += 1
            if length & 0x80: # Обработка длинных полей (упрощенно)
                length = ((length & 0x7F) << 8) | data[offset]
                offset += 1

            # 3. Читаем значение
            value_data = data[offset:offset+length]
            offset += length

            # 4. Декодируем значение в зависимости от типа
            if "STRING" in type_name:
                value = value_data.decode('utf-8', errors='ignore')
            elif "U32" in type_name:
                value = struct.unpack(">I", value_data)[0] if len(value_data) == 4 else value_data.hex()
            elif "BOOL" in type_name:
                value = bool(value_data[0]) if value_data else True
            else:
                value = value_data.hex()

            # Пытаемся сопоставить ID поля с известными нам s1, s3 и т.д.
            # В протоколе s1 обычно имеет ID 1, s3 - ID 3
            field_name = f"field_{field_id}"
            if field_id == 1: field_name = "user (s1)"
            if field_id == 3: field_name = "password/cred (s3)"
            if field_id == 0x2d: field_name = "token (s2d)"

            result[field_name] = value
            
        except Exception as e:
            print(f"Ошибка при парсинге на смещении {offset}: {e}")
            break

    return result

# ПРИМЕР ИСПОЛЬЗОВАНИЯ:
# Вставьте сюда Payload из Wireshark (правой кнопкой на поле Data -> Copy -> as Hex Stream)
raw_payload = "200000010561646d696e200000030870617373776f7264" 
# (Это пример: s1='admin', s3='password')

decoded = decode_mikrotik_payload(raw_payload)
for k, v in decoded.items():
    print(f"{k}: {v}")