|
@@ -0,0 +1,158 @@
|
|
|
+function ftci_dissector(buffer, pinfo, tree, FTCI_protocol, offset)
|
|
|
+
|
|
|
+ -- Define ProtoFields for each of the fields in the structure
|
|
|
+
|
|
|
+ -- Control Field 1 (1 byte)
|
|
|
+ local f_session_id = ProtoField.uint8("FileTransfer.session_id", "File Transfer Session ID", base.DEC)
|
|
|
+ local f_resume_context_mode = ProtoField.uint8("FileTransfer.resume_context_mode", "Resume Context Mode", base.DEC)
|
|
|
+ local f_seq_loss_detection_mode = ProtoField.string("FileTransfer.seq_loss_detection_mode", "Seq Loss Detection Mode")
|
|
|
+ local f_file_id = ProtoField.uint8("FileTransfer.file_id", "File ID", base.DEC)
|
|
|
+
|
|
|
+
|
|
|
+ -- Control Field 2 (1 byte)
|
|
|
+ local f_transfer_mode = ProtoField.uint8("FileTransfer.transfer_mode", "Transfer Mode (TXM)", base.DEC)
|
|
|
+ local f_file_format = ProtoField.uint8("FileTransfer.file_format", "File Format", base.HEX)
|
|
|
+ local f_unit_size = ProtoField.uint8("FileTransfer.unit_size", "Unit Size", base.DEC)
|
|
|
+ local f_size_field_type = ProtoField.uint8("FileTransfer.size_field_type", "Size Field Type", base.HEX)
|
|
|
+
|
|
|
+ -- Other fields
|
|
|
+ local f_checksum = ProtoField.uint32("FileTransfer.checksum", "Checksum",base.HEX)
|
|
|
+ local f_mtu_size = ProtoField.uint16("FileTransfer.mtu_size", "MTU Size", base.DEC)
|
|
|
+ local f_rx_con_fail_timeout = ProtoField.uint16("FileTransfer.rx_con_fail_timeout", "Receiver Connection Fail Timeout", base.DEC)
|
|
|
+ local f_major_version = ProtoField.uint8("FileTransfer.major_version", "Major Version", base.DEC)
|
|
|
+ local f_minor_version = ProtoField.uint8("FileTransfer.minor_version", "Minor Version", base.DEC)
|
|
|
+ local f_sct_instance_key = ProtoField.uint32("FileTransfer.sct_instance_key", "SCT Instance Key", base.DEC)
|
|
|
+ local f_file_mem_size = ProtoField.bytes("FileTransfer.file_mem_size", "File/Mem Size")
|
|
|
+ local f_dest_storage = ProtoField.uint8("FileTransfer.dest_storage", "Destination Storage", base.DEC)
|
|
|
+ local f_dest_mem_address = ProtoField.uint32("FileTransfer.dest_mem_address", "Destination Memory Address", base.HEX)
|
|
|
+ local f_file_path_len = ProtoField.uint8("FileTransfer.file_path_len", "File /Name Length", base.DEC)
|
|
|
+ local f_file_path = ProtoField.string("FileTransfer.file_path", "File /Name")
|
|
|
+
|
|
|
+ -- Add fields to protocol
|
|
|
+ FTCI_protocol.fields = {
|
|
|
+ f_session_id, f_resume_context_mode, f_seq_loss_detection_mode, f_file_id,
|
|
|
+ f_transfer_mode, f_file_format, f_unit_size, f_size_field_type,
|
|
|
+ f_checksum, f_mtu_size, f_rx_con_fail_timeout, f_major_version, f_minor_version,
|
|
|
+ f_sct_instance_key, f_file_mem_size, f_dest_storage, f_dest_mem_address,
|
|
|
+ f_file_path_len, f_file_path
|
|
|
+ }
|
|
|
+
|
|
|
+ -- Loop through the data instances
|
|
|
+ -- for i = 1, num_of_instance do
|
|
|
+ -- Add the new structure data as a subtree
|
|
|
+ local subtree = tree:add( FTCI_protocol, buffer(), "File Transfer Protocol")
|
|
|
+
|
|
|
+ -- dissect CONTROL FIELD 1 (1 byte)
|
|
|
+ local w=0
|
|
|
+ local control_field1 = buffer(offset, 1):le_uint()
|
|
|
+ local session_id = control_field1 & 0x07
|
|
|
+ local resume_context_mode = (control_field1 >>3) & 0x01
|
|
|
+ local seq_loss_detection_mode = (control_field1 >> 4) & 0x01
|
|
|
+ local file_id = (control_field1 >>5) & 0x07
|
|
|
+ subtree:add(f_session_id, session_id)
|
|
|
+ subtree:add(f_resume_context_mode, resume_context_mode)
|
|
|
+ if seq_loss_detection_mode == 0 then
|
|
|
+ subtree:add(f_seq_loss_detection_mode, "UNACK")
|
|
|
+ else
|
|
|
+ subtree:add(f_seq_loss_detection_mode, "ACK")
|
|
|
+ end
|
|
|
+ subtree:add(f_file_id, file_id)
|
|
|
+ offset = offset + 1
|
|
|
+
|
|
|
+ -- dissect CONTROL FIELD 2 (1 byte)
|
|
|
+ local control_field2 = buffer(offset, 1):le_uint()
|
|
|
+ local transfer_mode = (control_field2 >>0) & 0x01 --txm
|
|
|
+ local file_format = (control_field2 >>1) & 0x07
|
|
|
+ local unit_size = (control_field2 >>4) & 0x03
|
|
|
+ local size_field_type = (control_field2 >>6) & 0x03
|
|
|
+ if size_field_type == 0x01 then
|
|
|
+ w=0
|
|
|
+ elseif size_field_type == 0x02 then
|
|
|
+ w=1
|
|
|
+ elseif size_field_type > 0x02 then
|
|
|
+ w=2
|
|
|
+ end
|
|
|
+ subtree:add(f_transfer_mode, transfer_mode)
|
|
|
+ subtree:add(f_file_format, file_format)
|
|
|
+ subtree:add(f_unit_size, unit_size)
|
|
|
+ subtree:add(f_size_field_type, size_field_type)
|
|
|
+
|
|
|
+ offset = offset + 1
|
|
|
+ -- dissect MTU Size (2 bytes)
|
|
|
+ local mtu_size = buffer(offset, 2):le_uint()
|
|
|
+ subtree:add(f_mtu_size, mtu_size)
|
|
|
+ offset = offset + 2
|
|
|
+
|
|
|
+ -- dissect Checksum (4 bytes)
|
|
|
+ local checksum = buffer(offset, 4):le_uint()
|
|
|
+ subtree:add(f_checksum, checksum)
|
|
|
+ offset = offset + 4
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ -- dissect RX Connection Fail Timeout (2 bytes)
|
|
|
+ local rx_con_fail_timeout = buffer(offset, 2):le_uint()
|
|
|
+ subtree:add(f_rx_con_fail_timeout, rx_con_fail_timeout)
|
|
|
+ offset = offset + 2
|
|
|
+
|
|
|
+ -- dissect Major Version (1 byte)
|
|
|
+ local major_version = buffer(offset, 1):le_uint()
|
|
|
+ subtree:add(f_major_version, major_version)
|
|
|
+ offset = offset + 1
|
|
|
+
|
|
|
+ -- dissect Minor Version (1 byte)
|
|
|
+ local minor_version = buffer(offset, 1):le_uint()
|
|
|
+ subtree:add(f_minor_version, minor_version)
|
|
|
+ offset = offset + 1
|
|
|
+
|
|
|
+ -- dissect SCT Instance Key (4 bytes)
|
|
|
+ local sct_instance_key = buffer(offset, 4):le_uint()
|
|
|
+ subtree:add(f_sct_instance_key, sct_instance_key)
|
|
|
+ offset = offset + 4
|
|
|
+
|
|
|
+ -- dissect File/Mem Size (1-5 bytes, variable size)
|
|
|
+ --if unit_size then
|
|
|
+ local file_mem_size_len = unit_size
|
|
|
+ local file_mem_size = buffer(offset , file_mem_size_len)
|
|
|
+ subtree:add(f_file_mem_size, file_mem_size)
|
|
|
+ offset = offset + file_mem_size_len
|
|
|
+ --end
|
|
|
+
|
|
|
+ -- dissect Destination Storage (1 byte)
|
|
|
+ if transfer_mode == 0x01 then
|
|
|
+ local dest_storage = buffer(offset, 1):le_uint()
|
|
|
+ subtree:add(f_dest_storage, dest_storage)
|
|
|
+ offset = offset + 1
|
|
|
+
|
|
|
+ -- dissect Destination Memory Address (4 bytes)
|
|
|
+ local dest_mem_address = buffer(offset, 4):le_uint()
|
|
|
+ subtree:add(f_dest_mem_address, dest_mem_address)
|
|
|
+ offset = offset + 4
|
|
|
+ end
|
|
|
+
|
|
|
+ -- dissect File Path Length (1 byte)
|
|
|
+ local file_path_len = buffer(offset + w, 1):le_uint()
|
|
|
+ subtree:add(f_file_path_len, file_path_len)
|
|
|
+ --file_path_len=200
|
|
|
+ offset = offset + 1
|
|
|
+
|
|
|
+ -- dissect File Path/Name (variable length)
|
|
|
+ local substring_start = 0
|
|
|
+ local count = 0
|
|
|
+ local file_path = buffer(offset, file_path_len):string()
|
|
|
+ for i = file_path_len-1, 1, -1 do
|
|
|
+ local char=string.sub(file_path, i, i)
|
|
|
+ if char:match("\\.") then
|
|
|
+ substring_start = i
|
|
|
+ if count == 1 then
|
|
|
+ break -- Exit the loop once we find a special character
|
|
|
+ end
|
|
|
+ count = count +1
|
|
|
+ end
|
|
|
+ end
|
|
|
+
|
|
|
+ local new_string = string.sub(file_path, substring_start + 1)
|
|
|
+ subtree:add(f_file_path, new_string)
|
|
|
+ offset = offset + file_path_len
|
|
|
+ -- end
|
|
|
+end
|