├── .gitmodules ├── LICENSE ├── mpeg_packets_dump.lua ├── README.md ├── tcp_stats.lua ├── 1905.1.lua └── Lync-Skype4B-Plugin2.00.lua /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "gd_l4"] 2 | path = gd_l4 3 | url = git@github.com:phreakocious/gd_l4.git 4 | [submodule "gd_tcflag"] 5 | path = gd_tcflag 6 | url = git@github.com:phreakocious/gd_tcflag.git 7 | [submodule "wireshark-plugins"] 8 | path = wireshark-plugins 9 | url = https://github.com/kaos/wireshark-plugins.git 10 | [submodule "wireshark-nmea"] 11 | path = wireshark-nmea 12 | url = https://github.com/kmpm/wireshark-nmea 13 | [submodule "redis-wireshark"] 14 | path = redis-wireshark 15 | url = https://github.com/jzwinck/redis-wireshark.git 16 | [submodule "wireshark-tcpextend"] 17 | path = wireshark-tcpextend 18 | url = https://github.com/gaddman/wireshark-tcpextend.git 19 | [submodule "wireshark-http-extra"] 20 | path = wireshark-http-extra 21 | url = https://github.com/shomeax/wireshark-http-extra.git 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2019, phreakocious ತ‿ತ 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /mpeg_packets_dump.lua: -------------------------------------------------------------------------------- 1 | 2 | -- Wireshark extension to dump MPEG2 transport stream packets 3 | -- 4 | -- To use this script: 5 | -- 1. Save it in the Wireshark home directory e.g. c:\Program Files\Wireshark 6 | -- 2. Edit init.lua in the Wireshark home directory and add the following line 7 | -- dofile("mpeg_packets_dump.lua") 8 | -- 3. Restart Wireshark to add the extension 9 | -- 4. Capture some traffic which includes some MPEG transport packets, for 10 | -- example, it has been tested with MPEG transmitted via UDP multicast. 11 | -- 5. Stop the capture, and select Tools -> Dump MPEG TS Packets 12 | -- 6. Enter the file where the mpeg stream should be saved. 13 | -- 7. In order to select only one of many streams, enter a wireshark filter 14 | -- expression, or you can leave the filter blank. 15 | -- 8. Press okay. Any MPEG packets in the current capture which were detected 16 | -- by the MPEG dissector and that match your filter will be dumped to 17 | -- your output file. 18 | -- 19 | -- Tested with Wireshark 1.4.3 20 | -- ryan.gorsuch_at_echostar_com 21 | -- 2011-04-01 22 | -- Modified and tested with Wireshark 1.11.3 23 | -- hadrielk_at_yahoo_com 24 | -- 2014-02-17 25 | 26 | -- only works in wireshark, not tshark 27 | if not GUI_ENABLED then 28 | io.stderr:write("mpeg_packets_dump.lua only works in Wireshark\n") 29 | return 30 | end 31 | 32 | -- declare some field extractors 33 | local mpeg_pid = Field.new("mp2t.pid") 34 | local mpeg_pkt = Field.new("mp2t") 35 | 36 | -- declare some functions we define later 37 | local tobinary 38 | 39 | -- do a payload dump when prompted by the user 40 | local function init_payload_dump(file,filter) 41 | 42 | local packet_count = 0 43 | local tap = Listener.new(nil,filter) 44 | local myfile = assert(io.open(file, "w+b")) 45 | 46 | -- this function is going to be called once each time our filter matches 47 | function tap.packet(pinfo,tvb) 48 | 49 | if ( mpeg_pid() ) then 50 | packet_count = packet_count + 1 51 | 52 | -- there can be multiple mp2t packets in a given frame, so get them all into a table 53 | local contents = { mpeg_pkt() } 54 | 55 | for i,finfo in ipairs(contents) do 56 | local tvbrange = finfo.range 57 | myfile:write( tobinary( tostring( tvbrange:bytes() ) ) ) 58 | myfile:flush() 59 | end 60 | end 61 | end 62 | 63 | -- re-inspect all the packets that are in the current capture, thereby 64 | -- triggering the above tap.packet function 65 | retap_packets() 66 | 67 | -- cleanup 68 | myfile:close() 69 | tap:remove() 70 | debug("Dumped mpeg packets: " .. packet_count ) 71 | end 72 | 73 | -- show this dialog when the user select "Dump" from the Tools menu 74 | local function begin_dialog_menu() 75 | new_dialog("Dump MPEG TS Packets",init_payload_dump,"Output file","Packet filter (optional)\n\nExamples:\nip.dst == 225.1.1.4\nmp2t\nmp2t.pid == 0x300") 76 | end 77 | 78 | register_menu("Dump MPEG TS Packets",begin_dialog_menu,MENU_TOOLS_UNSORTED) 79 | 80 | 81 | local function hex(ascii_code) 82 | -- convert an ascii char code to an integer value "0" => 0, "1" => 1, etc 83 | if not ascii_code then 84 | return 0 85 | elseif ascii_code < 58 then 86 | return ascii_code - 48 87 | elseif ascii_code < 91 then 88 | return ascii_code - 65 + 10 89 | else 90 | return ascii_code - 97 + 10 91 | end 92 | end 93 | 94 | tobinary = function (hexbytes) 95 | -- this function converts a hex-string to raw bytes 96 | 97 | local binary = {} 98 | local sz = 1 99 | 100 | for i=1, string.len(hexbytes), 2 do 101 | binary[sz] = string.char( 16 * hex( string.byte(hexbytes,i) ) + hex( string.byte(hexbytes,i+1) ) ) 102 | sz = sz + 1 103 | end 104 | 105 | return table.concat(binary) 106 | 107 | end 108 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # plugin-shark 2 | **A collection of useful wireshark/tshark plugins** 3 | 4 | \*Plugins directly included in this repo have been tested and verified as functioning. 5 | 6 | If they are available on GitHub, they are included as submodules. Others have been copied from the sources cited below. 7 | 8 | | PLUGIN | SOURCE | 9 | | ------ | ------ | 10 | | [1905.1 Protocol Dissector](https://github.com/phreakocious/plugin-shark/blob/master/1905.1.lua) | [sourceforge.net](https://sourceforge.net/p/cdhn4ws) | 11 | | [Microsoft Lync / Skype for Business Plugin](https://github.com/phreakocious/plugin-shark/blob/master/Lync-Skype4B-Plugin2.00.lua) | [Microsoft](https://gallery.technet.microsoft.com/office/Lync-Skype-for-Businesss-d422212f) 12 | | [MPEG2 Transport Stream Packets Dump](https://github.com/phreakocious/plugin-shark/blob/master/mpeg_packets_dump.lua) |[Cisco](https://www.cisco.com/c/en/us/support/docs/broadband-cable/cable-modem-termination-systems-cmts/214210-convert-a-sniffer-trace-to-mpeg-video.html) 13 | | [TCP Statistics](https://github.com/phreakocious/plugin-shark/blob/master/tcp_stats.lua) | [wiki.wireshark.org](https://wiki.wireshark.org/Contrib#Statistic_Taps_or_Post-Dissectors) 14 | 15 | 16 | ### Untested Plugins 17 | 18 | **Disclaimer: plugins listed below have not been tested!** 19 | 20 | \*\*Denotes that plugin was written in a language other than Lua. 21 | 22 | | PLUGIN | DESCRIPTION | 23 | | ------ | ------ | 24 | |[Aerospike Plugin](https://github.com/aerospike/aerospike-wireshark-plugin) | Plugin to interpret Aerospike wire protocol 25 | | [amos-ss16-proj3](https://github.com/AMOS-ss16-proj3/amos-ss16-proj3) |Plugin for monitoring DoIP network traffic 26 | | [Cap'n Proto RPC protocol dissector](https://github.com/kaos/wireshark-plugins) | Cap'n Proto RPC protocol dissector custom plugin by Kaos 27 | | [CITP-Dissector](https://github.com/hossimo/CITP-Dissector) | Wireshark CITP Lua Dissector 28 | | [Cloudshark Plugin](https://github.com/cloudshark/) | Upload captures directly to CloudShark from Wireshark 29 | | [h264extractor](https://github.com/volvet/h264extractor) | Extract H.264 or opus stream from rtp packets 30 | | [HEP Wireshark](https://github.com/sipcapture/hep-wireshark) | Wireshark Dissector for the HEP Encapsulation Protocol 31 | | [KDNET Debugger](https://github.com/Lekensteyn/kdnet) | Windows Kernel Debugger over Network 32 | |[KSNIFF](https://github.com/eldadru/ksniff)| Kubectl plugin to ease sniffing on Kubernetes pods using tcpdump and Wireshark 33 | | [MQTT Dissector](https://github.com/Johann-Angeli/wireshark-plugin-mqtt) | Authorizes Wireshark to identify and display clearly MQTT messages decoding fixed and variable header 34 | | [protobuf dissector](https://github.com/128technology/protobuf_dissector) | Lua plugin for decoding Google protobuf packets 35 | | [Pyreshark\*\*](https://github.com/ashdnazg/pyreshark) | Provides a simple interface for writing dissectors in Python 36 | | [RFC8450 VC2 Dissector](https://github.com/bbc/rfc8450-vc2-dissector) | Wireshark plugin to parse RTP streams implementing the VC-2 HQ payload specification 37 | | [RSocket](https://github.com/rsocket/rsocket-wireshark) | Wireshark/tshark Plugin in C for RSocket & supports all RSocket frames, except resumption 38 | | [RTP Video and Audio Dissector Wireshark Plugin](https://github.com/hongch911/WiresharkPlugin) | Wireshark plugin for H.265, H.264, PS, PCM, AMR, and SILK Codecs by hongch911 39 | | [SAP Dissector Plugin for Wireshark](https://github.com/SecureAuthCorp/SAP-Dissection-plug-in-for-Wireshark) | Provides dissection of SAP's NI, Message Server, Router, Diag, Enqueue, IGS, SNC and HDB protocols 40 | | [STOMP Dissector](https://github.com/ficoos/wireshark-stomp-plugin) | STOMP dissector for Wireshark 41 | | [suriwire](https://github.com/regit/suriwire) | Displays Suricata analysis info 42 | | [Wireshark DLMS](https://github.com/bearxiong99/wireshark-dlms) | Dissects DLMS APDUs in HDLC frames, IEC 61334-4-32 frames, wrapper frames, or raw data 43 | | [Wireshark Plugin AFDX](https://github.com/redlab-i/wireshark-plugin-afdx) | AFDX protocol dissector for Wireshark 44 | | [WiresharkLIFXDissector](https://github.com/mab5vot9us9a/WiresharkLIFXDissector) | Dissects packets of the LIFX LAN Protocol -------------------------------------------------------------------------------- /tcp_stats.lua: -------------------------------------------------------------------------------- 1 | -- ** TCP Statistics ** 2 | -- Description: Usual TCP performance issues (low TCP window, high TCP delta times, long iRTT, etc.) 3 | -- Author: Silvio Gissi 4 | -- 5 | -- Invoke via tshark: tshark -o tcp.calculate_timestamps:TRUE -q -n -X lua_script:tcp_stats.lua -r captured_file.pcapng 6 | -- Optionally add filter by adding -X lua_script1:'ip.src==192.168.123.123', any display filter is acceptable as long as it doesn't filter out parts of the TCP stream 7 | 8 | -- Arguments, first one is used for filtering 9 | args = {...} 10 | 11 | tcp_stats={} 12 | -- src, dst: Source and destination 13 | -- src_port, dst_port: Source and destination 14 | -- high_delta: Highest TCP time delta (RST/FIN packets discarded) 15 | -- high_delta_frame: Frame number of time above 16 | -- low_window: Lowest value of the TCP window 17 | -- low_window_frame: Frame number of low window above 18 | -- hs_src_mss / hs_dst_mss: TCP handshake MSS from both sides 19 | -- hs_src_sack / hs_dst_sack: TCP handshake SACK support from both sides 20 | -- hs_src_ws / hs_dst_ws: TCP handshake Window Scaling factor from both sides 21 | -- hs_irtt: TCP initial handshake RTT 22 | 23 | -- Check if a filter was given 24 | filter="tcp" 25 | if args[1] then 26 | filter="("..filter..") && ("..args[1]..")" 27 | end 28 | tap_tcp = Listener.new(nil,filter) 29 | 30 | tcp_stream=Field.new("tcp.stream") 31 | tcp_ws=Field.new("tcp.window_size") 32 | tcp_f_syn=Field.new("tcp.flags.syn") 33 | tcp_f_ack=Field.new("tcp.flags.ack") 34 | tcp_f_rst=Field.new("tcp.flags.reset") 35 | tcp_f_fin=Field.new("tcp.flags.fin") 36 | tcp_irtt=Field.new("tcp.analysis.initial_rtt") 37 | tcp_hs_mss=Field.new("tcp.options.mss_val") 38 | tcp_hs_ws=Field.new("tcp.options.wscale.multiplier") 39 | tcp_hs_sack=Field.new("tcp.options.sack_perm") 40 | tcp_delta=Field.new("tcp.time_delta") 41 | 42 | function tap_tcp.packet(pinfo) 43 | -- TCP stream numbers 44 | stream=tcp_stream().value 45 | -- TCP SYN, RST and FIN flags 46 | syn=tcp_f_syn().value 47 | rst=tcp_f_rst().value 48 | fin=tcp_f_fin().value 49 | -- Frame number 50 | fnum=pinfo.number 51 | 52 | -- New stream, first packet must be SYN 53 | if not tcp_stats[stream] then 54 | -- Not pure SYN, ignore. Likely existing connection prior to capture start 55 | if (not tcp_f_syn().value) or tcp_f_ack().value then 56 | return 57 | end 58 | -- Initialize tcp_stats table 59 | tcp_stats[stream]={} 60 | end 61 | 62 | -- SYN packet, store handshake 63 | if syn then 64 | mss = tcp_hs_mss().value 65 | -- Check if Window Scaling factor is present 66 | ws = tcp_hs_ws() 67 | if ws then 68 | ws=tostring(ws) 69 | else 70 | ws="not supported" 71 | end 72 | 73 | -- Check if SACK option is present and true 74 | sack = tcp_hs_sack() 75 | if sack and sack.value then 76 | sack="Yes" 77 | else 78 | sack="No" 79 | end 80 | 81 | -- First packet, source handshake 82 | if not tcp_f_ack().value then 83 | tcp_stats[stream]["hs_src_mss"]=mss 84 | tcp_stats[stream]["hs_src_ws"]=ws 85 | tcp_stats[stream]["hs_src_sack"]=sack 86 | tcp_stats[stream]["src"]=tostring(pinfo.src) 87 | tcp_stats[stream]["src_port"]=pinfo.src_port 88 | tcp_stats[stream]["dst"]=tostring(pinfo.dst) 89 | tcp_stats[stream]["dst_port"]=pinfo.dst_port 90 | else 91 | tcp_stats[stream]["hs_dst_mss"]=tcp_hs_mss().value 92 | tcp_stats[stream]["hs_dst_ws"]=ws 93 | tcp_stats[stream]["hs_dst_sack"]=sack 94 | end 95 | end 96 | 97 | -- **** Initial Round Trip Time (iRTT) 98 | 99 | 100 | -- Check if not stored yet and if iRTT is calculated already (aro3rd packet) 101 | irtt=tcp_irtt() 102 | if not tcp_stats[stream]["hs_irtt"] and irtt then 103 | tcp_stats[stream]["hs_irtt"]=tonumber(tostring(irtt)) 104 | end 105 | 106 | -- **** Highest TCP time delta (time between TCP packets in the same stream) 107 | 108 | delta = tcp_delta() 109 | if delta then 110 | delta=tonumber(tostring(delta)) 111 | end 112 | -- Check if delta exists and is higher than current (if any) 113 | if delta and (not tcp_stats[stream]["high_delta"] or delta > tcp_stats[stream]["high_delta"]) then 114 | -- Ignore high deltas on RST or FIN packets 115 | if not rst and not fin then 116 | tcp_stats[stream]["high_delta"]=delta 117 | tcp_stats[stream]["high_delta_frame"]=fnum 118 | end 119 | end 120 | 121 | -- **** Lowest calculated window size 122 | ws = tcp_ws() 123 | -- Check if WS field is present and get value 124 | if ws then 125 | ws=ws.value 126 | end 127 | if ws and (not tcp_stats[stream]["low_ws"] or ws < tcp_stats[stream]["low_ws"]) then 128 | -- Ignore low window on RST or FIN packets 129 | if not rst and not fin then 130 | tcp_stats[stream]["low_ws"]=ws 131 | tcp_stats[stream]["low_ws_frame"]=fnum 132 | end 133 | end 134 | 135 | end 136 | 137 | -- Called at the end of TShark capture but frequently by Wireshark 138 | function tap_tcp.draw() 139 | print "TCP Stats" 140 | 141 | for stream,st in pairs(tcp_stats) do 142 | print("Stream " .. stream .. " Src "..st["src"]..":"..st["src_port"].." (MSS " .. st["hs_src_mss"] .. " WS "..st["hs_src_ws"].." SACK "..st["hs_src_sack"]..") -> Dst "..st["dst"]..":"..st["dst_port"].." (MSS " .. st["hs_dst_mss"].." WS "..st["hs_dst_ws"].." SACK "..st["hs_dst_sack"]..") iRTT "..string.format("%.0f",st["hs_irtt"]*1000).."ms Highest Delta "..st["high_delta"].."("..st["high_delta_frame"]..") Lowest Window Size "..st["low_ws"].."("..st["low_ws_frame"]..")") 143 | end 144 | end 145 | 146 | function tap_tcp.reset() 147 | print "Resetting counters" 148 | tcp_conn_stats={} 149 | tcp_stats={} 150 | end 151 | -------------------------------------------------------------------------------- /1905.1.lua: -------------------------------------------------------------------------------- 1 | -- This is an IEEE 1905.1 protocol dissector for Wireshark written in the Lua 2 | -- scripting language. 3 | -- 4 | -- Installation 5 | -- ************* 6 | -- Shutdown wireshark. Copy this file into the installation directory given 7 | -- below. 8 | -- 9 | -- Windows 10 | -- ------- 11 | -- The installation directory can be selected among the following: 12 | -- C:\Program Files\Wireshark\plugins\1.12.0\ 13 | -- Copying files there, needs Administrator privileges. 14 | -- C:\Users\[username]\AppData\Roaming\Wireshark\plugins 15 | -- No Admin privileges needed. 16 | -- 17 | -- Linux 18 | -- ----- 19 | -- The installation directory is: /usr/lib/wireshark/plugins/ 20 | -- 21 | -- Test 22 | -- **** 23 | -- Launch wireshark. If the dissector loaded correctly, the IEEE 1905.1 24 | -- protocol appears in the supported protocols list. This list can be shown by 25 | -- selecting "Internals | Supported protocols" menu item in the wireshark 26 | -- application. 27 | -- 28 | -- This program is free software: you can redistribute it and/or modify 29 | -- it under the terms of the GNU General Public License as published by 30 | -- the Free Software Foundation, either version 3 of the License, or 31 | -- (at your option) any later version. 32 | -- 33 | -- This program is distributed in the hope that it will be useful, 34 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of 35 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 36 | -- GNU General Public License for more details. 37 | -- 38 | -- You should have received a copy of the GNU General Public License 39 | -- along with this program. If not, see . 40 | -- 41 | -- Author: Oliver Maye 42 | -- IHP GmbH, Frankfurt (Oder), Germany 43 | -- Date : 28. October 2014 44 | -- 45 | 46 | 47 | -- declare protocol + version 48 | local version_string = "1.7.20150108" 49 | local cdhnp_proto = Proto("ieee_1905.1","IEEE 1905.1 Standard for a Convergent Digital Home Network (" .. version_string .. ")") 50 | 51 | -- translation tables used for some of the fields 52 | local tab_msg_type = { 53 | [0] = "Topology discovery", 54 | [1] = "Topology notification", 55 | [2] = "Topology query", 56 | [3] = "Topology response", 57 | [4] = "Vendor specific", 58 | [5] = "Link metric query", 59 | [6] = "Link metric response", 60 | [7] = "AP-autoconfiguration search", 61 | [8] = "AP-autoconfiguration response", 62 | [9] = "AP-autoconfiguration WiFi simple configuration (WSC)", 63 | [10] = "AP-autoconfiguration renew", 64 | [11] = "1905.1 push button event notification", 65 | [12] = "1905.1 push button join notification", 66 | } 67 | 68 | local tab_tlv_type = { 69 | [0] = "End of message", 70 | [1] = "1905.1 abstraction layer MAC address", 71 | [2] = "Interface MAC address", 72 | [3] = "Device information", 73 | [4] = "Device bridging capability", 74 | [6] = "Non-1905 neighbor device list", 75 | [7] = "Neighbor device", 76 | [8] = "Link metric query", 77 | [9] = "Transmitter link metric", 78 | [10] = "Receiver link metric", 79 | [11] = "Vendor specific", 80 | [12] = "Link metric result", 81 | [13] = "Autoconfig role", 82 | [14] = "Autoconfig frequency band", 83 | [15] = "Supported role", 84 | [16] = "Supported frequency band", 85 | [17] = "WiFi simple configuration (WSC)", 86 | [18] = "Push button event notification", 87 | [19] = "Push button join notification" 88 | } 89 | 90 | local tab_media_type = { 91 | [0x0000] = "IEEE 802.3u Fast Ethernet", 92 | [0x0001] = "IEEE 802.3ab Gigabit Ethernet", 93 | [0x0100] = "IEEE 802.11b (2.4 GHz)", 94 | [0x0101] = "IEEE 802.11g (2.4 GHz)", 95 | [0x0102] = "IEEE 802.11a (5 GHz)", 96 | [0x0103] = "IEEE 802.11n (2.4 GHz)", 97 | [0x0104] = "IEEE 802.11n (5 GHz)", 98 | [0x0105] = "IEEE 802.11ac (5 GHz)", 99 | [0x0106] = "IEEE 802.11ad (60 GHz)", 100 | [0x0107] = "IEEE 802.11af (Whitespace)", 101 | [0x0200] = "IEEE 1901 Wavelet", 102 | [0x0201] = "IEEE 1901 FFT", 103 | [0x0300] = "MoCA v1.1", 104 | [0xFFFF] = "Unknown media", 105 | } 106 | 107 | local tab_mi_ieee_role = { 108 | [0] = "Access point", 109 | [1] = "Reserved value", 110 | [2] = "Reserved value", 111 | [3] = "Reserved value", 112 | [4] = "non-AP / non-PCP STA", 113 | [8] = "WiFi P2P Client", 114 | [9] = "WiFi P2P Group owner", 115 | [10] = "802.11ad PCP", 116 | [11] = "Reserved value", 117 | [0xFF] = "Reserved value" 118 | } 119 | 120 | local tab_lm_nbor = { 121 | [0] = "All neighbors", 122 | [1] = "Specific neighbor", 123 | [2] = "Reserved value", 124 | [0xFF] = "Reserved value" 125 | } 126 | 127 | local tab_lm_req = { 128 | [0] = "Tx link metrics only", 129 | [1] = "Rx link metrics only", 130 | [2] = "Both, Tx and Rx link metrics", 131 | [0xFF] = "Reserved value" 132 | } 133 | 134 | local tab_lm_result = { 135 | [0] = "Invalid neighbor", 136 | [1] = "Reserved value", 137 | [0xFF] = "Reserved value" 138 | } 139 | 140 | local tab_role = { 141 | [0] = "Registrar", 142 | [1] = "Reserved value", 143 | [0xFF] = "Reserved value" 144 | } 145 | 146 | local tab_freq_band = { 147 | [0] = "802.11 2.4 GHz", 148 | [1] = "802.11 5 GHz", 149 | [2] = "802.11 60 GHz", 150 | [3] = "Reserved value", 151 | [0xFF] = "Reserved value" 152 | } 153 | 154 | 155 | --declare fields 156 | local pf_message_version = ProtoField.uint8( "cdhnp.msg_ver", "Message Version", base.HEX ) 157 | local pf_reserved = ProtoField.uint8( "cdhnp.reserved", "Reserved", base.HEX ) 158 | local pf_message_type = ProtoField.uint16( "cdhnp.msg_type", "Message Type", base.DEC, tab_msg_type ) 159 | local pf_message_id = ProtoField.uint16( "cdhnp.msg_id", "Message ID", base.HEX ) 160 | local pf_fragment_id = ProtoField.uint8( "cdhnp.frag_id", "Fragment ID", base.HEX ) 161 | local pf_indicators = ProtoField.uint8( "cdhnp.indicators", "Indicators", base.HEX ) 162 | local fl_ind_lastFragment = ProtoField.bool( "cdhnp.indicators.lastFragment", "Last Fragment", 2, nil, 0x80) 163 | local fl_ind_relay = ProtoField.bool( "cdhnp.indicators.relay", "Relay", 2, nil, 0x40 ) 164 | local pf_tlv = ProtoField.bytes( "cdhnp.tlv", "TLV" ) 165 | local pf_excess_data = ProtoField.bytes( "cdhnp.excess.data", "Excess data" ) 166 | local pf_padding = ProtoField.bytes( "cdhnp.padding", "Padding" ) 167 | local pf_generic_num8 = ProtoField.uint8( "cdhnp.generic.num8", "Number", base.DEC ) 168 | 169 | local pf_tlv_type = ProtoField.uint8( "cdhnp.tlv.type", "TLV type", base.HEX, tab_tlv_type ) 170 | local pf_tlv_len = ProtoField.uint16( "cdhnp.tlv.length", "TLV length", base.DEC ) 171 | local pf_tlv_value= ProtoField.bytes( "cdhnp.tlv.value", "TLV value" ) 172 | 173 | local pf_tlv_vs_oui = ProtoField.uint32( "cdhnp.tlv.vs.oui", "Vendor specific OUI", base.HEX ) 174 | local pf_tlv_vs_info = ProtoField.bytes( "cdhnp.tlv.vs.info", "Vendor specific information" ) 175 | local pf_tlv_mac = ProtoField.ether( "cdhnp.tlv.mac", "EUI-48" ) 176 | local pf_tlv_mac_tx = ProtoField.ether( "cdhnp.tlv.mac.tx", "MAC address of transmitter" ) 177 | local pf_tlv_mac_rx = ProtoField.ether( "cdhnp.tlv.mac.rx", "MAC address of receiver" ) 178 | local pf_tlv_mac_nbor = ProtoField.ether( "cdhnp.tlv.mac.nbor", "MAC address of neighbor" ) 179 | local pf_tlv_num_if = ProtoField.uint8( "cdhnp.tlv.num.if", "Number of interfaces", base.DEC ) 180 | local pf_tlv_if_info = ProtoField.bytes( "cdhnp.tlv.if.info", "Interface info" ) 181 | local pf_tlv_media_type = ProtoField.uint16( "cdhnp.tlv.media.type", "Media type", base.HEX, tab_media_type ) 182 | local pf_tlv_media_info_len = ProtoField.bytes( "cdhnp.tlv.media.info.len", "Length of media specific information" ) 183 | local pf_tlv_media_info = ProtoField.bytes( "cdhnp.tlv.media.info", "Media specific information" ) 184 | local pf_tlv_mi_ieee_role = ProtoField.uint8( "cdhnp.tlv.mi.ieee.role", "Role", base.HEX, tab_mi_ieee_role, 0xF0 ) 185 | local pf_tlv_mi_ieee_bw = ProtoField.uint8( "cdhnp.tlv.mi.ieee.bw", "Channel bandwidth", base.HEX ) 186 | local pf_tlv_mi_ieee_idx1 = ProtoField.uint8( "cdhnp.tlv.mi.ieee.idx1", "Center frequency index 1", base.HEX ) 187 | local pf_tlv_mi_ieee_idx2 = ProtoField.uint8( "cdhnp.tlv.mi.ieee.idx2", "Center frequency index 2", base.HEX ) 188 | local pf_tlv_bridge_tuple = ProtoField.bytes( "cdhnp.tlv.bridging.tuple", "Bridging tuple" ) 189 | local pf_tlv_bridge_exist = ProtoField.bool( "cdhnp.tlv.bridging.exist", "Bridge exists", 1, nil, 0x80) 190 | local pf_tlv_nbor_info = ProtoField.bytes( "cdhnp.tlv.nbor.info", "Neighbor info" ) 191 | local pf_tlv_lm_nbor = ProtoField.uint8( "cdhnp.tlv.lm.nbor", "Neighbor", base.HEX, tab_lm_nbor ) 192 | local pf_tlv_lm_req = ProtoField.uint8( "cdhnp.tlv.lm.req", "Link metrics requested", base.HEX, tab_lm_req ) 193 | local pf_tlv_lm_brex = ProtoField.bool( "cdhnp.tlv.bridging.exist", "IEEE 802.1 bridge", 8, nil, 0xFF) 194 | local pf_tlv_lm_pkt_err = ProtoField.uint32( "cdhnp.tlv.lm.pkt.err", "Packet errors", base.DEC ) 195 | local pf_tlv_lm_pkt_tx = ProtoField.uint32( "cdhnp.tlv.lm.pkt.tx", "Packets transmitted", base.DEC ) 196 | local pf_tlv_lm_mac_cap = ProtoField.uint16( "cdhnp.tlv.lm.mac.cap", "MAC throughput capacity (Mb/s)", base.DEC ) 197 | local pf_tlv_lm_avail = ProtoField.uint16( "cdhnp.tlv.lm.avail", "Link availability (%)", base.DEC ) 198 | local pf_tlv_lm_phy_rate = ProtoField.uint16( "cdhnp.tlv.lm.phy.rate", "PHY rate (Mb/s)", base.DEC ) 199 | local pf_tlv_lm_pkt_rx = ProtoField.uint32( "cdhnp.tlv.lm.pkt.rx", "Packets received", base.DEC ) 200 | local pf_tlv_lm_rssi = ProtoField.uint8( "cdhnp.tlv.lm.rssi", "RSSI (dB)", base.DEC ) 201 | local pf_tlv_lm_result = ProtoField.uint8( "cdhnp.tlv.lm.result", "Link metric result code", base.HEX, tab_lm_result ) 202 | local pf_tlv_role = ProtoField.uint8( "cdhnp.tlv.role", "Role", base.HEX, tab_role ) 203 | local pf_tlv_freq_band = ProtoField.uint8( "cdhnp.tlv.freq.band", "Frequency band", base.HEX, tab_freq_band) 204 | local pf_tlv_wsc= ProtoField.bytes( "cdhnp.tlv.wsc", "WSC frame" ) 205 | 206 | cdhnp_proto.fields = { pf_message_version, pf_reserved, pf_message_type, pf_message_id, 207 | pf_fragment_id, pf_indicators, 208 | fl_ind_lastFragment, fl_ind_relay, 209 | pf_tlv, pf_excess_data, pf_padding, pf_generic_num8, 210 | pf_tlv_type, pf_tlv_len, pf_tlv_value, 211 | pf_tlv_vs_oui, pf_tlv_vs_info, pf_tlv_mac, pf_tlv_num_if, 212 | pf_tlv_if_info, pf_tlv_media_type, pf_tlv_media_info_len, pf_tlv_media_info, 213 | pf_tlv_mi_ieee_role, pf_tlv_mi_ieee_bw, 214 | pf_tlv_mi_ieee_idx1, pf_tlv_mi_ieee_idx2, pf_tlv_bridge_tuple, 215 | pf_tlv_bridge_exist, pf_tlv_nbor_info, pf_tlv_lm_nbor, pf_tlv_lm_req, pf_tlv_mac_tx, 216 | pf_tlv_mac_rx, pf_tlv_mac_nbor, pf_tlv_lm_brex, pf_tlv_lm_pkt_err, 217 | pf_tlv_lm_pkt_tx, pf_tlv_lm_mac_cap, pf_tlv_lm_avail, 218 | pf_tlv_lm_phy_rate, pf_tlv_lm_pkt_rx, pf_tlv_lm_rssi, 219 | pf_tlv_lm_result, pf_tlv_role, pf_tlv_freq_band, pf_tlv_wsc } 220 | 221 | -- Constants 222 | local CDHNP_MIN_LEN = 50 223 | 224 | -- create a function to dissect it 225 | function cdhnp_proto.dissector(buffer,pinfo,tree) 226 | pinfo.cols.protocol = "IEEE 1905.1" 227 | local subtree = tree:add(cdhnp_proto, buffer(), "IEEE 1905.1 Protocol Data") 228 | local has_eof_tlv = false 229 | 230 | if buffer:len() >= 1 then 231 | subtree:add( pf_message_version, buffer:range(0,1) ) 232 | end 233 | if buffer:len() >= 2 then 234 | subtree:add( pf_reserved, buffer(1,1) ) 235 | end 236 | if buffer:len() >= 4 then 237 | subtree:add( pf_message_type, buffer:range(2,2) ) 238 | pinfo.cols.info:set(tab_msg_type[buffer:range(2,2):uint()]) 239 | else 240 | pinfo.cols.info:set("--Erroneous--") 241 | end 242 | if buffer:len() >= 6 then 243 | subtree:add( pf_message_id, buffer:range(4,2) ) 244 | end 245 | if buffer:len() >= 7 then 246 | subtree:add( pf_fragment_id, buffer:range(6,1) ) 247 | end 248 | if buffer:len() >= 8 then 249 | local ind_tree = subtree:add( pf_indicators, buffer:range(7,1) ) 250 | ind_tree:add(fl_ind_lastFragment, buffer:range(7,1) ) 251 | ind_tree:add(fl_ind_relay, buffer:range(7,1) ) 252 | else 253 | subtree:add_expert_info(PI_MALFORMED, PI_ERROR, "CMDU header too short") 254 | return 255 | end 256 | 257 | local offset = 8 258 | while offset < buffer:len() do 259 | if (offset+3) > buffer:len() then 260 | local tlv_tree = subtree:add(pf_tlv, buffer:range(offset, buffer:len()-offset) ) 261 | tlv_tree:add_expert_info(PI_MALFORMED, PI_ERROR, "TLV too short.") 262 | break 263 | end 264 | local tlv_type = buffer:range(offset, 1):uint() 265 | local tlv_len = buffer:range(offset+1,2):uint() 266 | if offset+3+tlv_len > buffer:len() then 267 | local tlv_tree = subtree:add(pf_tlv, buffer:range(offset, buffer:len()-offset) ) 268 | tlv_tree:add( pf_tlv_type, buffer:range(offset,1) ) 269 | tlv_tree:add( pf_tlv_len, buffer:range(offset+1,2) ) 270 | tlv_tree:add_expert_info(PI_MALFORMED, PI_ERROR, "TLV length exceeds packet size.") 271 | break 272 | end 273 | local tlv_tree = subtree:add(pf_tlv, buffer:range(offset, 3+tlv_len) ) 274 | local tlv_num_if=0 275 | if tab_tlv_type[tlv_type]~=nil then 276 | tlv_tree:set_text( "TLV: "..tab_tlv_type[tlv_type] ) 277 | end 278 | tlv_tree:add( pf_tlv_type, buffer:range(offset, 1) ) 279 | tlv_tree:add( pf_tlv_len, buffer:range(offset+1,2) ) 280 | 281 | if tlv_type==0 then 282 | has_eof_tlv = true 283 | if tlv_len~=0 then 284 | tlv_tree:add_expert_info(PI_PROTOCOL, PI_WARN, "Length is not zero!") 285 | end 286 | offset = offset + 3 287 | if offset < buffer:len() then 288 | if buffer:len() <= CDHNP_MIN_LEN then 289 | subtree:add_expert_info(PI_UNDECODED, PI_CHAT, "Ethernet padding follows.") 290 | subtree:add( pf_padding, buffer:range(offset, buffer:len()-offset) ) 291 | elseif offset < CDHNP_MIN_LEN then 292 | subtree:add_expert_info(PI_UNDECODED, PI_CHAT, "Ethernet padding follows.") 293 | subtree:add( pf_padding, buffer:range(offset, CDHNP_MIN_LEN-offset) ) 294 | subtree:add_expert_info(PI_SECURITY, PI_WARN, "Padding followed by further packet data.") 295 | subtree:add( pf_excess_data, buffer:range(CDHNP_MIN_LEN, buffer:len()-CDHNP_MIN_LEN) ) 296 | else 297 | subtree:add_expert_info(PI_SECURITY, PI_WARN, "End of message TLV followed by further packet data.") 298 | subtree:add( pf_excess_data, buffer:range(offset, buffer:len()-offset) ) 299 | end 300 | end 301 | break 302 | elseif tlv_type==1 then 303 | tlv_tree:add( pf_tlv_mac, buffer:range(offset+3,6) ) 304 | elseif tlv_type==2 then 305 | tlv_tree:add( pf_tlv_mac, buffer:range(offset+3,6) ) 306 | elseif tlv_type==3 then 307 | tlv_tree:add( pf_tlv_mac, buffer:range(offset+3,6) ) 308 | tlv_tree:add( pf_tlv_num_if, buffer:range(offset+9,1) ) 309 | tlv_num_if=buffer:range(offset+9,1):uint() 310 | local local_offset=offset+10 311 | local media_type=0 312 | for k=1, tlv_num_if do 313 | local local_n = buffer:range(local_offset+6+2,1):uint() 314 | local if_tree = tlv_tree:add( pf_tlv_if_info, buffer:range(local_offset,6+2+1+local_n) ) 315 | if_tree:set_text("Interface #" .. k) 316 | if_tree:add( pf_tlv_mac, buffer:range(local_offset,6) ) 317 | if_tree:add( pf_tlv_media_type, buffer:range(local_offset+6,2) ) 318 | media_type = buffer:range(local_offset+6,2):uint() 319 | if_tree:add( pf_tlv_media_info_len, buffer:range(local_offset+6+2,1) ) 320 | local mi_tree = if_tree:add( pf_tlv_media_info, buffer:range(local_offset+9,local_n) ) 321 | if media_type>=0x0100 and media_type<=0x0107 and local_n>=10 then 322 | local bssid_mac = buffer:range(local_offset+9, 6):ether() 323 | mi_tree:add( pf_tlv_mac, buffer:range(local_offset+9, 6) ):set_text("BSSID: " .. tostring(bssid_mac) ) 324 | mi_tree:add( pf_tlv_mi_ieee_role, buffer:range(local_offset+15, 1) ) 325 | mi_tree:add( pf_tlv_mi_ieee_bw, buffer:range(local_offset+16, 1) ) 326 | mi_tree:add( pf_tlv_mi_ieee_idx1, buffer:range(local_offset+17, 1) ) 327 | mi_tree:add( pf_tlv_mi_ieee_idx2, buffer:range(local_offset+18, 1) ) 328 | end 329 | local_offset = local_offset+6+2+1+local_n 330 | end 331 | elseif tlv_type==4 then 332 | local local_m = buffer:range( offset+3, 1):uint() 333 | tlv_tree:add( pf_generic_num8, buffer:range( offset+3, 1) ):set_text("Number of bridging tuples: " .. local_m) 334 | local local_offset=offset+3+1 335 | for m=1, local_m do 336 | local local_k = buffer:range( local_offset, 1):uint() 337 | local tuple_tree = tlv_tree:add( pf_tlv_bridge_tuple, buffer:range(local_offset,1+6*local_k) ) 338 | tuple_tree:set_text("Bridging tuple #" .. m) 339 | tuple_tree:add( pf_generic_num8, buffer:range( local_offset, 1) ):set_text("Number of MAC addresses in this bridging tuple: " .. local_k) 340 | local_offset = local_offset+1 341 | for k=1, local_k do 342 | tuple_tree:add( pf_tlv_mac, buffer:range(local_offset,6) ) 343 | local_offset = local_offset+6 344 | end 345 | end 346 | elseif tlv_type==6 then 347 | if tlv_len<6 then 348 | tlv_tree:add_expert_info(PI_PROTOCOL, PI_ERROR, "MAC address of the local interface missing/malformed.") 349 | else 350 | tlv_tree:add( pf_tlv_mac, buffer:range(offset+3,6) ) 351 | local local_offset=offset+3+6 352 | while local_offset+6 <= offset+3+tlv_len do 353 | tlv_tree:add( pf_tlv_mac_nbor, buffer:range(local_offset,6) ) 354 | local_offset = local_offset+6 355 | end 356 | if local_offset < offset + 3 + tlv_len then 357 | local xtra_tree 358 | xtra_tree = tlv_tree:add( pf_excess_data, buffer:range(local_offset, offset+3+tlv_len-local_offset) ) 359 | xtra_tree:add_expert_info(PI_SECURITY, PI_WARN, "TLV has extra data that cannot be interpreted!") 360 | end 361 | end 362 | elseif tlv_type==7 then 363 | if tlv_len<6 then 364 | tlv_tree:add_expert_info(PI_PROTOCOL, PI_ERROR, "MAC address of the local interface missing/malformed.") 365 | else 366 | tlv_tree:add( pf_tlv_mac, buffer:range(offset+3,6) ) 367 | local local_offset=offset+3+6 368 | local nbor_num=0 369 | local nbor_tree 370 | while local_offset+7 <= offset+3+tlv_len do 371 | nbor_tree = tlv_tree:add( pf_tlv_nbor_info, buffer:range( local_offset, 7 )) 372 | nbor_num = nbor_num+1 373 | nbor_tree:set_text("Neighbor #" .. nbor_num) 374 | nbor_tree:add( pf_tlv_mac_nbor, buffer:range(local_offset,6) ) 375 | nbor_tree:add( pf_tlv_bridge_exist, buffer:range(local_offset+6,1) ) 376 | local_offset = local_offset+7 377 | end 378 | if local_offset < offset + 3 + tlv_len then 379 | nbor_tree = tlv_tree:add( pf_excess_data, buffer:range(local_offset, offset+3+tlv_len-local_offset) ) 380 | nbor_tree:add_expert_info(PI_SECURITY, PI_WARN, "TLV has extra data that cannot be interpreted!") 381 | end 382 | end 383 | elseif tlv_type==8 then 384 | local nbor=buffer:range( offset+3, 1):uint() 385 | tlv_tree:add( pf_tlv_lm_nbor, buffer:range(offset+3,1) ) 386 | if nbor==1 then 387 | tlv_tree:add( pf_tlv_mac, buffer:range(offset+3+1,6) ) 388 | elseif tlv_len>2 then 389 | local xtra_tree = tlv_tree:add( pf_excess_data, buffer:range(offset+3+1, tlv_len-2) ) 390 | xtra_tree:add_expert_info(PI_SECURITY, PI_WARN, "TLV has extra data - superfluous AL neighbor mac address .... ?") 391 | end 392 | tlv_tree:add( pf_tlv_lm_req, buffer:range(offset+3+tlv_len-1,1) ) 393 | elseif tlv_type==9 then 394 | tlv_tree:add( pf_tlv_mac_tx, buffer:range(offset+3,6) ) 395 | tlv_tree:add( pf_tlv_mac_nbor, buffer:range(offset+3+6,6) ) 396 | for local_offset=offset+15, offset+tlv_len+2, 29 do 397 | if local_offset+29 > offset+3+tlv_len then 398 | local xtra_tree = tlv_tree:add( pf_excess_data, buffer:range(local_offset, offset+3+tlv_len-local_offset) ) 399 | xtra_tree:add_expert_info(PI_SECURITY, PI_WARN, "TLV has extra data or malformed interface pair.") 400 | else 401 | local ifpair_tree = tlv_tree:add( pf_tlv_value, buffer:range(local_offset,29) ) 402 | ifpair_tree:set_text("Interface pair") 403 | ifpair_tree:add( pf_tlv_mac_rx, buffer:range(local_offset,6) ) 404 | ifpair_tree:add( pf_tlv_mac_nbor, buffer:range(local_offset+6,6) ) 405 | ifpair_tree:add( pf_tlv_media_type, buffer:range(local_offset+12,2) ) 406 | ifpair_tree:add( pf_tlv_lm_brex, buffer:range(local_offset+14,1) ) 407 | ifpair_tree:add( pf_tlv_lm_pkt_err, buffer:range(local_offset+15,4) ) 408 | ifpair_tree:add( pf_tlv_lm_pkt_tx, buffer:range(local_offset+19,4) ) 409 | ifpair_tree:add( pf_tlv_lm_mac_cap, buffer:range(local_offset+23,2) ) 410 | ifpair_tree:add( pf_tlv_lm_avail, buffer:range(local_offset+25,2) ) 411 | ifpair_tree:add( pf_tlv_lm_phy_rate, buffer:range(local_offset+27,2) ) 412 | end 413 | end 414 | elseif tlv_type==10 then 415 | tlv_tree:add( pf_tlv_mac_tx, buffer:range(offset+3,6) ) 416 | tlv_tree:add( pf_tlv_mac_nbor, buffer:range(offset+3+6,6) ) 417 | for local_offset=offset+15, offset+tlv_len+2, 23 do 418 | if local_offset+23 > offset+3+tlv_len then 419 | local xtra_tree = tlv_tree:add( pf_excess_data, buffer:range(local_offset, offset+3+tlv_len-local_offset) ) 420 | xtra_tree:add_expert_info(PI_SECURITY, PI_WARN, "TLV has extra data or malformed interface pair.") 421 | else 422 | local ifpair_tree = tlv_tree:add( pf_tlv_value, buffer:range(local_offset,23) ) 423 | ifpair_tree:set_text("Interface pair") 424 | ifpair_tree:add( pf_tlv_mac_rx, buffer:range(local_offset,6) ) 425 | ifpair_tree:add( pf_tlv_mac_nbor, buffer:range(local_offset+6,6) ) 426 | ifpair_tree:add( pf_tlv_media_type, buffer:range(local_offset+12,2) ) 427 | ifpair_tree:add( pf_tlv_lm_pkt_err, buffer:range(local_offset+14,4) ) 428 | ifpair_tree:add( pf_tlv_lm_pkt_rx, buffer:range(local_offset+18,4) ) 429 | ifpair_tree:add( pf_tlv_lm_rssi, buffer:range(local_offset+22,1) ) 430 | end 431 | end 432 | elseif tlv_type==11 then 433 | tlv_tree:add( pf_tlv_vs_oui, buffer:range(offset+3,3) ) 434 | tlv_tree:add( pf_tlv_vs_info, buffer:range(offset+3+3, tlv_len-3) ) 435 | elseif tlv_type==12 then 436 | tlv_tree:add( pf_tlv_lm_result, buffer:range(offset+3, 1) ) 437 | elseif tlv_type==13 or tlv_type==15 then 438 | tlv_tree:add( pf_tlv_role, buffer:range(offset+3, 1) ) 439 | elseif tlv_type==14 or tlv_type==16 then 440 | tlv_tree:add( pf_tlv_freq_band, buffer:range(offset+3, 1) ) 441 | elseif tlv_type==17 then 442 | tlv_tree:add( pf_tlv_wsc, buffer:range(offset+3, tlv_len) ) 443 | elseif tlv_type==18 then 444 | local local_m = buffer:range( offset+3, 1):uint() 445 | local local_offset=offset+3+1 446 | local media_type=0 447 | for m=1, local_m do 448 | tlv_tree:add( pf_tlv_media_type, buffer:range(local_offset, 2) ) 449 | media_type = buffer:range(local_offset, 2):uint() 450 | local local_k = buffer:range( local_offset+2, 1):uint() 451 | if local_k > 0 then 452 | local mi_tree = tlv_tree:add( pf_tlv_media_info, buffer:range(local_offset+3, local_k) ) 453 | if media_type>=0x0100 and media_type<=0x0107 and local_k>=10 then 454 | mi_tree:add( pf_tlv_mac, buffer:range(local_offset+3, 6) ) 455 | mi_tree:add( pf_tlv_mi_ieee_role, buffer:range(local_offset+9, 1) ) 456 | mi_tree:add( pf_tlv_mi_ieee_bw, buffer:range(local_offset+10, 1) ) 457 | mi_tree:add( pf_tlv_mi_ieee_idx1, buffer:range(local_offset+11, 1) ) 458 | mi_tree:add( pf_tlv_mi_ieee_idx2, buffer:range(local_offset+12, 1) ) 459 | end 460 | end 461 | local_offset = local_offset + 3 + local_k 462 | end 463 | elseif tlv_type==19 then 464 | local mac_addr = buffer:range(offset+3, 6):ether() 465 | tlv_tree:add( pf_tlv_mac, buffer:range(offset+3, 6) ):set_text("Abstraction layer ID of the notification message sender: " .. tostring(mac_addr) ) 466 | tlv_tree:add( pf_message_id, buffer:range(offset+9, 2) ) 467 | mac_addr = buffer:range(offset+11, 6):ether() 468 | tlv_tree:add( pf_tlv_mac, buffer:range(offset+11, 6) ):set_text("Transmitting device in the medium on which a new device joined: " .. tostring(mac_addr) ) 469 | mac_addr = buffer:range(offset+17, 6):ether() 470 | tlv_tree:add( pf_tlv_mac, buffer:range(offset+17, 6) ):set_text("New device joined: " .. tostring(mac_addr) ) 471 | else 472 | tlv_tree:add( pf_tlv_type, buffer:range(offset,1) ) 473 | tlv_tree:add( pf_tlv_len, buffer:range(offset+1,2) ) 474 | if tlv_len>0 then 475 | tlv_tree:add( pf_tlv_value, buffer:range(offset+3,tlv_len) ) 476 | end 477 | end 478 | offset = offset + 3 + tlv_len 479 | end 480 | 481 | if not has_eof_tlv then 482 | subtree:add_expert_info(PI_MALFORMED, PI_ERROR, "Missing end-of-message TLV.") 483 | end 484 | if buffer:len() < CDHNP_MIN_LEN then 485 | subtree:add_expert_info(PI_MALFORMED, PI_ERROR, "Packet too short, needs more padding to suffice minimal ethernet packet size") 486 | end 487 | 488 | end 489 | 490 | -- load the ethernet table 491 | ether_table = DissectorTable.get("ethertype") 492 | 493 | -- register our protocol to handle ethernet packets of type 0x893A 494 | if ether_table~=nil then 495 | ether_table:add(0x893A,cdhnp_proto) 496 | end 497 | -------------------------------------------------------------------------------- /Lync-Skype4B-Plugin2.00.lua: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------------------------------------------------------- 2 | -- Name: Microsoft Lync / Skype for Business Wireshark Plugin 3 | -- Version: v2.0.0 (20/3/2016) 4 | -- Date: 1/5/2014 5 | -- Created By: James Cussen 6 | -- Web Site: http://www.myskypelab.com 7 | -- Notes: For more information on this plugin visit http://www.myskypelab.com/2014/05/microsoft-lync-wireshark-plugin.html 8 | -- Feedback: If you have feedback on the plugin you can send it to mylynclabgmailcom 9 | -- 10 | -- Copyright: Copyright (c) 2016, James Cussen (www.myskypelab.com) All rights reserved. 11 | -- Licence: Redistribution and use of script, source and binary forms, with or without modification, are permitted provided that the following conditions are met: 12 | -- 1) Redistributions of script code must retain the above copyright notice, this list of conditions and the following disclaimer. 13 | -- 2) Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 14 | -- 3) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 15 | -- 4) This license does not include any resale or commercial use of this software. 16 | -- 5) Any portion of this software may not be reproduced, duplicated, copied, sold, resold, or otherwise exploited for any commercial purpose without express written consent of James Cussen. 17 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; LOSS OF GOODWILL OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 18 | -- 19 | -- Protocol Documentation: [MS-TURNBWM] http://msdn.microsoft.com/en-us/library/ff595670.aspx 20 | -- [MS-TURN] http://msdn.microsoft.com/en-us/library/cc431507.aspx 21 | -- [MS-RTP] http://msdn.microsoft.com/en-us/library/cc431492.aspx 22 | -- [MS-SRTP] http://msdn.microsoft.com/en-us/library/cc431516.aspx 23 | -- [MS-RTASPF] http://msdn.microsoft.com/en-us/library/cc308725.aspx 24 | -- [MS-RTPDT] http://msdn.microsoft.com/en-us/library/cc485841.aspx 25 | -- [MS-ICE] http://msdn.microsoft.com/en-us/library/dd922095.aspx 26 | -- [MS-ICE2] http://msdn.microsoft.com/en-us/library/cc431504.aspx 27 | -- ICE RFC5245 - https://tools.ietf.org/html/rfc5245 28 | -- STUN RFC5389 - http://tools.ietf.org/html/rfc5389 29 | -- ICE-19 - http://tools.ietf.org/html/draft-ietf-mmusic-ice-19 30 | -- RTP / RTCP - http://tools.ietf.org/html/rfc3550 31 | -- 32 | -- Release Notes: 33 | -- 1.00 Initial Release. 34 | -- - This Wireshark plugin is designed to dissect Lync AV Edge and Internal Edge AV traffic. Captures can be taken on the Edge server (Capturing AV Edge External traffic, and Internal Interface traffic), or it can also be used on the client side for decoding STUN and RTP/RTCP traffic. 35 | -- - This Wireshark plugin dissects STUN/TURN traffic on Microsoft Lync Edge port 3478 (STUN, RTCP, RTP) 36 | -- - This Wireshark plugin dissects traffic on Microsoft Lync Edge port 443 (STUN, RTCP, RTP) 37 | -- - This Wireshark plugin dissects dynamically assigned RTP and RTCP traffic by using ports allocated in STUN requests. 38 | -- - Dissector can be turned on/off within Wireshark Preferences. (Edit->Preferences->Protocols->LYNC_SKYPE_PLUGIN) 39 | -- - Port numbers can be changed within Wireshark Preferences. (Edit->Preferences->Protocols->LYNC_SKYPE_PLUGIN) 40 | -- - If you enter “lync_skype_plugin” in the Filter bar, only the traffic that is being decoded by the Lync Plugin will be displayed. 41 | -- - To be used with the latest release of Wireshark 42 | -- 43 | -- 2.00 Wireshark 2.0 update 44 | -- - Some updates to work with Wireshark 2.0+ (Thank you to Vladimir Vysotsky for feedback) 45 | -- - Changed the naming of the plugin to LYNC_SKYPE_PLUGIN. 46 | -- - Big updates to RTP and STUN classification to fix detection issues. 47 | -- - Added TLS pass-through to the Wireshark default SSL dissector for Hello, Handshaking, and Application data. So now you can have the plugin running all the time and still troubleshoot TLS handshaking issues on port 443. This also makes the plugin better for client side testing. 48 | -- - Corrected some issues with decoding 0x0013 Data Attribute encapsulated data. 49 | -- - The decoding of port 443 can have false positive matches for different packet types. The amount of false positive in this version of the plugin has been greatly decreased. 50 | -- - Widened the scope of RTP port classification from 1024-59999 (which was limited for Edge use) to 1024-65535. This makes the plugin work better when testing client side connections. 51 | -- - And more! 52 | -- 53 | ------------------------------------------------------------------------------------------------------------------------- 54 | 55 | do 56 | local lync_wrapper_proto = Proto("lync_skype_plugin", "Microsoft Lync Skype Plugin"); 57 | 58 | --PREFERENCES 59 | local prefs = lync_wrapper_proto.prefs 60 | prefs.port3478 = Pref.bool( "Decode UDP Port (Default 3478)", true, "Decode UDP Port (Default 3478)" ) 61 | prefs.port443 = Pref.bool( "Decode Internal TCP Port (Default 443)", true, "Decode Internal TCP Port (Default 443)") 62 | prefs.portexternal443 = Pref.bool( "Decode External AV TCP Port (Default 443)", true, "Decode External AV TCP Port (Default 443)") 63 | prefs.port50000 = Pref.bool( "Decode 1024-65535 Dynamic Ports", true, "Decode 1024-65535 Dynamic Ports") 64 | prefs.udpprotocolport = Pref.uint( "UDP Port (default 3478)", 3478) 65 | prefs.tcpprotocolport = Pref.uint( "TCP Internal Port (default 443)", 443) 66 | prefs.tcpexternalprotocolport = Pref.uint( "TCP External AV Port (default 443)", 443) 67 | prefs.showorginal = Pref.bool( "Show orginal wireshark dissection tree", false, "Show orginal wireshark dissection tree") 68 | 69 | -- FIELDS 70 | local F_stuntype = ProtoField.string("lync_wrapper_proto.stuntype","Type") 71 | local F_stunname = ProtoField.string("lync_wrapper_proto.stunname","Name") 72 | local F_attribute = ProtoField.string("lync_wrapper_proto.attribute","Attribute") 73 | local F_attribute_sub = ProtoField.string("lync_wrapper_proto.attribute.attribute_sub","AttributeType") 74 | local f_tcp_srcport = Field.new("tcp.srcport") 75 | local f_tcp_dstport = Field.new("tcp.dstport") 76 | local f_udp_srcport = Field.new("udp.srcport") 77 | local f_udp_dstport = Field.new("udp.dstport") 78 | 79 | 80 | -- ADD THE FIELDS TO THE PROTOCOL 81 | lync_wrapper_proto.fields = {F_stuntype, F_stunname, F_attribute, F_attribute_sub} 82 | 83 | -- DECLARE THE FIELDS WE NEED TO READ 84 | local original_stun_dissector 85 | 86 | -- GET THE ORIGINAL SSL DISSECTOR 87 | local tcp_dissector_table = DissectorTable.get("tcp.port") 88 | original_ssl_dissector = tcp_dissector_table:get_dissector(443) 89 | 90 | function lync_wrapper_proto.dissector(tvbuffer, pinfo, treeitem) 91 | 92 | if tvbuffer:len() > 1 then 93 | 94 | -- THIS WILL INCLUDE THE ORIGINAL WIRESHARK DISSECTION TREE IN ADDITION TO THE LYNC EDGE DISSECTOR TREE 95 | if prefs.showorginal then 96 | original_stun_dissector:call(tvbuffer, pinfo, treeitem) 97 | end 98 | 99 | -- CREATE NEW TREE PANE FOR MSSTUN PROTOCOL 100 | local subtreeitem = treeitem:add(lync_wrapper_proto, tvbuffer) 101 | 102 | -- IF THIS IS A TCP PACKET THEN OFFSET THE FRAMING 103 | tcpOffset = 0 104 | 105 | -- MAGIC COOKIE 0x2112A442 106 | -- TCP FRAMING CHECK STUN 107 | frameCheck = tvbuffer(0,1):uint() 108 | if tvbuffer:len() >= 12 then 109 | magiccookie = tvbuffer:range(8,4):uint() 110 | else 111 | magiccookie = 0 112 | end 113 | 114 | stunDataindIcationCheck = tvbuffer:range(4,2):uint() 115 | 116 | if frameCheck == 0x02 and magiccookie == 0x2112a442 or stunDataindIcationCheck == 0x0115 then -- MAGIC COOKIE CHECK 117 | if f_tcp_srcport() ~= nil and f_tcp_dstport() ~= nil then -- CHECK IF TCP 118 | tcpOffset = 4 119 | subtreeitem:add(F_stunname, tvbuffer(0,4), cmd_str) 120 | :set_text("TCP Framing Bytes - Turn Control Message (4 Bytes)") 121 | end 122 | end 123 | 124 | -- TCP FRAMING CHECK FOR END-TO-END DATA 125 | if frameCheck == 0x03 then 126 | if f_tcp_srcport() ~= nil and f_tcp_dstport() ~= nil then 127 | packetlength = tvbuffer:len() 128 | length = tvbuffer(2,2):uint() 129 | -- CHECK LENGTH 130 | if (length + 4) == packetlength then 131 | 132 | tcpOffset = 6 133 | 134 | subtreeitem:add(F_stunname, tvbuffer(0,6), cmd_str) 135 | :set_text("TCP Framing Bytes - End-to-End Data Message (6 Bytes)") 136 | 137 | --Set the Protcol and Info Columns 138 | pinfo.cols.protocol = "MSSTUN" 139 | pinfo.cols.info = "STUN END-TO-END DATA (Content Sharing)" 140 | 141 | 142 | attribute_bytes = tostring(tvbuffer:range(0,1)):upper() 143 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(0,1), attribute_bytes) 144 | attributeTree:set_text("Type: " .. "(0x" .. attribute_bytes .. ")") 145 | 146 | attribute_bytes = tostring(tvbuffer:range(1,1)):upper() 147 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(1,1), attribute_bytes) 148 | attributeTree:set_text("Reserved: " .. "(0x" .. attribute_bytes .. ")") 149 | 150 | attribute_bytes = tostring(tvbuffer:range(2,2)):upper() 151 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(2,2), attribute_bytes) 152 | attributeTree:set_text("Payload Length: " .. "(0x" .. attribute_bytes .. ")") 153 | 154 | attribute_bytes = tostring(tvbuffer:range(4,2)):upper() 155 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(4,2), attribute_bytes) 156 | attributeTree:set_text("RTP Length: " .. "(0x" .. attribute_bytes .. ")") 157 | 158 | 159 | attributeTree = subtreeitem:add(F_attribute_sub, tvbuffer(6,tvbuffer:len()-6), cmd_str) 160 | attributeTree:set_text("End-to-End Data: " .. tostring(tvbuffer(6,tvbuffer:len()-6))) 161 | 162 | end 163 | end 164 | end 165 | 166 | 167 | -- TCP FRAMING RTP/RTCP 168 | --RFC 4571 Section 2 169 | -- 0 1 2 3 170 | --0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 171 | ----------------------------------------------------------------- 172 | --| LENGTH | RTP or RTCP packet ... | 173 | ----------------------------------------------------------------- 174 | 175 | frameCheck2 = tvbuffer(0,2):uint() 176 | totalPacketLength = tvbuffer:len() 177 | framesize = totalPacketLength - 2 178 | magiccookie = tvbuffer:range(4+tcpOffset,4) 179 | if f_tcp_srcport() ~= nil and f_tcp_dstport() ~= nil then -- CHECK IF IT'S TCP TRAFFIC 180 | if frameCheck2 ~= 0x1603 and frameCheck2 ~= 0x1703 then -- CHECK THAT IT'S NOT TLS TRAFFIC 181 | if magiccookie ~= 0x2112a442 then -- CHECK THAT IT'S NOT A STUN PACKET 182 | if frameCheck2 == framesize then -- 2.0 CHECK - THE FRAMING BITS SHOULD EQUAL THE LENGTH OF THE PACKET 183 | tcpOffset = 2 184 | subtreeitem:add(F_stunname, tvbuffer(0,2), cmd_str) 185 | :set_text("TCP Framing Bytes (2 Byte)") 186 | end 187 | end 188 | end 189 | end 190 | 191 | 192 | -- GET THE ATTRIBUTE 193 | attribute = tvbuffer(tcpOffset,2):uint() 194 | 195 | -- CHECK IF IT'S A MICROSOFT STUN ATTRIBUTE 196 | standard_attribute = tvbuffer(tcpOffset,1):uint() 197 | 198 | if tvbuffer:len() >= 8 then 199 | magiccookie = tvbuffer:range(4+tcpOffset,4):uint() -- MAGIC COOKIE 200 | else 201 | magiccookie = 0 202 | end 203 | 204 | --MAGICCOOKIE == 0x2112A442 205 | if attribute ~= 0x0300 and magiccookie == 0x2112a442 or attribute == 0x0115 then 206 | 207 | -- CHECK for MS STUN! 208 | if standard_attribute == 0x00 or standard_attribute == 0x01 then 209 | 210 | cmd = tvbuffer(tcpOffset,2):uint() 211 | 212 | cmd_str = "unknown 0x00 0x01 (Possible incorrect packet classification)" 213 | 214 | if cmd == 0x0001 then 215 | cmd_str = "STUN BINDING REQUEST" 216 | pinfo.cols.protocol = "MSSTUN" 217 | elseif cmd == 0x0101 then 218 | cmd_str = "STUN BINDING RESPONSE" 219 | pinfo.cols.protocol = "MSSTUN" 220 | elseif cmd == 0x0111 then 221 | cmd_str = "STUN BINDING ERROR RESPONSE" 222 | pinfo.cols.protocol = "MSSTUN" 223 | elseif cmd == 0x0011 then 224 | cmd_str = "STUN BINDING INDICATION" 225 | pinfo.cols.protocol = "MSSTUN" 226 | elseif cmd == 0x0002 then 227 | cmd_str = "STUN SHARED SECRET REQUEST - NOT SUPPORTED" 228 | pinfo.cols.protocol = "MSSTUN" 229 | elseif cmd == 0x0102 then 230 | cmd_str = "STUN SHARED SECRET RESPONSE - NOT SUPPORTED" 231 | pinfo.cols.protocol = "MSSTUN" 232 | elseif cmd == 0x0112 then 233 | cmd_str = "STUN SHARED SECRET ERROR RESPONSE - NOT SUPPORTED" 234 | pinfo.cols.protocol = "MSSTUN" 235 | elseif cmd == 0x0003 then 236 | cmd_str = "STUN ALLOCATE REQUEST" 237 | pinfo.cols.protocol = "MSSTUN" 238 | elseif cmd == 0x0103 then 239 | cmd_str = "STUN ALLOCATE RESPONSE" 240 | pinfo.cols.protocol = "MSSTUN" 241 | elseif cmd == 0x0113 then 242 | cmd_str = "STUN ALLOCATE ERROR RESPONSE" 243 | pinfo.cols.protocol = "MSSTUN" 244 | elseif cmd == 0x0004 then 245 | cmd_str = "STUN SEND REQUEST" 246 | pinfo.cols.protocol = "MSSTUN" 247 | elseif cmd == 0x0104 then 248 | cmd_str = "STUN REFRESH RESPONSE - NOT SUPPORTED" 249 | pinfo.cols.protocol = "MSSTUN" 250 | elseif cmd == 0x0114 then 251 | cmd_str = "STUN REFRESH ERROR RESPONSE - NOT SUPPORTED" 252 | pinfo.cols.protocol = "MSSTUN" 253 | elseif cmd == 0x0115 then 254 | cmd_str = "STUN DATA INDICATION" 255 | pinfo.cols.protocol = "MSSTUN" 256 | elseif cmd == 0x0006 then 257 | cmd_str = "STUN SET ACTIVE DESTINATION REQUEST" 258 | pinfo.cols.protocol = "MSSTUN" 259 | elseif cmd == 0x0016 then 260 | cmd_str = "STUN SEND INDICATION" 261 | pinfo.cols.protocol = "MSSTUN" 262 | elseif cmd == 0x0106 then 263 | cmd_str = "STUN SET ACTIVE DESTINATION RESPONSE" 264 | pinfo.cols.protocol = "MSSTUN" 265 | elseif cmd == 0x0116 then 266 | cmd_str = "STUN SET ACTIVE DESTINATION ERROR RESPONSE" 267 | pinfo.cols.protocol = "MSSTUN" 268 | elseif cmd == 0x0017 then 269 | cmd_str = "STUN DATA INDICATION" 270 | pinfo.cols.protocol = "MSSTUN" 271 | elseif cmd == 0x0008 then 272 | cmd_str = "STUN CREATE PERM REQUEST" 273 | pinfo.cols.protocol = "MSSTUN" 274 | elseif cmd == 0x0108 then 275 | cmd_str = "STUN CREATE PERM RESPONSE" 276 | pinfo.cols.protocol = "MSSTUN" 277 | elseif cmd == 0x0118 then 278 | cmd_str = "STUN CREATE_PERM ERROR RESPONSE" 279 | pinfo.cols.protocol = "MSSTUN" 280 | elseif cmd == 0x0009 then 281 | cmd_str = "STUN CHANNEL BIND REQUEST" 282 | pinfo.cols.protocol = "MSSTUN" 283 | elseif cmd == 0x0109 then 284 | cmd_str = "STUN CHANNEL BIND RESPONSE" 285 | pinfo.cols.protocol = "MSSTUN" 286 | elseif cmd == 0x0119 then 287 | cmd_str = "STUN CHANNEL BIND ERROR RESPONSE" 288 | pinfo.cols.protocol = "MSSTUN" 289 | else 290 | -- NO MATCH 291 | cmd_str = "" 292 | --IF IT'S ON PORT 443 THEN ASSUME THEN TRY THE TLS DECODER 293 | if f_tcp_srcport() ~= nil and f_tcp_dstport() ~= nil then 294 | if f_tcp_srcport().value == 443 or f_tcp_dstport().value == 443 then 295 | original_ssl_dissector:call(tvbuffer, pinfo, treeitem) --DECODE AS TLS 296 | end 297 | end 298 | end 299 | 300 | --cmd_str = cmd_str .. " attribute = " .. tostring(attribute):upper() .. " standard_attribute = " .. tostring(standard_attribute):upper() .. " Magic Cookie = " .. tostring(magiccookie):upper() 301 | 302 | 303 | field1_val = tostring(bit.tohex(tvbuffer(tcpOffset,2):uint(),4)):upper() 304 | subtreeitem:add(F_stunname, tvbuffer(tcpOffset,2), cmd_str) 305 | :set_text("Command String: " .. cmd_str .. " (0x" .. field1_val .. ")") 306 | 307 | 308 | attribute_length = string.format("%i", tvbuffer(2+tcpOffset,2):uint()) 309 | subtreeitem:add(F_stunname, tvbuffer(2+tcpOffset,2), attribute_length) 310 | :set_text("Attribute Length: " .. attribute_length .. " Bytes") 311 | 312 | field1_val = tostring(tvbuffer:range(4+tcpOffset,4)):upper() 313 | subtreeitem:add(F_stunname, tvbuffer(4+tcpOffset,4), cmd_str) 314 | :set_text("Magic Cookie: " .. "0x" .. field1_val) 315 | 316 | 317 | field1_val = tostring(tvbuffer:range(8+tcpOffset,12)):upper() 318 | subtreeitem:add(F_stunname, tvbuffer(8+tcpOffset,12), cmd_str) 319 | :set_text("Transaction ID: 0x" .. field1_val) 320 | 321 | --SET THE PROTCOL AND INFO COLUMNS 322 | pinfo.cols.info = cmd_str 323 | 324 | offset = 20 + tcpOffset 325 | relativePosition = 0 326 | 327 | -- START READING ATTRIBUTES - LOOK FOR MICROSOFT EXTENSIONS 328 | while true do 329 | 330 | -- POSITION IN PACKET 331 | local absolutePosition = offset + relativePosition 332 | 333 | -- GET THE ATTRIBUTE 334 | local attribute = tvbuffer(absolutePosition,2):uint() 335 | 336 | -- CHECK IF IT'S A MICROSOFT ATTRIBUTE 337 | local ms_attribute = tvbuffer(absolutePosition,1):uint() 338 | 339 | -- GET THE LENGTH OF THE ATTRIBUTE 340 | local lengthOfCommand = tvbuffer(absolutePosition+2,2):uint() 341 | 342 | -- CALCULATE THE FINAL POSITION 343 | local finalPosition = absolutePosition + lengthOfCommand + 4 344 | 345 | 346 | --NON MICROSOFT SPECIFIC ATTRIBUTES 347 | if ms_attribute == 0x00 then 348 | -- DEFINED IN IETFDRAFT-STUN-02 349 | if attribute == 0x0001 then 350 | att_str = "Mapped Address" 351 | elseif attribute == 0x0006 then 352 | att_str = "Username" 353 | elseif attribute == 0x0008 then 354 | att_str = "Message Integrity" 355 | elseif attribute == 0x0009 then 356 | att_str = "Error Code" 357 | elseif attribute == 0x000A then 358 | att_str = "Unknown Attributes" 359 | elseif attribute == 0x000D then 360 | att_str = "Lifetime" 361 | elseif attribute == 0x000E then 362 | att_str = "Alternate Server" 363 | elseif attribute == 0x000F then 364 | att_str = "Magic Cookie" 365 | elseif attribute == 0x0010 then 366 | att_str = "Bandwidth" 367 | elseif attribute == 0x0011 then 368 | att_str = "Destination Address" 369 | elseif attribute == 0x0012 then 370 | att_str = "Remote Address" 371 | elseif attribute == 0x0013 then 372 | att_str = "Data" 373 | elseif attribute == 0x0014 then 374 | att_str = "Nonce" 375 | elseif attribute == 0x0015 then 376 | att_str = "Realm" 377 | elseif attribute == 0x0017 then 378 | att_str = "Requested Address Family" 379 | elseif attribute == 0x0020 then 380 | att_str = "XOR Mapped Address" 381 | elseif attribute == 0x0024 then 382 | att_str = "Priority (RFC5245)" 383 | elseif attribute == 0x0025 then 384 | att_str = "Use-Candidate (RFC5245)" 385 | 386 | end 387 | 388 | 389 | attribute_val = tostring(bit.tohex(tvbuffer(absolutePosition,2):uint(),4)):upper() 390 | attributeTree = subtreeitem:add(F_attribute, tvbuffer(absolutePosition,lengthOfCommand+4), attribute_val) 391 | attributeTree:set_text("Attribute: 0x" .. attribute_val .. " (" .. att_str .. ")") 392 | 393 | attribute_length = string.format("%i", tvbuffer(absolutePosition+2,2):uint()) 394 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+2,2), attribute_length) 395 | :set_text("Attribute Length: " .. attribute_length .. " Bytes") 396 | 397 | 398 | 399 | -- Defined in IETFDRAFT-STUN-02 400 | if attribute == 0x0001 then 401 | --att_str = "Mapped Address" 402 | 403 | attribute_bytes = tostring(bit.tohex(tvbuffer(absolutePosition+4,1):uint(),1)):upper() 404 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,1), attribute_length) 405 | :set_text("Reserved " .. attribute_bytes) 406 | 407 | fam_type = tvbuffer(absolutePosition+5,1):uint() 408 | 409 | if fam_type == 0x01 then 410 | att_str = "IPv4" 411 | att_bytes = "0x01" 412 | elseif fam_type == 0x02 then 413 | att_str = "IPv6" 414 | att_bytes = "0x02" 415 | end 416 | 417 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+5,1), attribute_length) 418 | :set_text("Family: " .. att_str .. " (" .. att_bytes .. ")") 419 | 420 | 421 | port = tvbuffer(absolutePosition+6,2):uint() 422 | 423 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+6,2):uint()) 424 | portstring = string.format("%i", port) 425 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+6,2), attribute_length) 426 | :set_text("Port: " .. portstring .. " " .. attribute_bytes) 427 | 428 | 429 | if fam_type == 0x01 then 430 | 431 | oct1 = tvbuffer(absolutePosition+8,1):uint() 432 | oct2 = tvbuffer(absolutePosition+9,1):uint() 433 | oct3 = tvbuffer(absolutePosition+10,1):uint() 434 | oct4 = tvbuffer(absolutePosition+11,1):uint() 435 | 436 | ip1string = string.format("%i", oct1) 437 | ip2string = string.format("%i", oct2) 438 | ip3string = string.format("%i", oct3) 439 | ip4string = string.format("%i", oct4) 440 | 441 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+8,4):uint()) 442 | 443 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+8,4), attribute_length) 444 | :set_text("Address-IPv4: " .. ip1string .. "." .. ip2string .. "." .. ip3string .. "." .. ip4string .. " " .. attribute_bytes) 445 | 446 | elseif fam_type == 0x02 then 447 | -- Not decoding IPv6 fully yet. Need some capture data to test against. 448 | attribute_bytes = tostring(tvbuffer:range(absolutePosition+8,16)) 449 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+8,16), attribute_length) 450 | :set_text("Address_IPv6: 0x" .. attribute_bytes) 451 | end 452 | 453 | 454 | elseif attribute == 0x0006 then 455 | --att_str = "Username" 456 | 457 | attribute_bytes = tostring(tvbuffer:range(absolutePosition+4,lengthOfCommand-4)) 458 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,lengthOfCommand), attribute_length) 459 | :set_text("Username (): 0x" .. attribute_bytes) 460 | 461 | elseif attribute == 0x0008 then 462 | --att_str = "Message Integrity" 463 | 464 | attribute_bytes = tostring(tvbuffer:range(absolutePosition+4,lengthOfCommand-4)) 465 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,lengthOfCommand), attribute_length) 466 | :set_text("HMAC HASH: 0x" .. attribute_bytes) 467 | 468 | elseif attribute == 0x0009 then 469 | --att_str = "Error Code" 470 | 471 | -- 0 1 2 3 472 | -- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 473 | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 474 | -- | 0 |Class| Number | 475 | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 476 | -- | Reason Phrase (variable) .. 477 | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 478 | 479 | 480 | local bits = tvbuffer(absolutePosition+4,3):uint() 481 | 482 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,3), attribute_length) 483 | :set_text("Reserved Bytes: 0x" .. tostring(bit.tohex((bit.band(bits,0xFFFFF0)),6))) 484 | 485 | local bits2 = tvbuffer(absolutePosition+6,1):uint() 486 | local bits3 = tvbuffer(absolutePosition+7,1):uint() 487 | 488 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+6,2), attribute_length) 489 | :set_text("Error Code: " .. string.format("%01d", (bit.band(bits2,0x0F))) .. string.format("%02d", (bit.band(bits3,0xFF)))) 490 | 491 | 492 | -- Convert to ASCII 493 | local asc = "" 494 | for i = absolutePosition+8, absolutePosition+8+lengthOfCommand-4 do 495 | local c = tvbuffer(i,1):uint() 496 | asc = string.format("%s%c", asc, c) 497 | end 498 | 499 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+8,lengthOfCommand-4), attribute_length) 500 | :set_text("Error: " .. asc) 501 | 502 | 503 | 504 | elseif attribute == 0x000A then 505 | --att_str = "Unknown Attributes" 506 | 507 | attribute_bytes = tostring(bit.tohex(tvbuffer(absolutePosition+4,2):uint(),4)) 508 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+2,2), attribute_length) 509 | :set_text("Attribute 1 Type: 0x" .. attribute_bytes) 510 | 511 | attribute_bytes = tostring(bit.tohex(tvbuffer(absolutePosition+6,2):uint(),4)) 512 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+2,2), attribute_length) 513 | :set_text("Attribute 2 Type: 0x" .. attribute_bytes) 514 | 515 | elseif attribute == 0x000D then 516 | --att_str = "Lifetime" 517 | 518 | attribute_bytes = string.format("%i", tvbuffer(absolutePosition+4,4):uint()) 519 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,4), attribute_length) 520 | :set_text("Lifetime: " .. attribute_bytes .. " Seconds") 521 | 522 | elseif attribute == 0x000E then 523 | --att_str = "Alternate Server" 524 | 525 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+4,1):uint()) 526 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,1), attribute_length) 527 | :set_text("Reserved " .. attribute_bytes) 528 | 529 | fam_type = tvbuffer(absolutePosition+5,1):uint() 530 | 531 | if fam_type == 0x01 then 532 | att_str = "IPv4" 533 | att_bytes = "0x01" 534 | elseif fam_type == 0x02 then 535 | att_str = "IPv6" 536 | att_bytes = "0x02" 537 | end 538 | 539 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+5,1), attribute_length) 540 | :set_text("Family: " .. att_str .. " (" .. att_bytes .. ")") 541 | 542 | 543 | port = tvbuffer(absolutePosition+6,2):uint() 544 | 545 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+6,2):uint()) 546 | portstring = string.format("%i", port) 547 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+6,2), attribute_length) 548 | :set_text("Port: " .. portstring .. " " .. attribute_bytes) 549 | 550 | 551 | if fam_type == 0x01 then 552 | 553 | oct1 = tvbuffer(absolutePosition+8,1):uint() 554 | oct2 = tvbuffer(absolutePosition+9,1):uint() 555 | oct3 = tvbuffer(absolutePosition+10,1):uint() 556 | oct4 = tvbuffer(absolutePosition+11,1):uint() 557 | 558 | ip1string = string.format("%i", oct1) 559 | ip2string = string.format("%i", oct2) 560 | ip3string = string.format("%i", oct3) 561 | ip4string = string.format("%i", oct4) 562 | 563 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+8,4):uint()) 564 | 565 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+8,4), attribute_length) 566 | :set_text("Address-IPv4: " .. ip1string .. "." .. ip2string .. "." .. ip3string .. "." .. ip4string .. " " .. attribute_bytes) 567 | 568 | elseif fam_type == 0x02 then 569 | -- Not decoding IPv6 fully yet. 570 | attribute_bytes = tostring(tvbuffer:range(absolutePosition+8,16)) 571 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+8,16), attribute_length) 572 | :set_text("Address_IPv6: 0x" .. attribute_bytes) 573 | end 574 | 575 | elseif attribute == 0x000F then 576 | --att_str = "Magic Cookie" 577 | 578 | attribute_bytes = tostring(bit.tohex(tvbuffer(absolutePosition+4,4):uint(),8)):upper() 579 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,4), attribute_length) 580 | :set_text("Magic Cookie: 0x" .. attribute_bytes) 581 | 582 | elseif attribute == 0x0010 then 583 | --att_str = "Bandwidth" 584 | 585 | attribute_bytes = string.format("%i", tvbuffer(absolutePosition+4,4):uint()) 586 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,4), attribute_length) 587 | :set_text("Bandwidth (peak): " .. attribute_bytes .. " kbps") 588 | 589 | 590 | elseif attribute == 0x0011 then 591 | --att_str = "Desitination Address" 592 | 593 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+4,1):uint()) 594 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,1), attribute_length) 595 | :set_text("Reserved " .. attribute_bytes) 596 | 597 | fam_type = tvbuffer(absolutePosition+5,1):uint() 598 | 599 | if fam_type == 0x01 then 600 | att_str = "IPv4" 601 | att_bytes = "0x01" 602 | elseif fam_type == 0x02 then 603 | att_str = "IPv6" 604 | att_bytes = "0x02" 605 | end 606 | 607 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+5,1), attribute_length) 608 | :set_text("Family: " .. att_str .. " (" .. att_bytes .. ")") 609 | 610 | 611 | port = tvbuffer(absolutePosition+6,2):uint() 612 | 613 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+6,2):uint()) 614 | portstring = string.format("%i", port) 615 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+6,2), attribute_length) 616 | :set_text("Port: " .. portstring .. " " .. attribute_bytes) 617 | 618 | 619 | ----------------------------------------------- 620 | -- Decode the 1024-65535 range ports from STUN 621 | ----------------------------------------------- 622 | if prefs.port50000 then 623 | if port >= 1024 and port <= 65535 then 624 | myproto_udp_init(port) 625 | myproto_tcp_init(port) 626 | --RTCP 627 | myproto_udp_init(port+1) --RTCP Port 628 | myproto_tcp_init(port+1) --RTCP Port 629 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+6,2), attribute_length) 630 | :set_text("(INFO: Added " .. portstring .. " to decode.)") 631 | else 632 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+6,2), attribute_length) 633 | :set_text("(INFO: Not in 1024-65535 range. Not Added " .. portstring .. " to decode.)") 634 | end 635 | else 636 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+6,2), attribute_length) 637 | :set_text("(INFO: Removed " .. portstring .. " from decode.)") 638 | myproto_udp_remove_init(port) 639 | myproto_tcp_remove_init(port) 640 | myproto_udp_remove_init(port+1) -- RTCP Port 641 | myproto_tcp_remove_init(port+1) -- RTCP Port 642 | 643 | end 644 | 645 | 646 | if fam_type == 0x01 then 647 | 648 | oct1 = tvbuffer(absolutePosition+8,1):uint() 649 | oct2 = tvbuffer(absolutePosition+9,1):uint() 650 | oct3 = tvbuffer(absolutePosition+10,1):uint() 651 | oct4 = tvbuffer(absolutePosition+11,1):uint() 652 | 653 | ip1string = string.format("%i", oct1) 654 | ip2string = string.format("%i", oct2) 655 | ip3string = string.format("%i", oct3) 656 | ip4string = string.format("%i", oct4) 657 | 658 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+8,4):uint()) 659 | 660 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+8,4), attribute_length) 661 | :set_text("Address-IPv4: " .. ip1string .. "." .. ip2string .. "." .. ip3string .. "." .. ip4string .. " " .. attribute_bytes) 662 | 663 | elseif fam_type == 0x02 then 664 | -- Not decoding IPv6 fully yet. 665 | attribute_bytes = tostring(tvbuffer:range(absolutePosition+8,16)) 666 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+8,16), attribute_length) 667 | :set_text("Address_IPv6: 0x" .. attribute_bytes) 668 | end 669 | 670 | elseif attribute == 0x0012 then 671 | --att_str = "Remote Address" 672 | 673 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+4,1):uint()) 674 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,1), attribute_length) 675 | :set_text("Reserved " .. attribute_bytes) 676 | 677 | fam_type = tvbuffer(absolutePosition+5,1):uint() 678 | 679 | if fam_type == 0x01 then 680 | att_str = "IPv4" 681 | att_bytes = "0x01" 682 | elseif fam_type == 0x02 then 683 | att_str = "IPv6" 684 | att_bytes = "0x02" 685 | end 686 | 687 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+5,1), attribute_length) 688 | :set_text("Family: " .. att_str .. " (" .. att_bytes .. ")") 689 | 690 | 691 | port = tvbuffer(absolutePosition+6,2):uint() 692 | 693 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+6,2):uint()) 694 | portstring = string.format("%i", port) 695 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+6,2), attribute_length) 696 | :set_text("Port: " .. portstring .. " " .. attribute_bytes) 697 | 698 | 699 | if fam_type == 0x01 then 700 | 701 | oct1 = tvbuffer(absolutePosition+8,1):uint() 702 | oct2 = tvbuffer(absolutePosition+9,1):uint() 703 | oct3 = tvbuffer(absolutePosition+10,1):uint() 704 | oct4 = tvbuffer(absolutePosition+11,1):uint() 705 | 706 | ip1string = string.format("%i", oct1) 707 | ip2string = string.format("%i", oct2) 708 | ip3string = string.format("%i", oct3) 709 | ip4string = string.format("%i", oct4) 710 | 711 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+8,4):uint()) 712 | 713 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+8,4), attribute_length) 714 | :set_text("Address-IPv4: " .. ip1string .. "." .. ip2string .. "." .. ip3string .. "." .. ip4string .. " " .. attribute_bytes) 715 | 716 | elseif fam_type == 0x02 then 717 | -- Not decoding IPv6 fully yet. 718 | attribute_bytes = tostring(tvbuffer:range(absolutePosition+8,16)) 719 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+8,16), attribute_length) 720 | :set_text("Address_IPv6: 0x" .. attribute_bytes) 721 | end 722 | 723 | elseif attribute == 0x0013 then 724 | --att_str = "Data" 725 | 726 | attribute_bytes = tostring(tvbuffer:range(absolutePosition+4,lengthOfCommand)) 727 | dataTree = attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,lengthOfCommand), attribute_length) 728 | dataTree:set_text("Data: " .. attribute_bytes) 729 | 730 | rtpTcpOffset = 0 731 | -- If it's TCP then apply 2 bytes of framing 732 | if f_tcp_srcport() ~= nil and f_tcp_dstport() ~= nil then 733 | if f_tcp_srcport().value or f_tcp_dstport().value then 734 | rtpTcpOffset = 2 735 | dataTree:add(F_stunname, tvbuffer(absolutePosition+4,2), cmd_str) 736 | :set_text("TCP Framing Bytes (2 Byte)") 737 | end 738 | end 739 | 740 | 741 | local datatype = tvbuffer(absolutePosition+4+rtpTcpOffset,1):uint() 742 | 743 | 744 | -- STUN CHECK 745 | stuncmdbyte = tvbuffer(absolutePosition+4+rtpTcpOffset,1):uint() 746 | stuncmd = tvbuffer(absolutePosition+4+rtpTcpOffset,2):uint() 747 | 748 | -- Check if encapsulated data is a STUN message 749 | if stuncmdbyte == 0x00 or stuncmdbyte == 0x01 then 750 | 751 | stuncmd_str = "unknown (Possible incorrect packet classification)" 752 | 753 | if stuncmd == 0x0001 then 754 | stuncmd_str = "STUN BINDING REQUEST" 755 | elseif stuncmd == 0x0101 then 756 | stuncmd_str = "STUN BINDING RESPONSE" 757 | elseif stuncmd == 0x0111 then 758 | stuncmd_str = "STUN BINDING ERROR RESPONSE" 759 | elseif stuncmd == 0x0011 then 760 | stuncmd_str = "STUN BINDING INDICATION" 761 | elseif stuncmd == 0x0002 then 762 | stuncmd_str = "STUN SHARED SECRET REQUEST - NOT SUPPORTED" 763 | elseif stuncmd == 0x0102 then 764 | stuncmd_str = "STUN SHARED SECRET RESPONSE - NOT SUPPORTED" 765 | elseif stuncmd == 0x0112 then 766 | stuncmd_str = "STUN SHARED SECRET ERROR RESPONSE - NOT SUPPORTED" 767 | elseif stuncmd == 0x0003 then 768 | stuncmd_str = "STUN ALLOCATE REQUEST" 769 | elseif stuncmd == 0x0103 then 770 | stuncmd_str = "STUN ALLOCATE RESPONSE" 771 | elseif stuncmd == 0x0113 then 772 | stuncmd_str = "STUN ALLOCATE ERROR RESPONSE" 773 | elseif stuncmd == 0x0004 then 774 | stuncmd_str = "STUN SEND REQUEST" 775 | elseif stuncmd == 0x0104 then 776 | stuncmd_str = "STUN REFRESH RESPONSE - NOT SUPPORTED" 777 | elseif stuncmd == 0x0114 then 778 | stuncmd_str = "STUN REFRESH ERROR RESPONSE - NOT SUPPORTED" 779 | elseif stuncmd == 0x0115 then 780 | stuncmd_str = "STUN DATA INDICATION" 781 | elseif stuncmd == 0x0006 then 782 | stuncmd_str = "STUN SET ACTIVE DESTINATION REQUEST" 783 | elseif stuncmd == 0x0016 then 784 | stuncmd_str = "STUN SEND INDICATION" 785 | elseif stuncmd == 0x0106 then 786 | stuncmd_str = "STUN SET ACTIVE DESTINATION RESPONSE" 787 | elseif stuncmd == 0x0116 then 788 | stuncmd_str = "STUN SET ACTIVE DESTINATION ERROR RESPONSE" 789 | elseif stuncmd == 0x0017 then 790 | stuncmd_str = "STUN DATA INDICATION" 791 | elseif stuncmd == 0x0008 then 792 | stuncmd_str = "STUN CREATE PERM REQUEST" 793 | elseif stuncmd == 0x0108 then 794 | stuncmd_str = "STUN CREATE PERM RESPONSE" 795 | elseif stuncmd == 0x0118 then 796 | stuncmd_str = "STUN CREATE_PERM ERROR RESPONSE" 797 | elseif stuncmd == 0x0009 then 798 | stuncmd_str = "STUN CHANNEL BIND REQUEST" 799 | elseif stuncmd == 0x0109 then 800 | stuncmd_str = "STUN CHANNEL BIND RESPONSE" 801 | elseif stuncmd == 0x0119 then 802 | stuncmd_str = "STUN CHANNEL BIND ERROR RESPONSE" 803 | end 804 | 805 | attribute_bytes = tostring(tvbuffer:range(absolutePosition+4+rtpTcpOffset,2)):upper() 806 | dataTree:add(F_stunname, tvbuffer(absolutePosition+4+rtpTcpOffset,2), attribute_bytes) 807 | :set_text("STUN Message: " .. "Command String: " .. stuncmd_str .. " (0x" .. attribute_bytes .. ")") 808 | 809 | attribute_length_int = tvbuffer(absolutePosition+6+rtpTcpOffset,2):uint() 810 | attribute_length = string.format("%i", tvbuffer(absolutePosition+6+rtpTcpOffset,2):uint()) 811 | dataTree:add(F_stunname, tvbuffer(absolutePosition+6+rtpTcpOffset,2), attribute_length) 812 | :set_text("Attribute Length: " .. attribute_length .. " Bytes") 813 | 814 | field1_val = tostring(tvbuffer:range(absolutePosition+8+rtpTcpOffset,4)):upper() 815 | dataTree:add(F_stunname, tvbuffer(absolutePosition+8+rtpTcpOffset,4), cmd_str) 816 | :set_text("Magic Cookie: " .. "0x" .. field1_val) 817 | 818 | field1_val = tostring(tvbuffer:range(absolutePosition+12+rtpTcpOffset,12)):upper() 819 | dataTree:add(F_stunname, tvbuffer(absolutePosition+12+rtpTcpOffset,12), cmd_str) 820 | :set_text("Transaction ID: 0x" .. field1_val) 821 | 822 | 823 | --Set the Protcol and Info Columns 824 | pinfo.cols.info = cmd_str .. " : Encapsulated Data = " .. stuncmd_str 825 | 826 | 827 | --Limited decoding of the rest of the encapsulated STUN request... 828 | offset2 = absolutePosition + 24 + rtpTcpOffset 829 | relativePosition2 = 0 830 | -- Start reading Attributes - look for microsoft extensions 831 | 832 | 833 | -- Attribute Loop 834 | while true do 835 | 836 | -- position in packet 837 | local absolutePosition2 = offset2 + relativePosition2 838 | 839 | -- Get the attribute 840 | local attribute2 = tvbuffer(absolutePosition2,2):uint() 841 | 842 | -- Check if it's a microsoft attribute 843 | local ms_attribute2 = tvbuffer(absolutePosition2,1):uint() 844 | 845 | -- Get the Length of the attribute 846 | local lengthOfCommand2 = tvbuffer(absolutePosition2+2,2):uint() 847 | 848 | -- Calculate the final position 849 | local finalPosition2 = absolutePosition2 + lengthOfCommand2 + 4 850 | 851 | 852 | 853 | --Non Microsoft Specific Attributes 854 | -- Defined in IETFDRAFT-STUN-02 855 | if attribute2 == 0x0001 then 856 | att_str2 = "Mapped Address" 857 | elseif attribute2 == 0x0006 then 858 | att_str2 = "Username" 859 | elseif attribute2 == 0x0008 then 860 | att_str2 = "Message Integrity" 861 | elseif attribute2 == 0x0009 then 862 | att_str2 = "Error Code" 863 | elseif attribute2 == 0x000A then 864 | att_str2 = "Unknown Attributes" 865 | elseif attribute2 == 0x000D then 866 | att_str2 = "Lifetime" 867 | elseif attribute2 == 0x000E then 868 | att_str2 = "Alternate Server" 869 | elseif attribute2 == 0x000F then 870 | att_str2 = "Magic Cookie" 871 | elseif attribute2 == 0x0010 then 872 | att_str2 = "Bandwidth" 873 | elseif attribute2 == 0x0011 then 874 | att_str2 = "Destination Address" 875 | elseif attribute2 == 0x0012 then 876 | att_str2 = "Remote Address" 877 | elseif attribute2 == 0x0013 then 878 | att_str2 = "Data" 879 | elseif attribute2 == 0x0014 then 880 | att_str2 = "Nonce" 881 | elseif attribute2 == 0x0015 then 882 | att_str2 = "Realm" 883 | elseif attribute2 == 0x0017 then 884 | att_str2 = "Requested Address Family" 885 | elseif attribute2 == 0x0020 then 886 | att_str2 = "XOR Mapped Address" 887 | elseif attribute2 == 0x0024 then 888 | att_str2 = "Priority (RFC5245)" 889 | elseif attribute2 == 0x0025 then 890 | att_str2 = "Use-Candidate (RFC5245)" 891 | -- Microsoft Specific Attributes for STUN 892 | elseif attribute2 == 0x8008 then 893 | att_str2 = "MS-Version" 894 | elseif attribute2 == 0x8006 then 895 | att_str2 = "MS-Attribute" 896 | elseif attribute2 == 0x8020 then 897 | att_str2 = "XOR Mapped Address" 898 | elseif attribute2 == 0x8022 then 899 | att_str2 = "Software (RFC5389)" 900 | elseif attribute2 == 0x8023 then 901 | att_str2 = "Alternate-Server (RFC5389)" 902 | elseif attribute2 == 0x8028 then 903 | att_str2 = "Fingerprint (RFC5389)" 904 | elseif attribute2 == 0x8029 then 905 | att_str2 = "Ice Controlled (ICE-19)" 906 | elseif attribute2 == 0x802A then 907 | att_str2 = "Ice Controlling (ICE-19)" 908 | elseif attribute2 == 0x8050 then 909 | att_str2 = "MS-Sequence Number" 910 | elseif attribute2 == 0x8054 then 911 | att_str2 = "Candidate Identifier" 912 | elseif attribute2 == 0x8055 then 913 | att_str2 = "MS-Service Quality" 914 | elseif attribute2 == 0x8056 then 915 | att_str2 = "Bandwidth Admission Control Message" 916 | elseif attribute2 == 0x8057 then 917 | att_str2 = "Bandwidth Reservation Identifier" 918 | elseif attribute2 == 0x8058 then 919 | att_str2 = "Bandwidth Reservation Amount" 920 | elseif attribute2 == 0x8059 then 921 | att_str = "Remote Site Address" 922 | elseif attribute2 == 0x805A then 923 | att_str2 = "Remote Relay Site Address" 924 | elseif attribute2 == 0x805B then 925 | att_str2 = "Local Site Address" 926 | elseif attribute2 == 0x805C then 927 | att_str2 = "Local Relay Site Address" 928 | elseif attribute2 == 0x805D then 929 | att_str2 = "Remote Site Address Response" 930 | elseif attribute2 == 0x805E then 931 | att_str2 = "Remote Relay Site Address Response" 932 | elseif attribute2 == 0x805F then 933 | att_str2 = "Local Site Address Response" 934 | elseif attribute2 == 0x8060 then 935 | att_str2 = "Local Relay Site Address Response" 936 | elseif attribute2 == 0x8061 then 937 | att_str2 = "SIP Dialog Identifier" 938 | elseif attribute2 == 0x8062 then 939 | att_str2 = "SIP Call Identifier" 940 | elseif attribute2 == 0x8068 then 941 | att_str2 = "Location Profile" 942 | elseif attribute2 == 0x8070 then 943 | att_str2 = "Implementation Version" 944 | elseif attribute2 == 0x8090 then 945 | att_str2 = "MS-Alternate Mapped Address" 946 | else 947 | att_str2 = "Error: No Match (Possible incorrect packet classification)" 948 | 949 | end 950 | 951 | attribute_val2 = tostring(bit.tohex(tvbuffer(absolutePosition2,2):uint(),4)):upper() 952 | attributeTree2 = dataTree:add(F_attribute, tvbuffer(absolutePosition2,lengthOfCommand2+4), attribute_val2) 953 | attributeTree2:set_text("Data Attribute: 0x" .. attribute_val2 .. " (" .. att_str2 .. ")") 954 | 955 | attribute_length2Int = tvbuffer(absolutePosition2+2,2):uint() 956 | attribute_length2 = string.format("%i", tvbuffer(absolutePosition2+2,2):uint()) 957 | attributeTree2:add(F_attribute_sub, tvbuffer(absolutePosition2+2,2), attribute_length2) 958 | :set_text("Data Attribute Length: " .. attribute_length2 .. " Bytes") 959 | 960 | attributeTree2:add(F_attribute_sub, tvbuffer(absolutePosition2+4, attribute_length2Int) , cmd_str) 961 | :set_text("Data: 0x" .. tostring( tvbuffer(absolutePosition2+4,attribute_length2Int))) 962 | 963 | -- If the length of the attribute is 00 then assume there is an error and break loop 964 | if lengthOfCommand2 == 0x0000 then 965 | attributeTree2:add(F_attribute_sub, tvbuffer(absolutePosition2+2,2), attribute_length2) 966 | :set_text("Error with data length value") 967 | break 968 | end 969 | 970 | -- If the length of the attribute is longer than the packet length then assume there is an error and break loop 971 | if lengthOfCommand2 > attribute_length2Int then 972 | attributeTree2:add(F_attribute_sub, tvbuffer(absolutePosition2+2,2), attribute_length2) 973 | :set_text("Error with data length value") 974 | break 975 | end 976 | 977 | -- attribute_length_int 978 | if finalPosition2 >= (attribute_length_int + absolutePosition + 24 + rtpTcpOffset) then 979 | break 980 | end 981 | relativePosition2 = finalPosition2 - offset2 982 | end 983 | end 984 | 985 | 986 | 987 | -- RTP CHECK 988 | -- Check Data payload starts with 80 or 81 or 82 and assume RTP. This method whilst not ideal works in majority of cases with Lync. 989 | if datatype == 128 or datatype == 129 or datatype == 130 then 990 | 991 | attribute_bytes = tostring(tvbuffer:range(absolutePosition+5+rtpTcpOffset,1)):upper() 992 | dataTree:add(F_stunname, tvbuffer(absolutePosition+5+rtpTcpOffset,1), attribute_bytes) 993 | :set_text("RTP Message: " .. "(0x" .. attribute_bytes .. ")") 994 | 995 | 996 | local bits = tvbuffer(absolutePosition+4+rtpTcpOffset,1):uint() 997 | 998 | payload = bit.rshift(bit.band(bits,0xC0),6) 999 | 1000 | att_str = "RTP PAYLOAD TYPE" 1001 | if payload == 1 then 1002 | att_str = "Version 1" 1003 | elseif payload == 2 then 1004 | att_str = "Version 2" 1005 | end 1006 | dataTree:add(F_attribute_sub, tvbuffer(absolutePosition+4+rtpTcpOffset,1), cmd_str) 1007 | :set_text("RTP Version: " .. att_str .. " (" .. tostring(payload) .. ")") 1008 | 1009 | dataTree:add(F_attribute_sub, tvbuffer(absolutePosition+4+rtpTcpOffset,1), cmd_str) 1010 | :set_text("padding: 0x" .. tostring(bit.tohex((bit.band(bits,0x20)),2))) 1011 | 1012 | dataTree:add(F_attribute_sub, tvbuffer(absolutePosition+4+rtpTcpOffset,1), cmd_str) 1013 | :set_text("Extension: 0x" .. tostring(bit.tohex((bit.band(bits,0x10)),2))) 1014 | 1015 | local byte = tvbuffer(absolutePosition+4+rtpTcpOffset,1):uint() 1016 | 1017 | dataTree:add(F_attribute_sub, tvbuffer(absolutePosition+5+rtpTcpOffset,1), cmd_str) 1018 | :set_text("CSRC count: 0x" .. tostring(bit.tohex((bit.band(bits,0x0F)),2))) 1019 | 1020 | local byte = tvbuffer(absolutePosition+5+rtpTcpOffset,1):uint() 1021 | 1022 | dataTree:add(F_attribute_sub, tvbuffer(absolutePosition+5+rtpTcpOffset,1), cmd_str) 1023 | :set_text("Marker: 0x" .. tostring(bit.tohex((bit.band(byte,0x80)),2))) 1024 | 1025 | -- RTP Check 1026 | payload = bit.band(byte,0x7F) 1027 | 1028 | -- RTCP Check 1029 | rtcppayload = bit.band(byte,0xFF) 1030 | 1031 | att_str = "RTP PAYLOAD TYPE" 1032 | if payload == 0 then 1033 | att_str = "G.711 u-Law" 1034 | elseif payload == 3 then 1035 | att_str = "GSM 6.10" 1036 | elseif payload == 4 then 1037 | att_str = "G.723.1 " 1038 | elseif payload == 8 then 1039 | att_str = "G.711 A-Law" 1040 | elseif payload == 9 or payload == 117 then 1041 | att_str = "G.722" 1042 | elseif payload == 13 then 1043 | att_str = "Comfort Noise" 1044 | elseif payload == 97 then 1045 | att_str = "Redundant Audio Data Payload (FEC)" 1046 | elseif payload == 101 then 1047 | att_str = "DTMF" 1048 | elseif payload == 103 then 1049 | att_str = "SILK Narrowband" 1050 | elseif payload == 104 then 1051 | att_str = "SILK Wideband" 1052 | elseif payload == 111 then 1053 | att_str = "Siren" 1054 | elseif payload == 112 then 1055 | att_str = "G.722.1" 1056 | elseif payload == 114 then 1057 | att_str = "RT Audio Wideband" 1058 | elseif payload == 115 then 1059 | att_str = "RT Audio Narrowband" 1060 | elseif payload == 116 then 1061 | att_str = "G.726" 1062 | elseif payload == 118 then 1063 | att_str = "Comfort Noise Wideband" 1064 | elseif payload == 34 then 1065 | att_str = "H.263 [MS-H26XPF]" 1066 | elseif payload == 121 then 1067 | att_str = "RT Video" 1068 | elseif payload == 122 then 1069 | att_str = "H.264 [MS-H264PF]" 1070 | elseif payload == 123 then 1071 | att_str = "H.264 FEC [MS-H264PF]" 1072 | elseif payload == 127 then 1073 | att_str = "x-data (Content Sharing)" 1074 | elseif payload == 200 then 1075 | att_str = "RTCP PACKET SENDER" 1076 | elseif payload == 201 then 1077 | att_str = "RTCP PACKET RECEIVER" 1078 | elseif payload == 202 then 1079 | att_str = "RTCP Source Description" 1080 | elseif payload == 203 then 1081 | att_str = "RTCP Bye" 1082 | elseif rtcppayload == 0xC8 then 1083 | att_str = "RTCP PACKET SENDER" -- The RTP frame header is slightly different than RTCP. So the decoding is not perfect here. 1084 | elseif rtcppayload == 0xC9 then 1085 | att_str = "RTCP PACKET RECEIVER" -- The RTP frame header is slightly different than RTCP. So the decoding is not perfect here. 1086 | else 1087 | att_str = "Unknown Codec (Possible incorrect packet classification)" 1088 | 1089 | --IF IT'S ON PORT 443 THEN ASSUME THEN TRY THE TLS DECODER 1090 | if f_tcp_srcport() ~= nil and f_tcp_dstport() ~= nil then 1091 | if f_tcp_srcport().value == 443 or f_tcp_dstport().value == 443 then 1092 | original_ssl_dissector:call(tvbuffer, pinfo, treeitem) --DECODE AS TLS 1093 | end 1094 | end 1095 | end 1096 | 1097 | 1098 | dataTree:add(F_attribute_sub, tvbuffer(absolutePosition+5+rtpTcpOffset,1), cmd_str) 1099 | :set_text("Payload Type: " .. att_str .. " (" .. tostring(payload) .. ")") 1100 | 1101 | --Set the Protcol and Info Columns 1102 | pinfo.cols.info = cmd_str .. " : Encapsulated Data = Payload Type " .. att_str 1103 | 1104 | dataTree:add(F_attribute_sub, tvbuffer(absolutePosition+6+rtpTcpOffset,lengthOfCommand-(6+rtpTcpOffset)), cmd_str) 1105 | :set_text("Encapsulated Payload Data: " .. tostring(tvbuffer(absolutePosition+6+rtpTcpOffset,lengthOfCommand-(6+rtpTcpOffset)))) 1106 | end 1107 | 1108 | elseif attribute == 0x0014 then 1109 | --att_str = "Nonce" 1110 | 1111 | attribute_bytes = tostring(tvbuffer:range(absolutePosition+4,lengthOfCommand)) 1112 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,lengthOfCommand), attribute_length) 1113 | :set_text("Nonce: 0x" .. attribute_bytes) 1114 | 1115 | elseif attribute == 0x0015 then 1116 | --att_str = "Realm" 1117 | 1118 | -- Convert to ASCII 1119 | local asc = "" 1120 | for i = absolutePosition+4, absolutePosition+4+lengthOfCommand-1 do 1121 | local c = tvbuffer(i,1):uint() 1122 | asc = string.format("%s%c", asc, c) 1123 | end 1124 | 1125 | attribute_bytes = tostring(tvbuffer:range(absolutePosition+4,lengthOfCommand)) 1126 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,lengthOfCommand), attribute_length) 1127 | :set_text("Realm: " .. asc .. " (0x" .. attribute_bytes .. ")") 1128 | 1129 | elseif attribute == 0x0017 then 1130 | --att_str = "Requested Address Family" 1131 | 1132 | fam_type = tvbuffer(absolutePosition+4,1):uint() 1133 | 1134 | if fam_type == 0x01 then 1135 | att_str = "IPv4" 1136 | att_bytes = "0x01" 1137 | elseif fam_type == 0x02 then 1138 | att_str = "IPv6" 1139 | att_bytes = "0x02" 1140 | end 1141 | 1142 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,1), attribute_length) 1143 | :set_text("Family: " .. att_str .. " (" .. att_bytes .. ")") 1144 | 1145 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+5,3):uint()) 1146 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+5,3), attribute_length) 1147 | :set_text("Reserved " .. attribute_bytes) 1148 | 1149 | elseif attribute == 0x0020 then 1150 | --att_str = "XOR Mapped Address" from rfc5389 1151 | 1152 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+4,1):uint()) 1153 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,1), attribute_length) 1154 | :set_text("Reserved " .. attribute_bytes) 1155 | 1156 | fam_type = tvbuffer(absolutePosition+5,1):uint() 1157 | 1158 | if fam_type == 0x01 then 1159 | att_str = "IPv4" 1160 | att_bytes = "0x01" 1161 | elseif fam_type == 0x02 then 1162 | att_str = "IPv6" 1163 | att_bytes = "0x02" 1164 | end 1165 | 1166 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+5,1), attribute_length) 1167 | :set_text("Family: " .. att_str .. " (" .. att_bytes .. ")") 1168 | 1169 | 1170 | transaction_id_port = tvbuffer(4+tcpOffset,2):uint() 1171 | xport = tvbuffer(absolutePosition+6,2):uint() 1172 | port = bit.bxor(transaction_id_port, xport) 1173 | 1174 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+6,2):uint()) 1175 | portstring = string.format("%i", port) 1176 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+6,2), attribute_length) 1177 | :set_text("X-Port: " .. portstring .. " " .. attribute_bytes) 1178 | 1179 | 1180 | if fam_type == 0x01 then 1181 | 1182 | oct1 = tvbuffer(4+tcpOffset,1):uint() 1183 | xip1 = tvbuffer(absolutePosition+8,1):uint() 1184 | ip1 = bin_xor(oct1,xip1) 1185 | 1186 | oct2 = tvbuffer(5+tcpOffset,1):uint() 1187 | xip2 = tvbuffer(absolutePosition+9,1):uint() 1188 | ip2 = bin_xor(oct2, xip2) 1189 | 1190 | oct3 = tvbuffer(6+tcpOffset,1):uint() 1191 | xip3 = tvbuffer(absolutePosition+10,1):uint() 1192 | ip3 = bin_xor(oct3, xip3) 1193 | 1194 | oct4 = tvbuffer(7+tcpOffset,1):uint() 1195 | xip4 = tvbuffer(absolutePosition+11,1):uint() 1196 | ip4 = bin_xor(oct4, xip4) 1197 | 1198 | ip1string = string.format("%i", ip1) 1199 | ip2string = string.format("%i", ip2) 1200 | ip3string = string.format("%i", ip3) 1201 | ip4string = string.format("%i", ip4) 1202 | 1203 | 1204 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+8,4):uint()) 1205 | 1206 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+8,4), attribute_length) 1207 | :set_text("X-Address-IPv4: " .. ip1string .. "." .. ip2string .. "." .. ip3string .. "." .. ip4string .. " " .. attribute_bytes) 1208 | 1209 | elseif fam_type == 0x02 then 1210 | -- Not decoding IPv6 fully yet. 1211 | attribute_bytes = tostring(tvbuffer:range(absolutePosition+8,16)) 1212 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+8,16), attribute_length) 1213 | :set_text("X-Address_IPv6: 0x" .. attribute_bytes) 1214 | end 1215 | 1216 | elseif attribute == 0x0024 then 1217 | --att_str = "Priority" 1218 | attribute_bytes = tostring(tvbuffer:range(absolutePosition+4,lengthOfCommand)) 1219 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,lengthOfCommand), attribute_length) 1220 | :set_text("Priority: 0x" .. attribute_bytes) 1221 | 1222 | 1223 | elseif attribute == 0x0025 then 1224 | --att_str = "Use Candidate" 1225 | attribute_bytes = tostring(tvbuffer:range(absolutePosition+4,lengthOfCommand)) 1226 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,lengthOfCommand), attribute_length) 1227 | :set_text("Use Candidate: 0x" .. attribute_bytes) 1228 | 1229 | end 1230 | 1231 | end 1232 | if ms_attribute == 0x80 then 1233 | -- Microsoft Specific Attributes for STUN 1234 | att_str = "unknown 0x80XX (Possible incorrect packet classification)" 1235 | if attribute == 0x8008 then 1236 | att_str = "MS-Version" 1237 | elseif attribute == 0x8006 then 1238 | att_str = "MS-Attribute" 1239 | elseif attribute == 0x8020 then 1240 | att_str = "XOR Mapped Address" 1241 | elseif attribute == 0x8022 then 1242 | att_str = "Software (RFC5389)" 1243 | elseif attribute == 0x8023 then 1244 | att_str = "Alternate-Server (RFC5389)" 1245 | elseif attribute == 0x8028 then 1246 | att_str = "Fingerprint (RFC5389)" 1247 | elseif attribute == 0x8029 then 1248 | att_str = "Ice Controlled (ICE-19)" 1249 | elseif attribute == 0x802A then 1250 | att_str = "Ice Controlling (ICE-19)" 1251 | elseif attribute == 0x8050 then 1252 | att_str = "MS-Sequence Number" 1253 | elseif attribute == 0x8054 then 1254 | att_str = "Candidate Identifier" 1255 | elseif attribute == 0x8055 then 1256 | att_str = "MS-Service Quality" 1257 | elseif attribute == 0x8056 then 1258 | att_str = "Bandwidth Admission Control Message" 1259 | elseif attribute == 0x8057 then 1260 | att_str = "Bandwidth Reservation Identifier" 1261 | elseif attribute == 0x8058 then 1262 | att_str = "Bandwidth Reservation Amount" 1263 | elseif attribute == 0x8059 then 1264 | att_str = "Remote Site Address" 1265 | elseif attribute == 0x805A then 1266 | att_str = "Remote Relay Site Address" 1267 | elseif attribute == 0x805B then 1268 | att_str = "Local Site Address" 1269 | elseif attribute == 0x805C then 1270 | att_str = "Local Relay Site Address" 1271 | elseif attribute == 0x805D then 1272 | att_str = "Remote Site Address Response" 1273 | elseif attribute == 0x805E then 1274 | att_str = "Remote Relay Site Address Response" 1275 | elseif attribute == 0x805F then 1276 | att_str = "Local Site Address Response" 1277 | elseif attribute == 0x8060 then 1278 | att_str = "Local Relay Site Address Response" 1279 | elseif attribute == 0x8061 then 1280 | att_str = "SIP Dialog Identifier" 1281 | elseif attribute == 0x8062 then 1282 | att_str = "SIP Call Identifier" 1283 | elseif attribute == 0x8068 then 1284 | att_str = "Location Profile" 1285 | elseif attribute == 0x8070 then 1286 | att_str = "Implementation Version" 1287 | elseif attribute == 0x8090 then 1288 | att_str = "MS-Alternate Mapped Address" 1289 | end 1290 | 1291 | 1292 | attribute_val = string.format("0x%X", tvbuffer(absolutePosition,2):uint()) 1293 | attributeTree = subtreeitem:add(F_attribute, tvbuffer(absolutePosition,lengthOfCommand+4), attribute_val) 1294 | attributeTree:set_text("Attribute: " .. attribute_val .. " (" .. att_str .. ")") 1295 | 1296 | 1297 | attribute_length = string.format("%i", tvbuffer(absolutePosition+2,2):uint()) 1298 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+2,2), attribute_length) 1299 | :set_text("Attribute Length: " .. attribute_length .. " Bytes") 1300 | 1301 | 1302 | if attribute == 0x8008 then 1303 | --att_str = "MS-Version" 1304 | msg_type = tvbuffer(absolutePosition+4,4):uint() 1305 | 1306 | if msg_type == 0x00000001 then 1307 | att_str = "[MS-ICE]" 1308 | att_bytes = "0x00000001" 1309 | elseif msg_type == 0x00000002 then 1310 | att_str = "[MS-ICE2]" 1311 | att_bytes = "0x00000002" 1312 | elseif msg_type == 0x00000003 then 1313 | att_str = "[MS-ICE2] with support for HMACSHA-256" 1314 | att_bytes = "0x00000003" 1315 | elseif msg_type == 0x00000004 then 1316 | att_str = "[MS-ICE2] with support for HMACSHA-256 and IPv6" 1317 | att_bytes = "0x00000004" 1318 | end 1319 | 1320 | attribute_bytes = tostring(bit.tohex(tvbuffer(absolutePosition+4,4):uint(),4)) 1321 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,4), attribute_length) 1322 | :set_text("Version: " .. att_str .. " (" .. att_bytes .. ")") 1323 | 1324 | elseif attribute == 0x8006 then 1325 | --att_str = "MS-Attribute" 1326 | 1327 | attribute_bytes = tostring(bit.tohex(tvbuffer(absolutePosition+4,4):uint(),8)) 1328 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,4), attribute_length) 1329 | :set_text("Bytes: 0x" .. attribute_bytes) 1330 | 1331 | elseif attribute == 0x8020 then 1332 | --att_str = "XOR Mapped Address" http://msdn.microsoft.com/en-us/library/dd909268(v=office.12).aspx 1333 | 1334 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+4,1):uint()) 1335 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,1), attribute_length) 1336 | :set_text("Reserved " .. attribute_bytes) 1337 | 1338 | fam_type = tvbuffer(absolutePosition+5,1):uint() 1339 | 1340 | if fam_type == 0x01 then 1341 | att_str = "IPv4" 1342 | att_bytes = "0x01" 1343 | elseif fam_type == 0x02 then 1344 | att_str = "IPv6" 1345 | att_bytes = "0x02" 1346 | end 1347 | 1348 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+5,1), attribute_length) 1349 | :set_text("Family: " .. att_str .. " (" .. att_bytes .. ")") 1350 | 1351 | 1352 | transaction_id_port = tvbuffer(4+tcpOffset,2):uint() 1353 | xport = tvbuffer(absolutePosition+6,2):uint() 1354 | port = bit.bxor(transaction_id_port, xport) 1355 | 1356 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+6,2):uint()) 1357 | portstring = string.format("%i", port) 1358 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+6,2), attribute_length) 1359 | :set_text("X-Port: " .. portstring .. " " .. attribute_bytes) 1360 | 1361 | 1362 | if fam_type == 0x01 then 1363 | 1364 | oct1 = tvbuffer(4+tcpOffset,1):uint() 1365 | xip1 = tvbuffer(absolutePosition+8,1):uint() 1366 | ip1 = bin_xor(oct1,xip1) 1367 | 1368 | oct2 = tvbuffer(5+tcpOffset,1):uint() 1369 | xip2 = tvbuffer(absolutePosition+9,1):uint() 1370 | ip2 = bin_xor(oct2, xip2) 1371 | 1372 | oct3 = tvbuffer(6+tcpOffset,1):uint() 1373 | xip3 = tvbuffer(absolutePosition+10,1):uint() 1374 | ip3 = bin_xor(oct3, xip3) 1375 | 1376 | oct4 = tvbuffer(7+tcpOffset,1):uint() 1377 | xip4 = tvbuffer(absolutePosition+11,1):uint() 1378 | ip4 = bin_xor(oct4, xip4) 1379 | 1380 | ip1string = string.format("%i", ip1) 1381 | ip2string = string.format("%i", ip2) 1382 | ip3string = string.format("%i", ip3) 1383 | ip4string = string.format("%i", ip4) 1384 | 1385 | 1386 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+8,4):uint()) 1387 | 1388 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+8,4), attribute_length) 1389 | :set_text("X-Address-IPv4: " .. ip1string .. "." .. ip2string .. "." .. ip3string .. "." .. ip4string .. " " .. attribute_bytes) 1390 | 1391 | elseif fam_type == 0x02 then 1392 | -- Not decoding IPv6 fully yet. 1393 | attribute_bytes = tostring(tvbuffer:range(absolutePosition+8,16)) 1394 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+8,16), attribute_length) 1395 | :set_text("X-Address_IPv6: 0x" .. attribute_bytes) 1396 | end 1397 | 1398 | elseif attribute == 0x8028 then 1399 | --att_str = "Fingerprint" 1400 | attribute_bytes = tostring(tvbuffer:range(absolutePosition+4,lengthOfCommand)) 1401 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,lengthOfCommand), attribute_length) 1402 | :set_text("Fingerprint: 0x" .. attribute_bytes) 1403 | 1404 | 1405 | elseif attribute == 0x8029 then 1406 | --att_str = "ICE Controlled" 1407 | attribute_bytes = tostring(tvbuffer:range(absolutePosition+4,lengthOfCommand)) 1408 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,lengthOfCommand), attribute_length) 1409 | :set_text("ICE Controlled: 0x" .. attribute_bytes) 1410 | 1411 | 1412 | elseif attribute == 0x802A then 1413 | --att_str = "ICE Controlling" 1414 | attribute_bytes = tostring(tvbuffer:range(absolutePosition+4,lengthOfCommand)) 1415 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,lengthOfCommand), attribute_length) 1416 | :set_text("ICE Controlling: 0x" .. attribute_bytes) 1417 | 1418 | elseif attribute == 0x8054 then 1419 | --att_str = "Candidate Identifier" 1420 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+4,4):uint()) 1421 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,4), attribute_length) 1422 | :set_text("Foundation: " .. attribute_bytes) 1423 | 1424 | 1425 | 1426 | elseif attribute == 0x8050 then 1427 | --att_str = "MS-Sequence Number" http://msdn.microsoft.com/en-us/library/dd925584(v=office.12).aspx 1428 | 1429 | attribute_bytes = tostring(tvbuffer:range(absolutePosition+4,20)) 1430 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,20), attribute_length) 1431 | :set_text("Conenction ID: 0x" .. attribute_bytes) 1432 | 1433 | 1434 | attribute_reserved = string.format("(0x%X)", tvbuffer(absolutePosition+24,4):uint()) 1435 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+24,4), attribute_length) 1436 | :set_text("Sequence Number: " .. attribute_reserved) 1437 | 1438 | elseif attribute == 0x8055 then 1439 | --att_str = "MS-Service Quality" http://msdn.microsoft.com/en-us/library/dd949836(v=office.12).aspx 1440 | 1441 | msg_type = tvbuffer(absolutePosition+4,2):uint() 1442 | 1443 | if msg_type == 0x0001 then 1444 | att_str = "Audio" 1445 | att_bytes = "(0x0001)" 1446 | elseif msg_type == 0x0002 then 1447 | att_str = "Video" 1448 | att_bytes = "(0x0002)" 1449 | elseif msg_type == 0x0003 then 1450 | att_str = "Supplemental Video" 1451 | att_bytes = "(0x0003)" 1452 | elseif msg_type == 0x0004 then 1453 | att_str = "Data" 1454 | att_bytes = "(0x0004)" 1455 | else 1456 | att_str = "Unknown (Possible incorrect packet classification)" 1457 | att_bytes = "" 1458 | end 1459 | 1460 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+4,2):uint()) 1461 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,2), attribute_length) 1462 | :set_text("Stream Type: " .. att_str .. " " .. att_bytes) 1463 | 1464 | msg_type = tvbuffer(absolutePosition+6,2):uint() 1465 | 1466 | if msg_type == 0x0000 then 1467 | att_str = "Best Effort" 1468 | att_bytes = "(0x0000)" 1469 | elseif msg_type == 0x0001 then 1470 | att_str = "Reliable Delivery" 1471 | att_bytes = "(0x0001)" 1472 | else 1473 | att_str = "Unknown (Possible incorrect packet classification)" 1474 | att_bytes = "" 1475 | end 1476 | 1477 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+6,2):uint()) 1478 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+6,2), attribute_length) 1479 | :set_text("Quality Level: " .. att_str .. " " .. att_bytes) 1480 | 1481 | 1482 | elseif attribute == 0x8056 then 1483 | -- att_str = Bandwidth Admission Control Message 1484 | 1485 | attribute_reserved = string.format("(0x%X)", tvbuffer(absolutePosition+4,2):uint()) 1486 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,2), attribute_length) 1487 | :set_text("Reserved: " .. attribute_reserved) 1488 | 1489 | msg_type = tvbuffer(absolutePosition+6,2):uint() 1490 | if msg_type == 0x0000 then 1491 | att_str = "Reservation Check" 1492 | att_bytes = "0x0000" 1493 | elseif msg_type == 0x0001 then 1494 | att_str = "Reservation Commit" 1495 | att_bytes = "0x0001" 1496 | elseif msg_type == 0x0002 then 1497 | att_str = "Reservation Update" 1498 | att_bytes = "0x0002" 1499 | else 1500 | att_str = "Unknown (Possible incorrect packet classification)" 1501 | att_bytes = "" 1502 | end 1503 | 1504 | attribute_type = string.format("(0x%X)", tvbuffer(absolutePosition+6,2):uint()) 1505 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+6,2), att_str) 1506 | :set_text("Message Type: " .. att_str .. " (" .. att_bytes .. ")") 1507 | 1508 | elseif attribute == 0x8057 then 1509 | -- att_str = Bandwidth Reservation Identifier 1510 | 1511 | attribute_bytes = tostring(tvbuffer:range(absolutePosition+4,16)) 1512 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,16), attribute_length) 1513 | :set_text("Reservation Id: 0x" .. attribute_bytes) 1514 | 1515 | elseif attribute == 0x8058 then 1516 | -- att_str = Bandwidth Reservation Amount 1517 | 1518 | attribute_bytes = string.format("%i", tvbuffer(absolutePosition+4,4):uint()) 1519 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,4), attribute_length) 1520 | :set_text("Minimum Send Bandwidth: " .. attribute_bytes .. "kbps") 1521 | 1522 | attribute_bytes = string.format("%i", tvbuffer(absolutePosition+8,4):uint()) 1523 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+8,4), attribute_length) 1524 | :set_text("Maximum Send Bandwidth: " .. attribute_bytes .. "kbps") 1525 | 1526 | attribute_bytes = string.format("%i", tvbuffer(absolutePosition+12,4):uint()) 1527 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+12,4), attribute_length) 1528 | :set_text("Minimum Receive Bandwidth: " .. attribute_bytes .. "kbps") 1529 | 1530 | attribute_bytes = string.format("%i", tvbuffer(absolutePosition+16,4):uint()) 1531 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+16,4), attribute_length) 1532 | :set_text("Maximum Receive Bandwidth: " .. attribute_bytes .. "kbps") 1533 | 1534 | elseif attribute == 0x8059 then 1535 | -- att_str = Remote Site Address 1536 | 1537 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+4,1):uint()) 1538 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,1), attribute_length) 1539 | :set_text("Reserved " .. attribute_bytes) 1540 | 1541 | fam_type = tvbuffer(absolutePosition+5,1):uint() 1542 | 1543 | if fam_type == 0x01 then 1544 | att_str = "IPv4" 1545 | att_bytes = "0x01" 1546 | elseif fam_type == 0x02 then 1547 | att_str = "IPv6" 1548 | att_bytes = "0x02" 1549 | end 1550 | 1551 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+5,1), attribute_length) 1552 | :set_text("Family: " .. att_str .. " (" .. att_bytes .. ")") 1553 | 1554 | 1555 | transaction_id_port = tvbuffer(4+tcpOffset,2):uint() 1556 | xport = tvbuffer(absolutePosition+6,2):uint() 1557 | port = bit.bxor(transaction_id_port, xport) 1558 | 1559 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+6,2):uint()) 1560 | portstring = string.format("%i", port) 1561 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+6,2), attribute_length) 1562 | :set_text("X-Port: " .. portstring .. " " .. attribute_bytes) 1563 | 1564 | 1565 | if fam_type == 0x01 then 1566 | 1567 | oct1 = tvbuffer(4+tcpOffset,1):uint() 1568 | xip1 = tvbuffer(absolutePosition+8,1):uint() 1569 | ip1 = bin_xor(oct1,xip1) 1570 | 1571 | oct2 = tvbuffer(5+tcpOffset,1):uint() 1572 | xip2 = tvbuffer(absolutePosition+9,1):uint() 1573 | ip2 = bin_xor(oct2, xip2) 1574 | 1575 | oct3 = tvbuffer(6+tcpOffset,1):uint() 1576 | xip3 = tvbuffer(absolutePosition+10,1):uint() 1577 | ip3 = bin_xor(oct3, xip3) 1578 | 1579 | oct4 = tvbuffer(7+tcpOffset,1):uint() 1580 | xip4 = tvbuffer(absolutePosition+11,1):uint() 1581 | ip4 = bin_xor(oct4, xip4) 1582 | 1583 | ip1string = string.format("%i", ip1) 1584 | ip2string = string.format("%i", ip2) 1585 | ip3string = string.format("%i", ip3) 1586 | ip4string = string.format("%i", ip4) 1587 | 1588 | 1589 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+8,4):uint()) 1590 | 1591 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+8,4), attribute_length) 1592 | :set_text("X-Address-IPv4: " .. ip1string .. "." .. ip2string .. "." .. ip3string .. "." .. ip4string .. " " .. attribute_bytes) 1593 | 1594 | elseif fam_type == 0x02 then 1595 | -- Not decoding IPv6 fully yet. 1596 | attribute_bytes = tostring(tvbuffer:range(absolutePosition+8,16)) 1597 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+8,16), attribute_length) 1598 | :set_text("X-Address_IPv6: 0x" .. attribute_bytes) 1599 | end 1600 | 1601 | 1602 | elseif attribute == 0x805A then 1603 | -- att_str = Remote Relay Site Address 1604 | 1605 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+4,1):uint()) 1606 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,1), attribute_length) 1607 | :set_text("Reserved " .. attribute_bytes) 1608 | 1609 | fam_type = tvbuffer(absolutePosition+5,1):uint() 1610 | 1611 | if fam_type == 0x01 then 1612 | att_str = "IPv4" 1613 | att_bytes = "0x01" 1614 | elseif fam_type == 0x02 then 1615 | att_str = "IPv6" 1616 | att_bytes = "0x02" 1617 | end 1618 | 1619 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+5,1), attribute_length) 1620 | :set_text("Family: " .. att_str .. " (" .. att_bytes .. ")") 1621 | 1622 | --transaction_id = tvbuffer(51,63) 1623 | 1624 | transaction_id_port = tvbuffer(4+tcpOffset,2):uint() 1625 | xport = tvbuffer(absolutePosition+6,2):uint() 1626 | port = bit.bxor(transaction_id_port, xport) 1627 | 1628 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+6,2):uint()) 1629 | portstring = string.format("%i", port) 1630 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+6,2), attribute_length) 1631 | :set_text("X-Port: " .. portstring .. " " .. attribute_bytes) 1632 | 1633 | 1634 | if fam_type == 0x01 then 1635 | 1636 | oct1 = tvbuffer(4+tcpOffset,1):uint() 1637 | xip1 = tvbuffer(absolutePosition+8,1):uint() 1638 | ip1 = bin_xor(oct1,xip1) 1639 | 1640 | oct2 = tvbuffer(5+tcpOffset,1):uint() 1641 | xip2 = tvbuffer(absolutePosition+9,1):uint() 1642 | ip2 = bin_xor(oct2, xip2) 1643 | 1644 | oct3 = tvbuffer(6+tcpOffset,1):uint() 1645 | xip3 = tvbuffer(absolutePosition+10,1):uint() 1646 | ip3 = bin_xor(oct3, xip3) 1647 | 1648 | oct4 = tvbuffer(7+tcpOffset,1):uint() 1649 | xip4 = tvbuffer(absolutePosition+11,1):uint() 1650 | ip4 = bin_xor(oct4, xip4) 1651 | 1652 | ip1string = string.format("%i", ip1) 1653 | ip2string = string.format("%i", ip2) 1654 | ip3string = string.format("%i", ip3) 1655 | ip4string = string.format("%i", ip4) 1656 | 1657 | 1658 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+8,4):uint()) 1659 | 1660 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+8,4), attribute_length) 1661 | :set_text("X-Address-IPv4: " .. ip1string .. "." .. ip2string .. "." .. ip3string .. "." .. ip4string .. " " .. attribute_bytes) 1662 | 1663 | elseif fam_type == 0x02 then 1664 | -- Not decoding IPv6 fully yet. 1665 | attribute_bytes = tostring(tvbuffer:range(absolutePosition+8,16)) 1666 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+8,16), attribute_length) 1667 | :set_text("X-Address_IPv6: 0x" .. attribute_bytes) 1668 | end 1669 | 1670 | elseif attribute == 0x805B then 1671 | -- att_str = Local Site Address 1672 | 1673 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+4,1):uint()) 1674 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,1), attribute_length) 1675 | :set_text("Reserved " .. attribute_bytes) 1676 | 1677 | fam_type = tvbuffer(absolutePosition+5,1):uint() 1678 | 1679 | if fam_type == 0x01 then 1680 | att_str = "IPv4" 1681 | att_bytes = "0x01" 1682 | elseif fam_type == 0x02 then 1683 | att_str = "IPv6" 1684 | att_bytes = "0x02" 1685 | end 1686 | 1687 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+5,1), attribute_length) 1688 | :set_text("Family: " .. att_str .. " (" .. att_bytes .. ")") 1689 | 1690 | 1691 | transaction_id_port = tvbuffer(4+tcpOffset,2):uint() 1692 | xport = tvbuffer(absolutePosition+6,2):uint() 1693 | port = bit.bxor(transaction_id_port, xport) 1694 | 1695 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+6,2):uint()) 1696 | portstring = string.format("%i", port) 1697 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+6,2), attribute_length) 1698 | :set_text("X-Port: " .. portstring .. " " .. attribute_bytes) 1699 | 1700 | 1701 | 1702 | if fam_type == 0x01 then 1703 | 1704 | oct1 = tvbuffer(4+tcpOffset,1):uint() 1705 | xip1 = tvbuffer(absolutePosition+8,1):uint() 1706 | ip1 = bin_xor(oct1,xip1) 1707 | 1708 | oct2 = tvbuffer(5+tcpOffset,1):uint() 1709 | xip2 = tvbuffer(absolutePosition+9,1):uint() 1710 | ip2 = bin_xor(oct2, xip2) 1711 | 1712 | oct3 = tvbuffer(6+tcpOffset,1):uint() 1713 | xip3 = tvbuffer(absolutePosition+10,1):uint() 1714 | ip3 = bin_xor(oct3, xip3) 1715 | 1716 | oct4 = tvbuffer(7+tcpOffset,1):uint() 1717 | xip4 = tvbuffer(absolutePosition+11,1):uint() 1718 | ip4 = bin_xor(oct4, xip4) 1719 | 1720 | ip1string = string.format("%i", ip1) 1721 | ip2string = string.format("%i", ip2) 1722 | ip3string = string.format("%i", ip3) 1723 | ip4string = string.format("%i", ip4) 1724 | 1725 | 1726 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+8,4):uint()) 1727 | 1728 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+8,4), attribute_length) 1729 | :set_text("X-Address-IPv4: " .. ip1string .. "." .. ip2string .. "." .. ip3string .. "." .. ip4string .. " " .. attribute_bytes) 1730 | 1731 | elseif fam_type == 0x02 then 1732 | -- Not decoding IPv6 fully yet. 1733 | attribute_bytes = tostring(tvbuffer:range(absolutePosition+8,16)) 1734 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+8,16), attribute_length) 1735 | :set_text("X-Address_IPv6: 0x" .. attribute_bytes) 1736 | end 1737 | 1738 | elseif attribute == 0x805C then 1739 | -- att_str = Local Relay Site Address 1740 | 1741 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+4,1):uint()) 1742 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,1), attribute_length) 1743 | :set_text("Reserved " .. attribute_bytes) 1744 | 1745 | fam_type = tvbuffer(absolutePosition+5,1):uint() 1746 | 1747 | if fam_type == 0x01 then 1748 | att_str = "IPv4" 1749 | att_bytes = "0x01" 1750 | elseif fam_type == 0x02 then 1751 | att_str = "IPv6" 1752 | att_bytes = "0x02" 1753 | end 1754 | 1755 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+5,1), attribute_length) 1756 | :set_text("Family: " .. att_str .. " (" .. att_bytes .. ")") 1757 | 1758 | 1759 | transaction_id_port = tvbuffer(4+tcpOffset,2):uint() 1760 | xport = tvbuffer(absolutePosition+6,2):uint() 1761 | port = bit.bxor(transaction_id_port, xport) 1762 | 1763 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+6,2):uint()) 1764 | portstring = string.format("%i", port) 1765 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+6,2), attribute_length) 1766 | :set_text("X-Port: " .. portstring .. " " .. attribute_bytes) 1767 | 1768 | 1769 | if fam_type == 0x01 then 1770 | 1771 | oct1 = tvbuffer(4+tcpOffset,1):uint() 1772 | xip1 = tvbuffer(absolutePosition+8,1):uint() 1773 | ip1 = bin_xor(oct1,xip1) 1774 | 1775 | oct2 = tvbuffer(5+tcpOffset,1):uint() 1776 | xip2 = tvbuffer(absolutePosition+9,1):uint() 1777 | ip2 = bin_xor(oct2, xip2) 1778 | 1779 | oct3 = tvbuffer(6+tcpOffset,1):uint() 1780 | xip3 = tvbuffer(absolutePosition+10,1):uint() 1781 | ip3 = bin_xor(oct3, xip3) 1782 | 1783 | oct4 = tvbuffer(7+tcpOffset,1):uint() 1784 | xip4 = tvbuffer(absolutePosition+11,1):uint() 1785 | ip4 = bin_xor(oct4, xip4) 1786 | 1787 | ip1string = string.format("%i", ip1) 1788 | ip2string = string.format("%i", ip2) 1789 | ip3string = string.format("%i", ip3) 1790 | ip4string = string.format("%i", ip4) 1791 | 1792 | 1793 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+8,4):uint()) 1794 | 1795 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+8,4), attribute_length) 1796 | :set_text("X-Address-IPv4: " .. ip1string .. "." .. ip2string .. "." .. ip3string .. "." .. ip4string .. " " .. attribute_bytes) 1797 | 1798 | elseif fam_type == 0x02 then 1799 | -- Not decoding IPv6 fully yet. 1800 | attribute_bytes = tostring(tvbuffer:range(absolutePosition+8,16)) 1801 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+8,16), attribute_length) 1802 | :set_text("X-Address_IPv6: 0x" .. attribute_bytes) 1803 | end 1804 | 1805 | elseif attribute == 0x805D then 1806 | --att_str = "Remote Site Address Response" 1807 | 1808 | local c = tvbuffer(absolutePosition+4,1):uint() 1809 | 1810 | local BitTable = to_bits(c) 1811 | 1812 | if BitTable[8] == 0 then 1813 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,1), attribute_length) 1814 | :set_text("A Valid Flag: Failed Bandwidth Policy Check") 1815 | elseif BitTable[8] == 1 then 1816 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,1), attribute_length) 1817 | :set_text("A Valid Flag: Passed Bandwidth Policy Check") 1818 | end 1819 | 1820 | if BitTable[7] == 0 then 1821 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,1), attribute_length) 1822 | :set_text("B PSTN Failover Flag: Failed Bandwidth Policy Check") 1823 | elseif BitTable[7] == 1 then 1824 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,1), attribute_length) 1825 | :set_text("B PSTN Failover Flag: Passed Bandwidth Policy Check") 1826 | end 1827 | 1828 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,4), attribute_length) 1829 | :set_text("Reserved: MUST be zero") 1830 | 1831 | attribute_bytes = string.format("%i", tvbuffer(absolutePosition+8,4):uint()) 1832 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+8,4), attribute_length) 1833 | :set_text("Maximum Send Bandwidth: " .. attribute_bytes .. "kbs") 1834 | 1835 | attribute_bytes = string.format("%i", tvbuffer(absolutePosition+12,4):uint()) 1836 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+12,4), attribute_length) 1837 | :set_text("Maximum Receive Bandwidth: " .. attribute_bytes .. "kbs") 1838 | 1839 | elseif attribute == 0x805E then 1840 | --att_str = "Remote Relay Site Address Response" 1841 | 1842 | local c = tvbuffer(absolutePosition+4,1):uint() 1843 | 1844 | local BitTable = to_bits(c) 1845 | 1846 | if BitTable[8] == 0 then 1847 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,1), attribute_length) 1848 | :set_text("A Valid Flag: Failed Bandwidth Policy Check") 1849 | elseif BitTable[8] == 1 then 1850 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,1), attribute_length) 1851 | :set_text("A Valid Flag: Passed Bandwidth Policy Check") 1852 | end 1853 | 1854 | 1855 | 1856 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,4), attribute_length) 1857 | :set_text("Reserved: MUST be zero") 1858 | 1859 | attribute_bytes = string.format("%i", tvbuffer(absolutePosition+8,4):uint()) 1860 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+8,4), attribute_length) 1861 | :set_text("Maximum Send Bandwidth: " .. attribute_bytes .. "kbs") 1862 | 1863 | attribute_bytes = string.format("%i", tvbuffer(absolutePosition+12,4):uint()) 1864 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+12,4), attribute_length) 1865 | :set_text("Maximum Receive Bandwidth: " .. attribute_bytes .. "kbs") 1866 | 1867 | elseif attribute == 0x805F then 1868 | --att_str = "Local Site Address Response" 1869 | 1870 | local c = tvbuffer(absolutePosition+4,1):uint() 1871 | 1872 | local BitTable = to_bits(c) 1873 | 1874 | if BitTable[8] == 0 then 1875 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,1), attribute_length) 1876 | :set_text("A Valid Flag: Failed Bandwidth Policy Check") 1877 | elseif BitTable[8] == 1 then 1878 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,1), attribute_length) 1879 | :set_text("A Valid Flag: Passed Bandwidth Policy Check") 1880 | end 1881 | 1882 | if BitTable[7] == 0 then 1883 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,1), attribute_length) 1884 | :set_text("B PSTN Failover Flag: Failed Bandwidth Policy Check") 1885 | elseif BitTable[7] == 1 then 1886 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,1), attribute_length) 1887 | :set_text("B PSTN Failover Flag: Passed Bandwidth Policy Check") 1888 | end 1889 | 1890 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,4), attribute_length) 1891 | :set_text("Reserved: MUST be zero") 1892 | 1893 | attribute_bytes = string.format("%i", tvbuffer(absolutePosition+8,4):uint()) 1894 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+8,4), attribute_length) 1895 | :set_text("Maximum Send Bandwidth: " .. attribute_bytes .. "kbs") 1896 | 1897 | attribute_bytes = string.format("%i", tvbuffer(absolutePosition+12,4):uint()) 1898 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+12,4), attribute_length) 1899 | :set_text("Maximum Receive Bandwidth: " .. attribute_bytes .. "kbs") 1900 | 1901 | elseif attribute == 0x8060 then 1902 | --att_str = "Local Relay Site Address Response" 1903 | 1904 | local c = tvbuffer(absolutePosition+4,1):uint() 1905 | 1906 | local BitTable = to_bits(c) 1907 | 1908 | if BitTable[8] == 0 then 1909 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,1), attribute_length) 1910 | :set_text("A Valid Flag: Failed Bandwidth Policy Check") 1911 | elseif BitTable[8] == 1 then 1912 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,1), attribute_length) 1913 | :set_text("A Valid Flag: Passed Bandwidth Policy Check") 1914 | end 1915 | 1916 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,4), attribute_length) 1917 | :set_text("Reserved: MUST be zero") 1918 | 1919 | attribute_bytes = string.format("%i", tvbuffer(absolutePosition+8,4):uint()) 1920 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+8,4), attribute_length) 1921 | :set_text("Maximum Send Bandwidth: " .. attribute_bytes .. "kbs") 1922 | 1923 | attribute_bytes = string.format("%i", tvbuffer(absolutePosition+12,4):uint()) 1924 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+12,4), attribute_length) 1925 | :set_text("Maximum Receive Bandwidth: " .. attribute_bytes .. "kbs") 1926 | 1927 | elseif attribute == 0x8061 then 1928 | 1929 | --att_str = "SIP Dialog Identifier" 1930 | 1931 | -- CHANGED FOR 2.0 1932 | --attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+4,lengthOfCommand):uint()) 1933 | attribute_bytes = tvbuffer(absolutePosition+4,lengthOfCommand):string() 1934 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,lengthOfCommand), attribute_length) 1935 | :set_text("SIP Dialog Identifier: " .. attribute_bytes) 1936 | 1937 | 1938 | elseif attribute == 0x8062 then 1939 | --att_str = "SIP Call Identifier" 1940 | 1941 | -- CHANGED FOR 2.0 1942 | --attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+4,lengthOfCommand):uint()) 1943 | attribute_bytes = tvbuffer(absolutePosition+4,lengthOfCommand):string() 1944 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,lengthOfCommand), attribute_length) 1945 | :set_text("SIP Call Identifier: " .. attribute_bytes) 1946 | 1947 | 1948 | elseif attribute == 0x8068 then 1949 | --att_str = "Location Profile" 1950 | 1951 | peer_type = tvbuffer(absolutePosition+4,1):uint() 1952 | 1953 | if peer_type == 0x00 then 1954 | att_loc = "Unknown" 1955 | att_bytes = "0x00" 1956 | elseif peer_type == 0x01 then 1957 | att_loc = "Internet" 1958 | att_bytes = "0x01" 1959 | elseif peer_type == 0x02 then 1960 | att_loc = "Intranet" 1961 | att_bytes = "0x02" 1962 | end 1963 | 1964 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,1), attribute_length) 1965 | :set_text("Peer Location: " .. att_loc .. " (" .. att_bytes .. ")") 1966 | 1967 | peer_type = tvbuffer(absolutePosition+5,1):uint() 1968 | 1969 | if peer_type == 0x00 then 1970 | att_loc = "Unknown" 1971 | att_bytes = "0x00" 1972 | elseif peer_type == 0x01 then 1973 | att_loc = "Internet" 1974 | att_bytes = "0x01" 1975 | elseif peer_type == 0x02 then 1976 | att_loc = "Intranet" 1977 | att_bytes = "0x02" 1978 | end 1979 | 1980 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+5,1), attribute_length) 1981 | :set_text("Self Location: " .. att_loc .. " (" .. att_bytes .. ")") 1982 | 1983 | 1984 | peer_type = tvbuffer(absolutePosition+6,1):uint() 1985 | 1986 | if peer_type == 0x00 then 1987 | att_loc = "Unknown" 1988 | att_bytes = "0x00" 1989 | elseif peer_type == 0x01 then 1990 | att_loc = "Internet" 1991 | att_bytes = "0x01" 1992 | elseif peer_type == 0x02 then 1993 | att_loc = "Intranet" 1994 | att_bytes = "0x02" 1995 | end 1996 | 1997 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+6,1), attribute_length) 1998 | :set_text("Federation Location: " .. att_loc .. " (" .. att_bytes .. ")") 1999 | 2000 | attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+7,1):uint()) 2001 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+7,1), attribute_length) 2002 | :set_text("Reserved: " .. attribute_bytes) 2003 | 2004 | elseif attribute == 0x8070 then 2005 | --att_str = Version Number 2006 | 2007 | -- CHANGED FOR 2.0 2008 | --attribute_bytes = string.format("(0x%X)", tvbuffer(absolutePosition+4,lengthOfCommand):uint()) 2009 | attribute_bytes = tvbuffer(absolutePosition+4,lengthOfCommand):string() 2010 | attributeTree:add(F_attribute_sub, tvbuffer(absolutePosition+4,lengthOfCommand), attribute_length) 2011 | :set_text("Version Number: " .. attribute_bytes) 2012 | 2013 | 2014 | elseif attribute == 0x8090 then 2015 | --att_str = "MS-Alternate Mapped Address" 2016 | 2017 | end 2018 | end 2019 | 2020 | if finalPosition >= tvbuffer:len() then 2021 | return 2022 | end 2023 | 2024 | relativePosition = finalPosition - offset 2025 | 2026 | end 2027 | end 2028 | end 2029 | 2030 | ----- CHECK IF PACKETS ARE RTP OR RTCP! 2031 | cmd = tvbuffer(1+tcpOffset,1):uint() 2032 | 2033 | cmd_str = "unknown (Possible incorrect packet classification)" 2034 | 2035 | 2036 | -- 0 1 2 3 2037 | -- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2038 | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2039 | --header |V=2|P| RC | PT=SR=200 | length | 2040 | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2041 | -- | SSRC of sender | 2042 | -- +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 2043 | --sender | NTP timestamp, most significant word | 2044 | --info +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2045 | -- | NTP timestamp, least significant word | 2046 | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2047 | -- | RTP timestamp | 2048 | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2049 | -- | sender's packet count | 2050 | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2051 | -- | sender's octet count | 2052 | 2053 | --SRTCP 2054 | -- 0 1 2 3 2055 | -- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2056 | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<+ 2057 | -- |V=2|P| RC | PT=SR or RR | length | | 2058 | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 2059 | -- | SSRC of sender | | 2060 | -- +>+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | 2061 | -- | ~ sender info ~ | 2062 | -- | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 2063 | -- | ~ report block 1 ~ | 2064 | -- | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 2065 | -- | ~ report block 2 ~ | 2066 | -- | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 2067 | -- | ~ ... ~ | 2068 | -- | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 2069 | -- | |V=2|P| SC | PT=SDES=202 | length | | 2070 | -- | +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | 2071 | -- | | SSRC/CSRC_1 | | 2072 | -- | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 2073 | -- | ~ SDES items ~ | 2074 | -- | +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | 2075 | -- | ~ ... ~ | 2076 | -- +>+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | 2077 | -- | |E| SRTCP index | | 2078 | -- | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<+ 2079 | -- | ~ SRTCP MKI (OPTIONAL) ~ | 2080 | -- | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 2081 | -- | : authentication tag : | 2082 | -- | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 2083 | -- | | 2084 | -- +-- Encrypted Portion Authenticated Portion -----+ 2085 | 2086 | 2087 | if cmd == 0xC8 then 2088 | 2089 | if f_tcp_srcport() ~= nil and f_tcp_dstport() ~= nil and tcpOffset == 0 then 2090 | 2091 | -- Framing check failed so assume this isn't a TCP based RTP packet. Use SSL decoder if required. 2092 | if f_tcp_srcport().value == 443 or f_tcp_dstport().value == 443 then 2093 | 2094 | original_ssl_dissector:call(tvbuffer, pinfo, treeitem) --DECODE AS TLS 2095 | 2096 | else 2097 | 2098 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(0+tcpOffset,1), attribute_bytes) 2099 | attributeTree:set_text("UNABLE TO DECODE THIS PACKET :(") 2100 | 2101 | end 2102 | 2103 | else 2104 | 2105 | local bytes = tvbuffer(1+tcpOffset,1):uint() 2106 | 2107 | -- IS AN RTCP PACKET 2108 | cmd_str = "RTCP PACKET" 2109 | 2110 | --Set the Protcol and Info Columns 2111 | pinfo.cols.protocol = "MSRTCP" 2112 | 2113 | packetlength = tvbuffer:len() 2114 | length = tvbuffer(2+tcpOffset,2):uint() 2115 | -- If the length of the attribute is longer than the packet length then assume there is an error and break loop 2116 | 2117 | if length > packetlength then 2118 | 2119 | pinfo.cols.info = "RTCP PACKET SENDER (Incorrect Length)" 2120 | 2121 | attribute_bytes = tostring(tvbuffer:range(1+tcpOffset,1)):upper() 2122 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(1+tcpOffset,1), attribute_bytes) 2123 | attributeTree:set_text("RTCP Sender Message: " .. "Payload Type: " .. tostring(bytes)) 2124 | 2125 | --IF IT'S ON PORT 443 THEN ASSUME THEN TRY THE TLS DECODER 2126 | if f_tcp_srcport() ~= nil and f_tcp_dstport() ~= nil then 2127 | if f_tcp_srcport().value == 443 or f_tcp_dstport().value == 443 then 2128 | original_ssl_dissector:call(tvbuffer, pinfo, treeitem) --DECODE AS TLS 2129 | end 2130 | end 2131 | 2132 | 2133 | else 2134 | 2135 | pinfo.cols.info = "RTCP PACKET SENDER" 2136 | 2137 | attribute_bytes = tostring(tvbuffer:range(1+tcpOffset,1)):upper() 2138 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(1+tcpOffset,1), attribute_bytes) 2139 | attributeTree:set_text("RTCP Sender Message: " .. "Payload Type: " .. tostring(bytes)) 2140 | 2141 | end 2142 | 2143 | local bits = tvbuffer(0+tcpOffset,1):uint() 2144 | 2145 | attributeTree:add(F_attribute_sub, tvbuffer(0+tcpOffset,1), cmd_str) 2146 | :set_text("RTP Version: (2 bits) 0x" .. tostring(bit.tohex((bit.band(bits,0xC0)),2))) 2147 | 2148 | attributeTree:add(F_attribute_sub, tvbuffer(0+tcpOffset,1), cmd_str) 2149 | :set_text("padding: (1 bit) 0x" .. tostring(bit.tohex((bit.band(bits,0x20)),2))) 2150 | 2151 | attributeTree:add(F_attribute_sub, tvbuffer(0+tcpOffset,1), cmd_str) 2152 | :set_text("RC: (5 bits) 0x" .. tostring(bit.tohex((bit.band(bits,0x1F)),2))) 2153 | 2154 | local byte = tvbuffer(1+tcpOffset,1):uint() 2155 | 2156 | attributeTree:add(F_attribute_sub, tvbuffer(1+tcpOffset,1), cmd_str) 2157 | :set_text("Payload Type: (8 bits) " .. tostring(byte)) 2158 | 2159 | 2160 | length = tvbuffer(2+tcpOffset,2):uint() 2161 | 2162 | --length x 32 / 8 + 4 2163 | attributeTree:add(F_attribute_sub, tvbuffer(2+tcpOffset,2), cmd_str) 2164 | :set_text("Length: " .. tostring(length) .. " (" .. tostring(((length * 32) / 8)+4) .. " Bytes)") 2165 | 2166 | packetlength = tvbuffer:len() 2167 | length = tvbuffer(2+tcpOffset,2):uint() 2168 | -- If the length of the attribute is longer than the packet length then assume there is an error and break loop 2169 | if length > packetlength then 2170 | attributeTree:add(F_attribute_sub, tvbuffer(2+tcpOffset,2), cmd_str) 2171 | :set_text("(Error with data length value. Probably not an actual RTCP packet.)") 2172 | end 2173 | 2174 | local bytes = tvbuffer(4+tcpOffset,4):uint() 2175 | attributeTree:add(F_attribute_sub, tvbuffer(4+tcpOffset,4), cmd_str) 2176 | :set_text("SSRC of sender: 0x" .. tostring(bit.tohex((bytes),8)):upper()) 2177 | 2178 | attributeTree:add(F_attribute_sub, tvbuffer(8+tcpOffset, tvbuffer:len()-tcpOffset-8) , cmd_str) 2179 | :set_text("Payload: " .. tostring( tvbuffer(8+tcpOffset,tvbuffer:len()-tcpOffset-8)) ) 2180 | 2181 | -- Assumed Payload is encrypted, so not attempting any break down further of data. 2182 | 2183 | end 2184 | 2185 | elseif cmd == 0xC9 then 2186 | 2187 | if f_tcp_srcport() ~= nil and f_tcp_dstport() ~= nil and tcpOffset == 0 then 2188 | 2189 | -- Framing check failed so assume this isn't a TCP based RTP packet. Use SSL decoder if required. 2190 | if f_tcp_srcport().value == 443 or f_tcp_dstport().value == 443 then 2191 | 2192 | original_ssl_dissector:call(tvbuffer, pinfo, treeitem) --DECODE AS TLS 2193 | 2194 | else 2195 | 2196 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(0+tcpOffset,1), attribute_bytes) 2197 | attributeTree:set_text("UNABLE TO DECODE THIS PACKET :(") 2198 | 2199 | end 2200 | 2201 | else 2202 | 2203 | local bytes = tvbuffer(1+tcpOffset,1):uint() 2204 | 2205 | -- IS AN RTCP PACKET 2206 | cmd_str = "RTCP PACKET" 2207 | 2208 | --Set the Protcol and Info Columns 2209 | pinfo.cols.protocol = "MSRTCP" 2210 | 2211 | packetlength = tvbuffer:len() 2212 | length = tvbuffer(2+tcpOffset,2):uint() 2213 | -- If the length of the attribute is longer than the packet length then assume there is an error and break loop 2214 | if length > packetlength then 2215 | 2216 | pinfo.cols.info = "RTCP PACKET RECEIVER (Incorrect Length)" 2217 | 2218 | attribute_bytes = tostring(tvbuffer:range(1+tcpOffset,1)):upper() 2219 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(1+tcpOffset,1), attribute_bytes) 2220 | attributeTree:set_text("RTCP Receiver Message: " .. "Payload Type: " .. tostring(bytes)) 2221 | 2222 | --IF IT'S ON PORT 443 THEN ASSUME THEN TRY THE TLS DECODER 2223 | if f_tcp_srcport() ~= nil and f_tcp_dstport() ~= nil then 2224 | if f_tcp_srcport().value == 443 or f_tcp_dstport().value == 443 then 2225 | original_ssl_dissector:call(tvbuffer, pinfo, treeitem) --DECODE AS TLS 2226 | end 2227 | end 2228 | 2229 | 2230 | else 2231 | pinfo.cols.info = "RTCP PACKET RECEIVER" 2232 | 2233 | attribute_bytes = tostring(tvbuffer:range(1+tcpOffset,1)):upper() 2234 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(1+tcpOffset,1), attribute_bytes) 2235 | attributeTree:set_text("RTCP Receiver Message: " .. "Payload Type: " .. tostring(bytes)) 2236 | 2237 | end 2238 | 2239 | local bits = tvbuffer(0+tcpOffset,1):uint() 2240 | 2241 | attributeTree:add(F_attribute_sub, tvbuffer(0+tcpOffset,1), cmd_str) 2242 | :set_text("RTP Version: (2 bits) 0x" .. tostring(bit.tohex((bit.band(bits,0xC0)),2))) 2243 | 2244 | attributeTree:add(F_attribute_sub, tvbuffer(0+tcpOffset,1), cmd_str) 2245 | :set_text("padding: (1 bit) 0x" .. tostring(bit.tohex((bit.band(bits,0x20)),2))) 2246 | 2247 | attributeTree:add(F_attribute_sub, tvbuffer(0+tcpOffset,1), cmd_str) 2248 | :set_text("RC: (5 bits) 0x" .. tostring(bit.tohex((bit.band(bits,0x1F)),2))) 2249 | 2250 | local byte = tvbuffer(1+tcpOffset,1):uint() 2251 | 2252 | attributeTree:add(F_attribute_sub, tvbuffer(1+tcpOffset,1), cmd_str) 2253 | :set_text("Payload Type: (8 bits) " .. tostring(byte)) 2254 | 2255 | 2256 | length = tvbuffer(2+tcpOffset,2):uint() 2257 | 2258 | --length x 32 / 8 + 4 2259 | attributeTree:add(F_attribute_sub, tvbuffer(2+tcpOffset,2), cmd_str) 2260 | :set_text("Length: " .. tostring(length) .. " (" .. tostring(((length * 32) / 8)+4) .. " Bytes)") 2261 | 2262 | packetlength = tvbuffer:len() 2263 | length = tvbuffer(2+tcpOffset,2):uint() 2264 | -- If the length of the attribute is longer than the packet length then assume there is an error and break loop 2265 | if length > packetlength then 2266 | attributeTree:add(F_attribute_sub, tvbuffer(2+tcpOffset,2), cmd_str) 2267 | :set_text("(Error with data length value. Probably not an actual RTCP packet.)") 2268 | end 2269 | 2270 | local bytes = tvbuffer(4+tcpOffset,4):uint() 2271 | attributeTree:add(F_attribute_sub, tvbuffer(4+tcpOffset,4), cmd_str) 2272 | :set_text("SSRC of sender: 0x" .. tostring(bit.tohex((bytes),8)):upper()) 2273 | 2274 | attributeTree:add(F_attribute_sub, tvbuffer(8+tcpOffset, tvbuffer:len()-tcpOffset-8) , cmd_str) 2275 | :set_text("Payload: " .. tostring( tvbuffer(8+tcpOffset,tvbuffer:len()-tcpOffset-8)) ) 2276 | 2277 | -- Assumed Payload is encrypted, so not attempting any break down further of data. 2278 | 2279 | end 2280 | 2281 | elseif cmd == 0xCA then 2282 | 2283 | if f_tcp_srcport() ~= nil and f_tcp_dstport() ~= nil and tcpOffset == 0 then 2284 | 2285 | -- Framing check failed so assume this isn't a TCP based RTP packet. Use SSL decoder if required. 2286 | if f_tcp_srcport().value == 443 or f_tcp_dstport().value == 443 then 2287 | 2288 | original_ssl_dissector:call(tvbuffer, pinfo, treeitem) --DECODE AS TLS 2289 | 2290 | else 2291 | 2292 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(0+tcpOffset,1), attribute_bytes) 2293 | attributeTree:set_text("UNABLE TO DECODE THIS PACKET :(") 2294 | 2295 | end 2296 | 2297 | else 2298 | -- 0 1 2 3 2299 | -- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2300 | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2301 | --header |V=2|P| SC | PT=SDES=202 | length | 2302 | -- +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 2303 | --chunk | SSRC/CSRC_1 | 2304 | -- 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2305 | -- | SDES items | 2306 | -- | ... | 2307 | -- +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 2308 | --chunk | SSRC/CSRC_2 | 2309 | -- 2 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2310 | -- | SDES items | 2311 | -- | ... | 2312 | -- +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 2313 | 2314 | cmd_str = "RTCP PACKET" 2315 | 2316 | --Set the Protcol and Info Columns 2317 | pinfo.cols.protocol = "MSRTCP" 2318 | 2319 | local bytes = tvbuffer(1+tcpOffset,1):uint() 2320 | 2321 | packetlength = tvbuffer:len() 2322 | length = tvbuffer(2+tcpOffset,2):uint() 2323 | -- If the length of the attribute is longer than the packet length then assume there is an error and break loop 2324 | if length > packetlength then 2325 | 2326 | pinfo.cols.info = "RTCP PACKET SENDER (Incorrect Length)" 2327 | 2328 | attribute_bytes = tostring(tvbuffer:range(1+tcpOffset,1)):upper() 2329 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(1+tcpOffset,1), attribute_bytes) 2330 | attributeTree:set_text("Source Description RTCP Packet: " .. "(0x" .. attribute_bytes .. ")") 2331 | 2332 | --IF IT'S ON PORT 443 THEN ASSUME THEN TRY THE TLS DECODER 2333 | if f_tcp_srcport() ~= nil and f_tcp_dstport() ~= nil then 2334 | if f_tcp_srcport().value == 443 or f_tcp_dstport().value == 443 then 2335 | original_ssl_dissector:call(tvbuffer, pinfo, treeitem) --DECODE AS TLS 2336 | end 2337 | end 2338 | 2339 | else 2340 | pinfo.cols.info = "RTCP PACKET SENDER" 2341 | 2342 | attribute_bytes = tostring(tvbuffer:range(1+tcpOffset,1)):upper() 2343 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(1+tcpOffset,1), attribute_bytes) 2344 | attributeTree:set_text("Source Description RTCP Packet: " .. "(0x" .. attribute_bytes .. ")") 2345 | 2346 | end 2347 | 2348 | local bits = tvbuffer(0+tcpOffset,1):uint() 2349 | 2350 | attributeTree:add(F_attribute_sub, tvbuffer(0+tcpOffset,1), cmd_str) 2351 | :set_text("RTP Version: (2 bits) 0x" .. tostring(bit.tohex((bit.band(bits,0xC0)),2))) 2352 | 2353 | attributeTree:add(F_attribute_sub, tvbuffer(0+tcpOffset,1), cmd_str) 2354 | :set_text("padding: (1 bit) 0x" .. tostring(bit.tohex((bit.band(bits,0x20)),2))) 2355 | 2356 | attributeTree:add(F_attribute_sub, tvbuffer(0+tcpOffset,1), cmd_str) 2357 | :set_text("SC Type: (5 bits) 0x" .. tostring(bit.tohex((bit.band(bits,0x1F)),2))) 2358 | 2359 | local byte = tvbuffer(1+tcpOffset,1):uint() 2360 | 2361 | attributeTree:add(F_attribute_sub, tvbuffer(1+tcpOffset,1), cmd_str) 2362 | :set_text("Payload Type: (8 bits) " .. tostring(byte)) 2363 | 2364 | length = tvbuffer(2+tcpOffset,2):uint() 2365 | 2366 | attributeTree:add(F_attribute_sub, tvbuffer(2+tcpOffset,2), cmd_str) 2367 | :set_text("Length: " .. tostring(length) .. " (" .. tostring(((length * 32) / 8)+4) .. " Bytes)") 2368 | 2369 | packetlength = tvbuffer:len() 2370 | -- If the length of the attribute is longer than the packet length then assume there is an error and break loop 2371 | if length > packetlength then 2372 | attributeTree:add(F_attribute_sub, tvbuffer(2+tcpOffset,2), cmd_str) 2373 | :set_text("(Error with data length value. Probably not an actual RTCP packet.)") 2374 | end 2375 | 2376 | attributeTree:add(F_attribute_sub, tvbuffer(4+tcpOffset, tvbuffer:len()-tcpOffset-4) , cmd_str) 2377 | :set_text("Payload: " .. tostring( tvbuffer(4+tcpOffset,tvbuffer:len()-tcpOffset-4))) 2378 | 2379 | 2380 | -- Assumed Payload is encrypted, so not attempting any further decoding of data. 2381 | 2382 | end 2383 | 2384 | elseif cmd == 0xCB then 2385 | 2386 | if f_tcp_srcport() ~= nil and f_tcp_dstport() ~= nil and tcpOffset == 0 then 2387 | 2388 | -- Framing check failed so assume this isn't a TCP based RTP packet. Use SSL decoder if required. 2389 | if f_tcp_srcport().value == 443 or f_tcp_dstport().value == 443 then 2390 | 2391 | original_ssl_dissector:call(tvbuffer, pinfo, treeitem) --DECODE AS TLS 2392 | 2393 | else 2394 | 2395 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(0+tcpOffset,1), attribute_bytes) 2396 | attributeTree:set_text("UNABLE TO DECODE THIS PACKET :(") 2397 | 2398 | end 2399 | 2400 | else 2401 | 2402 | -- 0 1 2 3 2403 | -- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2404 | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2405 | -- |V=2|P| SC | PT=BYE=203 | length | 2406 | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2407 | -- | SSRC/CSRC | 2408 | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2409 | -- : ... : 2410 | -- +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 2411 | --(opt) | length | reason for leaving ... 2412 | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2413 | 2414 | cmd_str = "RTCP PACKET" 2415 | 2416 | --Set the Protcol and Info Columns 2417 | pinfo.cols.protocol = "MSRTCP" 2418 | 2419 | local bytes = tvbuffer(1+tcpOffset,1):uint() 2420 | 2421 | packetlength = tvbuffer:len() 2422 | length = tvbuffer(2+tcpOffset,2):uint() 2423 | -- If the length of the attribute is longer than the packet length then assume there is an error and break loop 2424 | if length > packetlength then 2425 | 2426 | pinfo.cols.info = "RTCP PACKET SENDER (Incorrect Length)" 2427 | 2428 | attribute_bytes = tostring(tvbuffer:range(1+tcpOffset,1)):upper() 2429 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(1+tcpOffset,1), attribute_bytes) 2430 | attributeTree:set_text("Source Description RTCP Packet: " .. "(0x" .. attribute_bytes .. ")") 2431 | 2432 | --IF IT'S ON PORT 443 THEN ASSUME THEN TRY THE TLS DECODER 2433 | if f_tcp_srcport() ~= nil and f_tcp_dstport() ~= nil then 2434 | if f_tcp_srcport().value == 443 or f_tcp_dstport().value == 443 then 2435 | original_ssl_dissector:call(tvbuffer, pinfo, treeitem) --DECODE AS TLS 2436 | end 2437 | end 2438 | 2439 | else 2440 | pinfo.cols.info = "RTCP PACKET SENDER" 2441 | 2442 | attribute_bytes = tostring(tvbuffer:range(1+tcpOffset,1)):upper() 2443 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(1+tcpOffset,1), attribute_bytes) 2444 | attributeTree:set_text("Source Description RTCP Packet: " .. "(0x" .. attribute_bytes .. ")") 2445 | 2446 | end 2447 | 2448 | local bits = tvbuffer(0+tcpOffset,1):uint() 2449 | 2450 | attributeTree:add(F_attribute_sub, tvbuffer(0+tcpOffset,1), cmd_str) 2451 | :set_text("RTP Version: (2 bits) 0x" .. tostring(bit.tohex((bit.band(bits,0xC0)),2))) 2452 | 2453 | attributeTree:add(F_attribute_sub, tvbuffer(0+tcpOffset,1), cmd_str) 2454 | :set_text("padding: (1 bit) 0x" .. tostring(bit.tohex((bit.band(bits,0x20)),2))) 2455 | 2456 | attributeTree:add(F_attribute_sub, tvbuffer(0+tcpOffset,1), cmd_str) 2457 | :set_text("SC Type: (5 bits) 0x" .. tostring(bit.tohex((bit.band(bits,0x1F)),2))) 2458 | 2459 | local byte = tvbuffer(1+tcpOffset,1):uint() 2460 | 2461 | attributeTree:add(F_attribute_sub, tvbuffer(1+tcpOffset,1), cmd_str) 2462 | :set_text("Payload Type: (8 bits) " .. tostring(byte)) 2463 | 2464 | 2465 | length = tvbuffer(2+tcpOffset,2):uint() 2466 | 2467 | attributeTree:add(F_attribute_sub, tvbuffer(2+tcpOffset,2), cmd_str) 2468 | :set_text("Length: " .. tostring(length) .. " (" .. tostring(((length * 32) / 8)+4) .. " Bytes)") 2469 | 2470 | packetlength = tvbuffer:len() 2471 | -- If the length of the attribute is longer than the packet length then assume there is an error and break loop 2472 | if length > packetlength then 2473 | attributeTree:add(F_attribute_sub, tvbuffer(2+tcpOffset,2), cmd_str) 2474 | :set_text("(Error with data length value. Probably not an actual RTCP packet.)") 2475 | end 2476 | 2477 | attributeTree:add(F_attribute_sub, tvbuffer(4+tcpOffset,4), cmd_str) 2478 | :set_text("SSRC of Sender: " .. tostring(tvbuffer(4+tcpOffset,4))) 2479 | 2480 | attributeTree:add(F_attribute_sub, tvbuffer(8+tcpOffset, tvbuffer:len()-tcpOffset-8) , cmd_str) 2481 | :set_text("Payload: " .. tostring( tvbuffer(8+tcpOffset,tvbuffer:len()-tcpOffset-8))) 2482 | 2483 | -- Assumed Payload is encrypted, so not attempting any break down further of data. 2484 | 2485 | end 2486 | 2487 | elseif cmd == 0xCE then 2488 | 2489 | if f_tcp_srcport() ~= nil and f_tcp_dstport() ~= nil and tcpOffset == 0 then 2490 | 2491 | -- Framing check failed so assume this isn't a TCP based RTP packet. Use SSL decoder if required. 2492 | if f_tcp_srcport().value == 443 or f_tcp_dstport().value == 443 then 2493 | 2494 | original_ssl_dissector:call(tvbuffer, pinfo, treeitem) --DECODE AS TLS 2495 | 2496 | else 2497 | 2498 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(0+tcpOffset,1), attribute_bytes) 2499 | attributeTree:set_text("UNABLE TO DECODE THIS PACKET :(") 2500 | 2501 | end 2502 | 2503 | else 2504 | 2505 | cmd_str = "RTCP PACKET" 2506 | 2507 | -- 0 1 2 3 2508 | -- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2509 | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2510 | -- |V=2|P| FMT | PT | length | 2511 | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2512 | -- | SSRC of packet sender | 2513 | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2514 | -- | SSRC of media source | 2515 | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2516 | -- : Feedback Control Information (FCI) : 2517 | -- : : 2518 | 2519 | --Set the Protcol and Info Columns 2520 | pinfo.cols.protocol = "MSRTCP" 2521 | 2522 | local bytes = tvbuffer(1+tcpOffset,1):uint() 2523 | 2524 | 2525 | packetlength = tvbuffer:len() 2526 | length = tvbuffer(2+tcpOffset,2):uint() 2527 | -- If the length of the attribute is longer than the packet length then assume there is an error and break loop 2528 | if length > packetlength then 2529 | 2530 | pinfo.cols.info = "RTCP PAYLOAD-SPECIFIC FEEDBACK (Incorrect Length)" 2531 | 2532 | attribute_bytes = tostring(tvbuffer:range(1+tcpOffset,1)):upper() 2533 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(1+tcpOffset,1), attribute_bytes) 2534 | attributeTree:set_text("Source Description RTCP Packet: " .. "(0x" .. attribute_bytes .. ")") 2535 | 2536 | --IF IT'S ON PORT 443 THEN ASSUME THEN TRY THE TLS DECODER 2537 | if f_tcp_srcport() ~= nil and f_tcp_dstport() ~= nil then 2538 | if f_tcp_srcport().value == 443 or f_tcp_dstport().value == 443 then 2539 | original_ssl_dissector:call(tvbuffer, pinfo, treeitem) --DECODE AS TLS 2540 | end 2541 | end 2542 | 2543 | else 2544 | pinfo.cols.info = "RTCP PAYLOAD-SPECIFIC FEEDBACK" 2545 | 2546 | attribute_bytes = tostring(tvbuffer:range(1+tcpOffset,1)):upper() 2547 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(1+tcpOffset,1), attribute_bytes) 2548 | attributeTree:set_text("Source Description RTCP Packet: " .. "(0x" .. attribute_bytes .. ")") 2549 | 2550 | end 2551 | 2552 | local bits = tvbuffer(0+tcpOffset,1):uint() 2553 | 2554 | attributeTree:add(F_attribute_sub, tvbuffer(0+tcpOffset,1), cmd_str) 2555 | :set_text("RTP Version: (2 bits) 0x" .. tostring(bit.tohex((bit.band(bits,0xC0)),2))) 2556 | 2557 | attributeTree:add(F_attribute_sub, tvbuffer(0+tcpOffset,1), cmd_str) 2558 | :set_text("padding: (1 bit) 0x" .. tostring(bit.tohex((bit.band(bits,0x20)),2))) 2559 | 2560 | attributeTree:add(F_attribute_sub, tvbuffer(0+tcpOffset,1), cmd_str) 2561 | :set_text("FMT: (5 bits) 0x" .. tostring(bit.tohex((bit.band(bits,0x1F)),2))) 2562 | 2563 | local byte = tvbuffer(1+tcpOffset,1):uint() 2564 | 2565 | attributeTree:add(F_attribute_sub, tvbuffer(1+tcpOffset,1), cmd_str) 2566 | :set_text("Payload Type: (8 bits) " .. tostring(byte)) 2567 | 2568 | 2569 | length = tvbuffer(2+tcpOffset,2):uint() 2570 | 2571 | attributeTree:add(F_attribute_sub, tvbuffer(2+tcpOffset,2), cmd_str) 2572 | :set_text("Length: " .. tostring(length) .. " (" .. tostring(((length * 32) / 8)+4) .. " Bytes)") 2573 | 2574 | packetlength = tvbuffer:len() 2575 | -- If the length of the attribute is longer than the packet length then assume there is an error and break loop 2576 | if length > packetlength then 2577 | attributeTree:add(F_attribute_sub, tvbuffer(2+tcpOffset,2), cmd_str) 2578 | :set_text("(Error with data length value. Probably not an actual RTCP packet.)") 2579 | end 2580 | 2581 | attributeTree:add(F_attribute_sub, tvbuffer(4+tcpOffset, tvbuffer:len()-tcpOffset-4) , cmd_str) 2582 | :set_text("Payload: " .. tostring( tvbuffer(4+tcpOffset,tvbuffer:len()-tcpOffset-4))) 2583 | 2584 | -- Assumed Payload is encrypted, so not attempting any break down further of data. 2585 | 2586 | end 2587 | 2588 | else -- ALL THE REST :) 2589 | 2590 | -- 0 1 2 3 2591 | -- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2592 | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2593 | -- |V=2|P|X| CC |M| PT | sequence number | 2594 | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2595 | -- | timestamp | 2596 | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2597 | -- | synchronization source (SSRC) identifier | 2598 | -- +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 2599 | -- | contributing source (CSRC) identifiers | 2600 | -- | .... | 2601 | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2602 | 2603 | --OTHER PACKET TYPE CHECKS 2604 | 2605 | -- PsudeoTLS Hello Check 2606 | frameCheck = tvbuffer(0,2):uint() 2607 | frameCheckOffset = tvbuffer(tcpOffset,2):uint() 2608 | 2609 | if frameCheck == 0x1603 then 2610 | 2611 | -- FALL BACK TO THE WIRESHARK STANDARD SSL/TLS DISSECTOR. DOES A LOT BETTER JOB THAN I DO OF DECODING TLS... 2612 | 2613 | original_ssl_dissector:call(tvbuffer, pinfo, treeitem) 2614 | 2615 | --[[ 2616 | --Set the Protcol and Info Columns 2617 | pinfo.cols.protocol = "MSTLS" 2618 | pinfo.cols.info = "TLS Negotiation (Possible Psuedo TLS setup)" 2619 | 2620 | subtreeitem:add(F_stunname, tvbuffer(0,2), cmd_str) 2621 | :set_text("TLS Negotiation") 2622 | 2623 | attribute_bytes = tostring(tvbuffer:range(0,1)):upper() 2624 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(0,1), attribute_bytes) 2625 | attributeTree:set_text("Record Layer: " .. "(0x" .. attribute_bytes .. ")") 2626 | 2627 | tlsversion = tvbuffer(1,2):uint() 2628 | 2629 | if tlsversion == 0x0003 then 2630 | versionstring = "SSL v3" 2631 | elseif tlsversion == 0x0301 then 2632 | versionstring = "TLS v1.0" 2633 | elseif tlsversion == 0x0302 then 2634 | versionstring = "TLS v1.1" 2635 | elseif tlsversion == 0x0303 then 2636 | versionstring = "TLS v1.2" 2637 | end 2638 | 2639 | attribute_bytes = tostring(tvbuffer:range(1,2)):upper() 2640 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(1,2), attribute_bytes) 2641 | attributeTree:set_text("Record Version: " .. versionstring .. " (0x" .. attribute_bytes .. ")") 2642 | 2643 | attribute_bytes = tostring(tvbuffer:range(3,2)):upper() 2644 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(3,2), attribute_bytes) 2645 | attributeTree:set_text("Record Length: " .. "(0x" .. attribute_bytes .. ")") 2646 | 2647 | local handshaketype = tvbuffer(5,1):uint() 2648 | 2649 | if handshaketype == 0x01 then 2650 | handshaketypestring = "Client Hello" 2651 | elseif handshaketype == 0x02 then 2652 | handshaketypestring = "Server Hello" 2653 | elseif handshaketype == 0x0B then 2654 | handshaketypestring = "Certificate" 2655 | elseif handshaketype == 0x0C then 2656 | handshaketypestring = "Server Key Exchange" 2657 | elseif handshaketype == 0x0E then 2658 | handshaketypestring = "Server Hello Done" 2659 | elseif handshaketype == 0x10 then 2660 | handshaketypestring = "Client Key Exchange" 2661 | elseif handshaketype == 0x14 then 2662 | handshaketypestring = "Finished" 2663 | end 2664 | 2665 | attribute_bytes = tostring(tvbuffer:range(5,1)):upper() 2666 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(5,1), attribute_bytes) 2667 | attributeTree:set_text("Handshake Type: " .. handshaketypestring .. " (0x" .. attribute_bytes .. ")") 2668 | 2669 | attribute_bytes = tostring(tvbuffer:range(6,3)):upper() 2670 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(6,3), attribute_bytes) 2671 | attributeTree:set_text("Handshake Length: " .. "(0x" .. attribute_bytes .. ")") 2672 | 2673 | attribute_bytes = tostring(tvbuffer:range(9,1)):upper() 2674 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(9,1), attribute_bytes) 2675 | attributeTree:set_text("Handshake Version Major: " .. "(0x" .. attribute_bytes .. ")") 2676 | 2677 | attribute_bytes = tostring(tvbuffer:range(10,1)):upper() 2678 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(10,1), attribute_bytes) 2679 | attributeTree:set_text("Handshake Version Minor: " .. "(0x" .. attribute_bytes .. ")") 2680 | 2681 | attribute_bytes = tostring(tvbuffer:range(11,4)):upper() 2682 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(11,4), attribute_bytes) 2683 | attributeTree:set_text("Timestamp: " .. "(0x" .. attribute_bytes .. ")") 2684 | 2685 | attribute_bytes = tostring(tvbuffer:range(15,28)):upper() 2686 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(15,28), attribute_bytes) 2687 | attributeTree:set_text("Random Value: " .. "(0x" .. attribute_bytes .. ")") 2688 | 2689 | sessionIdLength = tvbuffer(43,1):uint() 2690 | 2691 | attribute_bytes = tostring(tvbuffer:range(43,1)):upper() 2692 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(43,1), attribute_bytes) 2693 | attributeTree:set_text("Session ID Length: " .. "(0x" .. attribute_bytes .. ")") 2694 | 2695 | cipherSuiteLength = 0 2696 | 2697 | if sessionIdLength ~= 0 then 2698 | attribute_bytes = tostring(tvbuffer:range(44,sessionIdLength)):upper() 2699 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(44,sessionIdLength), attribute_bytes) 2700 | attributeTree:set_text("Session ID: " .. "(0x" .. attribute_bytes .. ")") 2701 | 2702 | else 2703 | cipherSuiteLength = tvbuffer(44+sessionIdLength,2):uint() 2704 | 2705 | attribute_bytes = tostring(tvbuffer:range(44+sessionIdLength,2)):upper() 2706 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(44+sessionIdLength,2), attribute_bytes) 2707 | attributeTree:set_text("Cipher Suite Length: " .. "(0x" .. attribute_bytes .. ")") 2708 | end 2709 | 2710 | 2711 | attribute_bytes = tostring(tvbuffer:range(44+sessionIdLength+cipherSuiteLength,2)):upper() 2712 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(44+sessionIdLength+cipherSuiteLength,2), attribute_bytes) 2713 | attributeTree:set_text("Cipher Suite: " .. "(0x" .. attribute_bytes .. ")") 2714 | 2715 | 2716 | attribute_bytes = tostring(tvbuffer:range(46+sessionIdLength+cipherSuiteLength,1)):upper() 2717 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(46+sessionIdLength+cipherSuiteLength,1), attribute_bytes) 2718 | attributeTree:set_text("Compression Method: " .. "(0x" .. attribute_bytes .. ")") 2719 | 2720 | attribute_bytes = tostring(tvbuffer:range(47+sessionIdLength+cipherSuiteLength,1)):upper() 2721 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(47+sessionIdLength+cipherSuiteLength,1), attribute_bytes) 2722 | attributeTree:set_text("Handshake Type: " .. "(0x" .. attribute_bytes .. ")") 2723 | 2724 | --]] 2725 | 2726 | elseif frameCheck == 0x1703 then 2727 | 2728 | -- FALL BACK TO THE WIRESHARK STANDARD SSL/TLS DISSECTOR. DOES A LOT BETTER JOB THAN I DO OF DECODING TLS... 2729 | 2730 | original_ssl_dissector:call(tvbuffer, pinfo, treeitem) 2731 | 2732 | --[[ 2733 | --Set the Protcol and Info Columns 2734 | pinfo.cols.protocol = "MSTLS" 2735 | pinfo.cols.info = "TLS Traffic (Application Data)" 2736 | 2737 | subtreeitem:add(F_stunname, tvbuffer(0,2), cmd_str) 2738 | :set_text("TLS Application Data") 2739 | 2740 | attribute_bytes = tostring(tvbuffer:range(0,1)):upper() 2741 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(0,1), attribute_bytes) 2742 | attributeTree:set_text("Record Layer: " .. "(0x" .. attribute_bytes .. ")") 2743 | 2744 | local tlsversion = tvbuffer(1,2):uint() 2745 | 2746 | if tlsversion == 0x0003 then 2747 | versionstring = "SSL v3" 2748 | elseif tlsversion == 0x0301 then 2749 | versionstring = "TLS v1.0" 2750 | elseif tlsversion == 0x0302 then 2751 | versionstring = "TLS v1.1" 2752 | elseif tlsversion == 0x0303 then 2753 | versionstring = "TLS v1.2" 2754 | end 2755 | 2756 | attribute_bytes = tostring(tvbuffer:range(1,2)):upper() 2757 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(1,2), attribute_bytes) 2758 | attributeTree:set_text("Record Version: " .. versionstring .. " (0x" .. attribute_bytes .. ")") 2759 | 2760 | attribute_bytes = tostring(tvbuffer:range(3,2)):upper() 2761 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(3,2), attribute_bytes) 2762 | attributeTree:set_text("Record Length: " .. tvbuffer(3,2):uint() .. " Bytes " .. "(0x" .. attribute_bytes .. ")") 2763 | 2764 | attributeTree = subtreeitem:add(F_attribute_sub, tvbuffer(5,tvbuffer:len()-5), cmd_str) 2765 | attributeTree:set_text("Data: " .. tostring(tvbuffer(5,tvbuffer:len()-5))) 2766 | 2767 | --]] 2768 | 2769 | elseif frameCheck == 0x1403 then 2770 | --Assume TLS 2771 | original_ssl_dissector:call(tvbuffer, pinfo, treeitem) 2772 | 2773 | elseif frameCheck == 0x1503 then 2774 | --Assume TLS 2775 | original_ssl_dissector:call(tvbuffer, pinfo, treeitem) 2776 | 2777 | elseif frameCheck == 0xFF80 then 2778 | 2779 | --Set the Protcol and Info Columns 2780 | pinfo.cols.protocol = "MSREP" 2781 | pinfo.cols.info = "LYNC EDGE INTERNAL REPLICATION DATA" 2782 | 2783 | subtreeitem:add(F_stunname, tvbuffer(0,4), cmd_str) 2784 | :set_text("Lync Replication Traffic - Proprietary Format") 2785 | 2786 | -- 0x4000 – 0xFFFF 2787 | elseif frameCheckOffset >= 0xFF00 and frameCheckOffset <= 0xFFFF then 2788 | 2789 | packetlength = tvbuffer:len() 2790 | -- Channel Data messages should be less than 22 bytes in size. 2791 | if(packetlength <= 22) then 2792 | 2793 | --Set the Protcol and Info Columns 2794 | pinfo.cols.protocol = "STUN" 2795 | pinfo.cols.info = "STUN ChannelData Message" 2796 | 2797 | attribute_bytes = tostring(tvbuffer:range(0+tcpOffset,4)):upper() 2798 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(0+tcpOffset,4), attribute_bytes) 2799 | attributeTree:set_text("Channel Data Message") 2800 | 2801 | attribute_bytes = string.format("(0x%X)", tvbuffer(0+tcpOffset,2):uint()) 2802 | attributeTree:add(F_attribute_sub, tvbuffer(0+tcpOffset,2), attribute_bytes) 2803 | :set_text("Channel Number: " .. attribute_bytes) 2804 | 2805 | attribute_bytes = string.format("(0x%X)", tvbuffer(2+tcpOffset,2):uint()) 2806 | attributeTree:add(F_attribute_sub, tvbuffer(2+tcpOffset,2), attribute_bytes) 2807 | :set_text("Length: " .. attribute_bytes) 2808 | 2809 | 2810 | port = tvbuffer(4+tcpOffset,2):uint() 2811 | attribute_bytes = string.format("(0x%X)", tvbuffer(4+tcpOffset,2):uint()) 2812 | portstring = string.format("%i", port) 2813 | attributeTree:add(F_attribute_sub, tvbuffer(4+tcpOffset,2), attribute_bytes) 2814 | :set_text("STUN Port: " .. portstring .. " " .. attribute_bytes) 2815 | 2816 | 2817 | ----------------------------------------------- 2818 | -- Decode the 1024-65535 range ports from STUN 2819 | ----------------------------------------------- 2820 | if prefs.port50000 then 2821 | if port >= 1024 and port <= 65535 then 2822 | attribute_bytes = string.format("(0x%X)", tvbuffer(4+tcpOffset,2):uint()) 2823 | attributeTree:add(F_attribute_sub, tvbuffer(4+tcpOffset,2), attribute_bytes) 2824 | :set_text("(INFO: Added " .. portstring .. " to decode.)") 2825 | myproto_udp_init(port) 2826 | myproto_tcp_init(port) 2827 | --RTCP 2828 | myproto_udp_init(port+1) 2829 | myproto_tcp_init(port+1) 2830 | else 2831 | attribute_bytes = string.format("(0x%X)", tvbuffer(4+tcpOffset,2):uint()) 2832 | attributeTree:add(F_attribute_sub, tvbuffer(4+tcpOffset,2), attribute_bytes) 2833 | :set_text("(INFO: Not in 1024-65535 range. Have not added " .. portstring .. " to decode.)") 2834 | end 2835 | else 2836 | myproto_udp_remove_init(port) 2837 | myproto_tcp_remove_init(port) 2838 | myproto_udp_remove_init(port+1) 2839 | myproto_tcp_remove_init(port+1) 2840 | end 2841 | 2842 | port = tvbuffer(6+tcpOffset,2):uint() 2843 | attribute_bytes = string.format("(0x%X)", tvbuffer(6+tcpOffset,2):uint()) 2844 | portstring = string.format("%i", port) 2845 | attributeTree:add(F_attribute_sub, tvbuffer(6+tcpOffset,2), attribute_bytes) 2846 | :set_text("STUN Port: " .. portstring .. " " .. attribute_bytes) 2847 | 2848 | ----------------------------------------------- 2849 | -- Decode the 1024-65535 range ports from STUN 2850 | ----------------------------------------------- 2851 | if prefs.port50000 then 2852 | if port >= 1024 and port <= 65535 then 2853 | attribute_bytes = string.format("(0x%X)", tvbuffer(4+tcpOffset,2):uint()) 2854 | attributeTree:add(F_attribute_sub, tvbuffer(4+tcpOffset,2), attribute_bytes) 2855 | :set_text("(INFO: Added " .. portstring .. " to decode.)") 2856 | 2857 | myproto_udp_init(port) 2858 | myproto_tcp_init(port) 2859 | --RTCP 2860 | myproto_udp_init(port+1) 2861 | myproto_tcp_init(port+1) 2862 | else 2863 | attribute_bytes = string.format("(0x%X)", tvbuffer(4+tcpOffset,2):uint()) 2864 | attributeTree:add(F_attribute_sub, tvbuffer(4+tcpOffset,2), attribute_bytes) 2865 | :set_text("(INFO: Not in 50000-65535 range. Have not added " .. portstring .. " to decode.)") 2866 | end 2867 | else 2868 | myproto_udp_remove_init(port) 2869 | myproto_tcp_remove_init(port) 2870 | myproto_udp_remove_init(port+1) -- RTCP Port 2871 | myproto_tcp_remove_init(port+1) -- RTCP Port 2872 | end 2873 | end 2874 | 2875 | else -- RTP Decode 2876 | 2877 | local datatype = tvbuffer(0+tcpOffset,1):uint() 2878 | 2879 | -- Check Data payload starts with 80 or 81 or 82 and assume RTP. This method whilst not ideal works in majority of cases with Lync / Skype for Business. 2880 | if datatype == 128 or datatype == 129 or datatype == 130 then 2881 | -- TCP FRAMING CHECK 2882 | if f_tcp_srcport() ~= nil and f_tcp_dstport() ~= nil and tcpOffset == 0 then 2883 | 2884 | -- Framing check failed so assume this isn't a TCP based RTP packet. Use SSL decoder if required. 2885 | if f_tcp_srcport().value == 443 or f_tcp_dstport().value == 443 then 2886 | 2887 | original_ssl_dissector:call(tvbuffer, pinfo, treeitem) --DECODE AS TLS 2888 | 2889 | else 2890 | 2891 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(0+tcpOffset,1), attribute_bytes) 2892 | attributeTree:set_text("UNABLE TO DECODE THIS PACKET :(") 2893 | 2894 | end 2895 | else 2896 | cmd_str = "RTP PACKET" 2897 | 2898 | local bytes = tvbuffer(1+tcpOffset,1):uint() 2899 | 2900 | attribute_bytes = tostring(tvbuffer:range(1+tcpOffset,1)):upper() 2901 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(1+tcpOffset,1), attribute_bytes) 2902 | attributeTree:set_text("RTP Message: " .. "Payload Type: " .. tostring((bit.band(bytes,0x7F)),2)) 2903 | 2904 | 2905 | local bits = tvbuffer(0+tcpOffset,1):uint() 2906 | 2907 | payload = bit.rshift(bit.band(bits,0xC0),6) 2908 | 2909 | att_str = "RTP PAYLOAD TYPE" 2910 | if payload == 1 then 2911 | att_str = "Version 1" 2912 | elseif payload == 2 then 2913 | att_str = "Version 2" 2914 | end 2915 | attributeTree:add(F_attribute_sub, tvbuffer(0+tcpOffset,1), cmd_str) 2916 | :set_text("RTP Version (2 bits): " .. att_str .. " (" .. tostring(payload) .. ")") 2917 | 2918 | attributeTree:add(F_attribute_sub, tvbuffer(0+tcpOffset,1), cmd_str) 2919 | :set_text("padding (1 bit): 0x" .. tostring(bit.tohex((bit.band(bits,0x20)),2))) 2920 | 2921 | attributeTree:add(F_attribute_sub, tvbuffer(0+tcpOffset,1), cmd_str) 2922 | :set_text("Extension (1 bit): 0x" .. tostring(bit.tohex((bit.band(bits,0x10)),2))) 2923 | 2924 | 2925 | attributeTree:add(F_attribute_sub, tvbuffer(0+tcpOffset,1), cmd_str) 2926 | :set_text("CSRC count (4 bits): 0x" .. tostring(bit.tohex((bit.band(bits,0x0F)),2))) 2927 | 2928 | local byte = tvbuffer(1+tcpOffset,1):uint() 2929 | 2930 | attributeTree:add(F_attribute_sub, tvbuffer(1+tcpOffset,1), cmd_str) 2931 | :set_text("Marker (1 bit): 0x" .. tostring(bit.tohex((bit.band(byte,0x80)),2))) 2932 | 2933 | 2934 | -- Can't decode payloads because of encryption :( 2935 | --0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2936 | --+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2937 | --|V=2|P|X| CC |M| PT | sequence number | 2938 | --| | | | |0| 101 | | 2939 | --+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2940 | --| timestamp | 2941 | --| | 2942 | --+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2943 | --| synchronization source (SSRC) identifier | 2944 | --| | 2945 | --+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2946 | --| event |E R| volume | duration | 2947 | --| 1 |1 0| 20 | 1760 | 2948 | --+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 2949 | 2950 | payload = bit.band(byte,0x7F) 2951 | 2952 | att_str = "RTP PAYLOAD TYPE" 2953 | if payload == 0 then 2954 | att_str = "G.711 u-Law" 2955 | elseif payload == 3 then 2956 | att_str = "GSM 6.10" 2957 | elseif payload == 4 then 2958 | att_str = "G.723.1 " 2959 | elseif payload == 8 then 2960 | att_str = "G.711 A-Law" 2961 | elseif payload == 9 or payload == 117 then 2962 | att_str = "G.722" 2963 | elseif payload == 13 then 2964 | att_str = "Comfort Noise" 2965 | elseif payload == 97 then 2966 | att_str = "Redundant Audio Data Payload (FEC)" 2967 | elseif payload == 101 then 2968 | att_str = "DTMF" 2969 | elseif payload == 103 then 2970 | att_str = "SILK Narrow" 2971 | elseif payload == 104 then 2972 | att_str = "SILK Wideband" 2973 | elseif payload == 111 then 2974 | att_str = "Siren" 2975 | elseif payload == 112 then 2976 | att_str = "G.722.1" 2977 | elseif payload == 114 then 2978 | att_str = "RT Audio Wideband" 2979 | elseif payload == 115 then 2980 | att_str = "RT Audio Narrowband" 2981 | elseif payload == 116 then 2982 | att_str = "G.726" 2983 | elseif payload == 118 then 2984 | att_str = "Comfort Noise Wideband" 2985 | elseif payload == 34 then 2986 | att_str = "H.263 [MS-H26XPF]" 2987 | elseif payload == 121 then 2988 | att_str = "RT Video" 2989 | elseif payload == 122 then 2990 | att_str = "H.264 [MS-H264PF]" 2991 | elseif payload == 123 then 2992 | att_str = "H.264 FEC [MS-H264PF]" 2993 | elseif payload == 127 then 2994 | att_str = "x-data" 2995 | else 2996 | att_str = "Unknown Codec" 2997 | 2998 | --IF IT'S ON PORT 443 THEN ASSUME THEN TRY THE TLS DECODER 2999 | if f_tcp_srcport() ~= nil and f_tcp_dstport() ~= nil then 3000 | if f_tcp_srcport().value == 443 or f_tcp_dstport().value == 443 then 3001 | original_ssl_dissector:call(tvbuffer, pinfo, treeitem) --DECODE AS TLS 3002 | end 3003 | end 3004 | end 3005 | 3006 | attributeTree:add(F_attribute_sub, tvbuffer(1+tcpOffset,1), cmd_str) 3007 | :set_text("Payload Type (7 bits): " .. att_str .. " (" .. tostring(payload) .. ")") 3008 | 3009 | --Set the Protcol and Info Columns 3010 | if(att_str ~= "Unknown Codec") then 3011 | pinfo.cols.protocol = "MSRTP" 3012 | pinfo.cols.info = "RTP PACKET : Payload Type = " .. att_str 3013 | end 3014 | 3015 | local bytes = tvbuffer(2+tcpOffset,2):uint() 3016 | 3017 | attributeTree:add(F_stunname, tvbuffer(2+tcpOffset,2), bytes) 3018 | :set_text("Sequence Number: " .. bytes) 3019 | 3020 | local bytes = tvbuffer(4+tcpOffset,4):uint() 3021 | 3022 | attributeTree:add(F_stunname, tvbuffer(4+tcpOffset,4), bytes) 3023 | :set_text("Timestamp: " .. tostring(bytes)) 3024 | 3025 | attributeTree:add(F_attribute_sub, tvbuffer(8+tcpOffset,tvbuffer:len()-8-tcpOffset), cmd_str) 3026 | :set_text("Payload: " .. tostring(tvbuffer(8+tcpOffset,tvbuffer:len()-8-tcpOffset))) 3027 | end 3028 | else 3029 | --IF WE HAVE MADE IT ALL THE WAY THOUGH AND PORT 443 IS BEING USED THEN ASSUME IT'S TLS 3030 | if f_tcp_srcport() ~= nil and f_tcp_dstport() ~= nil then 3031 | if f_tcp_srcport().value == 443 or f_tcp_dstport().value == 443 then 3032 | 3033 | original_ssl_dissector:call(tvbuffer, pinfo, treeitem) --DECODE AS TLS 3034 | 3035 | else 3036 | 3037 | attributeTree = subtreeitem:add(F_stunname, tvbuffer(0+tcpOffset,1), attribute_bytes) 3038 | attributeTree:set_text("UNABLE TO DECODE THIS PACKET :(") 3039 | 3040 | end 3041 | end 3042 | end 3043 | end 3044 | end 3045 | end -- 2.0 Buffer size check 3046 | end 3047 | 3048 | 3049 | -- Fast XOR Arno Wagner 3050 | function bin_xor(x, y) 3051 | local z = 0 3052 | for i = 0, 31 do 3053 | if (x % 2 == 0) then -- x had a '0' in bit i 3054 | if ( y % 2 == 1) then -- y had a '1' in bit i 3055 | y = y - 1 3056 | z = z + 2 ^ i -- set bit i of z to '1' 3057 | end 3058 | else -- x had a '1' in bit i 3059 | x = x - 1 3060 | if (y % 2 == 0) then -- y had a '0' in bit i 3061 | z = z + 2 ^ i -- set bit i of z to '1' 3062 | else 3063 | y = y - 1 3064 | end 3065 | end 3066 | y = y / 2 3067 | x = x / 2 3068 | end 3069 | return z 3070 | end 3071 | 3072 | -- Convert Byte to BitArray #################################################### 3073 | function to_bits(n) 3074 | --check_int(n) 3075 | --if(n < 0) then 3076 | -- negative 3077 | --return to_bits(bit.bnot(math.abs(n)) + 1) 3078 | --end 3079 | 3080 | -- to bits table 3081 | local tbl = {} 3082 | local cnt = 1 3083 | while (n > 0) do 3084 | --CHANGED FOR 2.0 - mod not supported anymore 3085 | --local last = math.mod(n,2) 3086 | local last = math.fmod(n,2) 3087 | if(last == 1) then 3088 | tbl[cnt] = 1 3089 | else 3090 | tbl[cnt] = 0 3091 | end 3092 | n = (n-last)/2 3093 | cnt = cnt + 1 3094 | end 3095 | return tbl 3096 | end 3097 | 3098 | original_udp_port = prefs.udpprotocolport 3099 | original_tcp_port = prefs.tcpprotocolport 3100 | 3101 | local udp_dissector_table = DissectorTable.get("udp.port") 3102 | original_stun_dissector = udp_dissector_table:get_dissector(original_udp_port) -- save the original dissector so we can still get to it 3103 | 3104 | local tcp_dissector_table = DissectorTable.get("tcp.port") 3105 | original_tcp_stun_dissector = tcp_dissector_table:get_dissector(original_tcp_port) -- save the original dissector so we can still get to it 3106 | 3107 | 3108 | function lync_wrapper_proto.init() --Preference Update 3109 | if original_udp_port ~= prefs.udpprotocolport then 3110 | udp_dissector_table:add(original_udp_port, original_stun_dissector) 3111 | udp_dissector_table:add(prefs.udpprotocolport, lync_wrapper_proto) 3112 | end 3113 | 3114 | if original_tcp_port ~= prefs.tcpprotocolport then 3115 | tcp_dissector_table:add(original_tcp_port, original_tcp_stun_dissector) 3116 | tcp_dissector_table:add(prefs.tcpprotocolport, lync_wrapper_proto) 3117 | end 3118 | 3119 | if prefs.port50000 and prefs.port3478 then 3120 | 3121 | --Add dissector for 3478 3122 | udp_dissector_table:add(prefs.udpprotocolport, lync_wrapper_proto) 3123 | 3124 | elseif not prefs.port50000 and prefs.port3478 then 3125 | 3126 | --Add dissector for 3478 3127 | udp_dissector_table:add(prefs.udpprotocolport, lync_wrapper_proto) 3128 | 3129 | elseif prefs.port50000 and not prefs.port3478 then 3130 | 3131 | --Remove dissector for 3478 3132 | udp_dissector_table:remove(prefs.udpprotocolport, lync_wrapper_proto) 3133 | 3134 | else 3135 | --Reset to initial dissector 3136 | udp_dissector_table:add(original_udp_port, original_stun_dissector) 3137 | end 3138 | 3139 | --Setup TCP Dissector 3140 | if prefs.port443 then 3141 | tcp_dissector_table:add(prefs.tcpprotocolport, lync_wrapper_proto) 3142 | else 3143 | tcp_dissector_table:add(original_tcp_port, original_tcp_stun_dissector) 3144 | end 3145 | 3146 | if prefs.portexternal443 then 3147 | tcp_dissector_table:add(prefs.tcpexternalprotocolport, lync_wrapper_proto) 3148 | else 3149 | tcp_dissector_table:add(original_tcp_port, original_tcp_stun_dissector) 3150 | end 3151 | 3152 | 3153 | end 3154 | 3155 | function myproto_udp_init(port) 3156 | -- load the udp.port table 3157 | udp_table = DissectorTable.get("udp.port") 3158 | -- register the protocol to handle rtp port dynamically 3159 | udp_table:add(port,lync_wrapper_proto) 3160 | end 3161 | 3162 | function myproto_udp_remove_init(port) 3163 | -- load the udp.port table 3164 | udp_table = DissectorTable.get("udp.port") 3165 | -- register the protocol to handle rtp port dynamically 3166 | udp_table:remove(port,lync_wrapper_proto) 3167 | end 3168 | 3169 | function myproto_tcp_init(port) 3170 | -- load the udp.port table 3171 | tcp_table = DissectorTable.get("tcp.port") 3172 | -- register the protocol to handle rtp port dynamically 3173 | tcp_table:add(port,lync_wrapper_proto) 3174 | end 3175 | 3176 | function myproto_tcp_remove_init(port) 3177 | -- load the tcp.port table 3178 | tcp_table = DissectorTable.get("tcp.port") 3179 | -- register the protocol to handle rtp port dynamically 3180 | tcp_table:remove(port,lync_wrapper_proto) 3181 | end 3182 | end 3183 | --------------------------------------------------------------------------------