1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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
|