aboutsummaryrefslogtreecommitdiff
path: root/wireshark/pictochat.lua
diff options
context:
space:
mode:
Diffstat (limited to 'wireshark/pictochat.lua')
-rw-r--r--wireshark/pictochat.lua117
1 files changed, 71 insertions, 46 deletions
diff --git a/wireshark/pictochat.lua b/wireshark/pictochat.lua
index 56300c3..756fe45 100644
--- a/wireshark/pictochat.lua
+++ b/wireshark/pictochat.lua
@@ -1,8 +1,8 @@
local pc = Proto("pictochat", "Nintendo DS PictoChat")
-pc.fields.unknown = ProtoField.bytes("pictochat.unknown", "Unknown")
+pc.fields.unknown = ProtoField.uint16("pictochat.unknown", "Unknown")
-pc.fields.msg_type = ProtoField.uint16("pictochat.msg_type", "Frame type", base.DEC, {
+pc.fields.frame_type = ProtoField.uint16("pictochat.frame_type", "Frame type", base.DEC, {
[0] = "Normal", -- Used for actual messages, ack packets
[1] = "Announcement", -- TODO: send broadcast???
})
@@ -10,24 +10,28 @@ pc.fields.resend = ProtoField.uint16("pictochat.resend", "Resend", base.DEC, {
[0] = "Resend",
[2] = "Original",
})
-pc.fields.length = ProtoField.uint16("pictochat.length", "Message length")
+pc.fields.msg_type = ProtoField.uint16("pictochat.msg_type", "Message type", base.DEC, {
+ [0] = "????", -- sent around room creation time??
+ [1] = "????", -- sent around room creation time??
+ [2] = "Room event", -- Used for drawing payload packets and join/leave stuff
+ [4] = "????", -- sent around room creation time??
+ [5] = "Spam", -- generic spam shit
+ -- msg_type 3 is never sent and a few arbitrary 'high' types (>10000) are
+ -- sent around startup
+})
+pc.fields.length = ProtoField.uint16("pictochat.length", "Length")
pc.fields.host = ProtoField.ether("pictochat.host", "Room host")
pc.fields.src = ProtoField.ether("pictochat.src", "Source")
pc.fields.dst = ProtoField.ether("pictochat.dst", "Destination")
-
--- Content offset appears to be some kind of offset for indicating where to
--- store the current frame's data in a larger buffer. Messages sent in multiple
--- parts increment this value by 160 for each new original (pictochat.resend ==
--- 2) message.
-pc.fields.content_offset = ProtoField.uint16("pictochat.content_offset", "Content offset")
--- This appears to be the actual message content (the drawing) sent as an array
--- of 8x8 tiles.
-pc.fields.content = ProtoField.bytes("pictochat.content", "Content")
+pc.fields.payload_len = ProtoField.uint16("pictochat.payload_len", "Payload length")
+pc.fields.data_len = ProtoField.uint8("pictochat.data_len", "Data length")
+pc.fields.data_end = ProtoField.bool("pictochat.data_end", "Data end")
+pc.fields.data_offset = ProtoField.uint16("pictochat.data_offset", "Data offset")
+pc.fields.data = ProtoField.bytes("pictochat.data", "Data")
pc.fields.sequence = ProtoField.uint16("pictochat.sequence", "Packet sequence")
local nifi_length_field = Field.new("nifi.length")
local pc_msg_type_field = Field.new("pictochat.msg_type")
-local pc_length_field = Field.new("pictochat.length")
local pc_resend_field = Field.new("pictochat.resend")
local pc_src_field = Field.new("pictochat.src")
local pc_dst_field = Field.new("pictochat.dst")
@@ -40,44 +44,65 @@ function pc.dissector(buffer, pinfo, tree)
local pc_tree = tree:add(pc, buffer(), "PictoChat: " .. header_length .. " bytes")
- pc_tree:add_le(pc.fields.msg_type, buffer(0x00, 2))
- pc_tree:add_le(pc.fields.resend, buffer(0x02, 2))
- pc_tree:add(pc.fields.unknown, buffer(0x04, 6))
- pc_tree:add_le(pc.fields.length, buffer(0x0a, 2))
- pc_tree:add(pc.fields.unknown, buffer(0x0c, 2))
- pc_tree:add(pc.fields.unknown, buffer(0x0e, 2))
- pc_tree:add_le(pc.fields.dst, buffer(0x10, 6))
- pc_tree:add_le(pc.fields.src, buffer(0x16, 6))
- pc_tree:add_le(pc.fields.host, buffer(0x1c, 6))
+ -- pictochat header
+ local pc_header = pc_tree:add(buffer(0x00, 12), "Header: 12 bytes")
+ pc_header:add_le(pc.fields.frame_type, buffer(0x00, 2))
+ pc_header:add_le(pc.fields.resend, buffer(0x02, 2))
+ pc_header:add_le(pc.fields.unknown, buffer(0x04, 2))
+ pc_header:add_le(pc.fields.unknown, buffer(0x06, 2))
+ pc_header:add_le(pc.fields.unknown, buffer(0x08, 2))
+ pc_header:add_le(pc.fields.length, buffer(0x0a, 2))
+ -- above length represents that of the remaining message so this info is
+ -- grouped and the buffer is advanced 12 bytes
+ buffer = buffer(0x0c)
+
+ pc_tree:add_le(pc.fields.unknown, buffer(0x00, 2))
+ pc_tree:add_le(pc.fields.unknown, buffer(0x02, 2))
+ pc_tree:add_le(pc.fields.dst, buffer(0x04, 6))
+ pc_tree:add_le(pc.fields.src, buffer(0x0a, 6))
+ pc_tree:add_le(pc.fields.host, buffer(0x10, 6))
+ pc_tree:add_le(pc.fields.unknown, buffer(0x16, 2)) -- counting?
+ pc_tree:add_le(pc.fields.unknown, buffer(0x18, 2))
+ pc_tree:add_le(pc.fields.resend, buffer(0x1a, 2))
+ pc_tree:add_le(pc.fields.unknown, buffer(0x1c, 2))
+ pc_tree:add_le(pc.fields.msg_type, buffer(0x1e, 2))
+ local msg_type = buffer(0x1e, 2):le_uint()
+ buffer = buffer(0x20)
+
+ if msg_type == 2 then -- type = room event?
+ pc_tree:add_le(pc.fields.payload_len, buffer(0x00, 2))
+ local payload_length = buffer(0x00, 2):le_uint()
+ local payload = pc_tree:add(buffer(0x02, payload_length), "Payload: " .. payload_length .. " bytes")
+ payload:add_le(pc.fields.unknown, buffer(0x02, 2))
+ payload:add_le(pc.fields.data_len, buffer(0x04, 1))
+ local data_length = buffer(0x04, 1):le_uint()
+ payload:add_le(pc.fields.data_end, buffer(0x05, 1))
+ -- This appears to be some kind of offset for indicating where to store the
+ -- current frame's data in a larger buffer. Messages sent in multiple parts
+ -- increment this value by 160 for each new original (pictochat.resend ==
+ -- 2) message.
+ payload:add_le(pc.fields.data_offset, buffer(0x06, 2))
+ payload:add_le(pc.fields.unknown, buffer(0x08, 2)) -- usually 0
+
+ buffer = buffer(0x0a)
+ -- This appears to be the actual message data (the drawing) sent as an
+ -- array of 8x8 tiles.
+ payload:add(pc.fields.data, buffer(0, data_length))
+ buffer = buffer(data_length)
+
+ payload:add_le(pc.fields.sequence, buffer(0x00, 2))
+ payload:add_le(pc.fields.resend, buffer(0x02, 2)) -- copy
+ buffer = buffer(0x04)
+ end
+
+ pc_tree:add_le(pc.fields.unknown, buffer(0x00, 2))
+ pc_tree:add_le(pc.fields.unknown, buffer(0x02, 2))
+ -- pretty wireshark shit
pinfo.cols.protocol = pc.name
pinfo.cols.src = tostring(pc_src_field())
pinfo.cols.dst = tostring(pc_dst_field())
pinfo.cols.info = pc_msg_type_field().display .. ", " .. pc_resend_field().display
-
- pc_tree:add_le(pc.fields.unknown, buffer(0x22, 2)) -- counting
- pc_tree:add_le(pc.fields.unknown, buffer(0x24, 2))
- pc_tree:add_le(pc.fields.resend, buffer(0x26, 2))
- pc_tree:add(pc.fields.unknown, buffer(0x28, 6))
- pc_tree:add(pc.fields.unknown, buffer(0x2e, 4))
-
- local msg_type = pc_msg_type_field()()
- if msg_type == 0 then -- type = Normal (TODO: this should be 'message = drawing')
- pc_tree:add_le(pc.fields.content_offset, buffer(0x32, 2))
- pc_tree:add_le(pc.fields.unknown, buffer(0x34, 2))
-
- local content_length = pc_length_field()() - 50 -- TODO: why 50?
- buffer = buffer(0x36)
- pc_tree:add(pc.fields.content, buffer(0, content_length))
- buffer = buffer(content_length)
-
- pc_tree:add_le(pc.fields.sequence, buffer(0x00, 2))
- pc_tree:add_le(pc.fields.resend, buffer(0x02, 2)) -- copy
- pc_tree:add(pc.fields.unknown, buffer(0x04, 2))
- pc_tree:add(pc.fields.unknown, buffer(0x06, 2))
- end
-
-
end
register_postdissector(pc)