add basic ITU-T T.70 and T.62 LUA dissectors
This commit is contained in:
parent
5ca585e4b0
commit
4431c23d40
|
@ -47,13 +47,13 @@ Pdu rsl_pdu Proto gsm_abis_rsl Transport gsm_ipa/tcp/ip {
|
|||
Criteria Accept Strict (rsl_msg_dsc {4|1|63}); // DCHAN || RLL || IPA
|
||||
};
|
||||
|
||||
/* somehow this definition for the Gop doesn't work, as ip_addr exists only one if source and dest are
|
||||
* identical */
|
||||
Gop rsl_lchan On rsl_pdu Match (ip_addr, ip_addr, port, port, rsl_cbits, rsl_tn) {
|
||||
Start (rsl_msg_type = 33); // CHAN_ACT
|
||||
Stop (rsl_msg_type {36|51}); // CHAN_ACT_NACK || RF_CHAN_REL_ACK
|
||||
};
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SCCP
|
||||
***********************************************************************/
|
||||
|
|
|
@ -0,0 +1,247 @@
|
|||
-- wireshark LUA dissector for the ITU-T T.62 protocol
|
||||
-- (C) 2024 by Harald Welte <laforge@osmocom.org>
|
||||
-- SPDX-License-Identifier: GPL-2.0+
|
||||
--
|
||||
-- Usage: Move this file to your "personal lua plugins" folder that
|
||||
-- can be found in the Wireshark Help->About Wireshark->Folders tab
|
||||
-- Windows: %APPDATA%\Wireshark\plugins.
|
||||
-- Unix-like systems: ~/.local/lib/wireshark/plugins.
|
||||
|
||||
t62_protocol = Proto("T.62", "ITU-T T.62 Control Procedures for Teletex and Group 4 Facsimile Services")
|
||||
|
||||
|
||||
local session_cri_names_long = {
|
||||
-- Table 4/T.62: CRI for session elements
|
||||
[0x0d] = "Command Session Start",
|
||||
[0x09] = "Command Session End",
|
||||
[0x19] = "Command Session Abort",
|
||||
[0x15] = "Command Session Change Control",
|
||||
[0x01] = "Command Session User Information",
|
||||
[0x0e] = "Response Session Start Positive",
|
||||
[0x0c] = "Response Session Start Negative",
|
||||
[0x0a] = "Response Session End Positive",
|
||||
[0x1a] = "Response Session Abort Positive",
|
||||
[0x16] = "Response Session Change Control Positive",
|
||||
[0x02] = "Response Session User Information",
|
||||
}
|
||||
local session_cri_names = {
|
||||
-- Table 4/T.62: CRI for session elements
|
||||
[0x0d] = "CSS",
|
||||
[0x09] = "CSE",
|
||||
[0x19] = "CSA",
|
||||
[0x15] = "CSCC",
|
||||
[0x01] = "CSUI",
|
||||
[0x0e] = "RSSP",
|
||||
[0x0c] = "RSSN",
|
||||
[0x0a] = "RSEP",
|
||||
[0x1a] = "RSAP",
|
||||
[0x16] = "RSCCP",
|
||||
[0x02] = "RSUI",
|
||||
}
|
||||
local hf_session_cri = ProtoField.uint8("t62.session.cri", "Command/Response Identifier", base.HEX, session_cri_names)
|
||||
local hf_session_li = ProtoField.uint8("t62.session.li", "Length Identifier", base.DEC)
|
||||
|
||||
-- Table 7/T.62
|
||||
local session_pi_pgi_names = {
|
||||
[0x00] = "Reserved for extension",
|
||||
[0x01] = "Session reference",
|
||||
[0x09] = "Terminal identifier of the called terminal",
|
||||
[0x0a] = "Terminal identifier of the calling terminal",
|
||||
[0x0b] = "Date and time",
|
||||
[0x0c] = "Additional session reference number",
|
||||
[0x02] = "Non-basic session capabilities",
|
||||
[0x0d] = "Miscellaneous session capabilities",
|
||||
[0x0e] = "Window size",
|
||||
-- No PGI associated with these PIs
|
||||
[0x08] = "Service identifier",
|
||||
[0x10] = "Session control functions",
|
||||
[0x11] = "Session termination parameter",
|
||||
[0x12] = "Inactivity timer",
|
||||
[0x14] = "Session service functions",
|
||||
[0x32] = "Reason",
|
||||
[0x41] = "Non-basic Teletex terminal capabilities",
|
||||
[0x49] = "Control character set",
|
||||
[0x4a] = "Teletex page format",
|
||||
[0x4b] = "Miscellaneous Teletex terminal capabilities",
|
||||
[0xc1] = "Session user data",
|
||||
[0xe0] = "Private use 0",
|
||||
[0xe1] = "Private use 1",
|
||||
[0xe2] = "Private use 2",
|
||||
[0xe3] = "Private use 3",
|
||||
[0xe4] = "Private use 4",
|
||||
[0xe5] = "Private use 5",
|
||||
[0xe6] = "Private use 6",
|
||||
[0xe7] = "Private use 7",
|
||||
[0xe8] = "Non-standardixed capabilities",
|
||||
}
|
||||
local hf_session_pi_pgi = ProtoField.uint8("t64.session.pi", "Parameter (Group) Identifier", base.HEX, session_pi_pgi_names)
|
||||
|
||||
local doc_cri_names_long = {
|
||||
-- Table 5/T.62: CRI for document command identifiers
|
||||
[0x2d] = "Command Document Start",
|
||||
[0x1d] = "Command Document Continue",
|
||||
[0x29] = "Command Document End",
|
||||
[0x19] = "Command Document Resynchronize",
|
||||
[0x39] = "Command Document Discard",
|
||||
[0x31] = "Comman Document Page Boundary",
|
||||
[0x3d] = "Command Document Capability List",
|
||||
[0x01] = "Command Document User Information",
|
||||
-- Table 6/T.62: CRI for document response identifiers
|
||||
[0x2a] = "Response Document End Potve",
|
||||
[0x1a] = "Response Document Resynchronize Positive",
|
||||
[0x3a] = "Response Document Discard Positive",
|
||||
[0x32] = "Response Document Page Boundary Positive",
|
||||
[0x30] = "Response Document Page Boundary Negative",
|
||||
[0x3e] = "Response Document Capability List Positive",
|
||||
[0x00] = "Resposne Documnet General Reject",
|
||||
}
|
||||
local doc_cri_names = {
|
||||
-- Table 5/T.62: CRI for document command identifiers
|
||||
[0x2d] = "CDS",
|
||||
[0x1d] = "CDC",
|
||||
[0x29] = "CDE",
|
||||
[0x19] = "CDR",
|
||||
[0x39] = "CDD",
|
||||
[0x31] = "CDPB",
|
||||
[0x3d] = "CDCL",
|
||||
[0x01] = "CDUI",
|
||||
-- Table 6/T.62: CRI for document response identifiers
|
||||
[0x2a] = "RDEP",
|
||||
[0x1a] = "RDRP",
|
||||
[0x3a] = "RDDP",
|
||||
[0x32] = "RDPBP",
|
||||
[0x30] = "RDPBN",
|
||||
[0x3e] = "RDCLP",
|
||||
[0x00] = "RDGR",
|
||||
}
|
||||
local hf_document_cri = ProtoField.uint8("t62.document.cri", "Command/Response Identifier", base.HEX, doc_cri_names)
|
||||
local hf_document_li = ProtoField.uint8("t62.document.li", "Length Identifier", base.DEC)
|
||||
|
||||
local hf_document_data = ProtoField.bytes("t62.document.data", "Data")
|
||||
|
||||
-- Table 8/T.62
|
||||
local doc_pi_pgi_names = {
|
||||
[0x20] = "Reserved fro extension",
|
||||
[0x21] = "Document linking",
|
||||
[0x09] = "Terminal identifier of the called terminal",
|
||||
[0x0a] = "Terminal identifier of the calling terminal",
|
||||
[0x0b] = "Date and time",
|
||||
[0x0c] = "Additional session reference number",
|
||||
[0x29] = "Document reference number",
|
||||
[0x2a] = "Checkpoint reference number",
|
||||
-- no PGI associated wih these PI
|
||||
[0x12] = "Inactivity timer",
|
||||
[0x28] = "Service interworking identifier",
|
||||
[0x29] = "Document reference number",
|
||||
[0x2a] = "Checkpoint reference number",
|
||||
[0x2c] = "Acceptance of CDCL parameters",
|
||||
[0x2d] = "Storage capacity negotiation",
|
||||
[0x2e] = "Receiving ability jeopardized",
|
||||
[0x2f] = "Reserved",
|
||||
[0x30] = "Document type identifier",
|
||||
[0x31] = "Reflect parameter values",
|
||||
[0x32] = "Reason",
|
||||
[0x40] = "Reserved for extension",
|
||||
[0x41] = "Non-basic Teletex terminal capabilities",
|
||||
[0x48] = "Graphic character set",
|
||||
[0x49] = "Control character set",
|
||||
[0x4a] = "Teletex page format",
|
||||
[0x4b] = "Miscellaneous Teletex terminal capabilities",
|
||||
[0x4d] = "Character box height",
|
||||
[0x4e] = "Character box width",
|
||||
[0xc1] = "Session user data",
|
||||
[0xe0] = "Private use 0",
|
||||
[0xe1] = "Private use 1",
|
||||
[0xe2] = "Private use 2",
|
||||
[0xe3] = "Private use 3",
|
||||
[0xe4] = "Private use 4",
|
||||
[0xe5] = "Private use 5",
|
||||
[0xe6] = "Private use 6",
|
||||
[0xe7] = "Private use 7",
|
||||
[0xe8] = "Non-standardized capabilities",
|
||||
}
|
||||
local hf_doc_pi_pgi = ProtoField.uint8("t64.document.pi", "Parameter (Group) Identifier", base.HEX, doc_pi_pgi_names)
|
||||
|
||||
-- 5.7.2.10 Reason (session or document)
|
||||
local reason_names = {
|
||||
[0x00] = "No specific reason stated (used for session or document reasons other than those listed)",
|
||||
[0x01] = "Temporarily unable to enter into, or to continue, a session (e.g. due to memory full or out of recording paper)",
|
||||
[0x02] = "Explicit text message only for use with RSSN",
|
||||
[0x03] = "Sequence error",
|
||||
[0x05] = "Local terminal error",
|
||||
[0x06] = "Unrecoverable procedural error",
|
||||
}
|
||||
|
||||
-- 5.7.3.7 Document type identiifer
|
||||
local doc_type_id_names = {
|
||||
[0x01] = "Operator document",
|
||||
[0x02] = "Control document",
|
||||
[0x03] = "Monitor document",
|
||||
}
|
||||
|
||||
-- Table 11/T.62
|
||||
local teletex_page_format_names = {
|
||||
[0x01] = "ISO A4, horizontal and vertical",
|
||||
[0x02] = "North American, horizontal and vertical",
|
||||
[0x84] = "ISO A4 extended (ISO standard 3535), vertical",
|
||||
[0x44] = "ISO A4 extended (ISO standard 3535), horizontal",
|
||||
[0x88] = "North American legal, vertical",
|
||||
[0x48] = "North American legal, horizontal",
|
||||
[0x03] = "ISO A4, horizontal and vertical (for use by Japanese Kanji and Chinese ideogram terminals)",
|
||||
[0x10] = "ISO B5, horizontal and vertical (for use by Japanese Kanji and Chinese ideogram terminals)",
|
||||
[0x20] = "ISO B4, horizontal and vertical (for use by Japanese Kanji and Chinese ideogram terminals)",
|
||||
}
|
||||
|
||||
t62_protocol.fields = {
|
||||
hf_session_cri, hf_session_li, hf_session_pi_pgi,
|
||||
hf_document_cri, hf_document_li, hf_doc_pi_pgi,
|
||||
hf_document_data,
|
||||
}
|
||||
|
||||
function decode_t62_document(buffer, pinfo, tree)
|
||||
local d_cri = buffer(0, 1):uint()
|
||||
local d_li = buffer(1, 1):uint()
|
||||
|
||||
pinfo.cols.info:append(" " .. doc_cri_names[d_cri])
|
||||
tree:append_text(" " .. doc_cri_names[d_cri] .. "(" .. doc_cri_names_long[d_cri] .. ")")
|
||||
tree:add(hf_document_cri, buffer(0, 1))
|
||||
tree:add(hf_document_li, buffer(1, 1))
|
||||
|
||||
if (d_li > 0) then
|
||||
-- FIXME: document parameters
|
||||
end
|
||||
|
||||
-- user data only exists in CDUI
|
||||
if (d_cri == 0x01) then
|
||||
tree:add(hf_document_data, buffer(2))
|
||||
end
|
||||
end
|
||||
|
||||
function t62_protocol.dissector(buffer, pinfo, tree)
|
||||
pinfo.cols.protocol = t62_protocol.name
|
||||
|
||||
local subtree = tree:add(t62_protocol, buffer(), "T.62")
|
||||
local offset = 0
|
||||
|
||||
local s_cri = buffer(0, 1):uint()
|
||||
local s_li = buffer(1, 1):uint()
|
||||
|
||||
pinfo.cols.info:append(" " .. session_cri_names[s_cri])
|
||||
subtree:append_text(" " .. session_cri_names[s_cri] .. " (" .. session_cri_names_long[s_cri] .. ")")
|
||||
subtree:add(hf_session_cri, buffer(0, 1))
|
||||
subtree:add(hf_session_li, buffer(1, 1))
|
||||
|
||||
if (s_li > 0) then
|
||||
-- FIXME: session parameters
|
||||
end
|
||||
|
||||
-- document layer data only exists in CSUI / RSUI
|
||||
if (s_cri == 0x01 or s_cri == 0x02) then
|
||||
decode_t62_document(buffer(2+s_li), pinfo, tree)
|
||||
end
|
||||
end
|
||||
|
||||
function t62_protocol.init()
|
||||
local t70_dissectors = DissectorTable.get("t70.subdissector")
|
||||
t70_dissectors:add_for_decode_as(t62_protocol)
|
||||
end
|
|
@ -0,0 +1,127 @@
|
|||
-- wireshark LUA dissector for the ITU-T T.70 protocol
|
||||
-- (C) 2024 by Harald Welte <laforge@osmocom.org>
|
||||
-- SPDX-License-Identifier: GPL-2.0+
|
||||
--
|
||||
-- Usage: Move this file to your "personal lua plugins" folder that
|
||||
-- can be found in the Wireshark Help->About Wireshark->Folders tab
|
||||
-- Windows: %APPDATA%\Wireshark\plugins.
|
||||
-- Unix-like systems: ~/.local/lib/wireshark/plugins.
|
||||
|
||||
t70_protocol = Proto("T.70", "ITU-T T.70 Network-Independent Basic Transport Service for the Telematic services")
|
||||
|
||||
t70_subdissectors = DissectorTable.new("t70.subdissector", "T.70 payload subdissector", ftypes.NONE, base.NONE, t70_protocol)
|
||||
|
||||
local hf_net_block_hdr_len = ProtoField.uint8("t70.net_block_hdr_len", "Network Block Header Length", base.DEC)
|
||||
local hf_net_block_hdr = ProtoField.bytes("t70.net_block_hdr", "Network Block Header")
|
||||
local hf_net_block_hdr_m = ProtoField.bool("70.net_block_hdr.m", "M(ore data mark) bit", base.HEX, nil, 0x80)
|
||||
local hf_net_block_hdr_q = ProtoField.bool("70.net_block_hdr.q", "Q(ualifier) bit", base.HEX, nil, 0x40)
|
||||
|
||||
local hf_src_ref = ProtoField.uint16("t70.src_ref", "Source Reference", base.HEX)
|
||||
local hf_dst_ref = ProtoField.uint16("t70.dst_ref", "Destination Reference", base.HEX)
|
||||
|
||||
-- Fogure 15/T.70
|
||||
local reject_cause_names = {
|
||||
[0x00] = "Reason not specified",
|
||||
[0x01] = "Function not implemented",
|
||||
[0x02] = "Invalid block",
|
||||
[0x03] = "Invalid parameter",
|
||||
}
|
||||
local hf_rej_cause = ProtoField.uint8("t70.rej_cause", "Reject Cause", base.HEX, reject_cause_names)
|
||||
local hf_block_len = ProtoField.uint8("t70.block_len", "Block Length", base.DEC)
|
||||
local block_types = {
|
||||
[0xe0] = "TCR",
|
||||
[0xd0] = "TCA",
|
||||
[0x80] = "TCC",
|
||||
[0x70] = "TBR",
|
||||
[0xf0] = "TDT",
|
||||
}
|
||||
local block_types_long = {
|
||||
[0xe0] = "Transport Connection Request",
|
||||
[0xd0] = "Transport Connection Accept",
|
||||
[0x80] = "Transport Connection Clear",
|
||||
[0x70] = "Transport Block Reject",
|
||||
[0xf0] = "Transport Data",
|
||||
}
|
||||
local hf_block_type = ProtoField.uint8("t70.block_type", "Block Type", base.HEX, block_types, 0xff)
|
||||
local hf_data = ProtoField.bytes("t70.data", "Data")
|
||||
|
||||
local param_names = {
|
||||
[0xc0] = "Transport data block size", -- Figure 11/T.70
|
||||
[0xc1] = "Calling address", -- Figure 10/T.70 (but also Figure 16/T.70: Rejected block)
|
||||
[0xc2] = "Called address", -- Fiure 10/T.70
|
||||
}
|
||||
|
||||
-- Figure 13/T.70
|
||||
local clearing_cause_names = {
|
||||
[0x00] = "Reason not specified",
|
||||
[0x01] = "Terminal occupied",
|
||||
[0x02] = "Terminal out of order",
|
||||
[0x03] = "Address unknown",
|
||||
}
|
||||
local hf_clearing_cause = ProtoField.uint8("t70.clearing_cause", "Clearing Cause", base.HEX, clearing_cause_names)
|
||||
|
||||
local hf_tsdu_end_mark = ProtoField.bool("t70.tsdu_end_mark", "TSDU end mark", base.HEX, nil, 0x80)
|
||||
|
||||
t70_protocol.fields = {
|
||||
hf_net_block_hdr_len, hf_net_block_hdr, hf_net_block_hdr_m, hf_net_block_hdr_q, hf_tsdu_end_mark,
|
||||
hf_src_ref, hf_dst_ref, hf_rej_cause, hf_block_len, hf_block_type, hf_data, hf_clearing_cause,
|
||||
}
|
||||
|
||||
function dissect_block(buffer, pinfo, tree, maintree)
|
||||
local blen = buffer(0, 1):uint()
|
||||
local btype = buffer(1, 1):uint()
|
||||
|
||||
pinfo.cols.info = block_types[btype]
|
||||
tree:append_text(" " .. block_types[btype] .. " (" .. block_types_long[btype] .. ")")
|
||||
|
||||
tree:add(hf_block_len, buffer(0, 1))
|
||||
tree:add(hf_block_type, buffer(1, 1))
|
||||
|
||||
if (btype == 0xe0) then -- TCR (Section 5.5.4)
|
||||
tree:add(hf_src_ref, buffer(4, 2))
|
||||
-- TODO: parameters (calling, called, block size)
|
||||
elseif (btype == 0xd0) then -- TCA (Section 5.5.5)
|
||||
tree:add(hf_dst_ref, buffer(2, 2))
|
||||
tree:add(hf_src_ref, buffer(4, 2))
|
||||
-- TODO: parameters (calling, called, block size)
|
||||
elseif (btype == 0x80) then -- TCC (Section 5.5.6)
|
||||
tree:add(hf_dst_ref, buffer(2, 2))
|
||||
tree:add(hf_src_ref, buffer(4, 2))
|
||||
tree:add(hf_clearing_cause, buffer(6, 1))
|
||||
-- TODO: parameters (addl clearing info)
|
||||
elseif (btype == 0x70) then -- TBR (Section 5.5.7)
|
||||
tree:add(hf_dst_ref, buffer(2, 2))
|
||||
tree:add(hf_rej_cause, buffer(4, 1))
|
||||
-- TODO: parameters (rejected block [mandatory])
|
||||
elseif (btype == 0xf0) then -- TDT (Section 5.5.8)
|
||||
-- TSDU end mark
|
||||
tree:add(hf_tsdu_end_mark, buffer(2, 1))
|
||||
-- data
|
||||
if (not t70_subdissectors:try(0, buffer(3):tvb(), pinfo, maintree)) then
|
||||
tree:add(hf_data, buffer(3))
|
||||
end
|
||||
else
|
||||
-- unknown
|
||||
end
|
||||
end
|
||||
|
||||
function t70_protocol.dissector(buffer, pinfo, tree)
|
||||
pinfo.cols.protocol = t70_protocol.name
|
||||
|
||||
local subtree = tree:add(t70_protocol, buffer(), "T.70")
|
||||
local net_bhl = buffer(0, 1):uint()
|
||||
|
||||
-- 2-byte network block header, see Figure 4/T.70
|
||||
subtree:add(hf_net_block_hdr_len, buffer(0, 1))
|
||||
subtree:add(hf_net_block_hdr, buffer(1, net_bhl))
|
||||
subtree:add(hf_net_block_hdr_m, buffer(1, 1))
|
||||
subtree:add(hf_net_block_hdr_q, buffer(1, 1))
|
||||
|
||||
-- actual block
|
||||
dissect_block(buffer(1+net_bhl), pinfo, subtree, tree)
|
||||
end
|
||||
|
||||
function t70_protocol.init()
|
||||
local x75_dissectors = DissectorTable.get("x75.subdissector")
|
||||
x75_dissectors:add_for_decode_as(t70_protocol)
|
||||
end
|
Loading…
Reference in New Issue