diff options
Diffstat (limited to 'wireshark/pcmsg.lua')
-rw-r--r-- | wireshark/pcmsg.lua | 79 |
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 + |