github.com/slackhq/nebula@v1.9.0/dist/wireshark/nebula.lua (about) 1 local nebula = Proto("nebula", "nebula") 2 3 local default_settings = { 4 port = 4242, 5 all_ports = false, 6 } 7 8 nebula.prefs.port = Pref.uint("Port number", default_settings.port, "The UDP port number for Nebula") 9 nebula.prefs.all_ports = Pref.bool("All ports", default_settings.all_ports, "Assume nebula packets on any port, useful when dealing with hole punching") 10 11 local pf_version = ProtoField.new("version", "nebula.version", ftypes.UINT8, nil, base.DEC, 0xF0) 12 local pf_type = ProtoField.new("type", "nebula.type", ftypes.UINT8, { 13 [0] = "handshake", 14 [1] = "message", 15 [2] = "recvError", 16 [3] = "lightHouse", 17 [4] = "test", 18 [5] = "closeTunnel", 19 }, base.DEC, 0x0F) 20 21 local pf_subtype = ProtoField.new("subtype", "nebula.subtype", ftypes.UINT8, nil, base.DEC) 22 local pf_subtype_test = ProtoField.new("subtype", "nebula.subtype", ftypes.UINT8, { 23 [0] = "request", 24 [1] = "reply", 25 }, base.DEC) 26 27 local pf_subtype_handshake = ProtoField.new("subtype", "nebula.subtype", ftypes.UINT8, { 28 [0] = "ix_psk0", 29 }, base.DEC) 30 31 local pf_reserved = ProtoField.new("reserved", "nebula.reserved", ftypes.UINT16, nil, base.HEX) 32 local pf_remote_index = ProtoField.new("remote index", "nebula.remote_index", ftypes.UINT32, nil, base.DEC) 33 local pf_message_counter = ProtoField.new("counter", "nebula.counter", ftypes.UINT64, nil, base.DEC) 34 local pf_payload = ProtoField.new("payload", "nebula.payload", ftypes.BYTES, nil, base.NONE) 35 36 nebula.fields = { pf_version, pf_type, pf_subtype, pf_subtype_handshake, pf_subtype_test, pf_reserved, pf_remote_index, pf_message_counter, pf_payload } 37 38 local ef_holepunch = ProtoExpert.new("nebula.holepunch.expert", "Nebula hole punch packet", expert.group.PROTOCOL, expert.severity.NOTE) 39 local ef_punchy = ProtoExpert.new("nebula.punchy.expert", "Nebula punchy keepalive packet", expert.group.PROTOCOL, expert.severity.NOTE) 40 41 nebula.experts = { ef_holepunch, ef_punchy } 42 local type_field = Field.new("nebula.type") 43 local subtype_field = Field.new("nebula.subtype") 44 45 function nebula.dissector(tvbuf, pktinfo, root) 46 -- set the protocol column to show our protocol name 47 pktinfo.cols.protocol:set("NEBULA") 48 49 local pktlen = tvbuf:reported_length_remaining() 50 local tree = root:add(nebula, tvbuf:range(0,pktlen)) 51 52 if pktlen == 0 then 53 tree:add_proto_expert_info(ef_holepunch) 54 pktinfo.cols.info:append(" (holepunch)") 55 return 56 elseif pktlen == 1 then 57 tree:add_proto_expert_info(ef_punchy) 58 pktinfo.cols.info:append(" (punchy)") 59 return 60 end 61 62 tree:add(pf_version, tvbuf:range(0,1)) 63 local type = tree:add(pf_type, tvbuf:range(0,1)) 64 65 local nebula_type = bit32.band(tvbuf:range(0,1):uint(), 0x0F) 66 if nebula_type == 0 then 67 local stage = tvbuf(8,8):uint64() 68 tree:add(pf_subtype_handshake, tvbuf:range(1,1)) 69 type:append_text(" stage " .. stage) 70 pktinfo.cols.info:append(" (" .. type_field().display .. ", stage " .. stage .. ", " .. subtype_field().display .. ")") 71 elseif nebula_type == 4 then 72 tree:add(pf_subtype_test, tvbuf:range(1,1)) 73 pktinfo.cols.info:append(" (" .. type_field().display .. ", " .. subtype_field().display .. ")") 74 else 75 tree:add(pf_subtype, tvbuf:range(1,1)) 76 pktinfo.cols.info:append(" (" .. type_field().display .. ")") 77 end 78 79 tree:add(pf_reserved, tvbuf:range(2,2)) 80 tree:add(pf_remote_index, tvbuf:range(4,4)) 81 tree:add(pf_message_counter, tvbuf:range(8,8)) 82 tree:add(pf_payload, tvbuf:range(16,tvbuf:len() - 16)) 83 end 84 85 function nebula.prefs_changed() 86 if default_settings.all_ports == nebula.prefs.all_ports and default_settings.port == nebula.prefs.port then 87 -- Nothing changed, bail 88 return 89 end 90 91 -- Remove our old dissector 92 DissectorTable.get("udp.port"):remove_all(nebula) 93 94 if nebula.prefs.all_ports and default_settings.all_ports ~= nebula.prefs.all_ports then 95 default_settings.all_port = nebula.prefs.all_ports 96 97 for i=0, 65535 do 98 DissectorTable.get("udp.port"):add(i, nebula) 99 end 100 101 -- no need to establish again on specific ports 102 return 103 end 104 105 106 if default_settings.all_ports ~= nebula.prefs.all_ports then 107 -- Add our new port dissector 108 default_settings.port = nebula.prefs.port 109 DissectorTable.get("udp.port"):add(default_settings.port, nebula) 110 end 111 end 112 113 DissectorTable.get("udp.port"):add(default_settings.port, nebula)