aboutsummaryrefslogtreecommitdiff
path: root/wireshark/pcmsg.lua
diff options
context:
space:
mode:
Diffstat (limited to 'wireshark/pcmsg.lua')
-rw-r--r--wireshark/pcmsg.lua79
1 files changed, 79 insertions, 0 deletions
diff --git a/wireshark/pcmsg.lua b/wireshark/pcmsg.lua
new file mode 100644
index 0000000..e3c946d
--- /dev/null
+++ b/wireshark/pcmsg.lua
@@ -0,0 +1,79 @@
+require "util"
+
+local p = Proto("pcmsg", "PictoChat Message")
+
+local MSG_TYPE = {
+ USER_JOIN_A = 0,
+ USER_JOIN_B = 1,
+ IMAGE = 2,
+}
+
+local MSG_TYPE_MAP = {
+ [MSG_TYPE.USER_JOIN_A] = "user join",
+ [MSG_TYPE.USER_JOIN_B] = "user join",
+ [MSG_TYPE.IMAGE] = "image",
+}
+
+p.fields.unknown = ProtoField.uint16("pcmsg.unknown", "Unknown")
+p.fields.padding = ProtoField.bytes("pcmsg.padding", "Padding")
+
+local dissect_msg_type = { }
+
+p.fields.user_addr = ProtoField.bytes("pcmsg.user.addr", "Address", base.COLON)
+p.fields.user_name = ProtoField.string("pcmsg.user.name", "Nickname")
+p.fields.user_msg = ProtoField.string("pcmsg.user.msg", "Message")
+p.fields.user_color = ProtoField.uint16("pcmsg.user.color", "Color", base.DEC, PROFILE_COLOR_MAP)
+p.fields.user_bday_month = ProtoField.uint8("pcmsg.user.bday_month", "Month")
+p.fields.user_bday_day = ProtoField.uint8("pcmsg.user.bday_day", "Day")
+dissect_msg_type[MSG_TYPE.USER_JOIN_A] = function (buffer, pinfo, tree)
+ add_addr_le(tree, p.fields.user_addr, buffer(0x02, 6))
+ local user_name = buffer(0x08, 20):le_ustring()
+ tree:add(p.fields.user_name, buffer(0x08, 20), user_name)
+ tree:add(p.fields.user_msg, buffer(0x1c, 52), buffer(0x1c, 52):le_ustring())
+ tree:add_le(p.fields.user_color, buffer(0x50, 2))
+ local bday_str = string.format("Birthday: %02d/%02d", buffer(0x52, 1):uint(), buffer(0x53, 1):uint())
+ local bday = tree:add(buffer(0x52, 2), bday_str)
+ bday:add(p.fields.user_bday_month, buffer(0x52, 1))
+ bday:add(p.fields.user_bday_day, buffer(0x53, 1))
+
+ register_addr_le(buffer(0x02, 6):raw(), user_name)
+
+ pinfo.cols.info = string.format("%s user join (%s)", pinfo.cols.info, user_name)
+end
+dissect_msg_type[MSG_TYPE.USER_JOIN_B] = dissect_msg_type[MSG_TYPE.USER_JOIN_A]
+
+p.fields.img_addr = ProtoField.bytes("pcmsg.img.addr", "Address", base.COLON)
+p.fields.img_data = ProtoField.bytes("pcmsg.img.data", "Image data")
+dissect_msg_type[MSG_TYPE.IMAGE] = function (buffer, pinfo, tree)
+ add_addr_le(tree, p.fields.img_addr, buffer(0x02, 6))
+ tree:add(p.fields.padding, buffer(0x08, 0x1c))
+ tree:add(p.fields.img_data, buffer(0x24))
+
+ local user = get_addr_label(fix_addr_endianness(buffer(0x02, 6):raw()))
+ local rows = (buffer:len() - 0x24) / 0x800
+ pinfo.cols.info = string.format("%s %d row drawing by %s", pinfo.cols.info, rows, user)
+end
+dissect_msg_type[MSG_TYPE.USER_JOIN_B] = dissect_msg_type[MSG_TYPE.USER_JOIN_A]
+
+p.fields.type = ProtoField.uint8("pcmsg.type", "Type", base.DEC, MSG_TYPE_MAP)
+function p.dissector(buffer, pinfo, tree)
+ local buffer_len = buffer:len()
+ local mid = pc_global.pid_mid_map[pinfo.number]
+ local type = buffer(0x01, 1):le_uint()
+ local type_str = MSG_TYPE_MAP[type] or ""
+ local subtree = tree:add(p, buffer(), string.format("%s %08x: %s, %d bytes", p.description, mid, type_str, buffer_len))
+
+ pinfo.cols.protocol = p.name
+ pinfo.cols.info = string.format("[%08x]", mid)
+
+ subtree:add_le(p.fields.unknown, buffer(0x00, 1))
+ subtree:add_le(p.fields.type, buffer(0x01, 1))
+
+ local subdissector = dissect_msg_type[type]
+ if subdissector ~= nil then
+ subdissector(buffer, pinfo, subtree)
+ end
+
+ return buffer_len
+end
+