diff options
Diffstat (limited to 'epan/dissectors/packet-rmt-lct.c')
-rw-r--r-- | epan/dissectors/packet-rmt-lct.c | 795 |
1 files changed, 795 insertions, 0 deletions
diff --git a/epan/dissectors/packet-rmt-lct.c b/epan/dissectors/packet-rmt-lct.c new file mode 100644 index 00000000..2b596b0d --- /dev/null +++ b/epan/dissectors/packet-rmt-lct.c @@ -0,0 +1,795 @@ +/* packet-rmt-lct.c + * Reliable Multicast Transport (RMT) + * LCT Building Block dissector + * Copyright 2005, Stefano Pettini <spettini@users.sourceforge.net> + * Copyright 2023, Sergey V. Lobanov <sergey@lobanov.in> + * + * Layered Coding Transport (LCT): + * ------------------------------- + * + * Provides transport level support for reliable content delivery + * and stream delivery protocols. LCT is specifically designed to + * support protocols using IP multicast, but also provides support + * to protocols that use unicast. LCT is compatible with congestion + * control that provides multiple rate delivery to receivers and + * is also compatible with coding techniques that provide + * reliable delivery of content. + * + * References: + * RFC 3451, Layered Coding Transport (LCT) Building Block + * RFC 5651, Layered Coding Transport (LCT) Building Block + * RFC 5775, Asynchronous Layered Coding (ALC) Protocol Instantiation + * + * ATSC3 Signaling, Delivery, Synchronization, and Error Protection (A/331) + * https://www.atsc.org/atsc-documents/3312017-signaling-delivery-synchronization-error-protection/ + * + * IANA Layered Coding Transport (LCT) Header Extension Types + * https://www.iana.org/assignments/lct-header-extensions/lct-header-extensions.txt + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "config.h" + +#include <math.h> + +#include <epan/packet.h> + +#include "packet-rmt-common.h" + +#define LCT_SCT_FLAG 0x0008 +#define LCT_ERT_FLAG 0x0004 +#define LCT_CLOSE_SESSION_FLAG 0x0002 +#define LCT_CLOSE_OBJECT_FLAG 0x0001 +#define LCT_PSI 0x0300 +#define LCT_PSI_MSB 0x0200 + +void proto_register_rmt_lct(void); + +static int proto_rmt_lct = -1; + +static int hf_version = -1; +static int hf_psi = -1; +static int hf_spi = -1; +static int hf_fsize_header = -1; +static int hf_fsize_cci = -1; +static int hf_fsize_tsi = -1; +static int hf_fsize_toi = -1; +static int hf_flags_header = -1; +static int hf_flags_sct_present = -1; +static int hf_flags_ert_present = -1; +static int hf_flags_close_session = -1; +static int hf_flags_close_object = -1; +static int hf_hlen = -1; +static int hf_codepoint = -1; +static int hf_codepoint_atsc3 = -1; +static int hf_cci = -1; +static int hf_tsi16 = -1; +static int hf_tsi32 = -1; +static int hf_tsi48 = -1; +static int hf_toi16 = -1; +static int hf_toi32 = -1; +static int hf_toi48 = -1; +static int hf_toi64 = -1; +static int hf_toi_extended = -1; +static int hf_sct = -1; +static int hf_ert = -1; +static int hf_ext = -1; +static int hf_hec_type = -1; +static int hf_hec_len = -1; +static int hf_hec_data = -1; +static int hf_send_rate = -1; +static int hf_cenc = -1; +static int hf_flute_version = -1; +static int hf_fdt_instance_id = -1; +static int hf_ext_tol_48_transfer_len = -1; +static int hf_ext_tol_24_transfer_len = -1; +/* Generated from convert_proto_tree_add_text.pl */ +static int hf_cc_rate = -1; +static int hf_cc_rtt = -1; +static int hf_cc_flags = -1; +static int hf_cc_loss = -1; +static int hf_cc_sequence = -1; + +static int ett_main = -1; +static int ett_fsize = -1; +static int ett_flags = -1; +static int ett_ext = -1; +static int ett_ext_ext = -1; +static int ett_psi = -1; + +/* Enumerated data types for LCT preferences */ +const enum_val_t enum_lct_ext_192[] = +{ + { "none", "Don't decode", LCT_PREFS_EXT_192_NONE }, + { "flute", "Decode as FLUTE extension (EXT_FDT)", LCT_PREFS_EXT_192_FLUTE }, + { NULL, NULL, 0 } +}; + +const enum_val_t enum_lct_ext_193[] = +{ + { "none", "Don't decode", LCT_PREFS_EXT_193_NONE }, + { "flute", "Decode as FLUTE extension (EXT_CENC)", LCT_PREFS_EXT_193_FLUTE }, + { NULL, NULL, 0 } +}; + +const enum_val_t enum_lct_atsc3_mode[] = +{ + { "disabled", "Do not decode as ATSC3 data", LCT_ATSC3_MODE_DISABLED }, + { "auto", "Auto Detect (if encap is ALP)", LCT_ATSC3_MODE_AUTO }, + { "force", "Force to decode as ATSC3 data", LCT_ATSC3_MODE_FORCE }, + { NULL, NULL, 0 } +}; + +static const value_string hec_type_vals[] = { + { 0, "EXT_NOP, No-Operation" }, + { 1, "EXT_AUTH, Packet authentication" }, + { 2, "EXT_TIME" }, + { 64, "EXT_FTI, FEC Object Transmission Information" }, + { 65, "DVB-IPTV CDS Completion Poll Request LCT" }, + { 66, "EXT_ROUTE_PRESENTATION_TIME" }, + { 67, "EXT_TOL, Transport Object Length (48-bit version)" }, + { 128, "EXT_RATE, Send Rate" }, + { 192, "EXT_FDT, FDT Instance Header" }, + { 193, "EXT_CENC, FDT Instance Content Encoding" }, + { 194, "EXT_TOL, Transport Object Length (24-bit version)" }, + + { 0, NULL } +}; + +static const value_string cp_type_vals[] = { + { 1, "NRT, File Mode" }, + { 2, "NRT, Entity Mode" }, + { 3, "NRT, Unsigned Package Mode" }, + { 4, "NRT, Signed Package Mode" }, + { 5, "New IS, timeline changed" }, + { 6, "New IS, timeline continued" }, + { 7, "Redundant IS" }, + { 8, "Media Segment, File Mode" }, + { 9, "Media Segment, Entity Mode" }, + + { 0, NULL } +}; + +/* LCT helper functions */ +/* ==================== */ + +static void lct_timestamp_parse(guint32 t, nstime_t* s) +{ + s->secs = t / 1000; + s->nsecs = (t % 1000) * 1000000; +} + +double rmt_decode_send_rate(guint16 send_rate ) +{ + double value; + + value = (send_rate >> 4) * 10.0 / 4096.0 * pow(10.0, (send_rate & 0xf)); + return value; +} + + +int lct_ext_decode(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, guint offset, guint offset_max, lct_data_exchange_t *data_exchange, + int hfext, int ettext) +{ + guint8 het; + guint i, count = 0; + guint length, + tmp_offset = offset, + start_offset = offset; + proto_item *ti; + proto_tree *hec_tree, *ext_tree; + double cc_loss; + + /* Figure out the extention count */ + while (tmp_offset < offset_max) + { + het = tvb_get_guint8(tvb, tmp_offset); + if (het <= 127) + { + length = tvb_get_guint8(tvb, tmp_offset+1)*4; + } + else + { + length = 4; + } + + /* Prevents infinite loops */ + if (length == 0) + break; + + tmp_offset += length; + count++; + } + + if (count == 0) + return 0; + + ti = proto_tree_add_uint(tree, hfext, tvb, offset, tmp_offset - offset, count); + hec_tree = proto_item_add_subtree(ti, ettext); + + for (i = 0; i < count; i++) + { + het = tvb_get_guint8(tvb, offset); + if (het <= 127) + { + length = tvb_get_guint8(tvb, offset+1)*4; + } + else + { + length = 4; + } + + ti = proto_tree_add_item(hec_tree, hf_hec_type, tvb, offset, 1, ENC_BIG_ENDIAN); + ext_tree = proto_item_add_subtree(ti, ett_ext_ext); + proto_item_set_len(ti, length); + + if (het <= 127) + { + proto_tree_add_item(ext_tree, hf_hec_len, tvb, offset+1, 1, ENC_BIG_ENDIAN); + } + + switch (het) + { + case 0: /* EXT_NOP */ + case 1: /* EXT_AUTH */ + default: + proto_tree_add_item(ext_tree, hf_hec_data, tvb, offset+2, length-2, ENC_NA); + break; + + case 3: /* EXT_CC RATE */ + proto_tree_add_item(ext_tree, hf_cc_sequence, tvb, offset+2, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(ext_tree, hf_cc_flags, tvb, offset+4, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(ext_tree, hf_cc_rtt, tvb, offset+5, 1, ENC_BIG_ENDIAN); + cc_loss = tvb_get_ntohs(tvb, offset+6)/65535.0; + proto_tree_add_double(ext_tree, hf_cc_loss, tvb, offset+6, 2, cc_loss); + proto_tree_add_item(ext_tree, hf_cc_rate, tvb, offset+8, 2, ENC_BIG_ENDIAN); + break; + + case 64: /* EXT_FTI */ + fec_decode_ext_fti(tvb, pinfo, ext_tree, offset, + (data_exchange == NULL) ? 0 : + data_exchange->is_sp ? 0 :data_exchange->codepoint); + break; + + case 67: /* EXT_TOL_48 */ + proto_tree_add_item(ext_tree, hf_ext_tol_48_transfer_len, tvb, offset+1, 6, ENC_BIG_ENDIAN); + break; + + case 128: /* EXT_RATE */ + proto_tree_add_double(ext_tree, hf_send_rate, tvb, offset+2, 2, + rmt_decode_send_rate(tvb_get_ntohs(tvb, offset+2))); + break; + + case 192: /* EXT_FDT */ + if ((data_exchange != NULL) && (data_exchange->ext_192 == LCT_PREFS_EXT_192_FLUTE)) + { + proto_tree_add_item(ext_tree, hf_flute_version, tvb, offset, 4, ENC_BIG_ENDIAN); + proto_tree_add_item(ext_tree, hf_fdt_instance_id, tvb, offset, 4, ENC_BIG_ENDIAN); + data_exchange->is_flute = TRUE; + } + break; + + case 193: /* EXT_CENC */ + if ((data_exchange != NULL) && (data_exchange->ext_193 == LCT_PREFS_EXT_193_FLUTE)) + { + proto_tree_add_item(ext_tree, hf_cenc, tvb, offset+3, 1, ENC_BIG_ENDIAN); + } + break; + + case 194: /* EXT_TOL_24 */ + proto_tree_add_item(ext_tree, hf_ext_tol_24_transfer_len, tvb, offset+1, 3, ENC_BIG_ENDIAN); + break; + } + + offset += length; + } + + return offset-start_offset; +} + +/* LCT exported functions */ +/* ====================== */ + +/* Dissection */ +/* ---------- */ + +/* Dissect an LCT header: + * l - ptr to the logical LCT packet representation to fill, and related wireshark stuffs + * f - ptr to the FEC infos to fill (EXT_FTI), and related wireshark stuffs + * tvb - buffer + * pinfo - packet info + * tree - tree where to add LCT header subtree + * offset - ptr to offset to use and update + */ + +/* + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | V | C | r |S| O |H|T|R|A|B| HDR_LEN | Codepoint (CP)| + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Congestion Control Information (CCI, length = 32*(C+1) bits) | + | ... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Transport Session Identifier (TSI, length = 32*S+16*H bits) | + | ... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Transport Object Identifier (TOI, length = 32*O+16*H bits) | + | ... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Sender Current Time (SCT, if T = 1) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Expected Residual Time (ERT, if R = 1) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Header Extensions (if applicable) | + | ... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Figure 1 - Default LCT header format + +*/ +static int +dissect_lct(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) +{ + int offset = 0; + guint16 buffer16; + + guint8 cci_size; + guint8 tsi_size; + guint8 toi_size; + guint64 tsi; + guint64 toi = 0; + guint16 hlen; + nstime_t tmp_time; + + /* Set up structures needed to add the protocol subtree and manage it */ + proto_item *ti; + proto_tree *lct_tree = tree, *lct_fsize_tree, *lct_flags_tree; + + lct_data_exchange_t *data_exchange = (lct_data_exchange_t *)data; + + /* LCT fixed-size fields dissection */ + /* -------------------------------- */ + buffer16 = tvb_get_ntohs(tvb, offset); + + cci_size = ((buffer16 & 0x0C00) >> 10) * 4 + 4; + tsi_size = ((buffer16 & 0x0080) >> 7) * 4 + ((buffer16 & 0x0010) >> 4) * 2; + toi_size = ((buffer16 & 0x0060) >> 5) * 4 + ((buffer16 & 0x0010) >> 4) * 2; + + hlen = tvb_get_guint8(tvb, offset+2) * 4; + + if (data_exchange != NULL) + { + data_exchange->codepoint = tvb_get_guint8(tvb, offset+3); + data_exchange->is_flute = FALSE; + } + + if (tree) + { + /* Create the LCT subtree */ + ti = proto_tree_add_item(tree, proto_rmt_lct, tvb, offset, hlen, ENC_NA); + lct_tree = proto_item_add_subtree(ti, ett_main); + + /* Fill the LCT subtree */ + + /* LCT version number (4 bits) */ + proto_tree_add_item(lct_tree, hf_version, tvb, offset, 2, ENC_BIG_ENDIAN); + ti = proto_tree_add_item(lct_tree, hf_psi, tvb, offset, 2, ENC_BIG_ENDIAN); + + if ((data_exchange != NULL) && data_exchange->is_atsc3) { + guint16 psi_msb = tvb_get_guint16(tvb, offset, ENC_BIG_ENDIAN) & LCT_PSI_MSB; + data_exchange->is_sp = !!psi_msb; + proto_tree *lct_psi_tree = proto_item_add_subtree(ti, ett_psi); + proto_tree_add_item(lct_psi_tree, hf_spi, tvb, offset, 2, ENC_BIG_ENDIAN); + } + + ti = proto_tree_add_item(lct_tree, hf_fsize_header, tvb, offset, 2, ENC_BIG_ENDIAN); + lct_fsize_tree = proto_item_add_subtree(ti, ett_fsize); + + /* Fill the LCT fsize subtree */ + PROTO_ITEM_SET_GENERATED( + proto_tree_add_uint(lct_fsize_tree, hf_fsize_cci, tvb, offset, 1, cci_size) + ); + PROTO_ITEM_SET_GENERATED( + proto_tree_add_uint(lct_fsize_tree, hf_fsize_tsi, tvb, offset, 2, tsi_size) + ); + PROTO_ITEM_SET_GENERATED( + proto_tree_add_uint(lct_fsize_tree, hf_fsize_toi, tvb, offset, 2, toi_size) + ); + + ti = proto_tree_add_item(lct_tree, hf_flags_header, tvb, offset, 2, ENC_BIG_ENDIAN); + lct_flags_tree = proto_item_add_subtree(ti, ett_flags); + + /* Fill the LCT flags subtree */ + proto_tree_add_item(lct_flags_tree, hf_flags_sct_present, tvb, offset, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(lct_flags_tree, hf_flags_ert_present, tvb, offset, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(lct_flags_tree, hf_flags_close_session, tvb, offset, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(lct_flags_tree, hf_flags_close_object, tvb, offset, 2, ENC_BIG_ENDIAN); + + proto_tree_add_uint(lct_tree, hf_hlen, tvb, offset+2, 1, hlen); + if ((data_exchange != NULL) && data_exchange->is_atsc3) { + if(data_exchange->codepoint < 128) { + proto_tree_add_item(lct_tree, hf_codepoint_atsc3, tvb, offset+3, 1, ENC_BIG_ENDIAN); + } else { + proto_tree_add_uint_format_value(lct_tree, hf_codepoint_atsc3, tvb, offset+3, 1, + data_exchange->codepoint, "Defined by SLS (%u)", data_exchange->codepoint); + } + } else { + proto_tree_add_item(lct_tree, hf_codepoint, tvb, offset+3, 1, ENC_BIG_ENDIAN); + } + + } + + offset += 4; + + /* LCT variable-size and optional fields dissection */ + /* ------------------------------------------------ */ + + /* Congestion Control Information (CCI) */ + if (cci_size > 0) { + proto_tree_add_item(lct_tree, hf_cci, tvb, offset, cci_size, ENC_NA); + offset += cci_size; + } + + /* Transmission Session Identifier (TSI) */ + if (tsi_size > 0) { + + switch (tsi_size) + { + case 2: + proto_tree_add_item(lct_tree, hf_tsi16, tvb, offset, tsi_size, ENC_BIG_ENDIAN); + tsi = tvb_get_ntohs(tvb, offset); + break; + + case 4: + proto_tree_add_item(lct_tree, hf_tsi32, tvb, offset, tsi_size, ENC_BIG_ENDIAN); + tsi = tvb_get_ntohl(tvb, offset); + break; + + case 6: + proto_tree_add_item(lct_tree, hf_tsi48, tvb, offset, tsi_size, ENC_BIG_ENDIAN); + tsi = tvb_get_ntoh48(tvb, offset); + break; + default: + tsi = 0; + break; + } + + col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "TSI: %" PRIu64, tsi); + offset += tsi_size; + } + + /* Transmission Object Identifier (TOI) */ + if (toi_size > 0) { + + switch (toi_size) + { + case 2: + proto_tree_add_item(lct_tree, hf_toi16, tvb, offset, toi_size, ENC_BIG_ENDIAN); + toi = tvb_get_ntohs(tvb, offset); + break; + + case 4: + proto_tree_add_item(lct_tree, hf_toi32, tvb, offset, toi_size, ENC_BIG_ENDIAN); + toi = tvb_get_ntohl(tvb, offset); + break; + + case 6: + proto_tree_add_item(lct_tree, hf_toi48, tvb, offset, toi_size, ENC_BIG_ENDIAN); + toi = tvb_get_ntoh48(tvb, offset); + break; + + case 8: + proto_tree_add_item(lct_tree, hf_toi64, tvb, offset, toi_size, ENC_BIG_ENDIAN); + toi = tvb_get_ntoh64(tvb, offset); + break; + + case 10: + proto_tree_add_item(lct_tree, hf_toi64, tvb, offset+2, 8, ENC_BIG_ENDIAN); + proto_tree_add_item(lct_tree, hf_toi_extended, tvb, offset, 2, ENC_BIG_ENDIAN); + break; + + case 12: + proto_tree_add_item(lct_tree, hf_toi64, tvb, offset+4, 8, ENC_BIG_ENDIAN); + proto_tree_add_item(lct_tree, hf_toi_extended, tvb, offset, 4, ENC_BIG_ENDIAN); + break; + + case 14: + proto_tree_add_item(lct_tree, hf_toi64, tvb, offset+6, 8, ENC_BIG_ENDIAN); + proto_tree_add_item(lct_tree, hf_toi_extended, tvb, offset, 6, ENC_BIG_ENDIAN); + break; + default: + break; + } + + if (toi_size <= 8) + col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "TOI: %" PRIu64, toi); + else + col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "TOI: 0x%s", tvb_bytes_to_str(pinfo->pool, tvb, offset, toi_size)); + offset += toi_size; + } + + if (buffer16 & LCT_CLOSE_SESSION_FLAG) + col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "Close session"); + + if (buffer16 & LCT_CLOSE_OBJECT_FLAG) + col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "Close object"); + + if ((data_exchange != NULL) && data_exchange->is_atsc3) { + if (data_exchange->is_sp) { + /* According to A/331:2022-11 A.3.4 Usage of ALC and LCT */ + col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "(Source)"); + } else { + /* According to A/331:2022-11 A.4.2.4 Repair Packet Structure */ + col_append_sep_str(pinfo->cinfo, COL_INFO, " ", " (Repair)"); + } + } + + /* Sender Current Time (SCT) */ + if (buffer16 & LCT_SCT_FLAG) { + lct_timestamp_parse(tvb_get_ntohl(tvb, offset), &tmp_time); + proto_tree_add_time(lct_tree, hf_sct, tvb, offset, 4, &tmp_time); + offset += 4; + } + + /* Expected Residual Time (ERT) */ + if (buffer16 & LCT_ERT_FLAG) { + lct_timestamp_parse(tvb_get_ntohl(tvb, offset), &tmp_time); + proto_tree_add_time(lct_tree, hf_ert, tvb, offset, 4, &tmp_time); + offset += 4; + } + + /* LCT header extensions, if applicable */ + /* ------------------------------------ */ + lct_ext_decode(lct_tree, tvb, pinfo, offset, hlen, data_exchange, hf_ext, ett_ext); + + return hlen; +} + +void +proto_register_rmt_lct(void) +{ + static hf_register_info hf[] = { + { &hf_version, + { "Version", "rmt-lct.version", + FT_UINT16, BASE_DEC, NULL, 0xF000, + NULL, HFILL } + }, + { &hf_psi, + { "Protocol-Specific Indication", "rmt-lct.psi", + FT_UINT16, BASE_HEX, NULL, LCT_PSI, + NULL, HFILL } + }, + { &hf_spi, + { "Source Packet Indicator", "rmt-lct.spi", + FT_BOOLEAN, 16, NULL, LCT_PSI_MSB, + NULL, HFILL } + }, + { &hf_fsize_header, + { "Field size flags", "rmt-lct.fsize", + FT_UINT16, BASE_HEX, NULL, 0x0FC0, + NULL, HFILL } + }, + { &hf_fsize_cci, + { "Congestion Control Information field size", "rmt-lct.fsize.cci", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_fsize_tsi, + { "Transport Session Identifier field size", "rmt-lct.fsize.tsi", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_fsize_toi, + { "Transport Object Identifier field size", "rmt-lct.fsize.toi", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_flags_header, + { "Flags", "rmt-lct.flags", + FT_UINT16, BASE_HEX, NULL, 0x001F, + NULL, HFILL } + }, + { &hf_flags_sct_present, + { "Sender Current Time present flag", "rmt-lct.flags.sct_present", + FT_BOOLEAN, 16, TFS(&tfs_set_notset), LCT_SCT_FLAG, + NULL, HFILL } + }, + { &hf_flags_ert_present, + { "Expected Residual Time present flag", "rmt-lct.flags.ert_present", + FT_BOOLEAN, 16, TFS(&tfs_set_notset), LCT_ERT_FLAG, + NULL, HFILL } + }, + { &hf_flags_close_session, + { "Close Session flag", "rmt-lct.flags.close_session", + FT_BOOLEAN, 16, TFS(&tfs_set_notset), LCT_CLOSE_SESSION_FLAG, + NULL, HFILL } + }, + { &hf_flags_close_object, + { "Close Object flag", "rmt-lct.flags.close_object", + FT_BOOLEAN, 16, TFS(&tfs_set_notset), LCT_CLOSE_OBJECT_FLAG, + NULL, HFILL } + }, + { &hf_hlen, + { "Header length", "rmt-lct.hlen", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_codepoint, + { "Codepoint", "rmt-lct.codepoint", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_codepoint_atsc3, + { "Codepoint", "rmt-lct.codepoint", + FT_UINT8, BASE_DEC, VALS(cp_type_vals), 0x0, + NULL, HFILL } + }, + { &hf_cci, + { "Congestion Control Information", "rmt-lct.cci", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_tsi16, + { "Transport Session Identifier", "rmt-lct.tsi", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_tsi32, + { "Transport Session Identifier", "rmt-lct.tsi", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_tsi48, + { "Transport Session Identifier", "rmt-lct.tsi64", + FT_UINT64, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_toi16, + { "Transport Object Identifier", "rmt-lct.toi", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_toi32, + { "Transport Object Identifier", "rmt-lct.toi", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_toi48, + { "Transport Object Identifier", "rmt-lct.toi64", + FT_UINT64, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_toi64, + { "Transport Object Identifier (up to 64 bits)", "rmt-lct.toi64", + FT_UINT64, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_toi_extended, + { "Transport Object Identifier (bits 64-112)", "rmt-lct.toi_extended", + FT_UINT64, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_sct, + { "Sender Current Time", "rmt-lct.sct", + FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ert, + { "Expected Residual Time", "rmt-lct.ert", + FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_ext, + { "Extension count", "rmt-lct.ext", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_hec_type, + { "Header Extension Type (HET)", "rmt-lct.hec.type", + FT_UINT8, BASE_DEC, VALS(hec_type_vals), 0x0, + NULL, HFILL } + }, + { &hf_hec_len, + { "Header Extension Length (HEL)", "rmt-lct.hec.len", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_hec_data, + { "Header Extension Data", "rmt-lct.hec.data", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_send_rate, + { "Send Rate", "rmt-lct.send_rate", + FT_DOUBLE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_cenc, + { "Content Encoding Algorithm (CENC)", "rmt-lct.cenc", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_flute_version, + { "FLUTE version (V)", "rmt-lct.flute_version", + FT_UINT32, BASE_DEC, NULL, 0x00F00000, + NULL, HFILL } + }, + { &hf_fdt_instance_id, + { "FDT Instance ID", "rmt-lct.fdt_instance_id", + FT_UINT32, BASE_DEC, NULL, 0x000FFFFF, + NULL, HFILL } + }, + { &hf_ext_tol_48_transfer_len, + { "EXT_TOL_48 Tranfer Length", "rmt-lct.ext_tol_tranfer_len", + FT_UINT48, BASE_DEC, NULL, 0, + NULL, HFILL } + }, + { &hf_ext_tol_24_transfer_len, + { "EXT_TOL_24 Tranfer Length", "rmt-lct.ext_tol_tranfer_len", + FT_UINT24, BASE_DEC, NULL, 0, + NULL, HFILL } + }, + { &hf_cc_sequence, + { "CC Sequence", "rmt-lct.cc_sequence", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_cc_flags, + { "CC Flags", "rmt-lct.cc_flags", + FT_UINT8, BASE_HEX, NULL, 0x0, + NULL, HFILL } + }, + { &hf_cc_rtt, + { "CC RTT", "rmt-lct.cc_rtt", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + { &hf_cc_loss, + { "CC Loss", "rmt-lct.cc_loss", + FT_DOUBLE, BASE_NONE, NULL, 0x0, + NULL, HFILL } + }, + { &hf_cc_rate, + { "CC Rate", "rmt-lct.cc_rate", + FT_UINT16, BASE_DEC, NULL, 0x0, + NULL, HFILL } + }, + }; + + /* Setup protocol subtree array */ + static gint *ett[] = { + &ett_main, + &ett_fsize, + &ett_flags, + &ett_ext, + &ett_ext_ext, + &ett_psi, + }; + + /* Register the protocol name and description */ + proto_rmt_lct = proto_register_protocol("Layered Coding Transport", "RMT-LCT", "rmt-lct"); + register_dissector("rmt-lct", dissect_lct, proto_rmt_lct); + + /* Required function calls to register the header fields and subtrees used */ + proto_register_field_array(proto_rmt_lct, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ |