Skip to content

Instantly share code, notes, and snippets.

@Green-Sky
Created April 29, 2019 20:04
Show Gist options
  • Save Green-Sky/3fd4f7583c485ee11c24d5cc4638bb48 to your computer and use it in GitHub Desktop.
Save Green-Sky/3fd4f7583c485ee11c24d5cc4638bb48 to your computer and use it in GitHub Desktop.
albion online wireshark dissector (some photon stuff only atm)
-- albion online wireshark dissector.... or at least a beginning
-- used as ref: https://github.com/rafalfigura/AO-Radar/blob/master/AlbionRadaro/PhotonPacketHandler/PhotonPacketHandler.cs
-- (c) Green Sky
photon_protocol = Proto("Photon", "Photon Protocol")
peer_id = ProtoField.uint16("photon.peer_id", "peer_id", base.DEC)
crc_enabled = ProtoField.bool( "photon.crc_enabled", "crc_enabled")
command_count = ProtoField.uint8( "photon.command_count", "command_count", base.DEC)
time_stamp = ProtoField.int32( "photon.time_stamp", "time_stamp", base.DEC)
challenge = ProtoField.int32( "photon.challenge", "challenge", base.DEC)
photon_protocol.fields = {
peer_id,
crc_enabled,
command_count,
time_stamp,
challenge
}
photon_commands_protocol = Proto("PhotonCommands", "Photon Commands Protocol")
command_type = ProtoField.uint8( "photonc.command_type", "command_type", base.DEC)
channel_id = ProtoField.uint8( "photonc.channel_id", "channel_id", base.DEC)
command_flags = ProtoField.uint8( "photonc.command_flags", "command_flags", base.HEX)
command_length = ProtoField.int32( "photonc.command_length", "command_length", base.DEC)
sequence_number = ProtoField.int32( "photonc.sequence_number", "sequence_number", base.DEC)
signifier_byte = ProtoField.uint8( "photonc.signifier_byte", "signifier_byte", base.HEX)
-- messages
message_type = ProtoField.uint8( "photonc.message_type", "message_type", base.DEC)
message_payload = ProtoField.bytes( "photonc.message_payload", "message_payload")
operation_request = ProtoField.uint8( "photonc.operation_request","operation_request", base.DEC)
photon_commands_protocol.fields = {
command_type,
channel_id,
command_flags,
command_length,
sequence_number,
signifier_byte,
message_type,
message_payload,
operation_request
}
ao_protocol = Proto("AlbionOnline", "AlbionOnline Protocol")
photon_commands_protocol.fields = {
}
function get_command_type_name(command_type)
local name = "unknown"
if command_type == 4 then name = "disconnect"
elseif command_type == 6 then name = "send reliable"
elseif command_type == 7 then name = "send unreliable"
end
return name
end
function photon_protocol.dissector(buffer, pinfo, root)
local length = buffer:len()
if length == 0 then return end
pinfo.cols.protocol = photon_protocol.name
local subtree = root:add(photon_protocol, buffer(), "Photon Protocol Data")
subtree:add(peer_id, buffer(0,2))
subtree:add(crc_enabled, buffer(2,1))
subtree:add(command_count, buffer(3,1))
local command_count_num = buffer(3,1):uint()
subtree:add(time_stamp, buffer(4,4))
subtree:add(challenge, buffer(8,4))
local curr_buffer_pos = 12
local command_header_length = 12
if command_count_num > 0 then
local commands_tree = subtree:add("commands")
for i = 1, command_count_num, 1 do
local command_length = buffer(curr_buffer_pos + 4, 4):int()
if command_length + curr_buffer_pos > length then
--commands_tree:add(photon_commands_protocol, buffer(curr_buffer_pos, length - curr_buffer_pos))
DissectorTable.get("photon_commands_dis"):try(1, buffer(curr_buffer_pos, length - curr_buffer_pos):tvb(), pinfo, commands_tree)
else
--commands_tree:add(photon_commands_protocol, buffer(curr_buffer_pos, command_length))
DissectorTable.get("photon_commands_dis"):try(1, buffer(curr_buffer_pos, command_length):tvb(), pinfo, commands_tree)
end
curr_buffer_pos = curr_buffer_pos + command_length
end
end
end
function photon_commands_protocol.init()
local photon_commands_dis_table = DissectorTable.new("photon_commands_dis")
photon_commands_dis_table:add(1, photon_commands_protocol)
end
function deserialize_op_req(buffer, tree)
local subtree = tree:add("op_req")
subtree:add(operation_request, buffer(0,1))
end
function deserialize_op_res(buffer, tree)
local subtree = tree:add("op_res")
end
function deserialize_event_data(buffer, tree)
local subtree = tree:add("event_data")
end
function photon_commands_protocol.dissector(buffer, pinfo, root)
length = buffer:len()
if length == 0 then
warn("error: commands length empty")
return
end
local command_type_num = buffer(0,1):uint()
local command_type_name = get_command_type_name(command_type_num)
local subtree = root:add(photon_commands_protocol, buffer(), "Photon Command " .. command_type_num .. " (" .. command_type_name .. ")")
subtree:add(command_type, buffer(0,1)):append_text(" (" .. command_type_name .. ")")
subtree:add(channel_id, buffer(1,1))
subtree:add(command_flags, buffer(2,1))
-- unk byte
subtree:add(command_length, buffer(4,4))
subtree:add(sequence_number, buffer(8,4))
if command_type_num == 6 or command_type_num == 7 then
local msg_buffer = buffer(12)
if command_type_num == 7 then
msg_buffer = buffer(12+4)
end
subtree:add(signifier_byte, msg_buffer(0, 1))
subtree:add(message_type, msg_buffer(1, 1))
subtree:add(message_payload, msg_buffer(2))
local msg_type_num = msg_buffer(1, 1):int()
if msg_type_num == 2 then
deserialize_op_req(msg_buffer(2), subtree)
elseif msg_type_num == 3 then
deserialize_op_res(msg_buffer(2), subtree)
elseif msg_type_num == 4 then
deserialize_event_data(msg_buffer(2), subtree)
end
end
end
function ao_protocol.dissector(buffer, pinfo, root)
length = buffer:len()
if length == 0 then return end
--pinfo.cols.protocol = ao_protocol.name
local subtree = root:add(ao_protocol, buffer(), "Albion")
end
local udp_port = DissectorTable.get("udp.port")
udp_port:add(5056, photon_protocol)
--local tcp_port = DissectorTable.get("tcp.port")
--tcp_port:add(5056, photon_protocol)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment