forked from jclehner/nmrpflash
-
Notifications
You must be signed in to change notification settings - Fork 0
/
wireshark-nmrp.lua
104 lines (85 loc) · 3.08 KB
/
wireshark-nmrp.lua
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
--
-- NMRP dissector for Wireshark
--
-- Copyright (C) 2016 Joseph C. Lehner
--
-- Licensed under the GNU GPL 3.0
--
nmrp_proto = Proto("nmrp", "NMRP")
src_f = ProtoField.string("nmrp.src", "Source")
dst_f = ProtoField.string("nmrp.dst", "Destination")
code_f = ProtoField.uint8("nmrp.code", "Code", base.HEX)
id_f = ProtoField.uint8("nmrp.id", "ID", base.HEX)
reserved_f = ProtoField.uint16("nmrp.reserved", "Reserved", base.HEX)
len_f = ProtoField.uint16("nmrp.len", "Length")
data_f = ProtoField.bytes("nmrp.opt", "Options")
opt_type_f = ProtoField.uint16("nmrp.opt.type", "Option", base.HEX)
opt_len_f = ProtoField.uint16("nmrp.opt.len", "Length")
opt_data_f = ProtoField.bytes("nmrp.opt.data", "Data")
nmrp_proto.fields = {
code_f, reserved_f, len_f, data_f, id_f, opt_type_f, opt_len_f, opt_data_f
}
function nmrp_code(code)
if code == 1 then return { "ADVERTISE", "Advertise" }
elseif code == 2 then return { "CONF_REQ", "Configuration Request" }
elseif code == 3 then return { "CONF_ACK", "Configuration" }
elseif code == 4 then return { "CLOSE_REQ", "Close Request" }
elseif code == 5 then return { "CLOSE_ACK", "Close Acknowledgement" }
elseif code == 6 then return { "KEEP_ALIVE_REQ", "Keep-alive Request" }
elseif code == 7 then return { "KEEP_ALIVE_ACK", "Keep-alive Acknowledgement" }
elseif code == 16 then return { "TFTP_UL_REQ", "Upload Request" }
else return { "#" .. code, "Unknown Opcode " .. code }
end
end
function nmrp_opt(opt)
if opt == 0x01 then return "Magic"
elseif opt == 0x02 then return "IP Configuration"
elseif opt == 0x04 then return "Region"
elseif opt == 0x0101 then return "Update Firmware"
elseif opt == 0x0102 then return "Update String Table"
elseif opt == 0x0181 then return "Filename"
else return "#" .. opt
end
end
function nmrp_dissect_opt(opt, buffer, tree)
if buffer:len() <= 4 then
return
end
tree:add(opt_len_f, buffer(2, 2))
if opt == 0x01 or opt == 0x0181 then
tree:add(buffer(4), "Value: " .. buffer(4):string())
elseif opt == 0x02 then
tree:add(buffer(4, 4), "Address: " .. tostring(buffer(4, 4):ipv4()))
tree:add(buffer(8, 4), "Netmask: " .. tostring(buffer(8, 4):ipv4()))
else
tree:add(opt_data_f, buffer(4, buffer:len() - 4))
end
end
function nmrp_proto.dissector(buffer, pinfo, tree)
pinfo.cols.protocol = "NMRP"
local code = buffer(2, 1)
local len = buffer(4, 2)
pinfo.cols.info = nmrp_code(code:uint())[2]
local subtree = tree:add(nmrp_proto, buffer(0))
subtree:add(code_f, code):append_text(" - " .. nmrp_code(code:uint())[2])
subtree:add(id_f, buffer(3, 1))
subtree:add(len_f, len)
subtree:add(reserved_f, buffer(0, 2))
local databuf = buffer(6, len:uint() - 6)
while databuf:len() > 0 do
local opt = databuf(0, 2):uint()
local optlen = databuf(2, 2):uint()
if databuf:len() < optlen then
break
end
local optitem = subtree:add(opt_type_f, databuf(0, 2)):append_text(" - " .. nmrp_opt(opt))
nmrp_dissect_opt(opt, databuf(0, optlen), optitem)
if databuf:len() > optlen then
databuf = databuf(optlen)
else
break
end
end
end
eth_table = DissectorTable.get("ethertype")
eth_table:add(0x0912, nmrp_proto)