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}")