1-- @brief srt-dev Protocol dissector plugin 2 3-- create a new dissector 4local NAME = "SRT-dev" 5local srt_dev = Proto(NAME, "SRT-dev Protocol") 6 7-- create a preference of a Protocol 8srt_dev.prefs["srt_udp_port"] = Pref.uint("SRT UDP Port", 1935, "SRT UDP Port") 9 10-- create fields of srt_dev 11-- Base.HEX, Base.DEC, Base.OCT, Base.UNIT_STRING, Base.NONE 12local fields = srt_dev.fields 13-- General field 14local pack_type_select = { 15 [0] = "Data Packet", 16 [1] = "Control Packet" 17} 18fields.pack_type_tree = ProtoField.uint32(NAME .. ".pack_type_tree", "Packet Type", base.HEX) 19fields.pack_type = ProtoField.uint16("srt_dev.pack_type", "Packet Type", base.HEX, pack_type_select, 0x8000) 20fields.reserve = ProtoField.uint16("srt_dev.reserve", "Reserve", base.DEC) 21fields.additional_info = ProtoField.uint32("srt_dev.additional_info", "Additional Information", base.DEC) 22fields.time_stamp = ProtoField.uint32("srt_dev.time_stamp", "Time Stamp", base.DEC) 23fields.dst_sock = ProtoField.uint32("srt_dev.dst_sock", "Destination Socket ID", base.DEC) 24fields.none = ProtoField.none("srt_dev.none", "none", base.NONE) 25 26-- Data packet fields 27fields.data_flag_info_tree = ProtoField.uint8("srt_dev.data_flag_info_tree", "Data Flag Info", base.HEX) 28local FF_state_select = { 29 [0] = "[Middle packet]", 30 [1] = "[Last packet]", 31 [2] = "[First packet]", 32 [3] = "[Single packet]" 33} 34fields.FF_state = ProtoField.uint8("srt_dev.FF_state", "FF state", base.HEX, FF_state_select, 0xC0) 35local O_state_select = { 36 [0] = "[ORD_RELAX]", 37 [1] = "[ORD_REQUIRED]" 38} 39fields.O_state = ProtoField.uint8("srt_dev.O_state", "O state", base.HEX, O_state_select, 0x20) 40local KK_state_select = { 41 [0] = "[Not encrypted]", 42 [1] = "[Data encrypted with even key]", 43 [2] = "[Data encrypted with odd key]" 44} 45fields.KK_state = ProtoField.uint8("srt_dev.KK_state", "KK state", base.HEX, KK_state_select, 0x18) 46local R_state_select = { 47 [0] = "[ORIGINAL]", 48 [1] = "[RETRANSMITTED]" 49} 50fields.R_state = ProtoField.uint8("srt_dev.R_state", "R state", base.HEX, R_state_select, 0x04) 51fields.seq_num = ProtoField.uint32("srt_dev.seq_num", "Sequence Number", base.DEC) 52fields.msg_num = ProtoField.uint32("srt_dev.msg_num", "Message Number", base.DEC)--, nil, 0x3FFFFFF) 53 54-- control packet fields 55local msg_type_select = { 56 [0] = "[HANDSHAKE]", 57 [1] = "[KEEPALIVE]", 58 [2] = "[ACK]", 59 [3] = "[NAK(Loss Report)]", 60 [4] = "[Congestion Warning]", 61 [5] = "[Shutdown]", 62 [6] = "[ACKACK]", 63 [7] = "[Drop Request]", 64 [8] = "[Peer Error]", 65 [0x7FFF] = "[Message Extension Type]" 66} 67fields.msg_type = ProtoField.uint16("srt_dev.msg_type", "Message Type", base.HEX, msg_type_select, 0x7FFF) 68fields.msg_ext_type = ProtoField.uint16("srt_dev.msg_ext_type", "Message Extented Type", base.DEC) 69 70local flag_state_select = { 71 [0] = "Unset", 72 [1] = "Set" 73} 74 75-- Handshake packet fields 76fields.UDT_version = ProtoField.uint32("srt_dev.UDT_version", "UDT Version", base.DEC) 77fields.sock_type = ProtoField.uint32("srt_dev.sock_type", "Socket Type", base.DEC) 78fields.ency_fld = ProtoField.uint16("srt_dev.ency_fld", "Encryption Field", base.DEC) 79fields.ext_fld = ProtoField.uint16("srt_dev.ext_fld", "Extension Fields", base.HEX) 80fields.ext_fld_tree = ProtoField.uint16("srt_dev.ext_fld_tree", "Extension Fields Tree", base.HEX) 81fields.hsreq = ProtoField.uint16("srt_dev.hsreq", "HS_EXT_HSREQ", base.HEX, flag_state_select, 0x1) 82fields.kmreq = ProtoField.uint16("srt_dev.kmreq", "HS_EXT_KMREQ", base.HEX, flag_state_select, 0x2) 83fields.config = ProtoField.uint16("srt_dev.config", "HS_EXT_CONFIG", base.HEX, flag_state_select, 0x4) 84fields.isn = ProtoField.uint32("srt_dev.isn", "Initial packet sequence number", base.DEC) 85fields.mss = ProtoField.uint32("srt_dev.mss", "Max Packet Size", base.DEC) 86fields.fc = ProtoField.uint32("srt_dev.fc", "Maximum Flow Window Size", base.DEC) 87fields.conn_type = ProtoField.int32("srt_dev.conn_type", "Connection Type", base.DEC) 88fields.sock_id = ProtoField.uint32("srt_dev.sock_id", "Socket ID", base.DEC) 89fields.syn_cookie = ProtoField.uint32("srt_dev.syn_cookie", "SYN cookie", base.DEC) 90fields.peer_ipaddr = ProtoField.none("srt_dev.peer_ipaddr", "Peer IP address", base.NONE) 91fields.peer_ipaddr_4 = ProtoField.ipv4("srt_dev.peer_ipaddr", "Peer IP address") 92fields.peer_ipaddr_6 = ProtoField.ipv6("srt_dev.peer_ipaddr", "Peer IP address") 93local ext_type_select = { 94 [-1] = "SRT_CMD_NONE", 95 [0] = "SRT_CMD_REJECT", 96 [1] = "SRT_CMD_HSREQ", 97 [2] = "SRT_CMD_HSRSP", 98 [3] = "SRT_CMD_KMREQ", 99 [4] = "SRT_CMD_KMRSP", 100 [5] = "SRT_CMD_SID", 101 [6] = "SRT_CMD_CONGESTION", 102 [7] = "SRT_CMD_FILTER", 103 [8] = "SRT_CMD_GROUP" 104} 105fields.ext_type_msg_tree = ProtoField.none("srt_dev.ext_type", "Extension Type Message", base.NONE) 106fields.ext_type = ProtoField.uint16("srt_dev.ext_type", "Extension Type", base.HEX, ext_type_select, 0xF) 107fields.ext_size = ProtoField.uint16("srt_dev.ext_size", "Extension Size", base.DEC) 108 109-- Handshake packet, ext type == SRT_CMD_HSREQ or SRT_CMD_HSRSP field 110fields.srt_version = ProtoField.uint32("srt_dev.srt_version", "SRT Version", base.HEX) 111fields.srt_flags = ProtoField.uint32("srt_dev.srt_flags", "SRT Flags", base.HEX) 112fields.tsbpb_resv = ProtoField.uint16("srt_dev.tsbpb_resv", "TsbPb Receive", base.DEC) 113fields.tsbpb_delay = ProtoField.uint16("srt_dev.tsbpb_delay", "TsbPb Delay", base.DEC) 114fields.tsbpd_delay = ProtoField.uint16("srt_dev.tsbpd_delay", "TsbPd Delay", base.DEC) 115fields.rcv_tsbpd_delay = ProtoField.uint16("srt_dev.rcv_tsbpd_delay", "Receiver TsbPd Delay", base.DEC) 116fields.snd_tsbpd_delay = ProtoField.uint16("srt_dev.snd_tsbpd_delay", "Sender TsbPd Delay", base.DEC) 117 118-- V adn PT status flag 119local V_state_select = { 120 [1] = "Initial version" 121} 122fields.V_state = ProtoField.uint8("srt_dev.V_state", "V", base.HEX, V_state_select, 0x70) 123local PT_state_select = { 124 [0] = "Reserved", 125 [1] = "MSmsg", 126 [2] = "KMmsg", 127 [7] = "Reserved to discriminate MPEG-TS packet(0x47=sync byte)" 128} 129fields.PT_state = ProtoField.uint8("srt_dev.PT_state", "PT", base.HEX, state_table, 0xF) 130fields.sign = ProtoField.uint16("srt_dev.sign", "Signature", base.HEX) 131local resv_select = { 132 [0] = "Reserved for flag extension or other usage" 133} 134fields.resv = ProtoField.uint8("srt_dev.resv", "Resv", base.DEC, state_table, 0xFC) 135fields.ext_KK_state = ProtoField.uint8("srt_dev.ext_KK_state", "KK_state", base.HEX, KK_state_select, 0x3) 136fields.KEKI = ProtoField.uint32("srt_dev.KEKI", "KEKI", base.DEC) 137fields.cipher = ProtoField.uint8("srt_dev.cipher", "Cipher", base.DEC) 138fields.auth = ProtoField.uint8("srt_dev.auth", "auth", base.DEC) 139fields.SE = ProtoField.uint8("srt_dev.SE", "SE", base.DEC) 140fields.resv1 = ProtoField.uint8("srt_dev.resv1", "resv1", base.DEC) 141fields.resv2 = ProtoField.uint16("srt_dev.resv2", "resv2", base.DEC) 142fields.slen = ProtoField.uint8("srt_dev.slen", "Salt length(bytes)/4", base.DEC) 143fields.klen = ProtoField.uint8("srt_dev.klen", "SEK length(bytes)/4", base.DEC) 144fields.salt = ProtoField.uint32("srt_dev.salt", "Salt key", base.DEC) 145fields.wrap = ProtoField.none("srt_dev.wrap", "Wrap key(s)", base.NONE) 146 147-- Wrap Field 148fields.ICV = ProtoField.uint64("srt_dev.ICV", "Integerity Check Vector", base.HEX) 149fields.odd_key = ProtoField.stringz("srt_dev.odd_key", "Odd key", base.ASCII) 150fields.even_key = ProtoField.stringz("srt_dev.even_key", "Even key", base.ASCII) 151 152-- ext_type == SRT_CMD_SID field 153fields.sid = ProtoField.string("srt_dev.sid", "Stream ID", base.ASCII) 154-- ext_type == SRT_CMD_CONGESTION field 155fields.congestion = ProtoField.string("srt_dev.congestion", "Congestion Controller", base.ASCII) 156-- ext_type == SRT_CMD_FILTER field 157fields.filter = ProtoField.string("srt_dev.filter", "Filter", base.ASCII) 158-- ext_type == SRT_CMD_GROUP field 159fields.group = ProtoField.string("srt_dev.group", "Group Data", base.ASCII) 160 161-- SRT flags 162fields.srt_opt_tsbpdsnd = ProtoField.uint32("srt_dev.srt_opt_tsbpdsnd", "SRT_OPT_TSBPDSND", base.HEX, flag_state_select, 0x1) 163fields.srt_opt_tsbpdrcv = ProtoField.uint32("srt_dev.srt_opt_tsbpdrcv", "SRT_OPT_TSBPDRCV", base.HEX, flag_state_select, 0x2) 164fields.srt_opt_haicrypt = ProtoField.uint32("srt_dev.srt_opt_haicrypt", "SRT_OPT_HAICRYPT", base.HEX, flag_state_select, 0x4) 165fields.srt_opt_tlpktdrop = ProtoField.uint32("srt_dev.srt_opt_tlpktdrop", "SRT_OPT_TLPKTDROP", base.HEX, flag_state_select, 0x8) 166fields.srt_opt_nakreport = ProtoField.uint32("srt_dev.srt_opt_nakreport", "SRT_OPT_NAKREPORT", base.HEX, flag_state_select, 0x10) 167fields.srt_opt_rexmitflg = ProtoField.uint32("srt_dev.srt_opt_rexmitflg", "SRT_OPT_REXMITFLG", base.HEX, flag_state_select, 0x20) 168fields.srt_opt_stream = ProtoField.uint32("srt_dev.srt_opt_stream", "SRT_OPT_STREAM", base.HEX, flag_state_select, 0x40) 169 170-- ACK fields 171fields.last_ack_pack = ProtoField.uint32("srt_dev.last_ack_pack", "Last ACK Packet Sequence Number", base.DEC) 172fields.rtt = ProtoField.int32("srt_dev.rtt", "Round Trip Time", base.DEC) 173fields.rtt_variance = ProtoField.int32("srt_dev.rtt_variance", "Round Trip Time Variance", base.DEC) 174fields.buf_size = ProtoField.uint32("srt_dev.buf_size", "Available Buffer Size", base.DEC) 175fields.pack_rcv_rate = ProtoField.uint32("srt_dev.pack_rcv_rate", "Packet Receiving Rate", base.DEC) 176fields.est_link_capacity = ProtoField.uint32("srt_dev.est_link_capacity", "Estimated Link Capacity", base.DEC) 177fields.rcv_rate = ProtoField.uint32("srt_dev.rcv_rate", "Receiving Rate", base.DEC) 178 179-- ACKACK fields 180fields.ack_num = ProtoField.uint32("srt_dev.ack_num", "ACK number", base.DEC) 181fields.ctl_info = ProtoField.uint32("srt_dev.ctl_info", "Control Information", base.DEC) 182 183-- KMRSP fields 184local srt_km_state_select = { 185 [0] = "[SRT_KM_UNSECURED]", 186 [1] = "[SRT_KM_SECURING]", 187 [2] = "[SRT_KM_SECURED]", 188 [3] = "[SRT_KM_NOSECRET]", 189 [4] = "[SRT_KM_BADSECRET]" 190} 191fields.km_err = ProtoField.uint32("srt_dev.km_err", "Key Message Error", base.HEX, srt_km_state_select, 0xF) 192 193-- NAK Control Packet fields 194fields.lost_list_tree = ProtoField.none("srt_dev.lost_list_tree", "Lost Packet List", base.NONE) 195fields.lost_pack_seq = ProtoField.uint32("srt_dev.lost_pack_seq", "Lost Packet Sequence Number", base.DEC) 196fields.lost_pack_range_tree = ProtoField.none("srt_dev.lost_pack_range_tree", "Lost Packet Range", base.NONE) 197fields.lost_start = ProtoField.uint32("srt_dev.lost_start", "Lost Starting Sequence", base.DEC) 198fields.lost_up_to = ProtoField.uint32("srt_dev.lost_up_to", "Lost Up To(including)", base.DEC) 199 200-- Dissect packet 201function srt_dev.dissector (tvb, pinfo, tree) 202 -- Packet is based on UDP, so the data can be processed directly after UDP 203 local subtree = tree:add(srt_dev, tvb()) 204 local offset = 0 205 206 -- Changes the protocol name 207 pinfo.cols.protocol = srt_dev.name 208 209 -- Take out the first bit of package 210 -- 0 -> Data Packet 211 -- 1 -> Control Packet 212 local typebit = bit.rshift(tvb(offset, 1):uint(), 7) 213 pack_type_tree = subtree:add(fields.pack_type_tree, tvb(offset, 4)) 214 215 if typebit == 1 then 216 -- Handle Control Packet 217 pack_type_tree:add(fields.pack_type, tvb(offset, 2)) 218 219 local msg_type = tvb(offset, 2):uint() 220 if msg_type ~= 0xFFFF then 221 -- If type field isn't '0x7FFF',it means packet is normal data packet, then handle type field 222 msg_type = bit.band(msg_type, 0x7FFF) 223 224 function parse_three_param() 225 -- Ignore Additional Info (this field is not defined in this packet type) 226 subtree:add(fields.additional_info, tvb(offset, 4)):append_text(" [undefined]") 227 offset = offset + 4 228 229 -- Handle Time Stamp 230 subtree:add(fields.time_stamp, tvb(offset, 4)):append_text(" μs") 231 offset = offset + 4 232 233 -- Handle Destination Socket 234 subtree:add(fields.dst_sock, tvb(offset, 4)) 235 offset = offset + 4 236 end 237 238 local switch = { 239 [0] = function() 240 pinfo.cols.info:append(" [HANDSHAKE]") 241 pack_type_tree:append_text(" [HANDSHAKE]") 242 pack_type_tree:add(fields.msg_type, tvb(offset, 2)) 243 pack_type_tree:add(fields.reserve, tvb(offset + 2, 2)):append_text(" [Undefined]") 244 offset = offset + 4 245 246 -- Handle Additional Info, Timestamp and Destination Socket 247 parse_three_param() 248 249 -- Handle UDT version field 250 local UDT_version = tvb(offset, 4):uint() 251 subtree:add(fields.UDT_version, tvb(offset, 4)) 252 offset = offset + 4 253 254 if UDT_version == 4 then 255 -- UDT version is 4, packet is diffrent from UDT version 5 256 -- Handle sock type 257 local sock_type = tvb(offset, 4):uint() 258 if sock_type == 1 then 259 subtree:add(fields.sock_type, tvb(offset, 4)):append_text(" [SRT_STREAM]") 260 elseif sock_type == 2 then 261 subtree:add(fields.sock_type, tvb(offset, 4)):append_text(" [SRT_DRAGAM]") 262 end 263 offset = offset + 4 264 elseif UDT_version == 5 then 265 -- Handle Encryption Field 266 local encr_fld = tvb(offset, 2):int() 267 if encr_fld == 0 then 268 subtree:add(fields.ency_fld, tvb(offset, 2)):append_text(" (PBKEYLEN not advertised)") 269 elseif encr_fld == 2 then 270 subtree:add(fields.ency_fld, tvb(offset, 2)):append_text(" (AES-128)") 271 elseif encr_fld == 3 then 272 subtree:add(fields.ency_fld, tvb(offset, 2)):append_text(" (AES-192)") 273 else 274 subtree:add(fields.ency_fld, tvb(offset, 2)):append_text(" (AES-256)") 275 end 276 offset = offset + 2 277 278 -- Handle Extension Field 279 local ext_fld = tvb(offset, 2):int() 280 if ext_fld == 0x4A17 then 281 subtree:add(fields.ext_fld, tvb(offset, 2)):append_text(" [HSv5 MAGIC]") 282 else 283 -- Extension Field is HS_EXT_prefix 284 -- The define is in fiel handshake.h 285 local ext_fld_tree = subtree:add(fields.ext_fld_tree, tvb(offset, 2)) 286 local str_table = { " [" } 287 ext_fld_tree:add(fields.hsreq, tvb(offset, 2)) 288 if bit.band(tvb(offset, 2):uint(), 0x1) == 1 then 289 table.insert(str_table, "HS_EXT_HSREQ") 290 table.insert(str_table, " | ") 291 end 292 ext_fld_tree:add(fields.kmreq, tvb(offset, 2)):append_text(" [HS_EXT_KMREQ]") 293 if bit.band(tvb(offset, 2):uint(), 0x2) == 2 then 294 table.insert(str_table, "HS_EXT_KMREQ") 295 table.insert(str_table, " | ") 296 end 297 ext_fld_tree:add(fields.config, tvb(offset, 2)):append_text(" [HS_EXT_CONFIG]") 298 if bit.band(tvb(offset, 2):uint(), 0x4) == 4 then 299 table.insert(str_table, "HS_EXT_CONFIG") 300 table.insert(str_table, " | ") 301 end 302 table.remove(str_table) 303 table.insert(str_table, "]") 304 if ext_fld ~= 0 then 305 ext_fld_tree:append_text(table.concat(str_table)) 306 end 307 end 308 offset = offset + 2 309 end 310 311 -- Handle Initial packet sequence number 312 subtree:add(fields.isn, tvb(offset, 4)) 313 offset = offset + 4 314 315 -- Handle Maximum Packet Size 316 subtree:add(fields.mss, tvb(offset, 4)) 317 offset = offset + 4 318 319 -- Handle Maximum Flow Window Size 320 subtree:add(fields.fc, tvb(offset, 4)) 321 offset = offset + 4 322 323 -- Handle Connection Type 324 local conn_type = tvb(offset, 4):int() 325 local conn_type_tree = subtree:add(fields.conn_type, tvb(offset, 4)) 326 if conn_type == 0 then 327 conn_type_tree:append_text(" [WAVEAHAND] (Rendezvous Mode)") 328 pinfo.cols.info:append(" [WAVEAHAND] (Rendezvous Mode)") 329 elseif conn_type == 1 then 330 conn_type_tree:append_text(" [INDUCTION]") 331 elseif conn_type == -1 then 332 conn_type_tree:append_text(" [CONCLUSION]") 333 elseif conn_type == -2 then 334 conn_type_tree:append_text(" [AGREEMENT] (Rendezvous Mode)") 335 pinfo.cols.info:append(" [AGREEMENT] (Rendezvous Mode)") 336 end 337 offset = offset + 4 338 339 -- Handle Socket ID 340 subtree:add(fields.sock_id, tvb(offset, 4)) 341 offset = offset + 4 342 343 -- Handle SYN cookie 344 local syn_cookie = tvb(offset, 4):int() 345 subtree:add(fields.syn_cookie, tvb(offset, 4)) 346 if syn_cookie == 0 then 347 conn_type_tree:append_text(" (Caller to Listener)") 348 pinfo.cols.info:append(" (Caller to Listener)") 349 else 350 if conn_type == 1 then 351 -- reports cookie from listener 352 conn_type_tree:append_text(" (Listener to Caller)") 353 pinfo.cols.info:append(" (Listener to Caller)") 354 end 355 end 356 offset = offset + 4 357 358 -- Handle Peer IP address 359 -- Note the network byte order 360 local the_last_96_bits = 0 361 the_last_96_bits = the_last_96_bits + math.floor(tvb(offset + 4, 4):int() * (2 ^ 16)) 362 the_last_96_bits = the_last_96_bits + math.floor(tvb(offset + 8, 4):int() * (2 ^ 8)) 363 the_last_96_bits = the_last_96_bits + tvb(offset + 12, 4):int() 364 if the_last_96_bits == 0 then 365 subtree:add_le(fields.peer_ipaddr_4, tvb(offset, 4)) 366 else 367 subtree:add_le(fields.peer_ipaddr, tvb(offset, 16)) 368 end 369 370 offset = offset + 16 371 372 -- UDT version is 4, packet handle finish 373 if UDT_version == 4 or offset == tvb:len() then 374 return 375 end 376 377 function process_ext_type() 378 -- Handle Ext Type, processing by type 379 local ext_type = tvb(offset, 2):int() 380 if ext_type == 1 or ext_type == 2 then 381 local ext_type_msg_tree = subtree:add(fields.ext_type_msg_tree, tvb(offset, 16)) 382 if ext_type == 1 then 383 ext_type_msg_tree:append_text(" [SRT_CMD_HSREQ]") 384 ext_type_msg_tree:add(fields.ext_type, tvb(offset, 2)) 385 conn_type_tree:append_text(" (Caller to Listener)") 386 pinfo.cols.info:append(" (Caller to Listener)") 387 else 388 ext_type_msg_tree:append_text(" [SRT_CMD_HSRSP]") 389 ext_type_msg_tree:add(fields.ext_type, tvb(offset, 2)) 390 conn_type_tree:append_text(" (Listener to Caller)") 391 pinfo.cols.info:append(" (Listener to Caller)") 392 end 393 offset = offset + 2 394 395 -- Handle Ext Size 396 ext_type_msg_tree:add(fields.ext_size, tvb(offset, 2)) 397 offset = offset + 2 398 399 -- Handle SRT Version 400 ext_type_msg_tree:add(fields.srt_version, tvb(offset, 4)) 401 offset = offset + 4 402 403 -- Handle SRT Flags 404 local SRT_flags_tree = ext_type_msg_tree:add(fields.srt_flags, tvb(offset, 4)) 405 SRT_flags_tree:add(fields.srt_opt_tsbpdsnd, tvb(offset, 4)) 406 SRT_flags_tree:add(fields.srt_opt_tsbpdrcv, tvb(offset, 4)) 407 SRT_flags_tree:add(fields.srt_opt_haicrypt, tvb(offset, 4)) 408 SRT_flags_tree:add(fields.srt_opt_tlpktdrop, tvb(offset, 4)) 409 SRT_flags_tree:add(fields.srt_opt_nakreport, tvb(offset, 4)) 410 SRT_flags_tree:add(fields.srt_opt_rexmitflg, tvb(offset, 4)) 411 SRT_flags_tree:add(fields.srt_opt_stream, tvb(offset, 4)) 412 offset = offset + 4 413 414 -- Handle Recv TsbPd Delay and Snd TsbPd Delay 415 if UDT_version == 4 then 416 ext_type_msg_tree:add(fields.tsbpd_delay, tvb(offset, 2)):append_text(" [Unused in HSv4]") 417 offset = offset + 2 418 ext_type_msg_tree:add(fields.tsbpb_delay, tvb(offset, 2)) 419 offset = offset + 2 420 else 421 ext_type_msg_tree:add(fields.rcv_tsbpd_delay, tvb(offset, 2)) 422 offset = offset + 2 423 ext_type_msg_tree:add(fields.snd_tsbpd_delay, tvb(offset, 2)) 424 offset = offset + 2 425 end 426 elseif ext_type == 3 or ext_type == 4 then 427 local ext_type_msg_tree = subtree:add(fields.ext_type_msg_tree, tvb(offset, 16)) 428 if ext_type == 3 then 429 ext_type_msg_tree:append_text(" [SRT_CMD_KMREQ]") 430 ext_type_msg_tree:add(fields.ext_type, tvb(offset, 2)) 431 conn_type_tree:append_text(" (Listener to Caller)") 432 else 433 ext_type_msg_tree:append_text(" [SRT_CMD_KMRSP]") 434 ext_type_msg_tree:add(fields.ext_type, tvb(offset, 2)) 435 end 436 offset = offset + 2 437 438 -- Handle Ext Size 439 local km_len = tvb(offset, 2):uint() 440 ext_type_msg_tree:add(fields.ext_size, tvb(offset, 2)):append_text(" (byte/4)") 441 offset = offset + 2 442 443 -- Handle SRT_CMD_KMREQ message 444 -- V and PT status flag 445 ext_type_msg_tree:add(fields.V_state, tvb(offset, 1)) 446 ext_type_msg_tree:add(fields.PT_state, tvb(offset, 1)) 447 offset = offset + 1 448 449 -- Handle sign 450 ext_type_msg_tree:add(fields.sign, tvb(offset, 2)):append_text(" (/'HAI/' PnP Vendor ID in big endian order)") 451 offset = offset + 2 452 453 -- Handle resv 454 ext_type_msg_tree:add(fields.resv, tvb(offset, 1)) 455 456 -- Handle KK flag 457 local KK = tvb(offset, 1):uint() 458 ext_type_msg_tree:add(fields.ext_KK_state, tvb(offset, 1)) 459 offset = offset + 1 460 461 -- Handle KEKI 462 if tvb(offset, 4):uint() == 0 then 463 ext_type_msg_tree:add(fields.KEKI, tvb(offset, 4)):append_text(" (Default stream associated key(stream/system default))") 464 else 465 ext_type_msg_tree:add(fields.KEKI, tvb(offset, 4)):append_text(" (Reserved for manually indexed keys)") 466 end 467 offset = offset + 4 468 469 -- Handle Cipher 470 local cipher_node = ext_type_msg_tree:add(fields.cipher, tvb(offset, 1)) 471 local cipher = tvb(offset, 1):uint() 472 if cipher == 0 then 473 elseif cipher == 1 then 474 cipher_node:append_text(" (AES-ECB(potentially for VF 2.0 compatible message))") 475 elseif cipher == 2 then 476 cipher_node:append_text(" (AES-CTR[FP800-38A])") 477 else 478 cipher_node:append_text(" (AES-CCM or AES-GCM)") 479 end 480 offset = offset + 1 481 482 -- Handle Auth 483 if tvb(offset, 1):uint() == 0 then 484 ext_type_msg_tree:add(fields.auth, tvb(offset, 1)):append_text(" (None or KEKI indexed crypto context)") 485 else 486 ext_type_msg_tree:add(fields.auth, tvb(offset, 1)) 487 end 488 offset = offset + 1 489 490 -- Handle SE 491 local SE_node = ext_type_msg_tree:add(fields.SE, tvb(offset, 1)) 492 local SE = tvb(offset, 1):uint() 493 if SE == 0 then 494 SE_node:append_text( " (Unspecified or KEKI indexed crypto context)") 495 elseif SE == 1 then 496 SE_node:append_text( " (MPEG-TS/UDP)") 497 elseif SE == 2 then 498 SE_node:append_text( " (MPEG-TS/SRT)") 499 end 500 offset = offset + 1 501 502 -- Handle resv1 503 ext_type_msg_tree:add(fields.resv1, tvb(offset, 1)) 504 offset = offset + 1 505 506 -- Handle resv2 507 ext_type_msg_tree:add(fields.resv2, tvb(offset, 2)) 508 offset = offset + 2 509 510 -- Handle slen 511 ext_type_msg_tree:add(fields.slen, tvb(offset, 1)) 512 offset = offset + 1 513 514 -- Handle klen 515 local klen = tvb(offset, 1):uint() 516 ext_type_msg_tree:add(fields.klen, tvb(offset, 1)) 517 offset = offset + 1 518 519 -- Handle salt key 520 ext_type_msg_tree:add(fields.salt, tvb(offset, slen * 4)) 521 offset = offset + slen * 4 522 523 -- Handle wrap 524 -- Handle ICV 525 local wrap_len = 8 + KK * klen 526 local wrap_tree = ext_type_msg_tree:add(fields.wrap, tvb(offset, wrap_len)) 527 wrap_tree:add(fields.ICV, tvb(offset, 8)) 528 offset = offset + 8 529 -- If KK == 2, first key is Even key 530 if KK == 2 then 531 wrap_tree:add(fields.even_key, tvb(offset, klen)) 532 offset = offset + klen; 533 end 534 535 -- Handle Odd key 536 wrap_tree:add(fields.odd_key, tvb(offset, klen)) 537 offset = offset + klen; 538 elseif ext_type >= 5 and ext_type <= 8 then 539 local value_size = tvb(offset + 2, 2):uint() * 4 540 local ext_msg_size = 2 + 2 + value_size 541 local type_array = { " [SRT_CMD_SID]", " [SRT_CMD_CONGESTION]", " [SRT_CMD_FILTER]", " [SRT_CMD_GROUP]" } 542 local field_array = { fields.sid, fields.congestion, fields.filter, fields.group } 543 local ext_type_msg_tree = subtree:add(fields.ext_type_msg_tree, tvb(offset, ext_msg_size)):append_text(type_array[ext_type - 4]) 544 ext_type_msg_tree:add(fields.ext_type, tvb(offset, 2)) 545 offset = offset + 2 546 547 -- Handle Ext Msg Value Size 548 ext_type_msg_tree:add(fields.ext_size, tvb(offset, 2)):append_text(" (byte/4)") 549 offset = offset + 2 550 551 -- Value 552 local value_table = {} 553 for pos = 0, value_size - 4, 4 do 554 table.insert(value_table, string.char(tvb(offset + pos + 3, 1):uint())) 555 table.insert(value_table, string.char(tvb(offset + pos + 2, 1):uint())) 556 table.insert(value_table, string.char(tvb(offset + pos + 1, 1):uint())) 557 table.insert(value_table, string.char(tvb(offset + pos, 1):uint())) 558 end 559 local value = table.concat(value_table) 560 ext_type_msg_tree:add(field_array[ext_type - 4], tvb(offset, value_size), value) 561 offset = offset + value_size 562 elseif ext_type == -1 then 563 local ext_type_msg_tree = subtree:add(fields.ext_type_msg_tree, tvb(offset, tvb:len() - offset)):append_text(" [SRT_CMD_NONE]") 564 ext_type_msg_tree:add(fields.ext_type, tvb(offset, 2)) 565 offset = offset + 2 566 567 -- none 568 if offset == tvb:len() then 569 return 570 end 571 ext_type_msg_tree:add(fields.none, tvb(offset, tvb:len() - offset)) 572 offset = tvb:len() 573 end 574 if offset == tvb:len() then 575 return 576 else 577 process_ext_type() 578 end 579 end 580 581 process_ext_type() 582 end, 583 [1] = function() 584 pinfo.cols.info:append(" [KEEPALIVE]") 585 pack_type_tree:append_text(" [KEEPALIVE]") 586 pack_type_tree:add(fields.msg_type, tvb(offset, 2)):append_text(" [KEEPALIVE]") 587 pack_type_tree:add(fields.reserve, tvb(offset + 2, 2)):append_text(" [Undefined]") 588 offset = offset + 4 589 590 -- Handle Additional Info, Time Stamp and Destination Socket 591 parse_three_param() 592 end, 593 [2] = function() 594 pinfo.cols.info:append(" [ACK]") 595 pack_type_tree:append_text(" [ACK]") 596 pack_type_tree:add(fields.msg_type, tvb(offset, 2)) 597 pack_type_tree:add(fields.reserve, tvb(offset + 2, 2)):append_text(" [Undefined]") 598 offset = offset + 4 599 600 -- Handle ACK Number 601 subtree:add(fields.ack_num, tvb(offset, 4)) 602 offset = offset + 4 603 604 -- Handle Time Stamp 605 subtree:add(fields.time_stamp, tvb(offset, 4)):append_text(" μs") 606 offset = offset + 4 607 608 -- Handle Destination Socket 609 subtree:add(fields.dst_sock, tvb(offset, 4)) 610 offset = offset + 4 611 612 -- Handle Last Ack Packet Sequence 613 local last_ack_pack = tvb(offset, 4):uint() 614 pinfo.cols.info:append(" (Last ACK Seq:" .. last_ack_pack .. ")") 615 subtree:add(fields.last_ack_pack, tvb(offset, 4)) 616 offset = offset + 4 617 618 -- Handle RTT 619 local rtt = tvb(offset, 4):int() 620 subtree:add(fields.rtt, tvb(offset, 4)):append_text(" μs") 621 offset = offset + 4 622 623 -- Handle RTT variance 624 if rtt < 0 then 625 subtree:add(fields.rtt_variance, tvb(offset, 4), -tvb(offset, 4):int()) 626 else 627 subtree:add(fields.rtt_variance, tvb(offset, 4)) 628 end 629 offset = offset + 4 630 631 -- Handle Available Buffer Size(pkts) 632 subtree:add(fields.buf_size, tvb(offset, 4)):append_text(" pkts") 633 offset = offset + 4 634 635 -- Handle Packets Receiving Rate(Pkts/sec) 636 subtree:add(fields.pack_rcv_rate, tvb(offset, 4)):append_text(" pkts/sec") 637 offset = offset + 4 638 639 -- Handle Estmated Link Capacity 640 subtree:add(fields.est_link_capacity, tvb(offset, 4)):append_text(" pkts/sec") 641 offset = offset + 4 642 643 -- Handle Receiving Rate(bps) 644 subtree:add(fields.rcv_rate, tvb(offset, 4)):append_text(" bps") 645 offset = offset + 4 646 end, 647 [3] = function() 648 pinfo.cols.info:append(" [NAK(loss Report)]") 649 pack_type_tree:append_text(" [NAK(loss Report)]") 650 pack_type_tree:add(fields.msg_type, tvb(offset, 2)) 651 pack_type_tree:add(fields.reserve, tvb(offset + 2, 2)):append_text(" [Undefined]") 652 offset = offset + 4 653 654 -- Handle Additional Info, Timestamp and Destination Socket 655 parse_three_param() 656 657 -- Handle lost packet sequence 658 -- lua does not support changing loop variables within loops, but in the form of closures 659 -- https://blog.csdn.net/Ai102iA/article/details/75371239 660 local start = offset 661 local ending = tvb:len() 662 local lost_list_tree = subtree:add(fields.lost_list_tree, tvb(offset, ending - offset)) 663 for start in function() 664 local first_bit = bit.rshift(tvb(start, 1):uint(), 7) 665 if first_bit == 1 then 666 local lost_pack_range_tree = lost_list_tree:add(fields.lost_pack_range_tree, tvb(start, 8)) 667 local lost_start = bit.band(tvb(start, 4):uint(), 0x7FFFFFFF) 668 lost_pack_range_tree:append_text(" (" .. lost_start .. " -> " .. tvb(start + 4, 4):uint() .. ")") 669 lost_pack_range_tree:add(fields.lost_start, tvb(start, 4), lost_start) 670 start = start + 4 671 lost_pack_range_tree:add(fields.lost_up_to, tvb(start, 4)) 672 start = start + 4 673 else 674 lost_list_tree:add(fields.lost_pack_seq, tvb(start, 4)) 675 start = start + 4 676 end 677 return start 678 end 679 do 680 if start == ending then 681 break 682 end 683 end 684 end, 685 [4] = function() 686 pinfo.cols.info:append(" [Congestion Warning]") 687 pack_type_tree:append_text(" [Congestion Warning]") 688 pack_type_tree:add(fields.msg_type, tvb(offset, 2)) 689 pack_type_tree:add(fields.reserve, tvb(offset + 2, 2)):append_text(" [Undefined]") 690 offset = offset + 4 691 end, 692 [5] = function() 693 pinfo.cols.info:append(" [Shutdown]") 694 pack_type_tree:append_text(" [Shutdown]") 695 pack_type_tree:add(fields.msg_type, tvb(offset, 2)) 696 pack_type_tree:add(fields.reserve, tvb(offset + 2, 2)):append_text(" [Undefined]") 697 offset = offset + 4 698 699 -- Handle Additional Info, Timestamp and Destination Socket 700 parse_three_param() 701 end, 702 [6] = function() 703 pinfo.cols.info:append(" [ACKACK]") 704 pack_type_tree:append_text(" [ACKACK]") 705 pack_type_tree:add(fields.msg_type, tvb(offset, 2)) 706 pack_type_tree:add(fields.reserve, tvb(offset + 2, 2)):append_text(" [Undefined]") 707 offset = offset + 4 708 709 -- Handle ACK sequence number 710 subtree:add(fields.ack_num, tvb(offset, 4)) 711 offset = offset + 4 712 713 -- Handle Time Stamp 714 subtree:add(fields.time_stamp, tvb(offset, 4)):append_text(" μs") 715 offset = offset + 4 716 717 -- Handle Destination Socket 718 subtree:add(fields.dst_sock, tvb(offset, 4)) 719 offset = offset + 4 720 721 -- Handle Control Information 722 subtree:add(fields.ctl_info, tvb(offset, 4)) 723 offset = offset + 4 724 end, 725 [7] = function() 726 pinfo.cols.info:append(" [Drop Request]") 727 pack_type_tree:append_text(" [Drop Request]") 728 pack_type_tree:add(fields.msg_type, tvb(offset, 2)):append_text(" [Drop Request]") 729 pack_type_tree:add(fields.reserve, tvb(offset + 2, 2)):append_text(" [Undefined]") 730 offset = offset + 4 731 end, 732 [8] = function() 733 pinfo.cols.info:append(" [Peer Error]") 734 pack_type_tree:append_text(" [Peer Error]") 735 pack_type_tree:add(fields.msg_type, tvb(offset, 2)):append_text(" [Peer Error]") 736 pack_type_tree:add(fields.reserve, tvb(offset + 2, 2)):append_text(" [Undefined]") 737 offset = offset + 4 738 end 739 } 740 -- Handle based on msg_type 741 local case = switch[msg_type] 742 if case then 743 case() 744 else 745 -- default case 746 subtree:add(fields.msg_type, tvb(offset, 2)):append_text(" [Unknown Message Type]") 747 offset = offset + 4 748 end 749 else 750 -- If type field is '0x7FFF', it means an extended type, Handle Reserve field 751 offset = offset + 2 752 local msg_ext_type = tvb(offset, 2):uint() 753 if msg_ext_type == 0 then 754 pinfo.cols.info:append(" [Message Extension]") 755 756 pack_type_tree:add(fields.msg_ext_type, tvb(offset, 2)):append_text(" [Message Extension]") 757 offset = offset + 2 758 759 -- Handle Additional Info, Time Stamp and Destination Socket 760 parse_three_param() 761 762 -- Control information: defined by user 763 elseif msg_ext_type == 1 or ext_type == 2 then 764 if msg_ext_type == 1 then 765 pack_type_tree:add(fields.msg_ext_type, tvb(offset, 2)):append_text(" [SRT Handshake Request]") 766 pinfo.cols.info:append(" [SRT Handshake Request]") 767 elseif msg_ext_type == 2 then 768 pack_type_tree:add(fields.msg_ext_type, tvb(offset, 2)):append_text(" [SRT Handshake Response]") 769 pinfo.cols.info:append(" [SRT Handshake Response]") 770 end 771 offset = offset + 2 772 773 -- Ignore additional info (this field is not defined in this packet type) 774 subtree:add(fields.additional_info, tvb(offset, 4)):append_text(" [undefined]") 775 offset = offset + 4 776 777 -- Handle Time Stamp 778 subtree:add(fields.time_stamp, tvb(offset, 4)):append_text("μs") 779 offset = offset + 4 780 781 -- Handle Destination Socket 782 subtree:add(fields.dst_sock, tvb(offset, 4)) 783 offset = offset + 4 784 785 -- Handle SRT Version field 786 subtree:add(fields.srt_version, tvb(offset, 4)) 787 offset = ofssset + 4 788 789 -- Handle SRT Flags 790 local SRT_flags_tree = subtree:add(fields.srt_flags, tvb(offset, 4)) 791 SRT_flags_tree:add(fields.srt_opt_tsbpdsnd, tvb(offset, 4)) 792 SRT_flags_tree:add(fields.srt_opt_tsbpdrcv, tvb(offset, 4)) 793 SRT_flags_tree:add(fields.srt_opt_haicrypt, tvb(offset, 4)) 794 SRT_flags_tree:add(fields.srt_opt_tlpktdrop, tvb(offset, 4)) 795 SRT_flags_tree:add(fields.srt_opt_nakreport, tvb(offset, 4)) 796 SRT_flags_tree:add(fields.srt_opt_rexmitflg, tvb(offset, 4)) 797 SRT_flags_tree:add(fields.srt_opt_stream, tvb(offset, 4)) 798 offset = offset + 4 799 800 -- Handle TsbPd Resv 801 subtree:add(fields.tsbpb_resv, tvb(offset, 2)) 802 offset = offset + 2 803 804 -- Handle TsbPb Delay 805 subtree:add(fields.tsbpb_delay, tvb(offset, 2)) 806 offset = offset + 2 807 808 -- Handle Reserved field 809 subtree:add(fields.reserve, tvb(offset, 4)) 810 offset = offset + 4 811 elseif msg_ext_type == 3 or msg_ext_type == 4 then 812 if msg_ext_type == 3 then 813 pack_type_tree:add(fields.msg_ext_type, tvb(offset, 2)):append_text(" [Encryption Keying Material Request]") 814 pinfo.cols.info:append(" [Encryption Keying Material Request]") 815 elseif msg_ext_type == 4 then 816 pack_type_tree:add(fields.msg_ext_type, tvb(offset, 2)):append_text(" [Encryption Keying Material Response]") 817 pinfo.cols.info:append(" [Encryption Keying Material Response]") 818 end 819 offset = offset + 2 820 821 -- Ignore additional info (this field is not defined in this packet type) 822 subtree:add(fields.additional_info, tvb(offset, 4)):append_text(" [undefined]") 823 offset = offset + 4 824 825 -- Handle Timestamp 826 subtree:add(fields.time_stamp, tvb(offset, 4)):append_text("μs") 827 offset = offset + 4 828 829 -- Handle Destination Socket 830 subtree:add(fields.dst_sock, tvb(offset, 4)) 831 offset = offset + 4 832 833 -- Handle KmErr 834 if msg_ext_type == 4 then 835 subtree:add(fields.km_err, tvb(offset, 4)) 836 offset = offset + 4 837 return 838 end 839 840 -- The encrypted message is not handled 841 end 842 end 843 else 844 -- 0 -> Data Packet 845 pack_type_tree:add(fields.pack_type, tvb(offset, 2)) 846 pack_type_tree:append_text(" (Data Packet)") 847 local seq_num = tvb(offset, 4):uint() 848 pinfo.cols.info:append(" (Data Packet)(Seq Num:" .. seq_num .. ")") 849 850 -- The first 4 bytes are the package sequence number 851 subtree:add(fields.seq_num, tvb(offset, 4)) 852 offset = offset + 4 853 854 data_flag_info_tree = subtree:add(fields.data_flag_info_tree, tvb(offset, 1)) 855 -- Handle FF flag 856 local FF_state = bit.rshift(bit.band(tvb(offset, 1):uint(), 0xC0), 6) 857 if FF_state == 0 then 858 data_flag_info_tree:append_text(" [Middle packet]") 859 elseif FF_state == 1 then 860 data_flag_info_tree:append_text(" [Last packet]") 861 elseif FF_state == 2 then 862 data_flag_info_tree:append_text(" [First packet]") 863 else 864 data_flag_info_tree:append_text(" [Single packet]") 865 end 866 data_flag_info_tree:add(fields.FF_state, tvb(offset, 1)) 867 868 -- Handle O flag 869 local O_state = bit.rshift(bit.band(tvb(offset, 1):uint(), 0x20), 5) 870 if O_state == 0 then 871 data_flag_info_tree:append_text(" [Data delivered unordered]") 872 else 873 data_flag_info_tree:append_text(" [Data delivered in order]") 874 end 875 data_flag_info_tree:add(fields.O_state, tvb(offset, 1)) 876 877 -- Handle KK flag 878 local KK_state = bit.rshift(bit.band(tvb(offset, 1):uint(), 0x18), 3) 879 if KK_state == 1 then 880 data_flag_info_tree:append_text(" [Encrypted with even key]") 881 elseif KK_state == 2 then 882 data_flag_info_tree:append_text(" [Encrypted with odd key]") 883 end 884 data_flag_info_tree:add(fields.KK_state, tvb(offset, 1)) 885 886 -- Handle R flag 887 local R_state = bit.rshift(bit.band(tvb(offset, 1):uint(), 0x04), 2) 888 if R_state == 1 then 889 data_flag_info_tree:append_text(" [Retransmit packet]") 890 pinfo.cols.info:append(" [Retransmit packet]") 891 end 892 data_flag_info_tree:add(fields.R_state, tvb(offset, 1)) 893 894 -- Handle message number 895 local msg_num = tvb(offset, 4):uint() 896 msg_num = bit.band(tvb(offset, 4):uint(), 0x03FFFFFF) 897 -- subtree:add(fields.msg_num, bit.band(tvb(offset, 4):uint(), 0x03FFFFFF)) 898 subtree:add(fields.msg_num, tvb(offset, 4), msg_num) 899 offset = offset + 4 900 901 -- Handle Timestamp 902 subtree:add(fields.time_stamp, tvb(offset, 4)):append_text(" μs") 903 offset = offset + 4 904 905 -- Handle destination socket 906 subtree:add(fields.dst_sock, tvb(offset, 4)) 907 offset = offset + 4 908 end 909end 910 911-- Add the protocol into udp table 912local port = 1935 913 914local function enable_dissector() 915 DissectorTable.get("udp.port"):add(port, srt_dev) 916end 917 918-- Call it now - enabled by default 919enable_dissector() 920 921local function disable_dissector() 922 DissectorTable.get("udp.port"):remove(port, srt_dev) 923end 924 925-- Prefs changed will listen at new port 926function srt_dev.prefs_changed() 927 if port ~= srt_dev.prefs.srt_udp_port then 928 if port ~= 0 then 929 disable_dissector() 930 end 931 932 port = srt_dev.prefs.srt_udp_port 933 934 if port ~= 0 then 935 enable_dissector() 936 end 937 end 938end 939