add domain packet dissector, improve entity dissector

This commit is contained in:
Stephen Birarda 2018-06-06 15:42:10 -07:00
parent b70ffa5bae
commit e82edb8b66
3 changed files with 133 additions and 36 deletions

View file

@ -0,0 +1,23 @@
-- create the domain protocol
p_hf_domain = Proto("hf-domain", "HF Domain Protocol")
-- domain packet fields
local f_domain_id = ProtoField.guid("hf_domain.domain_id", "Domain ID")
local f_domain_local_id = ProtoField.uint16("hf_domain.domain_local_id", "Domain Local ID")
p_hf_domain.fields = {
f_domain_id, f_domain_local_id
}
function p_hf_domain.dissector(buf, pinfo, tree)
pinfo.cols.protocol = p_hf_domain.name
domain_subtree = tree:add(p_hf_domain, buf())
local i = 0
domain_subtree:add(f_domain_id, buf(i, 16))
i = i + 16
domain_subtree:add_le(f_domain_local_id, buf(i, 2))
end

View file

@ -4,11 +4,21 @@ p_hf_entity = Proto("hf-entity", "HF Entity Protocol")
-- entity packet fields
local f_entity_sequence_number = ProtoField.uint16("hf_entity.sequence_number", "Sequence Number")
local f_entity_timestamp = ProtoField.uint64("hf_entity.timestamp", "Timestamp")
local f_octal_code_bytes = ProtoField.uint8("hf_entity.octal_code_bytes", "Octal Code Bytes")
local f_octal_code_three_bit_sections = ProtoField.uint8("hf_entity.octal_code_three_bit_sections", "Octal Code Three Bit Sections")
local f_octal_code = ProtoField.bytes("hf_entity.octal_code", "Octal Code")
local f_entity_id = ProtoField.guid("hf_entity.entity_id", "Entity ID")
local f_last_edited = ProtoField.uint64("hf_entity.last_edited", "Last Edited")
local f_coded_property_type = ProtoField.bytes("hf_entity.coded_property_type", "Coded Property Type")
local f_property_type = ProtoField.uint32("hf_entity.property_type", "Property Type")
local f_coded_update_delta = ProtoField.bytes("hf_entity.f_coded_update_delta", "Coded Update Delta")
local f_update_delta = ProtoField.uint32("hf_entity.update_delta", "Update Delta")
p_hf_entity.fields = {
f_entity_sequence_number, f_entity_timestamp, f_octal_code_bytes, f_entity_id
f_entity_sequence_number, f_entity_timestamp,
f_octal_code_three_bit_sections, f_octal_code,
f_last_edited, f_entity_id,
f_coded_property_type, f_property_type,
f_coded_update_delta, f_update_delta
}
function p_hf_entity.dissector(buf, pinfo, tree)
@ -16,21 +26,72 @@ function p_hf_entity.dissector(buf, pinfo, tree)
entity_subtree = tree:add(p_hf_entity, buf())
i = 0
local i = 0
entity_subtree:add_le(f_entity_sequence_number, buf(i, 2))
i = i + 2
entity_subtree:add_le(f_entity_timestamp, buf(i, 4))
i = i + 4
entity_subtree:add_le(f_entity_timestamp, buf(i, 8))
i = i + 8
-- figure out the number of bytes the octal code takes
local octal_code_bytes = buf(i, 1):le_uint()
entity_subtree:add_le(f_octal_code_bytes, buf(i, 1))
-- figure out the number of three bit sections in the octal code
local octal_code_three_bit_sections = buf(i, 1):le_uint()
entity_subtree:add_le(f_octal_code_three_bit_sections, buf(i, 1))
i = i + 1
-- skip over the octal code
i = i + 1 + octal_code_bytes
-- read the bytes for the octal code
local octal_code_bytes = math.ceil((octal_code_three_bit_sections * 3) / 8)
entity_subtree:add_le(f_octal_code, buf(i, octal_code_bytes))
i = i + octal_code_bytes
-- read the last edited timestamp
entity_subtree:add_le(f_last_edited, buf(i, 8))
i = i + 8
-- read the entity ID
entity_subtree:add(f_entity_id, buf(i, 16))
i = i + 16
-- figure out the property type and the size of the coded value
local property_type, coded_property_bytes = number_of_coded_bytes(buf(i))
entity_subtree:add(f_coded_property_type, buf(i, coded_property_bytes))
entity_subtree:add(f_property_type, property_type)
i = i + coded_property_bytes
-- figure out the update delta and the size of the coded value
local update_delta, coded_update_delta_bytes = number_of_coded_bytes(buf(i))
entity_subtree:add(f_coded_update_delta, buf(i, coded_update_delta_bytes))
entity_subtree:add(f_update_delta, update_delta)
i = i + coded_update_delta_bytes
end
function number_of_coded_bytes(buf)
local coded_buffer = buf(0, 4):le_uint() -- max 64 bit value means max 10 header bits
-- first figure out the total number of bytes for the coded value based
-- on the bits in the header
local total_coded_bytes = 1
for bit = 0, 10, 1 do
local header_bit = bit32.extract(coded_buffer, bit)
if header_bit == 1 then
total_coded_bytes = total_coded_bytes + 1
else
break
end
end
-- pull out the bits and write them to our decoded value
local decoded_value = 0
local decoded_position = 0
local total_bits = total_coded_bytes * 8
for bit = total_coded_bytes, total_bits - 1, 1 do
local value_bit = bit32.extract(coded_buffer, total_bits - bit - 1)
decoded_value = bit32.replace(decoded_value, value_bit, decoded_position)
decoded_position = decoded_position + 1
end
return decoded_value, total_coded_bytes
end

View file

@ -118,6 +118,10 @@ local packet_types = {
[54] = "AssetGetInfoReply"
}
local unsourced_packet_types = {
["DomainList"] = true
}
function p_hfudt.dissector(buf, pinfo, tree)
-- make sure this isn't a STUN packet - those don't follow HFUDT format
@ -230,54 +234,63 @@ function p_hfudt.dissector(buf, pinfo, tree)
-- if the message bit is set, handle the second word
if message_bit == 1 then
payload_offset = 12
payload_offset = 12
local second_word = buf(4, 4):le_uint()
local second_word = buf(4, 4):le_uint()
-- read message position from upper 2 bits
local message_position = bit32.rshift(second_word, 30)
local position = subtree:add(f_message_position, message_position)
-- read message position from upper 2 bits
local message_position = bit32.rshift(second_word, 30)
local position = subtree:add(f_message_position, message_position)
if message_positions[message_position] ~= nil then
-- if we know this position then add the name
position:append_text(" (".. message_positions[message_position] .. ")")
end
if message_positions[message_position] ~= nil then
-- if we know this position then add the name
position:append_text(" (".. message_positions[message_position] .. ")")
end
-- read message number from lower 30 bits
subtree:add(f_message_number, bit32.band(second_word, 0x3FFFFFFF))
-- read message number from lower 30 bits
subtree:add(f_message_number, bit32.band(second_word, 0x3FFFFFFF))
-- read the message part number
subtree:add(f_message_part_number, buf(8, 4):le_uint())
-- read the message part number
subtree:add(f_message_part_number, buf(8, 4):le_uint())
end
-- read the type
local packet_type = buf(payload_offset, 1):le_uint()
local ptype = subtree:add_le(f_type, buf(payload_offset, 1))
if packet_types[packet_type] ~= nil then
subtree:add(f_type_text, packet_types[packet_type])
local packet_type_text = packet_types[packet_type]
if packet_type_text ~= nil then
subtree:add(f_type_text, packet_type_text)
-- if we know this packet type then add the name
ptype:append_text(" (".. packet_types[packet_type] .. ")")
ptype:append_text(" (".. packet_type_text .. ")")
end
-- read the version
subtree:add_le(f_version, buf(payload_offset + 1, 1))
-- read node local ID
local sender_id = buf(payload_offset + 2, 2)
subtree:add_le(f_sender_id, sender_id)
local i = payload_offset + 2
local i = payload_offset + 4
if unsourced_packet_types[packet_type_text] == nil then
-- read node local ID
local sender_id = buf(payload_offset + 2, 2)
subtree:add_le(f_sender_id, sender_id)
i = i + 2
-- read HMAC MD5 hash
subtree:add(f_hmac_hash, buf(i, 16))
i = i + 16
-- read HMAC MD5 hash
subtree:add(f_hmac_hash, buf(i, 16))
i = i + 16
end
-- Domain packets
if packet_type_text == "DomainList" then
Dissector.get("hf-domain"):call(buf(i):tvb(), pinfo, tree)
end
-- AvatarData or BulkAvatarDataPacket
if packet_types[packet_type] == "AvatarData" or packet_types[packet_type] == "BulkAvatarDataPacket" then
if packet_type_text == "AvatarData" or packet_type_text == "BulkAvatarData" then
Dissector.get("hf-avatar"):call(buf(i):tvb(), pinfo, tree)
end
if packet_types[packet_type] == "EntityEdit" then
if packet_type_text == "EntityEdit" then
Dissector.get("hf-entity"):call(buf(i):tvb(), pinfo, tree)
end
end