mirror of
				https://github.com/ossrs/srs.git
				synced 2025-03-09 15:49:59 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			938 lines
		
	
	
	
		
			37 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			938 lines
		
	
	
	
		
			37 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| -- @brief srt-dev Protocol dissector plugin
 | |
| 
 | |
| -- create a new dissector
 | |
| local NAME = "SRT-dev"
 | |
| local srt_dev = Proto(NAME, "SRT-dev Protocol")
 | |
| 
 | |
| -- create a preference of a Protocol
 | |
| srt_dev.prefs["srt_udp_port"] = Pref.uint("SRT UDP Port", 1935, "SRT UDP Port")
 | |
| 
 | |
| -- create fields of srt_dev
 | |
| -- Base.HEX, Base.DEC, Base.OCT, Base.UNIT_STRING, Base.NONE
 | |
| local fields = srt_dev.fields
 | |
| -- General field
 | |
| local pack_type_select = {
 | |
| 	[0] = "Data Packet",
 | |
| 	[1] = "Control Packet"
 | |
| }
 | |
| fields.pack_type_tree = ProtoField.uint32(NAME .. ".pack_type_tree", "Packet Type", base.HEX)
 | |
| fields.pack_type = ProtoField.uint16("srt_dev.pack_type", "Packet Type", base.HEX, pack_type_select, 0x8000)
 | |
| fields.reserve = ProtoField.uint16("srt_dev.reserve", "Reserve", base.DEC)
 | |
| fields.additional_info = ProtoField.uint32("srt_dev.additional_info", "Additional Information", base.DEC)
 | |
| fields.time_stamp = ProtoField.uint32("srt_dev.time_stamp", "Time Stamp", base.DEC)
 | |
| fields.dst_sock = ProtoField.uint32("srt_dev.dst_sock", "Destination Socket ID", base.DEC)
 | |
| fields.none = ProtoField.none("srt_dev.none", "none", base.NONE)
 | |
| 
 | |
| -- Data packet fields
 | |
| fields.data_flag_info_tree = ProtoField.uint8("srt_dev.data_flag_info_tree", "Data Flag Info", base.HEX)
 | |
| local FF_state_select = {
 | |
| 	[0] = "[Middle packet]",
 | |
| 	[1] = "[Last packet]",
 | |
| 	[2] = "[First packet]",
 | |
| 	[3] = "[Single packet]"
 | |
| }
 | |
| fields.FF_state = ProtoField.uint8("srt_dev.FF_state", "FF state", base.HEX, FF_state_select, 0xC0)
 | |
| local O_state_select = {
 | |
| 	[0] = "[ORD_RELAX]",
 | |
| 	[1] = "[ORD_REQUIRED]"
 | |
| }
 | |
| fields.O_state = ProtoField.uint8("srt_dev.O_state", "O state", base.HEX, O_state_select, 0x20)
 | |
| local KK_state_select = {
 | |
| 	[0] = "[Not encrypted]",
 | |
| 	[1] = "[Data encrypted with even key]",
 | |
| 	[2] = "[Data encrypted with odd key]"
 | |
| }
 | |
| fields.KK_state = ProtoField.uint8("srt_dev.KK_state", "KK state", base.HEX, KK_state_select, 0x18)
 | |
| local R_state_select = {
 | |
| 	[0] = "[ORIGINAL]",
 | |
| 	[1] = "[RETRANSMITTED]"
 | |
| }
 | |
| fields.R_state = ProtoField.uint8("srt_dev.R_state", "R state", base.HEX, R_state_select, 0x04)
 | |
| fields.seq_num = ProtoField.uint32("srt_dev.seq_num", "Sequence Number", base.DEC)
 | |
| fields.msg_num = ProtoField.uint32("srt_dev.msg_num", "Message Number", base.DEC)--, nil, 0x3FFFFFF)
 | |
| 
 | |
| -- control packet fields
 | |
| local msg_type_select = {
 | |
| 	[0] = "[HANDSHAKE]",
 | |
| 	[1] = "[KEEPALIVE]",
 | |
| 	[2] = "[ACK]",
 | |
| 	[3] = "[NAK(Loss Report)]",
 | |
| 	[4] = "[Congestion Warning]",
 | |
| 	[5] = "[Shutdown]",
 | |
| 	[6] = "[ACKACK]",
 | |
| 	[7] = "[Drop Request]",
 | |
| 	[8] = "[Peer Error]",
 | |
| 	[0x7FFF] = "[Message Extension Type]"
 | |
| }
 | |
| fields.msg_type = ProtoField.uint16("srt_dev.msg_type", "Message Type", base.HEX, msg_type_select, 0x7FFF)
 | |
| fields.msg_ext_type = ProtoField.uint16("srt_dev.msg_ext_type", "Message Extented Type", base.DEC)
 | |
| 
 | |
| local flag_state_select = {
 | |
| 	[0] = "Unset",
 | |
| 	[1] = "Set"
 | |
| }
 | |
| 
 | |
| -- Handshake packet fields
 | |
| fields.UDT_version = ProtoField.uint32("srt_dev.UDT_version", "UDT Version", base.DEC)
 | |
| fields.sock_type = ProtoField.uint32("srt_dev.sock_type", "Socket Type", base.DEC)
 | |
| fields.ency_fld = ProtoField.uint16("srt_dev.ency_fld", "Encryption Field", base.DEC)
 | |
| fields.ext_fld = ProtoField.uint16("srt_dev.ext_fld", "Extension Fields", base.HEX)
 | |
| fields.ext_fld_tree = ProtoField.uint16("srt_dev.ext_fld_tree", "Extension Fields Tree", base.HEX)
 | |
| fields.hsreq = ProtoField.uint16("srt_dev.hsreq", "HS_EXT_HSREQ", base.HEX, flag_state_select, 0x1)
 | |
| fields.kmreq = ProtoField.uint16("srt_dev.kmreq", "HS_EXT_KMREQ", base.HEX, flag_state_select, 0x2)
 | |
| fields.config = ProtoField.uint16("srt_dev.config", "HS_EXT_CONFIG", base.HEX, flag_state_select, 0x4)
 | |
| fields.isn = ProtoField.uint32("srt_dev.isn", "Initial packet sequence number", base.DEC)
 | |
| fields.mss = ProtoField.uint32("srt_dev.mss", "Max Packet Size", base.DEC)
 | |
| fields.fc = ProtoField.uint32("srt_dev.fc", "Maximum Flow Window Size", base.DEC)
 | |
| fields.conn_type = ProtoField.int32("srt_dev.conn_type", "Connection Type", base.DEC)
 | |
| fields.sock_id = ProtoField.uint32("srt_dev.sock_id", "Socket ID", base.DEC)
 | |
| fields.syn_cookie = ProtoField.uint32("srt_dev.syn_cookie", "SYN cookie", base.DEC)
 | |
| fields.peer_ipaddr = ProtoField.none("srt_dev.peer_ipaddr", "Peer IP address", base.NONE)
 | |
| fields.peer_ipaddr_4 = ProtoField.ipv4("srt_dev.peer_ipaddr", "Peer IP address")
 | |
| fields.peer_ipaddr_6 = ProtoField.ipv6("srt_dev.peer_ipaddr", "Peer IP address")
 | |
| local ext_type_select = {
 | |
| 	[-1] = "SRT_CMD_NONE",
 | |
| 	[0] = "SRT_CMD_REJECT",
 | |
| 	[1] = "SRT_CMD_HSREQ",
 | |
| 	[2] = "SRT_CMD_HSRSP",
 | |
| 	[3] = "SRT_CMD_KMREQ",
 | |
| 	[4] = "SRT_CMD_KMRSP",
 | |
| 	[5] = "SRT_CMD_SID",
 | |
| 	[6] = "SRT_CMD_CONGESTION",
 | |
| 	[7] = "SRT_CMD_FILTER",
 | |
| 	[8] = "SRT_CMD_GROUP"
 | |
| }
 | |
| fields.ext_type_msg_tree = ProtoField.none("srt_dev.ext_type", "Extension Type Message", base.NONE)
 | |
| fields.ext_type = ProtoField.uint16("srt_dev.ext_type", "Extension Type", base.HEX, ext_type_select, 0xF)
 | |
| fields.ext_size = ProtoField.uint16("srt_dev.ext_size", "Extension Size", base.DEC)
 | |
| 
 | |
| -- Handshake packet, ext type == SRT_CMD_HSREQ or SRT_CMD_HSRSP field
 | |
| fields.srt_version = ProtoField.uint32("srt_dev.srt_version", "SRT Version", base.HEX)
 | |
| fields.srt_flags = ProtoField.uint32("srt_dev.srt_flags", "SRT Flags", base.HEX)
 | |
| fields.tsbpb_resv = ProtoField.uint16("srt_dev.tsbpb_resv", "TsbPb Receive", base.DEC)
 | |
| fields.tsbpb_delay = ProtoField.uint16("srt_dev.tsbpb_delay", "TsbPb Delay", base.DEC)
 | |
| fields.tsbpd_delay = ProtoField.uint16("srt_dev.tsbpd_delay", "TsbPd Delay", base.DEC)
 | |
| fields.rcv_tsbpd_delay = ProtoField.uint16("srt_dev.rcv_tsbpd_delay", "Receiver TsbPd Delay", base.DEC)
 | |
| fields.snd_tsbpd_delay = ProtoField.uint16("srt_dev.snd_tsbpd_delay", "Sender TsbPd Delay", base.DEC)
 | |
| 
 | |
| -- V and PT status flag
 | |
| local V_state_select = {
 | |
| 	[1] = "Initial version"
 | |
| }
 | |
| fields.V_state = ProtoField.uint8("srt_dev.V_state", "V", base.HEX, V_state_select, 0x70)
 | |
| local PT_state_select = {
 | |
| 	[0] = "Reserved",
 | |
| 	[1] = "MSmsg",
 | |
| 	[2] = "KMmsg",
 | |
| 	[7] = "Reserved to discriminate MPEG-TS packet(0x47=sync byte)"
 | |
| }
 | |
| fields.PT_state = ProtoField.uint8("srt_dev.PT_state", "PT", base.HEX, state_table, 0xF)
 | |
| fields.sign = ProtoField.uint16("srt_dev.sign", "Signature", base.HEX)
 | |
| local resv_select = {
 | |
| 	[0] = "Reserved for flag extension or other usage"
 | |
| }
 | |
| fields.resv = ProtoField.uint8("srt_dev.resv", "Resv", base.DEC, state_table, 0xFC)
 | |
| fields.ext_KK_state = ProtoField.uint8("srt_dev.ext_KK_state", "KK_state", base.HEX, KK_state_select, 0x3)
 | |
| fields.KEKI = ProtoField.uint32("srt_dev.KEKI", "KEKI", base.DEC)
 | |
| fields.cipher = ProtoField.uint8("srt_dev.cipher", "Cipher", base.DEC)
 | |
| fields.auth = ProtoField.uint8("srt_dev.auth", "auth", base.DEC)
 | |
| fields.SE = ProtoField.uint8("srt_dev.SE", "SE", base.DEC)
 | |
| fields.resv1 = ProtoField.uint8("srt_dev.resv1", "resv1", base.DEC)
 | |
| fields.resv2 = ProtoField.uint16("srt_dev.resv2", "resv2", base.DEC)
 | |
| fields.slen = ProtoField.uint8("srt_dev.slen", "Salt length(bytes)/4", base.DEC)
 | |
| fields.klen = ProtoField.uint8("srt_dev.klen", "SEK length(bytes)/4", base.DEC)
 | |
| fields.salt = ProtoField.uint32("srt_dev.salt", "Salt key", base.DEC)
 | |
| fields.wrap = ProtoField.none("srt_dev.wrap", "Wrap key(s)", base.NONE)
 | |
| 
 | |
| -- Wrap Field
 | |
| fields.ICV = ProtoField.uint64("srt_dev.ICV", "Integerity Check Vector", base.HEX)
 | |
| fields.odd_key = ProtoField.stringz("srt_dev.odd_key", "Odd key", base.ASCII)
 | |
| fields.even_key = ProtoField.stringz("srt_dev.even_key", "Even key", base.ASCII)
 | |
| 
 | |
| -- ext_type == SRT_CMD_SID field
 | |
| fields.sid = ProtoField.string("srt_dev.sid", "Stream ID", base.ASCII)
 | |
| -- ext_type == SRT_CMD_CONGESTION field
 | |
| fields.congestion = ProtoField.string("srt_dev.congestion", "Congestion Controller", base.ASCII)
 | |
| -- ext_type == SRT_CMD_FILTER field
 | |
| fields.filter = ProtoField.string("srt_dev.filter", "Filter", base.ASCII)
 | |
| -- ext_type == SRT_CMD_GROUP field
 | |
| fields.group = ProtoField.string("srt_dev.group", "Group Data", base.ASCII)
 | |
| 
 | |
| -- SRT flags
 | |
| fields.srt_opt_tsbpdsnd = ProtoField.uint32("srt_dev.srt_opt_tsbpdsnd", "SRT_OPT_TSBPDSND", base.HEX, flag_state_select, 0x1)
 | |
| fields.srt_opt_tsbpdrcv = ProtoField.uint32("srt_dev.srt_opt_tsbpdrcv", "SRT_OPT_TSBPDRCV", base.HEX, flag_state_select, 0x2)
 | |
| fields.srt_opt_haicrypt = ProtoField.uint32("srt_dev.srt_opt_haicrypt", "SRT_OPT_HAICRYPT", base.HEX, flag_state_select, 0x4)
 | |
| fields.srt_opt_tlpktdrop = ProtoField.uint32("srt_dev.srt_opt_tlpktdrop", "SRT_OPT_TLPKTDROP", base.HEX, flag_state_select, 0x8)
 | |
| fields.srt_opt_nakreport = ProtoField.uint32("srt_dev.srt_opt_nakreport", "SRT_OPT_NAKREPORT", base.HEX, flag_state_select, 0x10)
 | |
| fields.srt_opt_rexmitflg = ProtoField.uint32("srt_dev.srt_opt_rexmitflg", "SRT_OPT_REXMITFLG", base.HEX, flag_state_select, 0x20)
 | |
| fields.srt_opt_stream = ProtoField.uint32("srt_dev.srt_opt_stream", "SRT_OPT_STREAM", base.HEX, flag_state_select, 0x40)
 | |
| 
 | |
| -- ACK fields
 | |
| fields.last_ack_pack = ProtoField.uint32("srt_dev.last_ack_pack", "Last ACK Packet Sequence Number", base.DEC)
 | |
| fields.rtt = ProtoField.int32("srt_dev.rtt", "Round Trip Time", base.DEC)
 | |
| fields.rtt_variance = ProtoField.int32("srt_dev.rtt_variance", "Round Trip Time Variance", base.DEC)
 | |
| fields.buf_size = ProtoField.uint32("srt_dev.buf_size", "Available Buffer Size", base.DEC)
 | |
| fields.pack_rcv_rate = ProtoField.uint32("srt_dev.pack_rcv_rate", "Packet Receiving Rate", base.DEC)
 | |
| fields.est_link_capacity = ProtoField.uint32("srt_dev.est_link_capacity", "Estimated Link Capacity", base.DEC)
 | |
| fields.rcv_rate = ProtoField.uint32("srt_dev.rcv_rate", "Receiving Rate", base.DEC)
 | |
| 
 | |
| -- ACKACK fields
 | |
| fields.ack_num = ProtoField.uint32("srt_dev.ack_num", "ACK number", base.DEC)
 | |
| fields.ctl_info = ProtoField.uint32("srt_dev.ctl_info", "Control Information", base.DEC)
 | |
| 
 | |
| -- KMRSP fields
 | |
| local srt_km_state_select = {
 | |
| 	[0] = "[SRT_KM_UNSECURED]",
 | |
| 	[1] = "[SRT_KM_SECURING]",
 | |
| 	[2] = "[SRT_KM_SECURED]",
 | |
| 	[3] = "[SRT_KM_NOSECRET]",
 | |
| 	[4] = "[SRT_KM_BADSECRET]"
 | |
| }
 | |
| fields.km_err = ProtoField.uint32("srt_dev.km_err", "Key Message Error", base.HEX, srt_km_state_select, 0xF)
 | |
| 
 | |
| -- NAK Control Packet fields
 | |
| fields.lost_list_tree = ProtoField.none("srt_dev.lost_list_tree", "Lost Packet List", base.NONE)
 | |
| fields.lost_pack_seq = ProtoField.uint32("srt_dev.lost_pack_seq", "Lost Packet Sequence Number", base.DEC)
 | |
| fields.lost_pack_range_tree = ProtoField.none("srt_dev.lost_pack_range_tree", "Lost Packet Range", base.NONE)
 | |
| fields.lost_start = ProtoField.uint32("srt_dev.lost_start", "Lost Starting Sequence", base.DEC)
 | |
| fields.lost_up_to = ProtoField.uint32("srt_dev.lost_up_to", "Lost Up To(including)", base.DEC)
 | |
| 
 | |
| -- Dissect packet
 | |
| function srt_dev.dissector (tvb, pinfo, tree)
 | |
| 	-- Packet is based on UDP, so the data can be processed directly after UDP
 | |
| 	local subtree = tree:add(srt_dev, tvb())
 | |
| 	local offset = 0
 | |
| 	
 | |
| 	-- Changes the protocol name
 | |
| 	pinfo.cols.protocol = srt_dev.name
 | |
| 	
 | |
| 	-- Take out the first bit of package
 | |
| 	-- 0 -> Data Packet
 | |
| 	-- 1 -> Control Packet
 | |
| 	local typebit = bit.rshift(tvb(offset, 1):uint(), 7)
 | |
| 	pack_type_tree = subtree:add(fields.pack_type_tree, tvb(offset, 4))
 | |
| 	
 | |
| 	if typebit == 1 then
 | |
| 		-- Handle Control Packet
 | |
| 		pack_type_tree:add(fields.pack_type, tvb(offset, 2))
 | |
| 		
 | |
| 		local msg_type = tvb(offset, 2):uint()
 | |
| 		if msg_type ~= 0xFFFF then
 | |
| 			-- If type field isn't '0x7FFF',it means packet is normal data packet, then handle type field
 | |
| 			msg_type = bit.band(msg_type, 0x7FFF)
 | |
| 			
 | |
| 			function parse_three_param()
 | |
| 				-- Ignore Additional Info (this field is not defined in this packet type)
 | |
| 				subtree:add(fields.additional_info, tvb(offset, 4)):append_text(" [undefined]")
 | |
| 				offset = offset + 4
 | |
| 				
 | |
| 				-- Handle Time Stamp
 | |
| 				subtree:add(fields.time_stamp, tvb(offset, 4)):append_text(" μs")
 | |
| 				offset = offset + 4
 | |
| 				
 | |
| 				-- Handle Destination Socket
 | |
| 				subtree:add(fields.dst_sock, tvb(offset, 4))
 | |
| 				offset = offset + 4
 | |
| 			end
 | |
| 			
 | |
| 			local switch = {
 | |
| 				[0] = function()
 | |
| 					pinfo.cols.info:append(" [HANDSHAKE]")
 | |
| 					pack_type_tree:append_text(" [HANDSHAKE]")
 | |
| 					pack_type_tree:add(fields.msg_type, tvb(offset, 2))
 | |
| 					pack_type_tree:add(fields.reserve, tvb(offset + 2, 2)):append_text(" [Undefined]")
 | |
| 					offset = offset + 4
 | |
| 					
 | |
| 					-- Handle Additional Info, Timestamp and Destination Socket
 | |
| 					parse_three_param()
 | |
| 
 | |
| 					-- Handle UDT version field
 | |
| 					local UDT_version = tvb(offset, 4):uint()
 | |
| 					subtree:add(fields.UDT_version, tvb(offset, 4))
 | |
| 					offset = offset + 4
 | |
| 					
 | |
| 					if UDT_version == 4 then
 | |
| 						-- UDT version is 4, packet is different from UDT version 5
 | |
| 						-- Handle sock type
 | |
| 						local sock_type = tvb(offset, 4):uint()
 | |
| 						if sock_type == 1 then
 | |
| 							subtree:add(fields.sock_type, tvb(offset, 4)):append_text(" [SRT_STREAM]")
 | |
| 						elseif sock_type == 2 then
 | |
| 							subtree:add(fields.sock_type, tvb(offset, 4)):append_text(" [SRT_DRAGAM]")
 | |
| 						end
 | |
| 						offset = offset + 4
 | |
| 					elseif UDT_version == 5 then
 | |
| 						-- Handle Encryption Field
 | |
| 						local encr_fld = tvb(offset, 2):int()
 | |
| 						if encr_fld == 0 then
 | |
| 							subtree:add(fields.ency_fld, tvb(offset, 2)):append_text(" (PBKEYLEN not advertised)")
 | |
| 						elseif encr_fld == 2 then
 | |
| 							subtree:add(fields.ency_fld, tvb(offset, 2)):append_text(" (AES-128)")
 | |
| 						elseif encr_fld == 3 then
 | |
| 							subtree:add(fields.ency_fld, tvb(offset, 2)):append_text(" (AES-192)")
 | |
| 						else
 | |
| 							subtree:add(fields.ency_fld, tvb(offset, 2)):append_text(" (AES-256)")
 | |
| 						end
 | |
| 						offset = offset + 2
 | |
| 						
 | |
| 						-- Handle Extension Field
 | |
| 						local ext_fld = tvb(offset, 2):int()
 | |
| 						if ext_fld == 0x4A17 then
 | |
| 							subtree:add(fields.ext_fld, tvb(offset, 2)):append_text(" [HSv5 MAGIC]")
 | |
| 						else
 | |
| 							-- Extension Field is HS_EXT_prefix
 | |
| 							-- The define is in fiel handshake.h
 | |
| 							local ext_fld_tree = subtree:add(fields.ext_fld_tree, tvb(offset, 2))
 | |
| 							local str_table = { " [" }
 | |
| 							ext_fld_tree:add(fields.hsreq, tvb(offset, 2))
 | |
| 							if bit.band(tvb(offset, 2):uint(), 0x1) == 1 then
 | |
| 								table.insert(str_table, "HS_EXT_HSREQ")
 | |
| 								table.insert(str_table, " | ")
 | |
| 							end
 | |
| 							ext_fld_tree:add(fields.kmreq, tvb(offset, 2)):append_text(" [HS_EXT_KMREQ]")
 | |
| 							if bit.band(tvb(offset, 2):uint(), 0x2) == 2 then
 | |
| 								table.insert(str_table, "HS_EXT_KMREQ")
 | |
| 								table.insert(str_table, " | ")
 | |
| 							end
 | |
| 							ext_fld_tree:add(fields.config, tvb(offset, 2)):append_text(" [HS_EXT_CONFIG]")
 | |
| 							if bit.band(tvb(offset, 2):uint(), 0x4) == 4 then
 | |
| 								table.insert(str_table, "HS_EXT_CONFIG")
 | |
| 								table.insert(str_table, " | ")
 | |
| 							end
 | |
| 							table.remove(str_table)
 | |
| 							table.insert(str_table, "]")
 | |
| 							if ext_fld ~= 0 then
 | |
| 								ext_fld_tree:append_text(table.concat(str_table))
 | |
| 							end
 | |
| 						end
 | |
| 						offset = offset + 2
 | |
| 					end
 | |
| 					
 | |
| 					-- Handle Initial packet sequence number
 | |
| 					subtree:add(fields.isn, tvb(offset, 4))
 | |
| 					offset = offset + 4
 | |
| 					
 | |
| 					-- Handle Maximum Packet Size
 | |
| 					subtree:add(fields.mss, tvb(offset, 4))
 | |
| 					offset = offset + 4
 | |
| 					
 | |
| 					-- Handle Maximum Flow Window Size
 | |
| 					subtree:add(fields.fc, tvb(offset, 4))
 | |
| 					offset = offset + 4
 | |
| 					
 | |
| 					-- Handle Connection Type
 | |
| 					local conn_type = tvb(offset, 4):int()
 | |
| 					local conn_type_tree = subtree:add(fields.conn_type, tvb(offset, 4))
 | |
| 					if conn_type == 0 then
 | |
| 						conn_type_tree:append_text(" [WAVEAHAND] (Rendezvous Mode)")
 | |
| 						pinfo.cols.info:append(" [WAVEAHAND] (Rendezvous Mode)")
 | |
| 					elseif conn_type == 1 then
 | |
| 						conn_type_tree:append_text(" [INDUCTION]")
 | |
| 					elseif conn_type == -1 then
 | |
| 						conn_type_tree:append_text(" [CONCLUSION]")
 | |
| 					elseif conn_type == -2 then
 | |
| 						conn_type_tree:append_text(" [AGREEMENT] (Rendezvous Mode)")
 | |
| 						pinfo.cols.info:append(" [AGREEMENT] (Rendezvous Mode)")
 | |
| 					end
 | |
| 					offset = offset + 4
 | |
| 					
 | |
| 					-- Handle Socket ID
 | |
| 					subtree:add(fields.sock_id, tvb(offset, 4))
 | |
| 					offset = offset + 4
 | |
| 					
 | |
| 					-- Handle SYN cookie
 | |
| 					local syn_cookie = tvb(offset, 4):int()
 | |
| 					subtree:add(fields.syn_cookie, tvb(offset, 4))
 | |
| 					if syn_cookie == 0 then
 | |
| 						conn_type_tree:append_text(" (Caller to Listener)")
 | |
| 						pinfo.cols.info:append(" (Caller to Listener)")
 | |
| 					else
 | |
| 						if conn_type == 1 then
 | |
| 							-- reports cookie from listener
 | |
| 							conn_type_tree:append_text(" (Listener to Caller)")
 | |
| 							pinfo.cols.info:append(" (Listener to Caller)")
 | |
| 						end
 | |
| 					end
 | |
| 					offset = offset + 4
 | |
| 					
 | |
| 					-- Handle Peer IP address
 | |
| 					-- Note the network byte order
 | |
| 					local the_last_96_bits = 0
 | |
| 					the_last_96_bits = the_last_96_bits + math.floor(tvb(offset + 4, 4):int() * (2 ^ 16))
 | |
| 					the_last_96_bits = the_last_96_bits + math.floor(tvb(offset + 8, 4):int() * (2 ^ 8))
 | |
| 					the_last_96_bits = the_last_96_bits + tvb(offset + 12, 4):int()
 | |
| 					if the_last_96_bits == 0 then
 | |
| 						subtree:add_le(fields.peer_ipaddr_4, tvb(offset, 4))
 | |
| 					else
 | |
| 						subtree:add_le(fields.peer_ipaddr, tvb(offset, 16))
 | |
| 					end
 | |
| 					
 | |
| 					offset = offset + 16
 | |
| 					
 | |
| 					-- UDT version is 4, packet handle finish
 | |
| 					if UDT_version == 4 or offset == tvb:len() then
 | |
| 						return
 | |
| 					end
 | |
| 					
 | |
| 					function process_ext_type()
 | |
| 						-- Handle Ext Type, processing by type
 | |
| 						local ext_type = tvb(offset, 2):int()
 | |
| 						if ext_type == 1 or ext_type == 2 then
 | |
| 							local ext_type_msg_tree = subtree:add(fields.ext_type_msg_tree, tvb(offset, 16))
 | |
| 							if ext_type == 1 then
 | |
| 								ext_type_msg_tree:append_text(" [SRT_CMD_HSREQ]")
 | |
| 								ext_type_msg_tree:add(fields.ext_type, tvb(offset, 2))
 | |
| 								conn_type_tree:append_text(" (Caller to Listener)")
 | |
| 								pinfo.cols.info:append(" (Caller to Listener)")
 | |
| 							else
 | |
| 								ext_type_msg_tree:append_text(" [SRT_CMD_HSRSP]")
 | |
| 								ext_type_msg_tree:add(fields.ext_type, tvb(offset, 2))
 | |
| 								conn_type_tree:append_text(" (Listener to Caller)")
 | |
| 								pinfo.cols.info:append(" (Listener to Caller)")
 | |
| 							end
 | |
| 							offset = offset + 2
 | |
| 							
 | |
| 							-- Handle Ext Size
 | |
| 							ext_type_msg_tree:add(fields.ext_size, tvb(offset, 2))
 | |
| 							offset = offset + 2
 | |
| 							
 | |
| 							-- Handle SRT Version
 | |
| 							ext_type_msg_tree:add(fields.srt_version, tvb(offset, 4))
 | |
| 							offset = offset + 4
 | |
| 							
 | |
| 							-- Handle SRT Flags
 | |
| 							local SRT_flags_tree = ext_type_msg_tree:add(fields.srt_flags, tvb(offset, 4))
 | |
| 							SRT_flags_tree:add(fields.srt_opt_tsbpdsnd, tvb(offset, 4))
 | |
| 							SRT_flags_tree:add(fields.srt_opt_tsbpdrcv, tvb(offset, 4))
 | |
| 							SRT_flags_tree:add(fields.srt_opt_haicrypt, tvb(offset, 4))
 | |
| 							SRT_flags_tree:add(fields.srt_opt_tlpktdrop, tvb(offset, 4))
 | |
| 							SRT_flags_tree:add(fields.srt_opt_nakreport, tvb(offset, 4))
 | |
| 							SRT_flags_tree:add(fields.srt_opt_rexmitflg, tvb(offset, 4))
 | |
| 							SRT_flags_tree:add(fields.srt_opt_stream, tvb(offset, 4))
 | |
| 							offset = offset + 4
 | |
| 							
 | |
| 							-- Handle Recv TsbPd Delay and Snd TsbPd Delay
 | |
| 							if UDT_version == 4 then
 | |
| 								ext_type_msg_tree:add(fields.tsbpd_delay, tvb(offset, 2)):append_text(" [Unused in HSv4]")
 | |
| 								offset = offset + 2
 | |
| 								ext_type_msg_tree:add(fields.tsbpb_delay, tvb(offset, 2))
 | |
| 								offset = offset + 2
 | |
| 							else
 | |
| 								ext_type_msg_tree:add(fields.rcv_tsbpd_delay, tvb(offset, 2))
 | |
| 								offset = offset + 2
 | |
| 								ext_type_msg_tree:add(fields.snd_tsbpd_delay, tvb(offset, 2))
 | |
| 								offset = offset + 2
 | |
| 							end
 | |
| 						elseif ext_type == 3 or ext_type == 4 then
 | |
| 							local ext_type_msg_tree = subtree:add(fields.ext_type_msg_tree, tvb(offset, 16))
 | |
| 							if ext_type == 3 then
 | |
| 								ext_type_msg_tree:append_text(" [SRT_CMD_KMREQ]")
 | |
| 								ext_type_msg_tree:add(fields.ext_type, tvb(offset, 2))
 | |
| 								conn_type_tree:append_text(" (Listener to Caller)")
 | |
| 							else
 | |
| 								ext_type_msg_tree:append_text(" [SRT_CMD_KMRSP]")
 | |
| 								ext_type_msg_tree:add(fields.ext_type, tvb(offset, 2))
 | |
| 							end
 | |
| 							offset = offset + 2
 | |
| 							
 | |
| 							-- Handle Ext Size
 | |
| 							local km_len = tvb(offset, 2):uint()
 | |
| 							ext_type_msg_tree:add(fields.ext_size, tvb(offset, 2)):append_text(" (byte/4)")
 | |
| 							offset = offset + 2
 | |
| 							
 | |
| 							-- Handle SRT_CMD_KMREQ message
 | |
| 							-- V and PT status flag
 | |
| 							ext_type_msg_tree:add(fields.V_state, tvb(offset, 1))
 | |
| 							ext_type_msg_tree:add(fields.PT_state, tvb(offset, 1))
 | |
| 							offset = offset + 1
 | |
| 							
 | |
| 							-- Handle sign
 | |
| 							ext_type_msg_tree:add(fields.sign, tvb(offset, 2)):append_text(" (/'HAI/' PnP Vendor ID in big endian order)")
 | |
| 							offset = offset + 2
 | |
| 							
 | |
| 							-- Handle resv
 | |
| 							ext_type_msg_tree:add(fields.resv, tvb(offset, 1))
 | |
| 							
 | |
| 							-- Handle KK flag
 | |
| 							local KK = tvb(offset, 1):uint()
 | |
| 							ext_type_msg_tree:add(fields.ext_KK_state, tvb(offset, 1))
 | |
| 							offset = offset + 1
 | |
| 							
 | |
| 							-- Handle KEKI
 | |
| 							if tvb(offset, 4):uint() == 0 then
 | |
| 								ext_type_msg_tree:add(fields.KEKI, tvb(offset, 4)):append_text(" (Default stream associated key(stream/system default))")
 | |
| 							else
 | |
| 								ext_type_msg_tree:add(fields.KEKI, tvb(offset, 4)):append_text(" (Reserved for manually indexed keys)")
 | |
| 							end
 | |
| 							offset = offset + 4
 | |
| 							
 | |
| 							-- Handle Cipher
 | |
| 							local cipher_node = ext_type_msg_tree:add(fields.cipher, tvb(offset, 1))
 | |
| 							local cipher = tvb(offset, 1):uint()
 | |
| 							if cipher == 0 then
 | |
| 							elseif cipher == 1 then
 | |
| 								cipher_node:append_text(" (AES-ECB(potentially for VF 2.0 compatible message))")
 | |
| 							elseif cipher == 2 then
 | |
| 								cipher_node:append_text(" (AES-CTR[FP800-38A])")
 | |
| 							else
 | |
| 								cipher_node:append_text(" (AES-CCM or AES-GCM)")
 | |
| 							end
 | |
| 							offset = offset + 1
 | |
| 							
 | |
| 							-- Handle Auth
 | |
| 							if tvb(offset, 1):uint() == 0 then
 | |
| 								ext_type_msg_tree:add(fields.auth, tvb(offset, 1)):append_text(" (None or KEKI indexed crypto context)")
 | |
| 							else
 | |
| 								ext_type_msg_tree:add(fields.auth, tvb(offset, 1))
 | |
| 							end
 | |
| 							offset = offset + 1
 | |
| 							
 | |
| 							-- Handle SE
 | |
| 							local SE_node = ext_type_msg_tree:add(fields.SE, tvb(offset, 1))
 | |
| 							local SE = tvb(offset, 1):uint()
 | |
| 							if SE == 0 then
 | |
| 								SE_node:append_text( " (Unspecified or KEKI indexed crypto context)")
 | |
| 							elseif SE == 1 then
 | |
| 								SE_node:append_text( " (MPEG-TS/UDP)")
 | |
| 							elseif SE == 2 then
 | |
| 								SE_node:append_text( " (MPEG-TS/SRT)")
 | |
| 							end
 | |
| 							offset = offset + 1
 | |
| 							
 | |
| 							-- Handle resv1
 | |
| 							ext_type_msg_tree:add(fields.resv1, tvb(offset, 1))
 | |
| 							offset = offset + 1
 | |
| 							
 | |
| 							-- Handle resv2
 | |
| 							ext_type_msg_tree:add(fields.resv2, tvb(offset, 2))
 | |
| 							offset = offset + 2
 | |
| 							
 | |
| 							-- Handle slen
 | |
| 							ext_type_msg_tree:add(fields.slen, tvb(offset, 1))
 | |
| 							offset = offset + 1
 | |
| 							
 | |
| 							-- Handle klen
 | |
| 							local klen = tvb(offset, 1):uint()
 | |
| 							ext_type_msg_tree:add(fields.klen, tvb(offset, 1))
 | |
| 							offset = offset + 1
 | |
| 							
 | |
| 							-- Handle salt key
 | |
| 							ext_type_msg_tree:add(fields.salt, tvb(offset, slen * 4))
 | |
| 							offset = offset + slen * 4
 | |
| 							
 | |
| 							-- Handle wrap
 | |
| 							-- Handle ICV
 | |
| 							local wrap_len = 8 + KK * klen
 | |
| 							local wrap_tree = ext_type_msg_tree:add(fields.wrap, tvb(offset, wrap_len))
 | |
| 							wrap_tree:add(fields.ICV, tvb(offset, 8))
 | |
| 							offset = offset + 8
 | |
| 							-- If KK == 2, first key is Even key
 | |
| 							if KK == 2 then
 | |
| 								wrap_tree:add(fields.even_key, tvb(offset, klen))
 | |
| 								offset = offset + klen;
 | |
| 							end
 | |
| 
 | |
| 							-- Handle Odd key
 | |
| 							wrap_tree:add(fields.odd_key, tvb(offset, klen))
 | |
| 							offset = offset + klen;
 | |
| 						elseif ext_type >= 5 and ext_type <= 8 then
 | |
| 							local value_size = tvb(offset + 2, 2):uint() * 4
 | |
| 							local ext_msg_size = 2 + 2 + value_size
 | |
| 							local type_array = { " [SRT_CMD_SID]", " [SRT_CMD_CONGESTION]", " [SRT_CMD_FILTER]", " [SRT_CMD_GROUP]" }
 | |
| 							local field_array = { fields.sid, fields.congestion, fields.filter, fields.group }
 | |
| 							local ext_type_msg_tree = subtree:add(fields.ext_type_msg_tree, tvb(offset, ext_msg_size)):append_text(type_array[ext_type - 4])
 | |
| 							ext_type_msg_tree:add(fields.ext_type, tvb(offset, 2))
 | |
| 							offset = offset + 2
 | |
| 							
 | |
| 							-- Handle Ext Msg Value Size
 | |
| 							ext_type_msg_tree:add(fields.ext_size, tvb(offset, 2)):append_text(" (byte/4)")
 | |
| 							offset = offset + 2
 | |
| 							
 | |
| 							-- Value
 | |
| 							local value_table = {}
 | |
| 							for pos = 0, value_size - 4, 4 do
 | |
| 								table.insert(value_table, string.char(tvb(offset + pos + 3, 1):uint()))
 | |
| 								table.insert(value_table, string.char(tvb(offset + pos + 2, 1):uint()))
 | |
| 								table.insert(value_table, string.char(tvb(offset + pos + 1, 1):uint()))
 | |
| 								table.insert(value_table, string.char(tvb(offset + pos, 1):uint()))
 | |
| 							end
 | |
| 							local value = table.concat(value_table)
 | |
| 							ext_type_msg_tree:add(field_array[ext_type - 4], tvb(offset, value_size), value)
 | |
| 							offset = offset + value_size
 | |
| 						elseif ext_type == -1 then
 | |
| 							local ext_type_msg_tree = subtree:add(fields.ext_type_msg_tree, tvb(offset, tvb:len() - offset)):append_text(" [SRT_CMD_NONE]")
 | |
| 							ext_type_msg_tree:add(fields.ext_type, tvb(offset, 2))
 | |
| 							offset = offset + 2
 | |
| 							
 | |
| 							-- none
 | |
| 							if offset == tvb:len() then
 | |
| 								return
 | |
| 							end
 | |
| 							ext_type_msg_tree:add(fields.none, tvb(offset, tvb:len() - offset))
 | |
| 							offset = tvb:len()
 | |
| 						end
 | |
| 						if offset == tvb:len() then
 | |
| 							return
 | |
| 						else
 | |
| 							process_ext_type()
 | |
| 						end
 | |
| 					end
 | |
| 					
 | |
| 					process_ext_type()
 | |
| 				end,
 | |
| 				[1] = function()
 | |
| 					pinfo.cols.info:append(" [KEEPALIVE]")
 | |
| 					pack_type_tree:append_text(" [KEEPALIVE]")
 | |
| 					pack_type_tree:add(fields.msg_type, tvb(offset, 2)):append_text(" [KEEPALIVE]")
 | |
| 					pack_type_tree:add(fields.reserve, tvb(offset + 2, 2)):append_text(" [Undefined]")
 | |
| 					offset = offset + 4
 | |
| 					
 | |
| 					-- Handle Additional Info, Time Stamp and Destination Socket
 | |
| 					parse_three_param()
 | |
| 				end,
 | |
| 				[2] = function()
 | |
| 					pinfo.cols.info:append(" [ACK]")
 | |
| 					pack_type_tree:append_text(" [ACK]")
 | |
| 					pack_type_tree:add(fields.msg_type, tvb(offset, 2))
 | |
| 					pack_type_tree:add(fields.reserve, tvb(offset + 2, 2)):append_text(" [Undefined]")
 | |
| 					offset = offset + 4
 | |
| 					
 | |
| 					-- Handle ACK Number
 | |
| 					subtree:add(fields.ack_num, tvb(offset, 4))
 | |
| 					offset = offset + 4
 | |
| 					
 | |
| 					-- Handle Time Stamp
 | |
| 					subtree:add(fields.time_stamp, tvb(offset, 4)):append_text(" μs")
 | |
| 					offset = offset + 4
 | |
| 					
 | |
| 					-- Handle Destination Socket
 | |
| 					subtree:add(fields.dst_sock, tvb(offset, 4))
 | |
| 					offset = offset + 4
 | |
| 					
 | |
| 					-- Handle Last Ack Packet Sequence
 | |
| 					local last_ack_pack = tvb(offset, 4):uint()
 | |
| 					pinfo.cols.info:append(" (Last ACK Seq:" .. last_ack_pack .. ")")
 | |
| 					subtree:add(fields.last_ack_pack, tvb(offset, 4))
 | |
| 					offset = offset + 4
 | |
| 					
 | |
| 					-- Handle RTT
 | |
| 					local rtt = tvb(offset, 4):int()
 | |
| 					subtree:add(fields.rtt, tvb(offset, 4)):append_text(" μs")
 | |
| 					offset = offset + 4
 | |
| 					
 | |
| 					-- Handle RTT variance
 | |
| 					if rtt < 0 then
 | |
| 						subtree:add(fields.rtt_variance, tvb(offset, 4), -tvb(offset, 4):int())
 | |
| 					else
 | |
| 						subtree:add(fields.rtt_variance, tvb(offset, 4))
 | |
| 					end
 | |
| 					offset = offset + 4
 | |
| 					
 | |
| 					-- Handle Available Buffer Size(pkts)
 | |
| 					subtree:add(fields.buf_size, tvb(offset, 4)):append_text(" pkts")
 | |
| 					offset = offset + 4
 | |
| 					
 | |
| 					-- Handle Packets Receiving Rate(Pkts/sec)
 | |
| 					subtree:add(fields.pack_rcv_rate, tvb(offset, 4)):append_text(" pkts/sec")
 | |
| 					offset = offset + 4
 | |
| 					
 | |
| 					-- Handle Estmated Link Capacity
 | |
| 					subtree:add(fields.est_link_capacity, tvb(offset, 4)):append_text(" pkts/sec")
 | |
| 					offset = offset + 4
 | |
| 					
 | |
| 					-- Handle Receiving Rate(bps)
 | |
| 					subtree:add(fields.rcv_rate, tvb(offset, 4)):append_text(" bps")
 | |
| 					offset = offset + 4
 | |
| 				end,
 | |
| 				[3] = function()
 | |
| 					pinfo.cols.info:append(" [NAK(loss Report)]")
 | |
| 					pack_type_tree:append_text(" [NAK(loss Report)]")
 | |
| 					pack_type_tree:add(fields.msg_type, tvb(offset, 2))
 | |
| 					pack_type_tree:add(fields.reserve, tvb(offset + 2, 2)):append_text(" [Undefined]")
 | |
| 					offset = offset + 4
 | |
| 					
 | |
| 					-- Handle Additional Info, Timestamp and Destination Socket
 | |
| 					parse_three_param()
 | |
| 					
 | |
| 					-- Handle lost packet sequence
 | |
| 					-- lua does not support changing loop variables within loops, but in the form of closures
 | |
| 					-- https://blog.csdn.net/Ai102iA/article/details/75371239
 | |
| 					local start = offset
 | |
| 					local ending = tvb:len()
 | |
| 					local lost_list_tree = subtree:add(fields.lost_list_tree, tvb(offset, ending - offset))
 | |
| 					for start in function()
 | |
| 							local first_bit = bit.rshift(tvb(start, 1):uint(), 7)
 | |
| 							if first_bit == 1 then
 | |
| 								local lost_pack_range_tree = lost_list_tree:add(fields.lost_pack_range_tree, tvb(start, 8))
 | |
| 								local lost_start = bit.band(tvb(start, 4):uint(), 0x7FFFFFFF)
 | |
| 								lost_pack_range_tree:append_text(" (" .. lost_start .. " -> " .. tvb(start + 4, 4):uint() .. ")")
 | |
| 								lost_pack_range_tree:add(fields.lost_start, tvb(start, 4), lost_start)
 | |
| 								start = start + 4
 | |
| 								lost_pack_range_tree:add(fields.lost_up_to, tvb(start, 4))
 | |
| 								start = start + 4
 | |
| 							else
 | |
| 								lost_list_tree:add(fields.lost_pack_seq, tvb(start, 4))
 | |
| 								start = start + 4
 | |
| 							end
 | |
| 							return start
 | |
| 						end
 | |
| 						do
 | |
| 							if start == ending then
 | |
| 								break
 | |
| 							end
 | |
| 					end
 | |
| 				end,
 | |
| 				[4] = function()
 | |
| 					pinfo.cols.info:append(" [Congestion Warning]")
 | |
| 					pack_type_tree:append_text(" [Congestion Warning]")
 | |
| 					pack_type_tree:add(fields.msg_type, tvb(offset, 2))
 | |
| 					pack_type_tree:add(fields.reserve, tvb(offset + 2, 2)):append_text(" [Undefined]")
 | |
| 					offset = offset + 4
 | |
| 				end,
 | |
| 				[5] = function()
 | |
| 					pinfo.cols.info:append(" [Shutdown]")
 | |
| 					pack_type_tree:append_text(" [Shutdown]")
 | |
| 					pack_type_tree:add(fields.msg_type, tvb(offset, 2))
 | |
| 					pack_type_tree:add(fields.reserve, tvb(offset + 2, 2)):append_text(" [Undefined]")
 | |
| 					offset = offset + 4
 | |
| 					
 | |
| 					-- Handle Additional Info, Timestamp and Destination Socket
 | |
| 					parse_three_param()
 | |
| 				end,
 | |
| 				[6] = function()
 | |
| 					pinfo.cols.info:append(" [ACKACK]")
 | |
| 					pack_type_tree:append_text(" [ACKACK]")
 | |
| 					pack_type_tree:add(fields.msg_type, tvb(offset, 2))
 | |
| 					pack_type_tree:add(fields.reserve, tvb(offset + 2, 2)):append_text(" [Undefined]")
 | |
| 					offset = offset + 4
 | |
| 					
 | |
| 					-- Handle ACK sequence number
 | |
| 					subtree:add(fields.ack_num, tvb(offset, 4))
 | |
| 					offset = offset + 4
 | |
| 					
 | |
| 					-- Handle Time Stamp
 | |
| 					subtree:add(fields.time_stamp, tvb(offset, 4)):append_text(" μs")
 | |
| 					offset = offset + 4
 | |
| 					
 | |
| 					-- Handle Destination Socket
 | |
| 					subtree:add(fields.dst_sock, tvb(offset, 4))
 | |
| 					offset = offset + 4
 | |
| 					
 | |
| 					-- Handle Control Information
 | |
| 					subtree:add(fields.ctl_info, tvb(offset, 4))
 | |
| 					offset = offset + 4
 | |
| 				end,
 | |
| 				[7] = function()
 | |
| 					pinfo.cols.info:append(" [Drop Request]")
 | |
| 					pack_type_tree:append_text(" [Drop Request]")
 | |
| 					pack_type_tree:add(fields.msg_type, tvb(offset, 2)):append_text(" [Drop Request]")
 | |
| 					pack_type_tree:add(fields.reserve, tvb(offset + 2, 2)):append_text(" [Undefined]")
 | |
| 					offset = offset + 4
 | |
| 				end,
 | |
| 				[8] = function()
 | |
| 					pinfo.cols.info:append(" [Peer Error]")
 | |
| 					pack_type_tree:append_text(" [Peer Error]")
 | |
| 					pack_type_tree:add(fields.msg_type, tvb(offset, 2)):append_text(" [Peer Error]")
 | |
| 					pack_type_tree:add(fields.reserve, tvb(offset + 2, 2)):append_text(" [Undefined]")
 | |
| 					offset = offset + 4
 | |
| 				end
 | |
| 			}
 | |
| 			-- Handle based on msg_type
 | |
| 			local case = switch[msg_type]
 | |
| 			if case then
 | |
| 				case()
 | |
| 			else
 | |
| 				-- default case
 | |
| 				subtree:add(fields.msg_type, tvb(offset, 2)):append_text(" [Unknown Message Type]")
 | |
| 				offset = offset + 4
 | |
| 			end
 | |
| 		else
 | |
| 			-- If type field is '0x7FFF', it means an extended type, Handle Reserve field
 | |
| 			offset = offset + 2
 | |
| 			local msg_ext_type = tvb(offset, 2):uint()
 | |
| 			if msg_ext_type == 0 then
 | |
| 				pinfo.cols.info:append(" [Message Extension]")
 | |
| 				
 | |
| 				pack_type_tree:add(fields.msg_ext_type, tvb(offset, 2)):append_text(" [Message Extension]")
 | |
| 				offset = offset + 2
 | |
| 				
 | |
| 				-- Handle Additional Info, Time Stamp and Destination Socket
 | |
| 				parse_three_param()
 | |
| 				
 | |
| 				-- Control information: defined by user
 | |
| 			elseif msg_ext_type == 1 or ext_type == 2 then
 | |
| 				if msg_ext_type == 1 then
 | |
| 					pack_type_tree:add(fields.msg_ext_type, tvb(offset, 2)):append_text(" [SRT Handshake Request]")
 | |
| 					pinfo.cols.info:append(" [SRT Handshake Request]")
 | |
| 				elseif msg_ext_type == 2 then
 | |
| 					pack_type_tree:add(fields.msg_ext_type, tvb(offset, 2)):append_text(" [SRT Handshake Response]")
 | |
| 					pinfo.cols.info:append(" [SRT Handshake Response]")
 | |
| 				end
 | |
| 				offset = offset + 2
 | |
| 				
 | |
| 				-- Ignore additional info (this field is not defined in this packet type)
 | |
| 				subtree:add(fields.additional_info, tvb(offset, 4)):append_text(" [undefined]")
 | |
| 				offset = offset + 4
 | |
| 				
 | |
| 				-- Handle Time Stamp
 | |
| 				subtree:add(fields.time_stamp, tvb(offset, 4)):append_text("μs")
 | |
| 				offset = offset + 4
 | |
| 				
 | |
| 				-- Handle Destination Socket
 | |
| 				subtree:add(fields.dst_sock, tvb(offset, 4))
 | |
| 				offset = offset + 4
 | |
| 				
 | |
| 				-- Handle SRT Version field
 | |
| 				subtree:add(fields.srt_version, tvb(offset, 4))
 | |
| 				offset = ofssset + 4
 | |
| 				
 | |
| 				-- Handle SRT Flags
 | |
| 				local SRT_flags_tree = subtree:add(fields.srt_flags, tvb(offset, 4))
 | |
| 				SRT_flags_tree:add(fields.srt_opt_tsbpdsnd, tvb(offset, 4))
 | |
| 				SRT_flags_tree:add(fields.srt_opt_tsbpdrcv, tvb(offset, 4))
 | |
| 				SRT_flags_tree:add(fields.srt_opt_haicrypt, tvb(offset, 4))
 | |
| 				SRT_flags_tree:add(fields.srt_opt_tlpktdrop, tvb(offset, 4))
 | |
| 				SRT_flags_tree:add(fields.srt_opt_nakreport, tvb(offset, 4))
 | |
| 				SRT_flags_tree:add(fields.srt_opt_rexmitflg, tvb(offset, 4))
 | |
| 				SRT_flags_tree:add(fields.srt_opt_stream, tvb(offset, 4))
 | |
| 				offset = offset + 4
 | |
| 				
 | |
| 				-- Handle TsbPd Resv
 | |
| 				subtree:add(fields.tsbpb_resv, tvb(offset, 2))
 | |
| 				offset = offset + 2
 | |
| 				
 | |
| 				-- Handle TsbPb Delay
 | |
| 				subtree:add(fields.tsbpb_delay, tvb(offset, 2))
 | |
| 				offset = offset + 2
 | |
| 
 | |
| 				-- Handle Reserved field
 | |
| 				subtree:add(fields.reserve, tvb(offset, 4))
 | |
| 				offset = offset + 4
 | |
| 			elseif msg_ext_type == 3 or msg_ext_type == 4 then
 | |
| 				if msg_ext_type == 3 then
 | |
| 					pack_type_tree:add(fields.msg_ext_type, tvb(offset, 2)):append_text(" [Encryption Keying Material Request]")
 | |
| 					pinfo.cols.info:append(" [Encryption Keying Material Request]")
 | |
| 				elseif msg_ext_type == 4 then
 | |
| 					pack_type_tree:add(fields.msg_ext_type, tvb(offset, 2)):append_text(" [Encryption Keying Material Response]")
 | |
| 					pinfo.cols.info:append(" [Encryption Keying Material Response]")
 | |
| 				end
 | |
| 				offset = offset + 2
 | |
| 				
 | |
| 				-- Ignore additional info (this field is not defined in this packet type)
 | |
| 				subtree:add(fields.additional_info, tvb(offset, 4)):append_text(" [undefined]")
 | |
| 				offset = offset + 4
 | |
| 				
 | |
| 				-- Handle Timestamp
 | |
| 				subtree:add(fields.time_stamp, tvb(offset, 4)):append_text("μs")
 | |
| 				offset = offset + 4
 | |
| 				
 | |
| 				-- Handle Destination Socket
 | |
| 				subtree:add(fields.dst_sock, tvb(offset, 4))
 | |
| 				offset = offset + 4
 | |
| 				
 | |
| 				-- Handle KmErr
 | |
| 				if msg_ext_type == 4 then
 | |
| 					subtree:add(fields.km_err, tvb(offset, 4))
 | |
| 					offset = offset + 4
 | |
| 					return
 | |
| 				end
 | |
| 				
 | |
| 				-- The encrypted message is not handled
 | |
| 			end
 | |
| 		end
 | |
| 	else
 | |
| 		-- 0 -> Data Packet
 | |
| 		pack_type_tree:add(fields.pack_type, tvb(offset, 2))
 | |
| 		pack_type_tree:append_text(" (Data Packet)")
 | |
| 		local seq_num = tvb(offset, 4):uint()
 | |
| 		pinfo.cols.info:append(" (Data Packet)(Seq Num:" .. seq_num .. ")")
 | |
| 		
 | |
| 		-- The first 4 bytes are the package sequence number
 | |
| 		subtree:add(fields.seq_num, tvb(offset, 4))
 | |
| 		offset = offset + 4
 | |
| 		
 | |
| 		data_flag_info_tree = subtree:add(fields.data_flag_info_tree, tvb(offset, 1))
 | |
| 		-- Handle FF flag
 | |
| 		local FF_state = bit.rshift(bit.band(tvb(offset, 1):uint(), 0xC0), 6)
 | |
| 		if FF_state == 0 then
 | |
| 			data_flag_info_tree:append_text(" [Middle packet]")
 | |
| 		elseif FF_state == 1 then
 | |
| 			data_flag_info_tree:append_text(" [Last packet]")
 | |
| 		elseif FF_state == 2 then
 | |
| 			data_flag_info_tree:append_text(" [First packet]")
 | |
| 		else
 | |
| 			data_flag_info_tree:append_text(" [Single packet]")
 | |
| 		end
 | |
| 		data_flag_info_tree:add(fields.FF_state, tvb(offset, 1))
 | |
| 		
 | |
| 		-- Handle O flag
 | |
| 		local O_state = bit.rshift(bit.band(tvb(offset, 1):uint(), 0x20), 5)
 | |
| 		if O_state == 0 then
 | |
| 			data_flag_info_tree:append_text(" [Data delivered unordered]")
 | |
| 		else
 | |
| 			data_flag_info_tree:append_text(" [Data delivered in order]")
 | |
| 		end
 | |
| 		data_flag_info_tree:add(fields.O_state, tvb(offset, 1))
 | |
| 		
 | |
| 		-- Handle KK flag
 | |
| 		local KK_state = bit.rshift(bit.band(tvb(offset, 1):uint(), 0x18), 3)
 | |
| 		if KK_state == 1 then
 | |
| 			data_flag_info_tree:append_text(" [Encrypted with even key]")
 | |
| 		elseif KK_state == 2 then
 | |
| 			data_flag_info_tree:append_text(" [Encrypted with odd key]")
 | |
| 		end
 | |
| 		data_flag_info_tree:add(fields.KK_state, tvb(offset, 1))
 | |
| 		
 | |
| 		-- Handle R flag
 | |
| 		local R_state = bit.rshift(bit.band(tvb(offset, 1):uint(), 0x04), 2)
 | |
| 		if R_state == 1 then
 | |
| 			data_flag_info_tree:append_text(" [Retransmit packet]")
 | |
| 			pinfo.cols.info:append(" [Retransmit packet]")
 | |
| 		end
 | |
| 		data_flag_info_tree:add(fields.R_state, tvb(offset, 1))
 | |
| 		
 | |
| 		-- Handle message number
 | |
| 		local msg_num = tvb(offset, 4):uint()
 | |
| 		msg_num = bit.band(tvb(offset, 4):uint(), 0x03FFFFFF)
 | |
| 		-- subtree:add(fields.msg_num, bit.band(tvb(offset, 4):uint(), 0x03FFFFFF))
 | |
| 		subtree:add(fields.msg_num, tvb(offset, 4), msg_num)
 | |
| 		offset = offset + 4
 | |
| 		
 | |
| 		-- Handle Timestamp
 | |
| 		subtree:add(fields.time_stamp, tvb(offset, 4)):append_text(" μs")
 | |
| 		offset = offset + 4
 | |
| 		
 | |
| 		-- Handle destination socket
 | |
| 		subtree:add(fields.dst_sock, tvb(offset, 4))
 | |
| 		offset = offset + 4
 | |
| 	end
 | |
| end
 | |
| 
 | |
| -- Add the protocol into udp table
 | |
| local port = 1935
 | |
| 
 | |
| local function enable_dissector()
 | |
| 	DissectorTable.get("udp.port"):add(port, srt_dev)
 | |
| end
 | |
| 
 | |
| -- Call it now - enabled by default
 | |
| enable_dissector()
 | |
| 
 | |
| local function disable_dissector()
 | |
| 	DissectorTable.get("udp.port"):remove(port, srt_dev)
 | |
| end
 | |
| 
 | |
| -- Prefs changed will listen at new port
 | |
| function srt_dev.prefs_changed()
 | |
| 	if port ~= srt_dev.prefs.srt_udp_port then
 | |
| 		if port ~= 0 then
 | |
| 			disable_dissector()
 | |
| 		end
 | |
| 
 | |
| 		port = srt_dev.prefs.srt_udp_port
 | |
| 
 | |
| 		if port ~= 0 then
 | |
| 			enable_dissector()
 | |
| 		end
 | |
| 	end
 | |
| end
 |