aboutsummaryrefslogtreecommitdiff
path: root/wireshark/pictochat.lua
blob: ff09783039518a47a26d780b254f174f69df9265 (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
local pc = Proto("pictochat", "Nintendo DS PictoChat")

pc.fields.unknown = ProtoField.bytes("pictochat.unknown", "Unknown")

pc.fields.msg_type = ProtoField.uint16("pictochat.msg_type", "Frame type", base.DEC, {
	[0] = "Normal", -- Used for actual messages, ack packets
	[1] = "Announcement", -- TODO: send broadcast???
})
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.host = ProtoField.ether("pictochat.host", "Room host")
pc.fields.src = ProtoField.ether("pictochat.src", "Source")
pc.fields.dst = ProtoField.ether("pictochat.dst", "Destination")

pc.fields.content_offset = ProtoField.uint16("pictochat.content_offset", "Content offset")
pc.fields.content = ProtoField.bytes("pictochat.content", "Content")
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")

function pc.dissector(buffer, pinfo, tree)
	local header_length = nifi_length_field()()
	if header_length == 0 then return end

  buffer = buffer(0x18) -- skip the Ni-Fi header

	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_le(pc.fields.length, buffer(0x0a, 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))

	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))
  pc_tree:add_le(pc.fields.unknown, buffer(0x24, 2))

	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))

		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, 4))
	end


end

register_postdissector(pc)