2 * Reliable Multicast Transport (RMT)
3 * LCT Building Block dissector
4 * Copyright 2005, Stefano Pettini <spettini@users.sourceforge.net>
5 * Copyright 2023, Sergey V. Lobanov <sergey@lobanov.in>
7 * Layered Coding Transport (LCT):
8 * -------------------------------
10 * Provides transport level support for reliable content delivery
11 * and stream delivery protocols. LCT is specifically designed to
12 * support protocols using IP multicast, but also provides support
13 * to protocols that use unicast. LCT is compatible with congestion
14 * control that provides multiple rate delivery to receivers and
15 * is also compatible with coding techniques that provide
16 * reliable delivery of content.
19 * RFC 3451, Layered Coding Transport (LCT) Building Block
20 * RFC 5651, Layered Coding Transport (LCT) Building Block
21 * RFC 5775, Asynchronous Layered Coding (ALC) Protocol Instantiation
23 * ATSC3 Signaling, Delivery, Synchronization, and Error Protection (A/331)
24 * https://www.atsc.org/atsc-documents/3312017-signaling-delivery-synchronization-error-protection/
26 * IANA Layered Coding Transport (LCT) Header Extension Types
27 * https://www.iana.org/assignments/lct-header-extensions/lct-header-extensions.txt
29 * Wireshark - Network traffic analyzer
30 * By Gerald Combs <gerald@wireshark.org>
31 * Copyright 1998 Gerald Combs
33 * SPDX-License-Identifier: GPL-2.0-or-later
40 #include <epan/packet.h>
42 #include <wsutil/array.h>
43 #include "packet-rmt-common.h"
45 #define LCT_SCT_FLAG 0x0008
46 #define LCT_ERT_FLAG 0x0004
47 #define LCT_CLOSE_SESSION_FLAG 0x0002
48 #define LCT_CLOSE_OBJECT_FLAG 0x0001
49 #define LCT_PSI 0x0300
50 #define LCT_PSI_MSB 0x0200
52 void proto_register_rmt_lct(void);
54 static int proto_rmt_lct
;
56 static int hf_version
;
59 static int hf_fsize_header
;
60 static int hf_fsize_cci
;
61 static int hf_fsize_tsi
;
62 static int hf_fsize_toi
;
63 static int hf_flags_header
;
64 static int hf_flags_sct_present
;
65 static int hf_flags_ert_present
;
66 static int hf_flags_close_session
;
67 static int hf_flags_close_object
;
69 static int hf_codepoint
;
70 static int hf_codepoint_atsc3
;
79 static int hf_toi_extended
;
83 static int hf_hec_type
;
84 static int hf_hec_len
;
85 static int hf_hec_data
;
86 static int hf_send_rate
;
88 static int hf_flute_version
;
89 static int hf_fdt_instance_id
;
90 static int hf_ext_tol_48_transfer_len
;
91 static int hf_ext_tol_24_transfer_len
;
92 /* Generated from convert_proto_tree_add_text.pl */
93 static int hf_cc_rate
;
95 static int hf_cc_flags
;
96 static int hf_cc_loss
;
97 static int hf_cc_sequence
;
100 static int ett_fsize
;
101 static int ett_flags
;
103 static int ett_ext_ext
;
106 /* Enumerated data types for LCT preferences */
107 const enum_val_t enum_lct_ext_192
[] =
109 { "none", "Don't decode", LCT_PREFS_EXT_192_NONE
},
110 { "flute", "Decode as FLUTE extension (EXT_FDT)", LCT_PREFS_EXT_192_FLUTE
},
114 const enum_val_t enum_lct_ext_193
[] =
116 { "none", "Don't decode", LCT_PREFS_EXT_193_NONE
},
117 { "flute", "Decode as FLUTE extension (EXT_CENC)", LCT_PREFS_EXT_193_FLUTE
},
121 const enum_val_t enum_lct_atsc3_mode
[] =
123 { "disabled", "Do not decode as ATSC3 data", LCT_ATSC3_MODE_DISABLED
},
124 { "auto", "Auto Detect (if encap is ALP)", LCT_ATSC3_MODE_AUTO
},
125 { "force", "Force to decode as ATSC3 data", LCT_ATSC3_MODE_FORCE
},
129 static const value_string hec_type_vals
[] = {
130 { 0, "EXT_NOP, No-Operation" },
131 { 1, "EXT_AUTH, Packet authentication" },
133 { 64, "EXT_FTI, FEC Object Transmission Information" },
134 { 65, "DVB-IPTV CDS Completion Poll Request LCT" },
135 { 66, "EXT_ROUTE_PRESENTATION_TIME" },
136 { 67, "EXT_TOL, Transport Object Length (48-bit version)" },
137 { 128, "EXT_RATE, Send Rate" },
138 { 192, "EXT_FDT, FDT Instance Header" },
139 { 193, "EXT_CENC, FDT Instance Content Encoding" },
140 { 194, "EXT_TOL, Transport Object Length (24-bit version)" },
145 static const value_string cp_type_vals
[] = {
146 { 1, "NRT, File Mode" },
147 { 2, "NRT, Entity Mode" },
148 { 3, "NRT, Unsigned Package Mode" },
149 { 4, "NRT, Signed Package Mode" },
150 { 5, "New IS, timeline changed" },
151 { 6, "New IS, timeline continued" },
152 { 7, "Redundant IS" },
153 { 8, "Media Segment, File Mode" },
154 { 9, "Media Segment, Entity Mode" },
159 /* LCT helper functions */
160 /* ==================== */
162 static void lct_timestamp_parse(uint32_t t
, nstime_t
* s
)
165 s
->nsecs
= (t
% 1000) * 1000000;
168 double rmt_decode_send_rate(uint16_t send_rate
)
172 value
= (send_rate
>> 4) * 10.0 / 4096.0 * pow(10.0, (send_rate
& 0xf));
177 int lct_ext_decode(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, unsigned offset
, unsigned offset_max
, lct_data_exchange_t
*data_exchange
,
178 int hfext
, int ettext
)
181 unsigned i
, count
= 0;
184 start_offset
= offset
;
186 proto_tree
*hec_tree
, *ext_tree
;
189 /* Figure out the extension count */
190 while (tmp_offset
< offset_max
)
192 het
= tvb_get_uint8(tvb
, tmp_offset
);
195 length
= tvb_get_uint8(tvb
, tmp_offset
+1)*4;
202 /* Prevents infinite loops */
206 tmp_offset
+= length
;
213 ti
= proto_tree_add_uint(tree
, hfext
, tvb
, offset
, tmp_offset
- offset
, count
);
214 hec_tree
= proto_item_add_subtree(ti
, ettext
);
216 for (i
= 0; i
< count
; i
++)
218 het
= tvb_get_uint8(tvb
, offset
);
221 length
= tvb_get_uint8(tvb
, offset
+1)*4;
228 ti
= proto_tree_add_item(hec_tree
, hf_hec_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
229 ext_tree
= proto_item_add_subtree(ti
, ett_ext_ext
);
230 proto_item_set_len(ti
, length
);
234 proto_tree_add_item(ext_tree
, hf_hec_len
, tvb
, offset
+1, 1, ENC_BIG_ENDIAN
);
239 case 0: /* EXT_NOP */
240 case 1: /* EXT_AUTH */
242 proto_tree_add_item(ext_tree
, hf_hec_data
, tvb
, offset
+2, length
-2, ENC_NA
);
245 case 3: /* EXT_CC RATE */
246 proto_tree_add_item(ext_tree
, hf_cc_sequence
, tvb
, offset
+2, 2, ENC_BIG_ENDIAN
);
247 proto_tree_add_item(ext_tree
, hf_cc_flags
, tvb
, offset
+4, 1, ENC_BIG_ENDIAN
);
248 proto_tree_add_item(ext_tree
, hf_cc_rtt
, tvb
, offset
+5, 1, ENC_BIG_ENDIAN
);
249 cc_loss
= tvb_get_ntohs(tvb
, offset
+6)/65535.0;
250 proto_tree_add_double(ext_tree
, hf_cc_loss
, tvb
, offset
+6, 2, cc_loss
);
251 proto_tree_add_item(ext_tree
, hf_cc_rate
, tvb
, offset
+8, 2, ENC_BIG_ENDIAN
);
254 case 64: /* EXT_FTI */
255 fec_decode_ext_fti(tvb
, pinfo
, ext_tree
, offset
,
256 (data_exchange
== NULL
) ? 0 :
257 data_exchange
->is_sp
? 0 :data_exchange
->codepoint
);
260 case 67: /* EXT_TOL_48 */
261 proto_tree_add_item(ext_tree
, hf_ext_tol_48_transfer_len
, tvb
, offset
+1, 6, ENC_BIG_ENDIAN
);
264 case 128: /* EXT_RATE */
265 proto_tree_add_double(ext_tree
, hf_send_rate
, tvb
, offset
+2, 2,
266 rmt_decode_send_rate(tvb_get_ntohs(tvb
, offset
+2)));
269 case 192: /* EXT_FDT */
270 if ((data_exchange
!= NULL
) && (data_exchange
->ext_192
== LCT_PREFS_EXT_192_FLUTE
))
272 proto_tree_add_item(ext_tree
, hf_flute_version
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
273 proto_tree_add_item(ext_tree
, hf_fdt_instance_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
274 data_exchange
->is_flute
= true;
278 case 193: /* EXT_CENC */
279 if ((data_exchange
!= NULL
) && (data_exchange
->ext_193
== LCT_PREFS_EXT_193_FLUTE
))
281 proto_tree_add_item(ext_tree
, hf_cenc
, tvb
, offset
+3, 1, ENC_BIG_ENDIAN
);
285 case 194: /* EXT_TOL_24 */
286 proto_tree_add_item(ext_tree
, hf_ext_tol_24_transfer_len
, tvb
, offset
+1, 3, ENC_BIG_ENDIAN
);
293 return offset
-start_offset
;
296 /* LCT exported functions */
297 /* ====================== */
302 /* Dissect an LCT header:
303 * l - ptr to the logical LCT packet representation to fill, and related wireshark stuffs
304 * f - ptr to the FEC infos to fill (EXT_FTI), and related wireshark stuffs
306 * pinfo - packet info
307 * tree - tree where to add LCT header subtree
308 * offset - ptr to offset to use and update
313 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
314 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
315 | V | C | r |S| O |H|T|R|A|B| HDR_LEN | Codepoint (CP)|
316 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
317 | Congestion Control Information (CCI, length = 32*(C+1) bits) |
319 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
320 | Transport Session Identifier (TSI, length = 32*S+16*H bits) |
322 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
323 | Transport Object Identifier (TOI, length = 32*O+16*H bits) |
325 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
326 | Sender Current Time (SCT, if T = 1) |
327 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
328 | Expected Residual Time (ERT, if R = 1) |
329 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
330 | Header Extensions (if applicable) |
332 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
334 Figure 1 - Default LCT header format
338 dissect_lct(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
351 /* Set up structures needed to add the protocol subtree and manage it */
353 proto_tree
*lct_tree
= tree
, *lct_fsize_tree
, *lct_flags_tree
;
355 lct_data_exchange_t
*data_exchange
= (lct_data_exchange_t
*)data
;
357 /* LCT fixed-size fields dissection */
358 /* -------------------------------- */
359 buffer16
= tvb_get_ntohs(tvb
, offset
);
361 cci_size
= ((buffer16
& 0x0C00) >> 10) * 4 + 4;
362 tsi_size
= ((buffer16
& 0x0080) >> 7) * 4 + ((buffer16
& 0x0010) >> 4) * 2;
363 toi_size
= ((buffer16
& 0x0060) >> 5) * 4 + ((buffer16
& 0x0010) >> 4) * 2;
365 hlen
= tvb_get_uint8(tvb
, offset
+2) * 4;
367 if (data_exchange
!= NULL
)
369 data_exchange
->codepoint
= tvb_get_uint8(tvb
, offset
+3);
370 data_exchange
->is_flute
= false;
375 /* Create the LCT subtree */
376 ti
= proto_tree_add_item(tree
, proto_rmt_lct
, tvb
, offset
, hlen
, ENC_NA
);
377 lct_tree
= proto_item_add_subtree(ti
, ett_main
);
379 /* Fill the LCT subtree */
381 /* LCT version number (4 bits) */
382 proto_tree_add_item(lct_tree
, hf_version
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
383 ti
= proto_tree_add_item(lct_tree
, hf_psi
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
385 if ((data_exchange
!= NULL
) && data_exchange
->is_atsc3
) {
386 uint16_t psi_msb
= tvb_get_uint16(tvb
, offset
, ENC_BIG_ENDIAN
) & LCT_PSI_MSB
;
387 data_exchange
->is_sp
= !!psi_msb
;
388 proto_tree
*lct_psi_tree
= proto_item_add_subtree(ti
, ett_psi
);
389 proto_tree_add_item(lct_psi_tree
, hf_spi
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
392 ti
= proto_tree_add_item(lct_tree
, hf_fsize_header
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
393 lct_fsize_tree
= proto_item_add_subtree(ti
, ett_fsize
);
395 /* Fill the LCT fsize subtree */
396 PROTO_ITEM_SET_GENERATED(
397 proto_tree_add_uint(lct_fsize_tree
, hf_fsize_cci
, tvb
, offset
, 1, cci_size
)
399 PROTO_ITEM_SET_GENERATED(
400 proto_tree_add_uint(lct_fsize_tree
, hf_fsize_tsi
, tvb
, offset
, 2, tsi_size
)
402 PROTO_ITEM_SET_GENERATED(
403 proto_tree_add_uint(lct_fsize_tree
, hf_fsize_toi
, tvb
, offset
, 2, toi_size
)
406 ti
= proto_tree_add_item(lct_tree
, hf_flags_header
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
407 lct_flags_tree
= proto_item_add_subtree(ti
, ett_flags
);
409 /* Fill the LCT flags subtree */
410 proto_tree_add_item(lct_flags_tree
, hf_flags_sct_present
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
411 proto_tree_add_item(lct_flags_tree
, hf_flags_ert_present
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
412 proto_tree_add_item(lct_flags_tree
, hf_flags_close_session
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
413 proto_tree_add_item(lct_flags_tree
, hf_flags_close_object
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
415 proto_tree_add_uint(lct_tree
, hf_hlen
, tvb
, offset
+2, 1, hlen
);
416 if ((data_exchange
!= NULL
) && data_exchange
->is_atsc3
) {
417 if(data_exchange
->codepoint
< 128) {
418 proto_tree_add_item(lct_tree
, hf_codepoint_atsc3
, tvb
, offset
+3, 1, ENC_BIG_ENDIAN
);
420 proto_tree_add_uint_format_value(lct_tree
, hf_codepoint_atsc3
, tvb
, offset
+3, 1,
421 data_exchange
->codepoint
, "Defined by SLS (%u)", data_exchange
->codepoint
);
424 proto_tree_add_item(lct_tree
, hf_codepoint
, tvb
, offset
+3, 1, ENC_BIG_ENDIAN
);
431 /* LCT variable-size and optional fields dissection */
432 /* ------------------------------------------------ */
434 /* Congestion Control Information (CCI) */
436 proto_tree_add_item(lct_tree
, hf_cci
, tvb
, offset
, cci_size
, ENC_NA
);
440 /* Transmission Session Identifier (TSI) */
446 proto_tree_add_item(lct_tree
, hf_tsi16
, tvb
, offset
, tsi_size
, ENC_BIG_ENDIAN
);
447 tsi
= tvb_get_ntohs(tvb
, offset
);
451 proto_tree_add_item(lct_tree
, hf_tsi32
, tvb
, offset
, tsi_size
, ENC_BIG_ENDIAN
);
452 tsi
= tvb_get_ntohl(tvb
, offset
);
456 proto_tree_add_item(lct_tree
, hf_tsi48
, tvb
, offset
, tsi_size
, ENC_BIG_ENDIAN
);
457 tsi
= tvb_get_ntoh48(tvb
, offset
);
464 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, " ", "TSI: %" PRIu64
, tsi
);
468 /* Transmission Object Identifier (TOI) */
474 proto_tree_add_item(lct_tree
, hf_toi16
, tvb
, offset
, toi_size
, ENC_BIG_ENDIAN
);
475 toi
= tvb_get_ntohs(tvb
, offset
);
479 proto_tree_add_item(lct_tree
, hf_toi32
, tvb
, offset
, toi_size
, ENC_BIG_ENDIAN
);
480 toi
= tvb_get_ntohl(tvb
, offset
);
484 proto_tree_add_item(lct_tree
, hf_toi48
, tvb
, offset
, toi_size
, ENC_BIG_ENDIAN
);
485 toi
= tvb_get_ntoh48(tvb
, offset
);
489 proto_tree_add_item(lct_tree
, hf_toi64
, tvb
, offset
, toi_size
, ENC_BIG_ENDIAN
);
490 toi
= tvb_get_ntoh64(tvb
, offset
);
494 proto_tree_add_item(lct_tree
, hf_toi64
, tvb
, offset
+2, 8, ENC_BIG_ENDIAN
);
495 proto_tree_add_item(lct_tree
, hf_toi_extended
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
499 proto_tree_add_item(lct_tree
, hf_toi64
, tvb
, offset
+4, 8, ENC_BIG_ENDIAN
);
500 proto_tree_add_item(lct_tree
, hf_toi_extended
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
504 proto_tree_add_item(lct_tree
, hf_toi64
, tvb
, offset
+6, 8, ENC_BIG_ENDIAN
);
505 proto_tree_add_item(lct_tree
, hf_toi_extended
, tvb
, offset
, 6, ENC_BIG_ENDIAN
);
512 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, " ", "TOI: %" PRIu64
, toi
);
514 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, " ", "TOI: 0x%s", tvb_bytes_to_str(pinfo
->pool
, tvb
, offset
, toi_size
));
518 if (buffer16
& LCT_CLOSE_SESSION_FLAG
)
519 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, " ", "Close session");
521 if (buffer16
& LCT_CLOSE_OBJECT_FLAG
)
522 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, " ", "Close object");
524 if ((data_exchange
!= NULL
) && data_exchange
->is_atsc3
) {
525 if (data_exchange
->is_sp
) {
526 /* According to A/331:2022-11 A.3.4 Usage of ALC and LCT */
527 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, " ", "(Source)");
529 /* According to A/331:2022-11 A.4.2.4 Repair Packet Structure */
530 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, " ", " (Repair)");
534 /* Sender Current Time (SCT) */
535 if (buffer16
& LCT_SCT_FLAG
) {
536 lct_timestamp_parse(tvb_get_ntohl(tvb
, offset
), &tmp_time
);
537 proto_tree_add_time(lct_tree
, hf_sct
, tvb
, offset
, 4, &tmp_time
);
541 /* Expected Residual Time (ERT) */
542 if (buffer16
& LCT_ERT_FLAG
) {
543 lct_timestamp_parse(tvb_get_ntohl(tvb
, offset
), &tmp_time
);
544 proto_tree_add_time(lct_tree
, hf_ert
, tvb
, offset
, 4, &tmp_time
);
548 /* LCT header extensions, if applicable */
549 /* ------------------------------------ */
550 lct_ext_decode(lct_tree
, tvb
, pinfo
, offset
, hlen
, data_exchange
, hf_ext
, ett_ext
);
556 proto_register_rmt_lct(void)
558 static hf_register_info hf
[] = {
560 { "Version", "rmt-lct.version",
561 FT_UINT16
, BASE_DEC
, NULL
, 0xF000,
565 { "Protocol-Specific Indication", "rmt-lct.psi",
566 FT_UINT16
, BASE_HEX
, NULL
, LCT_PSI
,
570 { "Source Packet Indicator", "rmt-lct.spi",
571 FT_BOOLEAN
, 16, NULL
, LCT_PSI_MSB
,
575 { "Field size flags", "rmt-lct.fsize",
576 FT_UINT16
, BASE_HEX
, NULL
, 0x0FC0,
580 { "Congestion Control Information field size", "rmt-lct.fsize.cci",
581 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
585 { "Transport Session Identifier field size", "rmt-lct.fsize.tsi",
586 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
590 { "Transport Object Identifier field size", "rmt-lct.fsize.toi",
591 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
595 { "Flags", "rmt-lct.flags",
596 FT_UINT16
, BASE_HEX
, NULL
, 0x001F,
599 { &hf_flags_sct_present
,
600 { "Sender Current Time present flag", "rmt-lct.flags.sct_present",
601 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), LCT_SCT_FLAG
,
604 { &hf_flags_ert_present
,
605 { "Expected Residual Time present flag", "rmt-lct.flags.ert_present",
606 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), LCT_ERT_FLAG
,
609 { &hf_flags_close_session
,
610 { "Close Session flag", "rmt-lct.flags.close_session",
611 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), LCT_CLOSE_SESSION_FLAG
,
614 { &hf_flags_close_object
,
615 { "Close Object flag", "rmt-lct.flags.close_object",
616 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), LCT_CLOSE_OBJECT_FLAG
,
620 { "Header length", "rmt-lct.hlen",
621 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
625 { "Codepoint", "rmt-lct.codepoint",
626 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
629 { &hf_codepoint_atsc3
,
630 { "Codepoint", "rmt-lct.codepoint",
631 FT_UINT8
, BASE_DEC
, VALS(cp_type_vals
), 0x0,
635 { "Congestion Control Information", "rmt-lct.cci",
636 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
640 { "Transport Session Identifier", "rmt-lct.tsi",
641 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
645 { "Transport Session Identifier", "rmt-lct.tsi",
646 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
650 { "Transport Session Identifier", "rmt-lct.tsi64",
651 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
655 { "Transport Object Identifier", "rmt-lct.toi",
656 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
660 { "Transport Object Identifier", "rmt-lct.toi",
661 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
665 { "Transport Object Identifier", "rmt-lct.toi64",
666 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
670 { "Transport Object Identifier (up to 64 bits)", "rmt-lct.toi64",
671 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
675 { "Transport Object Identifier (bits 64-112)", "rmt-lct.toi_extended",
676 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
680 { "Sender Current Time", "rmt-lct.sct",
681 FT_RELATIVE_TIME
, BASE_NONE
, NULL
, 0x0,
685 { "Expected Residual Time", "rmt-lct.ert",
686 FT_RELATIVE_TIME
, BASE_NONE
, NULL
, 0x0,
690 { "Extension count", "rmt-lct.ext",
691 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
695 { "Header Extension Type (HET)", "rmt-lct.hec.type",
696 FT_UINT8
, BASE_DEC
, VALS(hec_type_vals
), 0x0,
700 { "Header Extension Length (HEL)", "rmt-lct.hec.len",
701 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
705 { "Header Extension Data", "rmt-lct.hec.data",
706 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
710 { "Send Rate", "rmt-lct.send_rate",
711 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
715 { "Content Encoding Algorithm (CENC)", "rmt-lct.cenc",
716 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
720 { "FLUTE version (V)", "rmt-lct.flute_version",
721 FT_UINT32
, BASE_DEC
, NULL
, 0x00F00000,
724 { &hf_fdt_instance_id
,
725 { "FDT Instance ID", "rmt-lct.fdt_instance_id",
726 FT_UINT32
, BASE_DEC
, NULL
, 0x000FFFFF,
729 { &hf_ext_tol_48_transfer_len
,
730 { "EXT_TOL_48 Transfer Length", "rmt-lct.ext_tol_transfer_len",
731 FT_UINT48
, BASE_DEC
, NULL
, 0,
734 { &hf_ext_tol_24_transfer_len
,
735 { "EXT_TOL_24 Transfer Length", "rmt-lct.ext_tol_transfer_len",
736 FT_UINT24
, BASE_DEC
, NULL
, 0,
740 { "CC Sequence", "rmt-lct.cc_sequence",
741 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
745 { "CC Flags", "rmt-lct.cc_flags",
746 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
750 { "CC RTT", "rmt-lct.cc_rtt",
751 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
755 { "CC Loss", "rmt-lct.cc_loss",
756 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
760 { "CC Rate", "rmt-lct.cc_rate",
761 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
766 /* Setup protocol subtree array */
767 static int *ett
[] = {
776 /* Register the protocol name and description */
777 proto_rmt_lct
= proto_register_protocol("Layered Coding Transport", "RMT-LCT", "rmt-lct");
778 register_dissector("rmt-lct", dissect_lct
, proto_rmt_lct
);
780 /* Required function calls to register the header fields and subtrees used */
781 proto_register_field_array(proto_rmt_lct
, hf
, array_length(hf
));
782 proto_register_subtree_array(ett
, array_length(ett
));
786 * Editor modelines - https://www.wireshark.org/tools/modelines.html
791 * indent-tabs-mode: nil
794 * ex: set shiftwidth=4 tabstop=8 expandtab:
795 * :indentSize=4:tabSize=8:noTabs=true: