Use libnl to add/remove IPs on Linux
[oweals/nmrpflash.git] / wireshark-nmrp.lua
1 --
2 -- NMRP dissector for Wireshark
3 --
4 -- Copyright (C) 2016 Joseph C. Lehner
5 --
6 -- Licensed under the GNU GPL 3.0
7 --
8
9 nmrp_proto = Proto("nmrp", "NMRP")
10
11 src_f = ProtoField.string("nmrp.src", "Source")
12 dst_f = ProtoField.string("nmrp.dst", "Destination")
13 code_f = ProtoField.uint8("nmrp.code", "Code", base.HEX)
14 id_f = ProtoField.uint8("nmrp.id", "ID", base.HEX)
15 reserved_f = ProtoField.uint16("nmrp.reserved", "Reserved", base.HEX)
16 len_f = ProtoField.uint16("nmrp.len", "Length")
17 data_f = ProtoField.bytes("nmrp.opt", "Options")
18 opt_type_f = ProtoField.uint16("nmrp.opt.type", "Option", base.HEX)
19 opt_len_f = ProtoField.uint16("nmrp.opt.len", "Length")
20 opt_data_f = ProtoField.bytes("nmrp.opt.data", "Data")
21
22 nmrp_proto.fields = {
23         code_f, reserved_f, len_f, data_f, id_f, opt_type_f, opt_len_f, opt_data_f
24 }
25
26 function nmrp_code(code)
27         if code == 1 then return { "ADVERTISE", "Advertise" }
28         elseif code == 2 then return { "CONF_REQ", "Configuration Request" }
29         elseif code == 3 then return { "CONF_ACK", "Configuration" }
30         elseif code == 4 then return { "CLOSE_REQ", "Close Request" }
31         elseif code == 5 then return { "CLOSE_ACK", "Close Acknowledgement" }
32         elseif code == 6 then return { "KEEP_ALIVE_REQ", "Keep-alive Request" }
33         elseif code == 7 then return { "KEEP_ALIVE_ACK", "Keep-alive Acknowledgement" }
34         elseif code == 16 then return { "TFTP_UL_REQ", "Upload Request" }
35         else return { "#" .. code, "Unknown Opcode " .. code }
36         end
37 end
38
39 function nmrp_opt(opt)
40         if opt == 0x01 then return "Magic"
41         elseif opt == 0x02 then return "IP Configuration"
42         elseif opt == 0x04 then return "Region"
43         elseif opt == 0x0101 then return "Update Firmware"
44         elseif opt == 0x0102 then return "Update String Table"
45         elseif opt == 0x0181 then return "Filename"
46         else return "#" .. opt
47         end
48 end
49
50 function nmrp_dissect_opt(opt, buffer, tree)
51         if buffer:len() <= 4 then
52                 return
53         end
54
55         if opt == 0x01 or opt == 0x0181 then
56                 tree:add(buffer(4), "Value: " .. buffer(4):string())
57         elseif opt == 0x02 then
58                 tree:add(buffer(4, 4), "Address: " .. tostring(buffer(4, 4):ipv4()))
59                 tree:add(buffer(8, 4), "Netmask: " .. tostring(buffer(8, 4):ipv4()))
60         else
61                 tree:add(opt_len_f, buffer(2, 2))
62                 tree:add(opt_data_f, buffer(4, buffer:len() - 4))
63         end
64 end
65
66
67 function nmrp_proto.dissector(buffer, pinfo, tree)
68         pinfo.cols.protocol = "NMRP"
69
70         local code = buffer(2, 1)
71         local len = buffer(4, 2)
72
73         pinfo.cols.info = nmrp_code(code:uint())[2]
74
75         local subtree = tree:add(nmrp_proto, buffer(0))
76         subtree:add(code_f, code):append_text(" - " .. nmrp_code(code:uint())[2])
77         subtree:add(id_f, buffer(3, 1))
78         subtree:add(len_f, len)
79         subtree:add(reserved_f, buffer(0, 2))
80
81         local databuf = buffer(6, len:uint() - 6)
82
83         while databuf:len() > 0 do
84                 local opt = databuf(0, 2):uint()
85                 local optlen = databuf(2, 2):uint()
86
87                 if databuf:len() < optlen then
88                         break
89                 end
90
91                 local optitem = subtree:add(opt_type_f, databuf(0, 2)):append_text(" - " .. nmrp_opt(opt))
92                 nmrp_dissect_opt(opt, databuf(0, optlen), optitem)
93
94                 if databuf:len() > optlen then
95                         databuf = databuf(optlen)
96                 else
97                         break
98                 end
99         end
100 end
101
102 eth_table = DissectorTable.get("ethertype")
103 eth_table:add(0x0912, nmrp_proto)