dissector_itlc.lua 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. local itlc = Proto("ITLC", "ITL Chorus Protocol")
  2. local fields = {
  3. command = ProtoField.new("Command", "itlc.cmd", ftypes.UINT32),
  4. pingdata = ProtoField.new("Ping Data", "itlc.ping", ftypes.BYTES),
  5. seconds = ProtoField.new("Seconds", "itlc.secs", ftypes.UINT32),
  6. microseconds = ProtoField.new("Microseconds", "itlc.usecs", ftypes.UINT32),
  7. frequency = ProtoField.new("Frequency(Hz)", "itlc.freq", ftypes.UINT32),
  8. amplitude = ProtoField.new("Amplitude", "itlc.amp", ftypes.FLOAT),
  9. port = ProtoField.new("Port", "itlc.port", ftypes.UINT32),
  10. ports = ProtoField.new("Ports", "itlc.ports", ftypes.UINT32),
  11. type = ProtoField.new("Client Type", "itlc.type", ftypes.STRING),
  12. ident = ProtoField.new("Client ID", "itlc.ident", ftypes.STRING),
  13. pcm = ProtoField.new("PCM Data", "itlc.pcm", ftypes.INT16),
  14. data = ProtoField.new("Unknown Data", "itlc.data", ftypes.BYTES),
  15. }
  16. local fieldarray = {}
  17. for _, v in pairs(fields) do table.insert(fieldarray, v) end
  18. itlc.fields = fieldarray
  19. local commands = {
  20. [0] = "KA (keep alive)",
  21. [1] = "PING",
  22. [2] = "QUIT",
  23. [3] = "PLAY",
  24. [4] = "CAPS",
  25. [5] = "PCM",
  26. }
  27. setmetatable(commands, {__index = function(self, k) return "(Unknown command!)" end})
  28. local subdis = {
  29. [0] = function(buffer, tree) end, -- Nothing interesting...
  30. [1] = function(buffer, tree)
  31. tree:add(fields.pingdata, buffer())
  32. end,
  33. [2] = function(buffer, tree) end, -- Nothing interesting...
  34. [3] = function(buffer, tree, pinfo)
  35. tree:add(fields.seconds, buffer(0, 4))
  36. tree:add(fields.microseconds, buffer(4, 4))
  37. local freq = buffer(8, 4):uint()
  38. local fr = tree:add(fields.frequency, buffer(8, 4))
  39. tree:add(fields.amplitude, buffer(12, 4))
  40. tree:add(fields.port, buffer(16, 4))
  41. local midi = 12 * math.log(freq / 440.0) / math.log(2) + 69
  42. fr:append_text(" [MIDI pitch approx. " .. midi .. "]")
  43. pinfo.cols.info = tostring(pinfo.cols.info) .. string.format(" freq=%d (MIDI %f) amp=%f dur=%f port=%d", freq, midi, buffer(12,4):float(), buffer(0, 4):uint() + 0.000001 * buffer(4, 4):uint(), buffer(16, 4):uint())
  44. end,
  45. [4] = function(buffer, tree, pinfo)
  46. local pt = tree:add(fields.ports, buffer(0, 4))
  47. if buffer(0,4):uint() == 0 then
  48. pt:append_text(" [probably a request from the broadcaster]")
  49. pinfo.cols.info = tostring(pinfo.cols.info) .. " [request]"
  50. else
  51. pinfo.cols.info = tostring(pinfo.cols.info) .. string.format(" type=%q uid=%q", buffer(4, 4):string(), buffer(8):string())
  52. end
  53. tree:add(fields.type, buffer(4, 4))
  54. tree:add(fields.ident, buffer(8))
  55. end,
  56. [5] = function(buffer, tree)
  57. tree:add(fields.pcm, buffer())
  58. end,
  59. }
  60. setmetatable(subdis, {__index = function(self, k) return function(buffer, tree)
  61. tree:add(fields.data, buffer())
  62. end end})
  63. function itlc.dissector(buffer, pinfo, tree)
  64. pinfo.cols.protocol = "ITLC"
  65. local st = tree:add(itlc, buffer(), "ITL Chorus Packet")
  66. local cmd = buffer(0,4):uint()
  67. st:add(fields.command, buffer(0,4), cmd, "Command: " .. commands[cmd] .. "(" .. cmd .. ")")
  68. pinfo.cols.info = commands[cmd]
  69. subdis[cmd](buffer(4):tvb(), st, pinfo)
  70. end
  71. local udp = DissectorTable.get("udp.port")
  72. udp:add(13676, itlc)
  73. udp:add(13677, itlc)
  74. print('ITLC dissector loaded!')