Merge "Apply layouts in Qt Creator. Fix a tooltip."
[metze/wireshark/wip.git] / epan / dissectors / packet-rmt-lct.c
1 /* packet-rmt-lct.c
2  * Reliable Multicast Transport (RMT)
3  * LCT Building Block dissector
4  * Copyright 2005, Stefano Pettini <spettini@users.sourceforge.net>
5  *
6  * Layered Coding Transport (LCT):
7  * -------------------------------
8  *
9  * Provides transport level support for reliable content delivery
10  * and stream delivery protocols. LCT is specifically designed to
11  * support protocols using IP multicast, but also provides support
12  * to protocols that use unicast. LCT is compatible with congestion
13  * control that provides multiple rate delivery to receivers and
14  * is also compatible with coding techniques that provide
15  * reliable delivery of content.
16  *
17  * References:
18  *     RFC 3451, Layered Coding Transport (LCT) Building Block
19  *
20  * $Id$
21  *
22  * Wireshark - Network traffic analyzer
23  * By Gerald Combs <gerald@wireshark.org>
24  * Copyright 1998 Gerald Combs
25  *
26  * This program is free software; you can redistribute it and/or
27  * modify it under the terms of the GNU General Public License
28  * as published by the Free Software Foundation; either version 2
29  * of the License, or (at your option) any later version.
30  *
31  * This program is distributed in the hope that it will be useful,
32  * but WITHOUT ANY WARRANTY; without even the implied warranty of
33  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
34  * GNU General Public License for more details.
35  *
36  * You should have received a copy of the GNU General Public License
37  * along with this program; if not, write to the Free Software
38  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
39  */
40
41 #include "config.h"
42
43 #include <glib.h>
44
45 #include <epan/packet.h>
46 #include <epan/params.h>
47 #include <epan/strutil.h>
48
49 #include <math.h>
50
51 #include "packet-rmt-common.h"
52
53 #define LCT_SCT_FLAG           0x0008
54 #define LCT_ERT_FLAG           0x0004
55 #define LCT_CLOSE_SESSION_FLAG 0x0002
56 #define LCT_CLOSE_OBJECT_FLAG  0x0001
57
58 void proto_register_rmt_lct(void);
59
60 static int proto_rmt_lct = -1;
61
62 static int hf_version = -1;
63 static int hf_fsize_header = -1;
64 static int hf_fsize_cci = -1;
65 static int hf_fsize_tsi = -1;
66 static int hf_fsize_toi = -1;
67 static int hf_flags_header = -1;
68 static int hf_flags_sct_present = -1;
69 static int hf_flags_ert_present = -1;
70 static int hf_flags_close_session = -1;
71 static int hf_flags_close_object = -1;
72 static int hf_hlen = -1;
73 static int hf_codepoint = -1;
74 static int hf_cci = -1;
75 static int hf_tsi = -1;
76 static int hf_tsi16 = -1;
77 static int hf_tsi32 = -1;
78 static int hf_tsi48 = -1;
79 static int hf_toi = -1;
80 static int hf_toi16 = -1;
81 static int hf_toi32 = -1;
82 static int hf_toi48 = -1;
83 static int hf_toi64 = -1;
84 static int hf_toi_extended = -1;
85 static int hf_sct = -1;
86 static int hf_ert = -1;
87 static int hf_ext = -1;
88 static int hf_hec_type = -1;
89 static int hf_hec_len = -1;
90 static int hf_hec_data = -1;
91 static int hf_send_rate = -1;
92 static int hf_cenc = -1;
93 static int hf_flute_version = -1;
94 static int hf_fdt_instance_id = -1;
95
96 static int ett_main = -1;
97 static int ett_fsize = -1;
98 static int ett_flags = -1;
99 static int ett_ext = -1;
100 static int ett_ext_ext = -1;
101
102 /* Enumerated data types for LCT preferences */
103 const enum_val_t enum_lct_ext_192[] =
104 {
105     { "none",  "Don't decode", LCT_PREFS_EXT_192_NONE },
106     { "flute", "Decode as FLUTE extension (EXT_FDT)", LCT_PREFS_EXT_192_FLUTE },
107     { NULL, NULL, 0 }
108 };
109
110 const enum_val_t enum_lct_ext_193[] =
111 {
112     { "none", "Don't decode", LCT_PREFS_EXT_193_NONE },
113     { "flute", "Decode as FLUTE extension (EXT_CENC)", LCT_PREFS_EXT_193_FLUTE },
114     { NULL, NULL, 0 }
115 };
116
117 static const value_string hec_type_vals[] = {
118     {   0,  "EXT_NOP, No-Operation" },
119     {   1,  "EXT_AUTH, Packet authentication" },
120     {   2,  "EXT_CC, Congestion Control Feedback" },
121     {  64,  "EXT_FTI, FEC Object Transmission Information" },
122     { 128,  "EXT_RATE, Send Rate" },
123     { 192,  "EXT_FDT, FDT Instance Header" },
124     { 193,  "EXT_CENC, FDT Instance Content Encoding" },
125
126     { 0,  NULL }
127 };
128
129 /* LCT helper functions */
130 /* ==================== */
131
132 static void lct_timestamp_parse(guint32 t, nstime_t* s)
133 {
134     s->secs  = t / 1000;
135     s->nsecs = (t % 1000) * 1000000;
136 }
137
138 double rmt_decode_send_rate(guint16 send_rate )
139 {
140     double value;
141
142     value = (send_rate >> 4) * 10.0 / 4096.0 * pow(10.0, (send_rate & 0xf));
143     return value;
144 }
145
146
147 int lct_ext_decode(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, guint offset, guint offset_max, lct_data_exchange_t *data_exchange,
148                    int hfext, int ettext)
149 {
150     guint8      het;
151     guint       i, count = 0;
152     guint       length,
153                 tmp_offset   = offset,
154                 start_offset = offset;
155     proto_item *ti;
156     proto_tree *hec_tree, *ext_tree;
157
158     /* Figure out the extention count */
159     while (tmp_offset < offset_max)
160     {
161         het = tvb_get_guint8(tvb, tmp_offset);
162         if (het <= 127)
163         {
164             length = tvb_get_guint8(tvb, tmp_offset+1)*4;
165         }
166         else
167         {
168             length = 4;
169         }
170
171         /* Prevents infinite loops */
172         if (length == 0)
173             break;
174
175         tmp_offset += length;
176         count++;
177     }
178
179     if (count == 0)
180         return 0;
181
182     ti = proto_tree_add_uint(tree, hfext, tvb, offset, tmp_offset - offset, count);
183     hec_tree = proto_item_add_subtree(ti, ettext);
184
185     for (i = 0; i < count; i++)
186     {
187         het = tvb_get_guint8(tvb, offset);
188         if (het <= 127)
189         {
190             length = tvb_get_guint8(tvb, offset+1)*4;
191         }
192         else
193         {
194             length = 4;
195         }
196
197         ti = proto_tree_add_item(hec_tree, hf_hec_type, tvb, offset, 1, ENC_BIG_ENDIAN);
198         ext_tree = proto_item_add_subtree(ti, ett_ext_ext);
199         proto_item_set_len(ti, length);
200
201         if (het <= 127)
202         {
203             proto_tree_add_item(ext_tree, hf_hec_len, tvb, offset+1, 1, ENC_BIG_ENDIAN);
204         }
205
206         switch (het)
207         {
208             case 0: /* EXT_NOP */
209             case 1: /* EXT_AUTH */
210             default:
211                 proto_tree_add_item(ext_tree, hf_hec_data, tvb, offset+2, length-2, ENC_NA);
212                 break;
213
214             case 3: /* EXT_CC RATE */
215                 proto_tree_add_text(ext_tree, tvb, offset+2, 2,
216                                     "CC Sequence: %u", tvb_get_ntohs(tvb, offset+2));
217                 proto_tree_add_text(ext_tree, tvb, offset+4, 1,
218                                     "CC Flags: 0x%x", tvb_get_guint8(tvb, offset+4));
219                 proto_tree_add_text(ext_tree, tvb, offset+5, 1,
220                                     "CC RTT: %u", tvb_get_guint8(tvb, offset+5));
221                 proto_tree_add_text(ext_tree, tvb, offset+6, 2,
222                                     "CC Loss: %g", tvb_get_ntohs(tvb, offset+6)/65535.0);
223                 proto_tree_add_text(ext_tree, tvb, offset+8, 2,
224                                     "CC Rate: %u", tvb_get_ntohs(tvb, offset+8));
225                 break;
226
227             case 64: /* EXT_FTI */
228                 fec_decode_ext_fti(tvb, pinfo, ext_tree, offset,
229                                    (data_exchange == NULL) ? 0 : data_exchange->codepoint);
230                 break;
231
232             case 128: /* EXT_RATE */
233                 proto_tree_add_double(ext_tree, hf_send_rate, tvb, offset+2, 2,
234                                       rmt_decode_send_rate(tvb_get_ntohs(tvb, offset+2)));
235                 break;
236
237             case 192: /* EXT_FDT */
238                 if ((data_exchange != NULL) && (data_exchange->ext_192 == LCT_PREFS_EXT_192_FLUTE))
239                 {
240                     proto_tree_add_item(ext_tree, hf_flute_version, tvb, offset, 4, ENC_BIG_ENDIAN);
241                     proto_tree_add_item(ext_tree, hf_fdt_instance_id, tvb, offset, 4, ENC_BIG_ENDIAN);
242                     data_exchange->is_flute = TRUE;
243                 }
244                 break;
245
246             case 193: /* EXT_CENC */
247                 if ((data_exchange != NULL) && (data_exchange->ext_193 == LCT_PREFS_EXT_193_FLUTE))
248                 {
249                     proto_tree_add_item(ext_tree, hf_cenc, tvb, offset+3, 1, ENC_BIG_ENDIAN);
250                 }
251                 break;
252         }
253
254         offset += length;
255     }
256
257     return offset-start_offset;
258 }
259
260 /* LCT exported functions */
261 /* ====================== */
262
263 /* Dissection */
264 /* ---------- */
265
266 /* Dissect an LCT header:
267  * l - ptr to the logical LCT packet representation to fill, and related wireshark stuffs
268  * f - ptr to the FEC infos to fill (EXT_FTI), and related wireshark stuffs
269  * tvb - buffer
270  * pinfo - packet info
271  * tree - tree where to add LCT header subtree
272  * offset - ptr to offset to use and update
273  */
274
275 /*
276   0                   1                   2                   3
277   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
278   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
279   |   V   | C | r |S| O |H|T|R|A|B|   HDR_LEN     | Codepoint (CP)|
280   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
281   | Congestion Control Information (CCI, length = 32*(C+1) bits)  |
282   |                          ...                                  |
283   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
284   |  Transport Session Identifier (TSI, length = 32*S+16*H bits)  |
285   |                          ...                                  |
286   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
287   |   Transport Object Identifier (TOI, length = 32*O+16*H bits)  |
288   |                          ...                                  |
289   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
290   |               Sender Current Time (SCT, if T = 1)             |
291   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
292   |              Expected Residual Time (ERT, if R = 1)           |
293   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
294   |                Header Extensions (if applicable)              |
295   |                          ...                                  |
296   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
297
298   Figure 1 - Default LCT header format
299
300 */
301 static int
302 dissect_lct(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
303 {
304     int      offset = 0;
305     guint16  buffer16;
306
307     guint8   cci_size;
308     guint8   tsi_size;
309     guint8   toi_size;
310     guint64  tsi;
311     guint64  toi    = 0;
312     guint16  hlen;
313     nstime_t tmp_time;
314
315     /* Set up structures needed to add the protocol subtree and manage it */
316     proto_item *ti;
317     proto_tree *lct_tree = tree, *lct_fsize_tree, *lct_flags_tree;
318
319     lct_data_exchange_t *data_exchange = (lct_data_exchange_t *)data;
320
321     /* LCT fixed-size fields dissection */
322     /* -------------------------------- */
323     buffer16 = tvb_get_ntohs(tvb, offset);
324
325     cci_size = ((buffer16 & 0x0C00) >> 10) * 4 + 4;
326     tsi_size = ((buffer16 & 0x0080) >> 7) * 4 + ((buffer16 & 0x0010) >> 4) * 2;
327     toi_size = ((buffer16 & 0x0060) >> 5) * 4 + ((buffer16 & 0x0010) >> 4) * 2;
328
329     hlen = tvb_get_guint8(tvb, offset+2) * 4;
330
331     if (data_exchange != NULL)
332     {
333         data_exchange->codepoint = tvb_get_guint8(tvb, offset+3);
334         data_exchange->is_flute = FALSE;
335     }
336
337     if (tree)
338     {
339         /* Create the LCT subtree */
340         ti = proto_tree_add_item(tree, proto_rmt_lct, tvb, offset, hlen, ENC_NA);
341         lct_tree = proto_item_add_subtree(ti, ett_main);
342
343         /* Fill the LCT subtree */
344         proto_tree_add_item(lct_tree, hf_version, tvb, offset, 2, ENC_BIG_ENDIAN);
345
346         ti = proto_tree_add_item(lct_tree, hf_fsize_header, tvb, offset, 2, ENC_BIG_ENDIAN);
347         lct_fsize_tree = proto_item_add_subtree(ti, ett_fsize);
348
349         /* Fill the LCT fsize subtree */
350         proto_tree_add_uint(lct_fsize_tree, hf_fsize_cci, tvb, offset, 2, cci_size);
351         proto_tree_add_uint(lct_fsize_tree, hf_fsize_tsi, tvb, offset, 2, tsi_size);
352         proto_tree_add_uint(lct_fsize_tree, hf_fsize_toi, tvb, offset, 2, toi_size);
353
354         ti = proto_tree_add_item(lct_tree, hf_flags_header, tvb, offset, 2, ENC_BIG_ENDIAN);
355         lct_flags_tree = proto_item_add_subtree(ti, ett_flags);
356
357         /* Fill the LCT flags subtree */
358         proto_tree_add_item(lct_flags_tree, hf_flags_sct_present, tvb, offset, 2, ENC_BIG_ENDIAN);
359         proto_tree_add_item(lct_flags_tree, hf_flags_ert_present, tvb, offset, 2, ENC_BIG_ENDIAN);
360         proto_tree_add_item(lct_flags_tree, hf_flags_close_session, tvb, offset, 2, ENC_BIG_ENDIAN);
361         proto_tree_add_item(lct_flags_tree, hf_flags_close_object, tvb, offset, 2, ENC_BIG_ENDIAN);
362
363         proto_tree_add_uint(lct_tree, hf_hlen, tvb, offset+2, 1, hlen);
364         proto_tree_add_item(lct_tree, hf_codepoint, tvb, offset+3, 1, ENC_BIG_ENDIAN);
365
366     }
367
368     offset += 4;
369
370     /* LCT variable-size and optional fields dissection */
371     /* ------------------------------------------------ */
372
373     /* Congestion Control Information (CCI) */
374     if (cci_size > 0) {
375         proto_tree_add_item(lct_tree, hf_cci, tvb, offset, cci_size, ENC_NA);
376         offset += cci_size;
377     }
378
379     /* Transmission Session Identifier (TSI) */
380     if (tsi_size > 0) {
381
382         switch (tsi_size)
383         {
384             case 0:
385                 proto_tree_add_uint(lct_tree, hf_tsi, tvb, offset, tsi_size, 0);
386                 tsi = 0;
387                 break;
388
389             case 2:
390                 proto_tree_add_item(lct_tree, hf_tsi16, tvb, offset, tsi_size, ENC_BIG_ENDIAN);
391                 tsi = tvb_get_ntohs(tvb, offset);
392                 break;
393
394             case 4:
395                 proto_tree_add_item(lct_tree, hf_tsi32, tvb, offset, tsi_size, ENC_BIG_ENDIAN);
396                 tsi = tvb_get_ntohl(tvb, offset);
397                 break;
398
399             case 6:
400                 proto_tree_add_item(lct_tree, hf_tsi48, tvb, offset, tsi_size, ENC_BIG_ENDIAN);
401                 tsi = tvb_get_ntoh48(tvb, offset);
402                 break;
403             default:
404                 tsi = 0;
405                 break;
406         }
407
408         col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "TSI: %" G_GINT64_MODIFIER "u", tsi);
409         offset += tsi_size;
410     }
411
412     /* Transmission Object Identifier (TOI) */
413     if (toi_size > 0) {
414
415         switch (toi_size)
416         {
417             case 0:
418                 proto_tree_add_uint(lct_tree, hf_toi, tvb, offset, toi_size, 0);
419                 toi = 0;
420                 break;
421
422             case 2:
423                 proto_tree_add_item(lct_tree, hf_toi16, tvb, offset, toi_size, ENC_BIG_ENDIAN);
424                 toi = tvb_get_ntohs(tvb, offset);
425                 break;
426
427             case 4:
428                 proto_tree_add_item(lct_tree, hf_toi32, tvb, offset, toi_size, ENC_BIG_ENDIAN);
429                 toi = tvb_get_ntohl(tvb, offset);
430                 break;
431
432             case 6:
433                 proto_tree_add_item(lct_tree, hf_toi48, tvb, offset, toi_size, ENC_BIG_ENDIAN);
434                 toi = tvb_get_ntoh48(tvb, offset);
435                 break;
436
437             case 8:
438                 proto_tree_add_item(lct_tree, hf_toi64, tvb, offset, toi_size, ENC_BIG_ENDIAN);
439                 toi = tvb_get_ntoh64(tvb, offset);
440                 break;
441
442             case 10:
443                 proto_tree_add_item(lct_tree, hf_toi64, tvb, offset+2, 8, ENC_BIG_ENDIAN);
444                 proto_tree_add_item(lct_tree, hf_toi_extended, tvb, offset, 2, ENC_BIG_ENDIAN);
445                 break;
446
447             case 12:
448                 proto_tree_add_item(lct_tree, hf_toi64, tvb, offset+4, 8, ENC_BIG_ENDIAN);
449                 proto_tree_add_item(lct_tree, hf_toi_extended, tvb, offset, 4, ENC_BIG_ENDIAN);
450                 break;
451
452             case 14:
453                 proto_tree_add_item(lct_tree, hf_toi64, tvb, offset+6, 8, ENC_BIG_ENDIAN);
454                 proto_tree_add_item(lct_tree, hf_toi_extended, tvb, offset, 6, ENC_BIG_ENDIAN);
455                 break;
456             default:
457                 break;
458         }
459
460         if (toi_size <= 8)
461             col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "TOI: %" G_GINT64_MODIFIER "u", toi);
462         else
463             col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "TOI: 0x%s", tvb_bytes_to_ep_str(tvb, offset, toi_size));
464         offset += toi_size;
465     }
466
467     if (buffer16 & LCT_CLOSE_SESSION_FLAG)
468         col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "Close session");
469
470     if (buffer16 & LCT_CLOSE_OBJECT_FLAG)
471         col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "Close object");
472
473     /* Sender Current Time (SCT) */
474     if (buffer16 & LCT_SCT_FLAG) {
475         lct_timestamp_parse(tvb_get_ntohl(tvb, offset), &tmp_time);
476         proto_tree_add_time(lct_tree, hf_sct, tvb, offset, 4, &tmp_time);
477         offset += 4;
478     }
479
480     /* Expected Residual Time (ERT) */
481     if (buffer16 & LCT_ERT_FLAG) {
482         lct_timestamp_parse(tvb_get_ntohl(tvb, offset), &tmp_time);
483         proto_tree_add_time(lct_tree, hf_ert, tvb, offset, 4, &tmp_time);
484         offset += 4;
485     }
486
487     /* LCT header extensions, if applicable */
488     /* ------------------------------------ */
489     lct_ext_decode(lct_tree, tvb, pinfo, offset, hlen, data_exchange, hf_ext, ett_ext);
490
491     return hlen;
492 }
493
494 void
495 proto_register_rmt_lct(void)
496 {
497     static hf_register_info hf[] = {
498         { &hf_version,
499           { "Version", "rmt-lct.version",
500             FT_UINT16, BASE_DEC, NULL, 0xF000,
501             NULL, HFILL }
502         },
503         { &hf_fsize_header,
504           { "Field size flags", "rmt-lct.fsize",
505             FT_UINT16, BASE_HEX, NULL, 0x0FD0,
506             NULL, HFILL }
507         },
508         { &hf_fsize_cci,
509           { "Congestion Control Information field size", "rmt-lct.fsize.cci",
510             FT_UINT16, BASE_DEC, NULL, 0x0,
511             NULL, HFILL }
512         },
513         { &hf_fsize_tsi,
514           { "Transport Session Identifier field size", "rmt-lct.fsize.tsi",
515             FT_UINT16, BASE_DEC, NULL, 0x0,
516             NULL, HFILL }
517         },
518         { &hf_fsize_toi,
519           { "Transport Object Identifier field size", "rmt-lct.fsize.toi",
520             FT_UINT16, BASE_DEC, NULL, 0x0,
521             NULL, HFILL }
522         },
523         { &hf_flags_header,
524           { "Flags", "rmt-lct.flags",
525             FT_UINT16, BASE_HEX, NULL, 0x001F,
526             NULL, HFILL }
527         },
528         { &hf_flags_sct_present,
529           { "Sender Current Time present flag", "rmt-lct.flags.sct_present",
530             FT_BOOLEAN, 16, TFS(&tfs_set_notset), LCT_SCT_FLAG,
531             NULL, HFILL }
532         },
533         { &hf_flags_ert_present,
534           { "Expected Residual Time present flag", "rmt-lct.flags.ert_present",
535             FT_BOOLEAN, 16, TFS(&tfs_set_notset), LCT_ERT_FLAG,
536             NULL, HFILL }
537         },
538         { &hf_flags_close_session,
539           { "Close Session flag", "rmt-lct.flags.close_session",
540             FT_BOOLEAN, 16, TFS(&tfs_set_notset), LCT_CLOSE_SESSION_FLAG,
541             NULL, HFILL }
542         },
543         { &hf_flags_close_object,
544           { "Close Object flag", "rmt-lct.flags.close_object",
545             FT_BOOLEAN, 16, TFS(&tfs_set_notset), LCT_CLOSE_OBJECT_FLAG,
546             NULL, HFILL }
547         },
548         { &hf_hlen,
549           { "Header length", "rmt-lct.hlen",
550             FT_UINT16, BASE_DEC, NULL, 0x0,
551             NULL, HFILL }
552         },
553         { &hf_codepoint,
554           { "Codepoint", "rmt-lct.codepoint",
555             FT_UINT8, BASE_DEC, NULL, 0x0,
556             NULL, HFILL }
557         },
558         { &hf_cci,
559           { "Congestion Control Information", "rmt-lct.cci",
560             FT_BYTES, BASE_NONE, NULL, 0x0,
561             NULL, HFILL }
562         },
563         { &hf_tsi,
564           { "Transport Session Identifier", "rmt-lct.tsi",
565             FT_UINT8, BASE_DEC, NULL, 0x0,
566             NULL, HFILL }
567         },
568         { &hf_tsi16,
569           { "Transport Session Identifier", "rmt-lct.tsi",
570             FT_UINT16, BASE_DEC, NULL, 0x0,
571             NULL, HFILL }
572         },
573         { &hf_tsi32,
574           { "Transport Session Identifier", "rmt-lct.tsi",
575             FT_UINT32, BASE_DEC, NULL, 0x0,
576             NULL, HFILL }
577         },
578         { &hf_tsi48,
579           { "Transport Session Identifier", "rmt-lct.tsi",
580             FT_UINT64, BASE_DEC, NULL, 0x0,
581             NULL, HFILL }
582         },
583         { &hf_toi,
584           { "Transport Object Identifier", "rmt-lct.toi",
585             FT_UINT8, BASE_DEC, NULL, 0x0,
586             NULL, HFILL }
587         },
588         { &hf_toi16,
589           { "Transport Object Identifier", "rmt-lct.toi",
590             FT_UINT16, BASE_DEC, NULL, 0x0,
591             NULL, HFILL }
592         },
593         { &hf_toi32,
594           { "Transport Object Identifier", "rmt-lct.toi",
595             FT_UINT32, BASE_DEC, NULL, 0x0,
596             NULL, HFILL }
597         },
598         { &hf_toi48,
599           { "Transport Object Identifier", "rmt-lct.toi",
600             FT_UINT64, BASE_DEC, NULL, 0x0,
601             NULL, HFILL }
602         },
603         { &hf_toi64,
604           { "Transport Object Identifier (up to 64 bits)", "rmt-lct.toi",
605             FT_UINT64, BASE_DEC, NULL, 0x0,
606             NULL, HFILL }
607         },
608         { &hf_toi_extended,
609           { "Transport Object Identifier (bits 64-112)", "rmt-lct.toi_extended",
610             FT_UINT64, BASE_DEC, NULL, 0x0,
611             NULL, HFILL }
612         },
613         { &hf_sct,
614           { "Sender Current Time", "rmt-lct.sct",
615             FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
616             NULL, HFILL }
617         },
618         { &hf_ert,
619           { "Expected Residual Time", "rmt-lct.ert",
620             FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
621             NULL, HFILL }
622         },
623         { &hf_ext,
624           { "Extension count", "rmt-lct.ext",
625             FT_UINT8, BASE_DEC, NULL, 0x0,
626             NULL, HFILL }
627         },
628         { &hf_hec_type,
629           { "Header Extension Type (HET)", "rmt-lct.hec.type",
630             FT_UINT8, BASE_DEC, VALS(hec_type_vals), 0x0,
631             NULL, HFILL }
632         },
633         { &hf_hec_len,
634           { "Header Extension Length (HEL)", "rmt-lct.hec.len",
635             FT_UINT8, BASE_DEC, NULL, 0x0,
636             NULL, HFILL }
637         },
638         { &hf_hec_data,
639           { "Header Extension Data", "rmt-lct.hec.data",
640             FT_BYTES, BASE_NONE, NULL, 0x0,
641             NULL, HFILL }
642         },
643         { &hf_send_rate,
644           { "Send Rate", "rmt-lct.send_rate",
645             FT_DOUBLE, BASE_NONE, NULL, 0x0,
646             NULL, HFILL }
647         },
648         { &hf_cenc,
649           { "Content Encoding Algorithm (CENC)", "rmt-lct.cenc",
650             FT_UINT8, BASE_DEC, NULL, 0x0,
651             NULL, HFILL }
652         },
653         { &hf_flute_version,
654           { "FLUTE version (V)", "rmt-lct.flute_version",
655             FT_UINT32, BASE_DEC, NULL, 0x00F00000,
656             NULL, HFILL }
657         },
658         { &hf_fdt_instance_id,
659           { "FDT Instance ID", "rmt-lct.fdt_instance_id",
660             FT_UINT32, BASE_DEC, NULL, 0x000FFFFF,
661             NULL, HFILL }
662         },
663     };
664
665     /* Setup protocol subtree array */
666     static gint *ett[] = {
667         &ett_main,
668         &ett_fsize,
669         &ett_flags,
670         &ett_ext,
671         &ett_ext_ext
672     };
673
674     /* Register the protocol name and description */
675     proto_rmt_lct = proto_register_protocol("Layered Coding Transport", "RMT-LCT", "rmt-lct");
676     new_register_dissector("rmt-lct", dissect_lct, proto_rmt_lct);
677
678     /* Required function calls to register the header fields and subtrees used */
679     proto_register_field_array(proto_rmt_lct, hf, array_length(hf));
680     proto_register_subtree_array(ett, array_length(ett));
681 }
682
683 /*
684  * Editor modelines - http://www.wireshark.org/tools/modelines.html
685  *
686  * Local variables:
687  * c-basic-offset: 4
688  * tab-width: 8
689  * indent-tabs-mode: nil
690  * End:
691  *
692  * ex: set shiftwidth=4 tabstop=8 expandtab:
693  * :indentSize=4:tabSize=8:noTabs=true:
694  */