aboutsummaryrefslogtreecommitdiff
path: root/wireshark/pcmsg.lua
blob: e3c946dea1b6b0d69beb9d97716365887c29ca95 (plain)
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