wireshark-nmrp.lua 3.1 KB

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