Remove all $Id$ from top of file
[metze/wireshark/wip.git] / epan / dissectors / packet-rdt.c
1 /* packet-rdt.c
2  *
3  * Routines for RDT dissection
4  * RDT = Real Data Transport
5  *
6  * Copyright 2005
7  * Written by Martin Mathieson and Tom Marshall
8  *
9  * Wireshark - Network traffic analyzer
10  * By Gerald Combs <gerald@wireshark.org>
11  * Copyright 1998 Gerald Combs
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26  */
27
28 /* Information sources:
29  * helixcommunity.org sources, in particular
30  * server/protocol/transport/rdt/pub/tngpkt.pm
31  */
32
33 #include "config.h"
34
35 #include <glib.h>
36
37 #include <epan/packet.h>
38 #include <epan/conversation.h>
39 #include <epan/prefs.h>
40 #include <epan/strutil.h>
41 #include <epan/wmem/wmem.h>
42
43 #include "packet-rdt.h"
44
45 static dissector_handle_t rdt_handle;
46
47 static gint    proto_rdt                        = -1;
48
49 /* Packet fields */
50 static gint    hf_rdt_packet                    = -1;
51
52 /* flags1: shared */
53 static gint    hf_rdt_len_included              = -1;
54
55 /* flags1: data packet */
56 static gint    hf_rdt_data_flags1               = -1;
57 static gint    hf_rdt_data_need_reliable        = -1;
58 static gint    hf_rdt_data_stream_id            = -1;
59 static gint    hf_rdt_data_is_reliable          = -1;
60
61 /* flags2: data packet */
62 static gint    hf_rdt_data_flags2               = -1;
63 static gint    hf_rdt_data_backtoback           = -1;
64 static gint    hf_rdt_data_slowdata             = -1;
65 static gint    hf_rdt_data_asmrule              = -1;
66
67 /* flags1: asm action packet */
68 static gint    hf_rdt_aact_flags                = -1;
69 static gint    hf_rdt_aact_stream_id            = -1;
70
71 /* flags1: ack packet */
72 static gint    hf_rdt_ack_flags                 = -1;
73 static gint    hf_rdt_ack_lost_high             = -1;
74
75 /* flags1: latency report packet */
76 static gint    hf_rdt_latency_report_flags      = -1;
77
78 /* flags1: bandwidth report packet */
79 static gint    hf_rdt_bandwidth_report_flags    = -1;
80
81 /* flags1: stream end packet */
82 static gint    hf_rdt_stre_flags                = -1;
83 static gint    hf_rdt_stre_need_reliable        = -1;
84 static gint    hf_rdt_stre_stream_id            = -1;
85 static gint    hf_rdt_stre_packet_sent          = -1;
86 static gint    hf_rdt_stre_ext_flag             = -1;
87
88 /* static gint    hf_rdt_rtt_request_flags         = -1; */
89 /* static gint    hf_rdt_rtt_response_flags        = -1; */
90 /* static gint    hf_rdt_congestion_flags          = -1; */
91 static gint    hf_rdt_report_flags              = -1;
92 /* static gint    hf_rdt_tirq_flags                = -1; */
93 static gint    hf_rdt_tirp_flags                = -1;
94 static gint    hf_rdt_bw_probing_flags          = -1;
95
96 /* Octets 1-2: sequence number or packet type */
97 static gint    hf_rdt_sequence_number           = -1;
98 static gint    hf_rdt_packet_type               = -1;
99
100 /* Only present if length_included */
101 static gint    hf_rdt_packet_length             = -1;
102
103 /* General shared fields */
104 static gint    hf_rdt_timestamp                 = -1;
105 static gint    hf_rdt_stream_id_ex              = -1;
106 static gint    hf_rdt_asmrule_ex                = -1;
107 static gint    hf_rdt_total_reliable            = -1;
108 static gint    hf_rdt_data                      = -1;
109
110 /* Special use fields */
111 static gint    hf_rdt_aact_reliable_seqno       = -1;
112 static gint    hf_rdt_brpt_interval             = -1;
113 static gint    hf_rdt_brpt_bandwidth            = -1;
114 static gint    hf_rdt_brpt_sequence             = -1;
115 static gint    hf_rdt_rtrp_ts_sec               = -1;
116 static gint    hf_rdt_rtrp_ts_usec              = -1;
117 static gint    hf_rdt_cong_xmit_mult            = -1;
118 static gint    hf_rdt_cong_recv_mult            = -1;
119 static gint    hf_rdt_stre_seqno                = -1;
120 static gint    hf_rdt_stre_dummy_flags1         = -1;
121 static gint    hf_rdt_stre_dummy_type           = -1;
122 static gint    hf_rdt_stre_reason_code          = -1;
123 static gint    hf_rdt_lrpt_server_out_time      = -1;
124 static gint    hf_rdt_tirq_request_rtt_info     = -1;
125 static gint    hf_rdt_tirq_request_buffer_info  = -1;
126 static gint    hf_rdt_tirq_request_time_msec    = -1;
127 static gint    hf_rdt_tirp_has_rtt_info         = -1;
128 static gint    hf_rdt_tirp_is_delayed           = -1;
129 static gint    hf_rdt_tirp_has_buffer_info      = -1;
130 static gint    hf_rdt_tirp_request_time_msec    = -1;
131 static gint    hf_rdt_tirp_response_time_msec   = -1;
132 static gint    hf_rdt_tirp_buffer_info          = -1;
133 static gint    hf_rdt_tirp_buffer_info_count    = -1;
134 static gint    hf_rdt_tirp_buffer_info_stream_id         = -1;
135 static gint    hf_rdt_tirp_buffer_info_lowest_timestamp  = -1;
136 static gint    hf_rdt_tirp_buffer_info_highest_timestamp = -1;
137 static gint    hf_rdt_tirp_buffer_info_bytes_buffered    = -1;
138 static gint    hf_rdt_bwpp_seqno                = -1;
139 static gint    hf_rdt_unk_flags1                = -1;
140
141 /* RDT setup fields */
142 static gint    hf_rdt_setup                     = -1;
143 static gint    hf_rdt_setup_frame               = -1;
144 static gint    hf_rdt_setup_method              = -1;
145 static gint    hf_rdt_feature_level             = -1;
146
147 /* RDT fields defining a sub tree */
148 static gint    ett_rdt                          = -1;
149 static gint    ett_rdt_packet                   = -1;
150 static gint    ett_rdt_setup                    = -1;
151 static gint    ett_rdt_data_flags1              = -1;
152 static gint    ett_rdt_data_flags2              = -1;
153 static gint    ett_rdt_aact_flags               = -1;
154 static gint    ett_rdt_ack_flags                = -1;
155 static gint    ett_rdt_latency_report_flags     = -1;
156 static gint    ett_rdt_bandwidth_report_flags   = -1;
157 static gint    ett_rdt_stre_flags               = -1;
158 static gint    ett_rdt_rtt_request_flags        = -1;
159 static gint    ett_rdt_rtt_response_flags       = -1;
160 static gint    ett_rdt_congestion_flags         = -1;
161 static gint    ett_rdt_report_flags             = -1;
162 static gint    ett_rdt_tirq_flags               = -1;
163 static gint    ett_rdt_tirp_flags               = -1;
164 static gint    ett_rdt_tirp_buffer_info         = -1;
165 static gint    ett_rdt_bw_probing_flags         = -1;
166
167 /* Port preference settings */
168 static gboolean global_rdt_register_udp_port = FALSE;
169 static guint    global_rdt_udp_port = 6970;
170
171 void proto_register_rdt(void);
172 void proto_reg_handoff_rdt(void);
173
174 /* Main dissection function */
175 static void dissect_rdt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
176
177 /* Parse individual packet types */
178 static guint dissect_rdt_data_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
179 static guint dissect_rdt_asm_action_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
180 static guint dissect_rdt_bandwidth_report_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
181 static guint dissect_rdt_ack_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
182 static guint dissect_rdt_rtt_request_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
183 static guint dissect_rdt_rtt_response_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
184 static guint dissect_rdt_congestion_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
185 static guint dissect_rdt_stream_end_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
186 static guint dissect_rdt_report_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
187 static guint dissect_rdt_latency_report_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
188 static guint dissect_rdt_transport_info_request_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
189 static guint dissect_rdt_transport_info_response_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
190 static guint dissect_rdt_bw_probing_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
191 static guint dissect_rdt_unknown_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
192
193 static void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
194
195 /* Preferences bool to control whether or not setup info should be shown */
196 static gboolean global_rdt_show_setup_info = TRUE;
197
198 /* Packet types */
199 #define RDT_ASMACTIION_PACKET               0xff00
200 #define RDT_BANDWIDTHREPORT_PACKET          0xff01
201 #define RDT_ACK_PACKET                      0xff02
202 #define RDT_RTTREQUEST_PACKET               0xff03
203 #define RDT_RTTRESPONSE_PACKET              0xff04
204 #define RDT_CONGESTION_PACKET               0xff05
205 #define RDT_STREAMEND_PACKET                0xff06
206 #define RDT_REPORT_PACKET                   0xff07
207 #define RDT_LATENCYREPORT_PACKET            0xff08
208 #define RDT_TRANSPORTINFO_PACKET            0xff09
209 #define RDT_TRANSPORTINFORESPONSE_PACKET    0xff0a
210 #define RDT_BWPROBING_PACKET                0xff0b
211
212 static const value_string packet_type_vals[] =
213 {
214     { RDT_ASMACTIION_PACKET,             "Asm action"  },
215     { RDT_BANDWIDTHREPORT_PACKET,        "Bandwidth report"  },
216     { RDT_ACK_PACKET,                    "Ack"  },
217     { RDT_RTTREQUEST_PACKET,             "RTT request"  },
218     { RDT_RTTRESPONSE_PACKET,            "RTT response"  },
219     { RDT_CONGESTION_PACKET,             "Congestion"  },
220     { RDT_STREAMEND_PACKET,              "Stream end" },
221     { RDT_REPORT_PACKET,                 "Report" },
222     { RDT_LATENCYREPORT_PACKET,          "Latency report" },
223     { RDT_TRANSPORTINFO_PACKET,          "Transport info" },
224     { RDT_TRANSPORTINFORESPONSE_PACKET,  "Transport info response" },
225     { RDT_BWPROBING_PACKET,              "BW probing" },
226     { 0, NULL }
227 };
228
229
230 /* Set up an RDT conversation */
231 void rdt_add_address(packet_info *pinfo,
232                      address *addr, int port,
233                      int other_port,
234                      const gchar *setup_method,
235                      gint  rdt_feature_level)
236 {
237     address null_addr;
238     conversation_t* p_conv;
239     struct _rdt_conversation_info *p_conv_data;
240
241     /* If this isn't the first time this packet has been processed,
242        we've already done this work, so we don't need to do it
243       again. */
244     if (pinfo->fd->flags.visited)
245     {
246         return;
247     }
248
249     SET_ADDRESS(&null_addr, AT_NONE, 0, NULL);
250
251     /* Check if the ip address and port combination is not already registered
252        as a conversation. */
253     p_conv = find_conversation(pinfo->fd->num, addr, &null_addr, PT_UDP, port, other_port,
254                                NO_ADDR_B | (!other_port ? NO_PORT_B : 0));
255
256     /* If not, create a new conversation. */
257     if ( !p_conv || p_conv->setup_frame != pinfo->fd->num)
258     {
259         p_conv = conversation_new(pinfo->fd->num, addr, &null_addr, PT_UDP,
260                                   (guint32)port, (guint32)other_port,
261                                   NO_ADDR2 | (!other_port ? NO_PORT2 : 0));
262     }
263
264     /* Set dissector */
265     conversation_set_dissector(p_conv, rdt_handle);
266
267     /* Check if the conversation has data associated with it. */
268     p_conv_data = (struct _rdt_conversation_info *)conversation_get_proto_data(p_conv, proto_rdt);
269
270     /* If not, add a new data item. */
271     if (!p_conv_data)
272     {
273         /* Create conversation data */
274         p_conv_data = wmem_new(wmem_file_scope(), struct _rdt_conversation_info);
275         conversation_add_proto_data(p_conv, proto_rdt, p_conv_data);
276     }
277
278     /* Update the conversation data. */
279     g_strlcpy(p_conv_data->method, setup_method, MAX_RDT_SETUP_METHOD_SIZE);
280     p_conv_data->frame_number = pinfo->fd->num;
281     p_conv_data->feature_level = rdt_feature_level;
282 }
283
284
285
286 /****************************************************************************/
287 /* Main dissection function                                                 */
288 /****************************************************************************/
289 static void dissect_rdt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
290 {
291     guint       previous_offset = 0;
292     gint        offset = 0;
293     proto_item  *ti;
294     proto_tree  *rdt_tree = NULL;
295     proto_tree  *rdt_packet_tree;
296     guint16     packet_type;
297
298     /* Set/clear columns */
299     col_set_str(pinfo->cinfo, COL_PROTOCOL, "RDT");
300     col_clear(pinfo->cinfo, COL_INFO);
301
302     /* Create RDT protocol tree */
303     if (tree)
304     {
305         ti = proto_tree_add_item(tree, proto_rdt, tvb, offset, -1, ENC_NA);
306         rdt_tree = proto_item_add_subtree(ti, ett_rdt);
307     }
308
309     /* Conversation setup info */
310     if (global_rdt_show_setup_info)
311     {
312         show_setup_info(tvb, pinfo, rdt_tree);
313     }
314
315     /* Parse all RDT packets found in the frame */
316     while (offset != -1 && tvb_length_remaining(tvb, offset))
317     {
318         /* Every packet type should have at least 3 bytes */
319         tvb_ensure_bytes_exist(tvb, offset, 3);
320
321         /* 2nd & 3rd bytes determine packet type */
322         packet_type = tvb_get_ntohs(tvb, offset+1);
323
324         /* Add a tree for the next individual packet */
325         ti =  proto_tree_add_string_format(rdt_tree, hf_rdt_packet, tvb, offset, -1,
326                                            "",
327                                            "RDT packet (%s)",
328                                            packet_type < 0xff00 ? "Data" :
329                                                val_to_str_const(packet_type, packet_type_vals, "Unknown"));
330         rdt_packet_tree = proto_item_add_subtree(ti, ett_rdt_packet);
331
332         /* Dissect the details of the next packet in this frame */
333         if (packet_type < 0xff00)
334         {
335             offset = dissect_rdt_data_packet(tvb, pinfo, rdt_packet_tree, offset);
336         }
337         else
338         {
339             switch (packet_type)
340             {
341             case RDT_ASMACTIION_PACKET:
342                 offset = dissect_rdt_asm_action_packet(tvb, pinfo, rdt_packet_tree, offset);
343                 break;
344             case RDT_BANDWIDTHREPORT_PACKET:
345                 offset = dissect_rdt_bandwidth_report_packet(tvb, pinfo, rdt_packet_tree, offset);
346                 break;
347             case RDT_ACK_PACKET:
348                 offset = dissect_rdt_ack_packet(tvb, pinfo, rdt_packet_tree, offset);
349                 break;
350             case RDT_RTTREQUEST_PACKET:
351                 offset = dissect_rdt_rtt_request_packet(tvb, pinfo, rdt_packet_tree, offset);
352                 break;
353             case RDT_RTTRESPONSE_PACKET:
354                 offset = dissect_rdt_rtt_response_packet(tvb, pinfo, rdt_packet_tree, offset);
355                 break;
356             case RDT_CONGESTION_PACKET:
357                 offset = dissect_rdt_congestion_packet(tvb, pinfo, rdt_packet_tree, offset);
358                 break;
359             case RDT_STREAMEND_PACKET:
360                 offset = dissect_rdt_stream_end_packet(tvb, pinfo, rdt_packet_tree, offset);
361                 break;
362             case RDT_REPORT_PACKET:
363                 offset = dissect_rdt_report_packet(tvb, pinfo, rdt_packet_tree, offset);
364                 break;
365             case RDT_LATENCYREPORT_PACKET:
366                 offset = dissect_rdt_latency_report_packet(tvb, pinfo, rdt_packet_tree, offset);
367                 break;
368             case RDT_TRANSPORTINFO_PACKET:
369                 offset = dissect_rdt_transport_info_request_packet(tvb, pinfo, rdt_packet_tree, offset);
370                 break;
371             case RDT_TRANSPORTINFORESPONSE_PACKET:
372                 offset = dissect_rdt_transport_info_response_packet(tvb, pinfo, rdt_packet_tree, offset);
373                 break;
374             case RDT_BWPROBING_PACKET:
375                 offset = dissect_rdt_bw_probing_packet(tvb, pinfo, rdt_packet_tree, offset);
376                 break;
377
378             default:
379                 /* Unknown control packet */
380                 offset = dissect_rdt_unknown_control(tvb, pinfo, rdt_packet_tree, offset);
381                 break;
382             }
383         }
384
385         /* Select correct number of bytes for the tree showing this packet */
386         if (offset != -1)
387         {
388             proto_item_set_len(rdt_packet_tree, offset-previous_offset);
389         }
390         previous_offset = offset;
391     }
392 }
393
394
395
396 /************************************************/
397 /* Functions to dissect individual packet types */
398 /************************************************/
399
400 /* Dissect a data packet */
401 guint dissect_rdt_data_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
402 {
403     guint       start_offset = offset;
404     guint16     packet_length;
405     guint8      flags1;
406     guint8      length_included_flag;
407     guint8      need_reliable_flag;
408     guint16     stream_id;
409     guint16     sequence_number;
410     guint8      is_reliable_flag;
411     guint8      flags2;
412     guint32     timestamp;
413     guint16     asm_rule_number;
414     guint8      back_to_back;
415     guint8      slow_data;
416     proto_tree  *flags_tree1;
417     proto_tree  *flags_tree2;
418     proto_item  *ti;
419
420     /* Flags in first byte */
421     flags1 = tvb_get_guint8(tvb, offset);
422     length_included_flag = (flags1 & 0x80) >> 7;
423     need_reliable_flag = (flags1 & 0x40) >> 6;
424     stream_id = (flags1 & 0x3e) >> 1;
425     is_reliable_flag = flags1 & 0x01;
426
427     /* Create subtree for flags1 fields */
428     if (tree)
429     {
430         ti =  proto_tree_add_string_format(tree, hf_rdt_data_flags1, tvb, offset, 1,
431                                            "",
432                                            "Length-included=%u, need-reliable=%u, stream-id=%u, is-reliable=%u",
433                                            length_included_flag,
434                                            need_reliable_flag,
435                                            stream_id,
436                                            is_reliable_flag);
437         flags_tree1 = proto_item_add_subtree(ti, ett_rdt_data_flags1);
438
439         proto_tree_add_item(flags_tree1, hf_rdt_len_included, tvb, offset, 1, ENC_BIG_ENDIAN);
440         proto_tree_add_item(flags_tree1, hf_rdt_data_need_reliable, tvb, offset, 1, ENC_BIG_ENDIAN);
441         proto_tree_add_item(flags_tree1, hf_rdt_data_stream_id, tvb, offset, 1, ENC_BIG_ENDIAN);
442         proto_tree_add_item(flags_tree1, hf_rdt_data_is_reliable, tvb, offset, 1, ENC_BIG_ENDIAN);
443     }
444
445     offset++;
446
447     /* Sequence number */
448     sequence_number = tvb_get_ntohs(tvb, offset);
449     proto_tree_add_item(tree, hf_rdt_sequence_number, tvb, offset, 2, ENC_BIG_ENDIAN);
450     offset += 2;
451
452     /* Length field is optional */
453     if (length_included_flag)
454     {
455         packet_length = tvb_get_ntohs(tvb, offset);
456         proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, ENC_BIG_ENDIAN);
457         offset += 2;
458
459         /* Check that there are as many bytes as reported */
460         tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
461     }
462     else
463     {
464         packet_length = tvb_length_remaining(tvb, start_offset);
465     }
466
467     /* More flags */
468     flags2 = tvb_get_guint8(tvb, offset);
469     back_to_back = (flags2 & 0x80) >> 7;
470     slow_data = (flags2 & 0x40) >> 6;
471     asm_rule_number = flags2 & 0x3f;
472
473
474     /* Create subtree for flags2 fields */
475     if (tree)
476     {
477         ti =  proto_tree_add_string_format(tree, hf_rdt_data_flags2, tvb, offset, 1,
478                                            "",
479                                            "Back-to-back=%u, slow-data=%u, asm-rule=%u",
480                                            back_to_back,
481                                            slow_data,
482                                            asm_rule_number);
483
484         /* Create subtree for flags and add fields */
485         flags_tree2 = proto_item_add_subtree(ti, ett_rdt_data_flags2);
486
487         proto_tree_add_item(flags_tree2, hf_rdt_data_backtoback, tvb, offset, 1, ENC_BIG_ENDIAN);
488         proto_tree_add_item(flags_tree2, hf_rdt_data_slowdata, tvb, offset, 1, ENC_BIG_ENDIAN);
489         proto_tree_add_item(flags_tree2, hf_rdt_data_asmrule, tvb, offset, 1, ENC_BIG_ENDIAN);
490     }
491     offset++;
492
493     /* Timestamp */
494     timestamp = tvb_get_ntohl(tvb, offset);
495     proto_tree_add_item(tree, hf_rdt_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
496     offset += 4;
497
498     /* Stream ID expansion */
499     if (stream_id == 31)
500     {
501         stream_id = tvb_get_ntohs(tvb, offset);
502         proto_tree_add_item(tree, hf_rdt_stream_id_ex, tvb, offset, 2, ENC_BIG_ENDIAN);
503         offset += 2;
504     }
505
506     /* Total reliable */
507     if (need_reliable_flag)
508     {
509         proto_tree_add_item(tree, hf_rdt_total_reliable, tvb, offset, 2, ENC_BIG_ENDIAN);
510         offset += 2;
511     }
512
513     /* Asm rule number */
514     if (asm_rule_number == 63)
515     {
516         asm_rule_number = tvb_get_ntohs(tvb, offset);
517         proto_tree_add_item(tree, hf_rdt_asmrule_ex, tvb, offset, 2, ENC_BIG_ENDIAN);
518         offset += 2;
519     }
520
521     col_append_fstr(pinfo->cinfo, COL_INFO,
522                     "DATA: stream-id=%02u asm-rule=%02u seq=%05u ts=%05u  ",
523                     stream_id, asm_rule_number, sequence_number, timestamp);
524
525     /* The remaining data is unparsed. */
526     proto_tree_add_item(tree, hf_rdt_data, tvb, offset, -1, ENC_NA);
527     offset += tvb_length_remaining(tvb, offset);
528
529     if (packet_length < (offset - start_offset) ||
530         packet_length > tvb_length_remaining(tvb, start_offset))
531     {
532         proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
533         packet_length = tvb_length_remaining(tvb, start_offset);
534     }
535
536     return start_offset + packet_length;
537 }
538
539 /* Dissect an asm-action packet */
540 guint dissect_rdt_asm_action_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
541 {
542     guint       start_offset = offset;
543     guint16     packet_length;
544     guint8      flags1;
545     guint8      length_included_flag;
546     guint16     stream_id;
547     guint16     rel_seqno;
548     proto_tree  *flags_tree;
549     proto_item  *ti;
550
551     /* Flags in first byte */
552     flags1 = tvb_get_guint8(tvb, offset);
553     length_included_flag = (flags1 & 0x80) >> 7;
554     stream_id = (flags1 & 0x7c) >> 2;
555
556     /* Create subtree for flags fields */
557     if (tree)
558     {
559         proto_tree_add_item(tree, proto_rdt, tvb, offset, -1, ENC_NA);
560         ti =  proto_tree_add_string_format(tree, hf_rdt_aact_flags, tvb, offset, 1,
561                                            "",
562                                            "Length-included=%u, stream_id=%u",
563                                            length_included_flag,
564                                            stream_id);
565         flags_tree = proto_item_add_subtree(ti, ett_rdt_aact_flags);
566
567         proto_tree_add_item(flags_tree, hf_rdt_len_included, tvb, offset, 1, ENC_BIG_ENDIAN);
568         proto_tree_add_item(flags_tree, hf_rdt_aact_stream_id, tvb, offset, 1, ENC_BIG_ENDIAN);
569     }
570     offset++;
571
572     /* Packet type */
573     proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
574     offset += 2;
575
576     rel_seqno = tvb_get_ntohs(tvb, offset);
577     proto_tree_add_item(tree, hf_rdt_aact_reliable_seqno, tvb, offset, 2, ENC_BIG_ENDIAN);
578     offset += 2;
579
580     /* Length field is optional */
581     if (length_included_flag)
582     {
583         packet_length = tvb_get_ntohs(tvb, offset);
584         proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, ENC_BIG_ENDIAN);
585         offset += 2;
586
587         /* Check that there are as many bytes as reported */
588         tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
589     }
590     else
591     {
592         packet_length = tvb_length_remaining(tvb, start_offset);
593     }
594
595     /* Stream ID expansion */
596     if (stream_id == 31)
597     {
598         stream_id = tvb_get_ntohs(tvb, offset);
599         proto_tree_add_item(tree, hf_rdt_stream_id_ex, tvb, offset, 2, ENC_BIG_ENDIAN);
600         offset += 2;
601     }
602
603     col_append_fstr(pinfo->cinfo, COL_INFO,
604                     "ASM-ACTION: stream-id=%02u rel-seqno=%05u  ",
605                     stream_id, rel_seqno);
606
607     /* The remaining data is unparsed. */
608     proto_tree_add_item(tree, hf_rdt_data, tvb, offset, -1, ENC_NA);
609
610     if (packet_length < (offset - start_offset) ||
611         packet_length > tvb_length_remaining(tvb, start_offset))
612     {
613         proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
614         packet_length = tvb_length_remaining(tvb, start_offset);
615     }
616
617     return start_offset + packet_length;
618 }
619
620 /* Dissect an bandwidth-report packet */
621 guint dissect_rdt_bandwidth_report_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
622 {
623     guint       start_offset = offset;
624     guint16     packet_length;
625     guint8      flags1;
626     guint8      length_included_flag;
627     proto_tree  *flags_tree;
628     proto_item  *ti;
629
630     /* Flags in first byte */
631     flags1 = tvb_get_guint8(tvb, offset);
632     length_included_flag = (flags1 & 0x80) >> 7;
633
634     /* Create subtree for flags fields */
635     if (tree)
636     {
637         ti =  proto_tree_add_string_format(tree, hf_rdt_bandwidth_report_flags, tvb, offset, 1,
638                                            "",
639                                            "Length-included=%u",
640                                            length_included_flag);
641         flags_tree = proto_item_add_subtree(ti, ett_rdt_bandwidth_report_flags);
642
643         proto_tree_add_item(flags_tree, hf_rdt_len_included, tvb, offset, 1, ENC_BIG_ENDIAN);
644     }
645     offset++;
646
647     /* Packet type */
648     proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
649     offset += 2;
650
651     /* Length field is optional */
652     if (length_included_flag)
653     {
654         packet_length = tvb_get_ntohs(tvb, offset);
655         proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, ENC_BIG_ENDIAN);
656         offset += 2;
657
658         /* Check that there are as many bytes as reported */
659         tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
660     }
661     else
662     {
663         packet_length = tvb_length_remaining(tvb, start_offset);
664     }
665
666     proto_tree_add_item(tree, hf_rdt_brpt_interval, tvb, offset, 2, ENC_BIG_ENDIAN);
667     offset += 2;
668     proto_tree_add_item(tree, hf_rdt_brpt_bandwidth, tvb, offset, 4, ENC_BIG_ENDIAN);
669     offset += 4;
670     proto_tree_add_item(tree, hf_rdt_brpt_sequence, tvb, offset, 1, ENC_BIG_ENDIAN);
671     offset += 1;
672
673     col_append_str(pinfo->cinfo, COL_INFO, "BANDWIDTH-REPORT:  ");
674
675     if (packet_length < (offset - start_offset) ||
676         packet_length > tvb_length_remaining(tvb, start_offset))
677     {
678         proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
679         packet_length = tvb_length_remaining(tvb, start_offset);
680     }
681
682     return start_offset + packet_length;
683 }
684
685 /* Dissect an ack packet */
686 guint dissect_rdt_ack_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
687 {
688     guint       start_offset = offset;
689     guint16     packet_length;
690     guint8      flags1;
691     guint8      length_included_flag;
692     guint8      lost_high_flag;
693     proto_tree  *flags_tree;
694     proto_item  *ti;
695
696     /* Flags in first byte */
697     flags1 = tvb_get_guint8(tvb, offset);
698     length_included_flag = (flags1 & 0x80) >> 7;
699     lost_high_flag = (flags1 & 0x40) >> 6;
700
701     /* Create subtree for flags fields */
702     if (tree)
703     {
704         ti =  proto_tree_add_string_format(tree, hf_rdt_ack_flags, tvb, offset, 1,
705                                            "",
706                                            "Length-included=%u, lost-high=%u",
707                                            length_included_flag,
708                                            lost_high_flag);
709         flags_tree = proto_item_add_subtree(ti, ett_rdt_ack_flags);
710
711         proto_tree_add_item(flags_tree, hf_rdt_len_included, tvb, offset, 1, ENC_BIG_ENDIAN);
712         proto_tree_add_item(flags_tree, hf_rdt_ack_lost_high, tvb, offset, 1, ENC_BIG_ENDIAN);
713     }
714     offset++;
715
716     /* Packet type */
717     proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
718     offset += 2;
719
720     /* Length field is optional */
721     if (length_included_flag)
722     {
723         packet_length = tvb_get_ntohs(tvb, offset);
724         proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, ENC_BIG_ENDIAN);
725         offset += 2;
726
727         /* Check that there are as many bytes as reported */
728         tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
729     }
730     else
731     {
732         packet_length = tvb_length_remaining(tvb, start_offset);
733     }
734
735     /* XXX: The remaining data is unparsed. */
736     proto_tree_add_item(tree, hf_rdt_data, tvb, offset, -1, ENC_NA);
737
738     col_append_fstr(pinfo->cinfo, COL_INFO, "ACK: lh=%u  ", lost_high_flag);
739
740     if (packet_length < (offset - start_offset) ||
741         packet_length > tvb_length_remaining(tvb, start_offset))
742     {
743         proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
744         packet_length = tvb_length_remaining(tvb, start_offset);
745     }
746
747     return start_offset + packet_length;
748 }
749
750 /* Dissect an att-request packet */
751 guint dissect_rdt_rtt_request_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
752 {
753     /* Flags in first byte */
754     offset++;
755
756     /* Packet type */
757     proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
758     offset += 2;
759
760     col_append_str(pinfo->cinfo, COL_INFO, "RTT-REQUEST:  ");
761
762     return offset;
763 }
764
765 /* Dissect an att-response packet */
766 guint dissect_rdt_rtt_response_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
767 {
768     /* Flags in first byte */
769     offset++;
770
771     /* Packet type */
772     proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
773     offset += 2;
774
775     proto_tree_add_item(tree, hf_rdt_rtrp_ts_sec, tvb, offset, 4, ENC_BIG_ENDIAN);
776     offset += 4;
777     proto_tree_add_item(tree, hf_rdt_rtrp_ts_usec, tvb, offset, 4, ENC_BIG_ENDIAN);
778     offset += 4;
779
780     col_append_str(pinfo->cinfo, COL_INFO, "RTT-RESPONSE:  ");
781
782     return offset;
783 }
784
785 /* Dissect an congestion packet */
786 guint dissect_rdt_congestion_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
787 {
788     /* Flags in first byte */
789     offset++;
790
791     /* Packet type */
792     proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
793     offset += 2;
794
795     proto_tree_add_item(tree, hf_rdt_cong_xmit_mult, tvb, offset, 4, ENC_BIG_ENDIAN);
796     offset += 4;
797     proto_tree_add_item(tree, hf_rdt_cong_recv_mult, tvb, offset, 4, ENC_BIG_ENDIAN);
798     offset += 4;
799
800     col_append_str(pinfo->cinfo, COL_INFO, "CONGESTION:  ");
801
802     return offset;
803 }
804
805 /* Dissect an stream-end packet */
806 guint dissect_rdt_stream_end_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
807 {
808     guint8      flags1;
809     guint8      need_reliable;
810     guint16     stream_id;
811     guint8      packet_sent;
812     guint8      ext_flag;
813     proto_tree  *flags_tree;
814     proto_item  *ti;
815
816     /* Flags in first byte */
817     flags1 = tvb_get_guint8(tvb, offset);
818     need_reliable = (flags1 & 0x80) >> 7;
819     stream_id = (flags1 & 0x7c) >> 2;
820     packet_sent = (flags1 & 0x2) >> 1;
821     ext_flag = flags1 & 0x1;
822
823     /* Create subtree for flags fields */
824     if (tree)
825     {
826         ti =  proto_tree_add_string_format(tree, hf_rdt_stre_flags, tvb, offset, 1,
827                                            "",
828                                            "Need-reliable=%u, stream-id=%u, packet-sent=%u, ext-flag=%u",
829                                            need_reliable,
830                                            stream_id,
831                                            packet_sent,
832                                            ext_flag);
833         flags_tree = proto_item_add_subtree(ti, ett_rdt_stre_flags);
834
835         proto_tree_add_item(flags_tree, hf_rdt_stre_need_reliable, tvb, offset, 1, ENC_BIG_ENDIAN);
836         proto_tree_add_item(flags_tree, hf_rdt_stre_stream_id, tvb, offset, 1, ENC_BIG_ENDIAN);
837         proto_tree_add_item(flags_tree, hf_rdt_stre_packet_sent, tvb, offset, 1, ENC_BIG_ENDIAN);
838         proto_tree_add_item(flags_tree, hf_rdt_stre_ext_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
839     }
840     offset++;
841
842     /* Packet type */
843     proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
844     offset += 2;
845
846     proto_tree_add_item(tree, hf_rdt_stre_seqno, tvb, offset, 2, ENC_BIG_ENDIAN);
847     offset += 2;
848     proto_tree_add_item(tree, hf_rdt_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
849     offset += 4;
850
851     /* Stream ID expansion */
852     if (stream_id == 31)
853     {
854         stream_id = tvb_get_ntohs(tvb, offset);
855         proto_tree_add_item(tree, hf_rdt_stream_id_ex, tvb, offset, 2, ENC_BIG_ENDIAN);
856         offset += 2;
857     }
858
859     /* Total reliable */
860     if (need_reliable)
861     {
862         proto_tree_add_item(tree, hf_rdt_total_reliable, tvb, offset, 2, ENC_BIG_ENDIAN);
863         offset += 2;
864     }
865
866     if (ext_flag)
867     {
868         proto_tree_add_item(tree, hf_rdt_stre_dummy_flags1, tvb, offset, 1, ENC_BIG_ENDIAN);
869         offset += 1;
870         proto_tree_add_item(tree, hf_rdt_stre_dummy_type, tvb, offset, 2, ENC_BIG_ENDIAN);
871         offset += 2;
872         proto_tree_add_item(tree, hf_rdt_stre_reason_code, tvb, offset, 4, ENC_BIG_ENDIAN);
873         offset += 4;
874         /* XXX: Remainder is reason_text */
875         offset += tvb_length_remaining(tvb, offset);
876     }
877
878     col_append_fstr(pinfo->cinfo, COL_INFO, "STREAM-END: stream-id=%02u  ", stream_id);
879
880     return offset;
881 }
882
883 /* Dissect an report packet */
884 guint dissect_rdt_report_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
885 {
886     guint       start_offset = offset;
887     guint16     packet_length;
888     guint8      flags1;
889     guint8      length_included_flag;
890     proto_tree  *flags_tree;
891     proto_item  *ti;
892
893     /* Flags in first byte */
894     flags1 = tvb_get_guint8(tvb, offset);
895     length_included_flag = (flags1 & 0x80) >> 7;
896
897     /* Create subtree for flags fields */
898     if (tree)
899     {
900         ti =  proto_tree_add_string_format(tree, hf_rdt_report_flags, tvb, offset, 1,
901                                            "",
902                                            "Length-included=%u",
903                                            length_included_flag);
904         flags_tree = proto_item_add_subtree(ti, ett_rdt_report_flags);
905
906         proto_tree_add_item(flags_tree, hf_rdt_len_included, tvb, offset, 1, ENC_BIG_ENDIAN);
907     }
908     offset++;
909
910     /* Packet type */
911     proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
912     offset += 2;
913
914     /* Length field is optional */
915     if (length_included_flag)
916     {
917         packet_length = tvb_get_ntohs(tvb, offset);
918         proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, ENC_BIG_ENDIAN);
919         offset += 2;
920
921         /* Check that there are as many bytes as reported */
922         tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
923     }
924     else
925     {
926         packet_length = tvb_length_remaining(tvb, start_offset);
927     }
928
929     col_append_str(pinfo->cinfo, COL_INFO, "REPORT:  ");
930
931     /* The remaining data is unparsed. */
932     proto_tree_add_item(tree, hf_rdt_data, tvb, offset, -1, ENC_NA);
933
934     if (packet_length < (offset - start_offset) ||
935         packet_length > tvb_length_remaining(tvb, start_offset))
936     {
937         proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
938         packet_length = tvb_length_remaining(tvb, start_offset);
939     }
940
941     return start_offset + packet_length;
942 }
943
944 /* Dissect an latency-report packet */
945 guint dissect_rdt_latency_report_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
946 {
947     guint       start_offset = offset;
948     guint16     packet_length;
949     guint8      flags1;
950     guint8      length_included_flag;
951     guint32     server_out_time;
952     proto_tree  *flags_tree;
953     proto_item  *ti;
954
955     /* Flags in first byte */
956     flags1 = tvb_get_guint8(tvb, offset);
957     length_included_flag = (flags1 & 0x80) >> 7;
958
959     /* Create subtree for flags fields */
960     if (tree)
961     {
962         ti =  proto_tree_add_string_format(tree, hf_rdt_latency_report_flags, tvb, offset, 1,
963                                            "",
964                                            "Length-included=%u",
965                                            length_included_flag);
966         flags_tree = proto_item_add_subtree(ti, ett_rdt_latency_report_flags);
967
968         proto_tree_add_item(flags_tree, hf_rdt_len_included, tvb, offset, 1, ENC_BIG_ENDIAN);
969     }
970     offset++;
971
972     /* Packet type */
973     proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
974     offset += 2;
975
976     /* Length field is optional */
977     if (length_included_flag)
978     {
979         packet_length = tvb_get_ntohs(tvb, offset);
980         proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, ENC_BIG_ENDIAN);
981         offset += 2;
982
983         /* Check that there are as many bytes as reported */
984         tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
985     }
986     else
987     {
988         packet_length = tvb_length_remaining(tvb, start_offset);
989     }
990
991     server_out_time = tvb_get_ntohl(tvb, offset);
992     proto_tree_add_item(tree, hf_rdt_lrpt_server_out_time, tvb, offset, 4, ENC_BIG_ENDIAN);
993     offset += 4;
994
995     col_append_fstr(pinfo->cinfo, COL_INFO, "LATENCY-REPORT: t=%u  ", server_out_time);
996
997     if (packet_length < (offset - start_offset) ||
998         packet_length > tvb_length_remaining(tvb, start_offset))
999     {
1000         proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
1001         packet_length = tvb_length_remaining(tvb, start_offset);
1002     }
1003
1004     return start_offset + packet_length;
1005 }
1006
1007 /* Dissect a transport-info packet */
1008 guint dissect_rdt_transport_info_request_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
1009 {
1010     guint8      flags1;
1011     guint8      request_rtt_info_flag;
1012     guint8      request_buffer_info_flag;
1013     proto_tree  *flags_tree;
1014     proto_item  *ti;
1015
1016     /* Flags in first byte */
1017     flags1 = tvb_get_guint8(tvb, offset);
1018     request_rtt_info_flag = (flags1 & 0x2) >> 1;
1019     request_buffer_info_flag = (flags1 & 0x01);
1020
1021     /* Create subtree for flags fields */
1022     if (tree)
1023     {
1024         ti =  proto_tree_add_string_format(tree, hf_rdt_ack_flags, tvb, offset, 1,
1025                                            "",
1026                                            "Request-rtt-info=%u, request-buffer-info=%u",
1027                                            request_rtt_info_flag,
1028                                            request_buffer_info_flag);
1029         flags_tree = proto_item_add_subtree(ti, ett_rdt_tirq_flags);
1030
1031         proto_tree_add_item(flags_tree, hf_rdt_tirq_request_rtt_info, tvb, offset, 1, ENC_BIG_ENDIAN);
1032         proto_tree_add_item(flags_tree, hf_rdt_tirq_request_buffer_info, tvb, offset, 1, ENC_BIG_ENDIAN);
1033     }
1034     offset++;
1035
1036     /* Packet type */
1037     proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
1038     offset += 2;
1039
1040     if (request_rtt_info_flag)
1041     {
1042         proto_tree_add_item(tree, hf_rdt_tirq_request_time_msec, tvb, offset, 4, ENC_BIG_ENDIAN);
1043         offset += 4;
1044     }
1045
1046     col_append_str(pinfo->cinfo, COL_INFO, "TRANSPORT-INFO-REQUEST:  ");
1047
1048     return offset;
1049 }
1050
1051 /* Dissect an transport-info-response packet */
1052 guint dissect_rdt_transport_info_response_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
1053 {
1054     guint8      flags1;
1055     guint8      has_rtt_info;
1056     guint8      is_delayed;
1057     guint8      has_buffer_info;
1058     proto_tree  *flags_tree;
1059     proto_item  *ti;
1060
1061     /* Flags in first byte */
1062     flags1 = tvb_get_guint8(tvb, offset);
1063     has_rtt_info = (flags1 & 0x4) >> 2;
1064     is_delayed = (flags1 & 0x2) >> 1;
1065     has_buffer_info = (flags1 & 0x1);
1066
1067     /* Create subtree for flags fields */
1068     if (tree)
1069     {
1070         ti =  proto_tree_add_string_format(tree, hf_rdt_tirp_flags, tvb, offset, 1,
1071                                            "",
1072                                            "Has-rtt-info=%u, is-delayed=%u, has-buffer-info=%u",
1073                                            has_rtt_info,
1074                                            is_delayed,
1075                                            has_buffer_info);
1076         flags_tree = proto_item_add_subtree(ti, ett_rdt_tirp_flags);
1077
1078         proto_tree_add_item(flags_tree, hf_rdt_tirp_has_rtt_info, tvb, offset, 1, ENC_BIG_ENDIAN);
1079         proto_tree_add_item(flags_tree, hf_rdt_tirp_is_delayed, tvb, offset, 1, ENC_BIG_ENDIAN);
1080         proto_tree_add_item(flags_tree, hf_rdt_tirp_has_buffer_info, tvb, offset, 1, ENC_BIG_ENDIAN);
1081     }
1082     offset++;
1083
1084     /* Packet type */
1085     proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
1086     offset += 2;
1087
1088     /* RTT info */
1089     if (has_rtt_info)
1090     {
1091         proto_tree_add_item(tree, hf_rdt_tirp_request_time_msec, tvb, offset, 4, ENC_BIG_ENDIAN);
1092         offset += 4;
1093
1094         if (is_delayed)
1095         {
1096             proto_tree_add_item(tree, hf_rdt_tirp_response_time_msec, tvb, offset, 4, ENC_BIG_ENDIAN);
1097             offset += 4;
1098         }
1099     }
1100
1101     /* Buffer info */
1102     if (has_buffer_info)
1103     {
1104         guint16 n;
1105
1106         /* Read number of buffers */
1107         guint16 buffer_info_count = tvb_get_ntohs(tvb, offset);
1108         proto_tree_add_item(tree, hf_rdt_tirp_buffer_info_count, tvb, offset, 2, ENC_BIG_ENDIAN);
1109         offset += 2;
1110
1111         for (n=0; n < buffer_info_count; n++)
1112         {
1113             proto_tree  *buffer_info_tree;
1114             proto_item  *ti2;
1115
1116             /* Each buffer info in a new subtree */
1117             ti2 =  proto_tree_add_string_format(tree, hf_rdt_tirp_buffer_info, tvb, offset, 14,
1118                                                "",
1119                                                "Buffer info %u",
1120                                                n+1);
1121             buffer_info_tree = proto_item_add_subtree(ti2, ett_rdt_tirp_buffer_info);
1122
1123             /* Read individual buffer info */
1124             proto_tree_add_item(buffer_info_tree, hf_rdt_tirp_buffer_info_stream_id, tvb, offset, 2, ENC_BIG_ENDIAN);
1125             offset += 2;
1126             proto_tree_add_item(buffer_info_tree, hf_rdt_tirp_buffer_info_lowest_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
1127             offset += 4;
1128             proto_tree_add_item(buffer_info_tree, hf_rdt_tirp_buffer_info_highest_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
1129             offset += 4;
1130             proto_tree_add_item(buffer_info_tree, hf_rdt_tirp_buffer_info_bytes_buffered, tvb, offset, 4, ENC_BIG_ENDIAN);
1131             offset += 4;
1132         }
1133     }
1134
1135     /* Report what is left */
1136     offset += tvb_length_remaining(tvb, offset);
1137
1138     col_append_str(pinfo->cinfo, COL_INFO, "RESPONSE:  ");
1139
1140     return offset;
1141 }
1142
1143 /* Dissect a bw-probing packet */
1144 guint dissect_rdt_bw_probing_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
1145 {
1146     guint       start_offset = offset;
1147     guint16     packet_length;
1148     guint8      flags1;
1149     guint8      length_included_flag;
1150     proto_tree  *flags_tree;
1151     proto_item  *ti;
1152
1153     /* Flags in first byte */
1154     flags1 = tvb_get_guint8(tvb, offset);
1155     length_included_flag = (flags1 & 0x80) >> 7;
1156
1157     /* Create subtree for flags fields */
1158     if (tree)
1159     {
1160         ti =  proto_tree_add_string_format(tree, hf_rdt_bw_probing_flags, tvb, offset, 1,
1161                                            "",
1162                                            "Length-included=%u",
1163                                            length_included_flag);
1164         flags_tree = proto_item_add_subtree(ti, ett_rdt_bw_probing_flags);
1165
1166         proto_tree_add_item(flags_tree, hf_rdt_len_included, tvb, offset, 1, ENC_BIG_ENDIAN);
1167     }
1168     offset++;
1169
1170     /* Packet type */
1171     proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
1172     offset += 2;
1173
1174     /* Length field is optional */
1175     if (length_included_flag)
1176     {
1177         packet_length = tvb_get_ntohs(tvb, offset);
1178         proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, ENC_BIG_ENDIAN);
1179         offset += 2;
1180
1181         /* Check that there are as many bytes as reported */
1182         tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
1183     }
1184     else
1185     {
1186         packet_length = tvb_length_remaining(tvb, start_offset);
1187     }
1188
1189     proto_tree_add_item(tree, hf_rdt_bwpp_seqno, tvb, offset, 1, ENC_BIG_ENDIAN);
1190     offset += 1;
1191     proto_tree_add_item(tree, hf_rdt_timestamp, tvb, offset, 1, ENC_BIG_ENDIAN);
1192     offset += 4;
1193
1194     col_append_str(pinfo->cinfo, COL_INFO, "BW-PROBING:  ");
1195
1196     if (packet_length < (offset - start_offset) ||
1197         packet_length > tvb_length_remaining(tvb, start_offset))
1198     {
1199         proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
1200         packet_length = tvb_length_remaining(tvb, start_offset);
1201     }
1202
1203     return start_offset + packet_length;
1204 }
1205
1206 /* Dissect an unknown control packet */
1207 guint dissect_rdt_unknown_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
1208 {
1209     /* Flags in first byte */
1210     proto_tree_add_item(tree, hf_rdt_unk_flags1, tvb, offset, 1, ENC_BIG_ENDIAN);
1211     offset++;
1212
1213     /* Packet type */
1214     proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
1215     offset += 2;
1216
1217     /* The remaining data is unparsed. */
1218     proto_tree_add_item(tree, hf_rdt_data, tvb, offset, -1, ENC_NA);
1219     offset += tvb_length_remaining(tvb, offset);
1220
1221     col_append_str(pinfo->cinfo, COL_INFO, "UNKNOWN-CTL:  ");
1222
1223     return offset;
1224 }
1225
1226 /* Look for conversation info and display any setup info found */
1227 static void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1228 {
1229     /* Conversation and current data */
1230     conversation_t *p_conv;
1231     struct _rdt_conversation_info *p_conv_data;
1232
1233     /* Use existing packet info if available */
1234     p_conv_data = (struct _rdt_conversation_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_rdt, 0);
1235
1236     if (!p_conv_data)
1237     {
1238         /* First time, get info from conversation */
1239         p_conv = find_conversation(pinfo->fd->num, &pinfo->net_dst, &pinfo->net_src,
1240                                    pinfo->ptype,
1241                                    pinfo->destport, pinfo->srcport, NO_ADDR_B);
1242         if (p_conv)
1243         {
1244             /* Create space for conversation info */
1245             struct _rdt_conversation_info *p_conv_packet_data;
1246             p_conv_data = (struct _rdt_conversation_info *)conversation_get_proto_data(p_conv, proto_rdt);
1247
1248             if (p_conv_data)
1249             {
1250                 /* Save this conversation info into packet info */
1251                 p_conv_packet_data = wmem_new(wmem_file_scope(), struct _rdt_conversation_info);
1252                 g_strlcpy(p_conv_packet_data->method, p_conv_data->method, MAX_RDT_SETUP_METHOD_SIZE);
1253                 p_conv_packet_data->frame_number = p_conv_data->frame_number;
1254                 p_conv_packet_data->feature_level = p_conv_data->feature_level;
1255                 p_add_proto_data(wmem_file_scope(), pinfo, proto_rdt, 0, p_conv_packet_data);
1256             }
1257         }
1258     }
1259
1260     /* Create setup info subtree with summary info. */
1261     if (p_conv_data)
1262     {
1263         proto_tree *rdt_setup_tree;
1264         proto_item *ti =  proto_tree_add_string_format(tree, hf_rdt_setup, tvb, 0, 0,
1265                                                        "",
1266                                                        "Stream setup by %s (frame %u), feature level %d",
1267                                                        p_conv_data->method,
1268                                                        p_conv_data->frame_number,
1269                                                        p_conv_data->feature_level);
1270         PROTO_ITEM_SET_GENERATED(ti);
1271         rdt_setup_tree = proto_item_add_subtree(ti, ett_rdt_setup);
1272         if (rdt_setup_tree)
1273         {
1274             /* Add details into subtree */
1275             proto_item* item = proto_tree_add_uint(rdt_setup_tree, hf_rdt_setup_frame,
1276                                                    tvb, 0, 0, p_conv_data->frame_number);
1277             PROTO_ITEM_SET_GENERATED(item);
1278             item = proto_tree_add_string(rdt_setup_tree, hf_rdt_setup_method,
1279                                          tvb, 0, 0, p_conv_data->method);
1280             PROTO_ITEM_SET_GENERATED(item);
1281             item = proto_tree_add_int(rdt_setup_tree, hf_rdt_feature_level,
1282                                       tvb, 0, 0, p_conv_data->feature_level);
1283             PROTO_ITEM_SET_GENERATED(item);
1284         }
1285     }
1286 }
1287
1288
1289 void proto_register_rdt(void)
1290 {
1291     static hf_register_info hf[] =
1292     {
1293         {
1294             &hf_rdt_packet,
1295             {
1296                 "RDT packet",
1297                 "rdt.packet",
1298                 FT_STRING,
1299                 BASE_NONE,
1300                 NULL,
1301                 0x0,
1302                 NULL, HFILL
1303             }
1304         },
1305         {
1306             &hf_rdt_data_flags1,
1307             {
1308                 "RDT data flags 1",
1309                 "rdt.data-flags1",
1310                 FT_STRING,
1311                 BASE_NONE,
1312                 NULL,
1313                 0x0,
1314                 NULL, HFILL
1315             }
1316         },
1317         {
1318             &hf_rdt_len_included,
1319             {
1320                 "Length included",
1321                 "rdt.length-included",
1322                 FT_UINT8,
1323                 BASE_DEC,
1324                 NULL,
1325                 0x80,
1326                 NULL, HFILL
1327             }
1328         },
1329         {
1330             &hf_rdt_data_need_reliable,
1331             {
1332                 "Need reliable",
1333                 "rdt.need-reliable",
1334                 FT_UINT8,
1335                 BASE_DEC,
1336                 NULL,
1337                 0x40,
1338                 NULL, HFILL
1339             }
1340         },
1341         {
1342             &hf_rdt_data_stream_id,
1343             {
1344                 "Stream ID",
1345                 "rdt.stream-id",
1346                 FT_UINT8,
1347                 BASE_DEC,
1348                 NULL,
1349                 0x3e,
1350                 NULL, HFILL
1351             }
1352         },
1353         {
1354             &hf_rdt_data_is_reliable,
1355             {
1356                 "Is reliable",
1357                 "rdt.is-reliable",
1358                 FT_UINT8,
1359                 BASE_DEC,
1360                 NULL,
1361                 0x01,
1362                 NULL, HFILL
1363             }
1364         },
1365         {
1366             &hf_rdt_data_flags2,
1367             {
1368                 "RDT data flags 2",
1369                 "rdt.data-flags2",
1370                 FT_STRING,
1371                 BASE_NONE,
1372                 NULL,
1373                 0x0,
1374                 "RDT data flags2", HFILL
1375             }
1376         },
1377         {
1378             &hf_rdt_data_backtoback,
1379             {
1380                 "Back-to-back",
1381                 "rdt.back-to-back",
1382                 FT_UINT8,
1383                 BASE_DEC,
1384                 NULL,
1385                 0x80,
1386                 NULL, HFILL
1387             }
1388         },
1389         {
1390             &hf_rdt_data_slowdata,
1391             {
1392                 "Slow data",
1393                 "rdt.slow-data",
1394                 FT_UINT8,
1395                 BASE_DEC,
1396                 NULL,
1397                 0x40,
1398                 NULL, HFILL
1399             }
1400         },
1401         {
1402             &hf_rdt_data_asmrule,
1403             {
1404                 "asm rule",
1405                 "rdt.asm-rule",
1406                 FT_UINT8,
1407                 BASE_DEC,
1408                 NULL,
1409                 0x3f,
1410                 NULL, HFILL
1411             }
1412         },
1413         {
1414             &hf_rdt_aact_flags,
1415             {
1416                 "RDT asm-action flags 1",
1417                 "rdt.aact-flags",
1418                 FT_STRING,
1419                 BASE_NONE,
1420                 NULL,
1421                 0x0,
1422                 "RDT aact flags", HFILL
1423             }
1424         },
1425         {
1426             &hf_rdt_aact_stream_id,
1427             {
1428                 "Stream ID",
1429                 "rdt.stream-id",
1430                 FT_UINT8,
1431                 BASE_DEC,
1432                 NULL,
1433                 0x7c,
1434                 NULL, HFILL
1435             }
1436         },
1437         {
1438             &hf_rdt_sequence_number,
1439             {
1440                 "Sequence number",
1441                 "rdt.sequence-number",
1442                 FT_UINT16,
1443                 BASE_DEC,
1444                 NULL,
1445                 0x0,
1446                 NULL, HFILL
1447             }
1448         },
1449         {
1450             &hf_rdt_packet_type,
1451             {
1452                 "Packet type",
1453                 "rdt.packet-type",
1454                 FT_UINT16,
1455                 BASE_HEX,
1456                 VALS(packet_type_vals),
1457                 0x0,
1458                 NULL, HFILL
1459             }
1460         },
1461         {
1462             &hf_rdt_ack_flags,
1463             {
1464                 "RDT ack flags",
1465                 "rdt.ack-flags",
1466                 FT_STRING,
1467                 BASE_NONE,
1468                 NULL,
1469                 0x0,
1470                 NULL, HFILL
1471             }
1472         },
1473         {
1474             &hf_rdt_ack_lost_high,
1475             {
1476                 "Lost high",
1477                 "rdt.lost-high",
1478                 FT_UINT8,
1479                 BASE_DEC,
1480                 NULL,
1481                 0x40,
1482                 NULL, HFILL
1483             }
1484         },
1485         {
1486             &hf_rdt_latency_report_flags,
1487             {
1488                 "RDT latency report flags",
1489                 "rdt.latency-report-flags",
1490                 FT_STRING,
1491                 BASE_NONE,
1492                 NULL,
1493                 0x0,
1494                 NULL, HFILL
1495             }
1496         },
1497         {
1498             &hf_rdt_bandwidth_report_flags,
1499             {
1500                 "RDT bandwidth report flags",
1501                 "rdt.bandwidth-report-flags",
1502                 FT_STRING,
1503                 BASE_NONE,
1504                 NULL,
1505                 0x0,
1506                 NULL, HFILL
1507             }
1508         },
1509         {
1510             &hf_rdt_stre_flags,
1511             {
1512                 "RDT stream end flags",
1513                 "rdt.stream-end-flags",
1514                 FT_STRING,
1515                 BASE_NONE,
1516                 NULL,
1517                 0x0,
1518                 NULL, HFILL
1519             }
1520         },
1521 #if 0
1522         {
1523             &hf_rdt_rtt_request_flags,
1524             {
1525                 "RDT rtt request flags",
1526                 "rdt.rtt-request-flags",
1527                 FT_STRING,
1528                 BASE_NONE,
1529                 NULL,
1530                 0x0,
1531                 NULL, HFILL
1532             }
1533         },
1534 #endif
1535 #if 0
1536         {
1537             &hf_rdt_rtt_response_flags,
1538             {
1539                 "RDT rtt response flags",
1540                 "rdt.rtt-response-flags",
1541                 FT_STRING,
1542                 BASE_NONE,
1543                 NULL,
1544                 0x0,
1545                 NULL, HFILL
1546             }
1547         },
1548 #endif
1549 #if 0
1550         {
1551             &hf_rdt_congestion_flags,
1552             {
1553                 "RDT congestion flags",
1554                 "rdt.congestion-flags",
1555                 FT_STRING,
1556                 BASE_NONE,
1557                 NULL,
1558                 0x0,
1559                 NULL, HFILL
1560             }
1561         },
1562 #endif
1563         {
1564             &hf_rdt_report_flags,
1565             {
1566                 "RDT report flags",
1567                 "rdt.report-flags",
1568                 FT_STRING,
1569                 BASE_NONE,
1570                 NULL,
1571                 0x0,
1572                 NULL, HFILL
1573             }
1574         },
1575 #if 0
1576         {
1577             &hf_rdt_tirq_flags,
1578             {
1579                 "RDT transport info request flags",
1580                 "rdt.transport-info-request-flags",
1581                 FT_STRING,
1582                 BASE_NONE,
1583                 NULL,
1584                 0x0,
1585                 NULL, HFILL
1586             }
1587         },
1588 #endif
1589         {
1590             &hf_rdt_tirp_flags,
1591             {
1592                 "RDT transport info response flags",
1593                 "rdt.transport-info-response-flags",
1594                 FT_STRING,
1595                 BASE_NONE,
1596                 NULL,
1597                 0x0,
1598                 NULL, HFILL
1599             }
1600         },
1601         {
1602             &hf_rdt_bw_probing_flags,
1603             {
1604                 "RDT bw probing flags",
1605                 "rdt.bw-probing-flags",
1606                 FT_STRING,
1607                 BASE_NONE,
1608                 NULL,
1609                 0x0,
1610                 NULL, HFILL
1611             }
1612         },
1613         {
1614             &hf_rdt_packet_length,
1615             {
1616                 "Packet length",
1617                 "rdt.packet-length",
1618                 FT_UINT16,
1619                 BASE_DEC,
1620                 NULL,
1621                 0x0,
1622                 NULL, HFILL
1623             }
1624         },
1625         {
1626             &hf_rdt_timestamp,
1627             {
1628                 "Timestamp",
1629                 "rdt.timestamp",
1630                 FT_UINT32,
1631                 BASE_DEC,
1632                 NULL,
1633                 0x0,
1634                 NULL, HFILL
1635             }
1636         },
1637         {
1638             &hf_rdt_stream_id_ex,
1639             {
1640                 "Stream-id expansion",
1641                 "rdt.stream-id-expansion",
1642                 FT_UINT16,
1643                 BASE_DEC,
1644                 NULL,
1645                 0x0,
1646                 NULL, HFILL
1647             }
1648         },
1649         {
1650             &hf_rdt_asmrule_ex,
1651             {
1652                 "Asm rule expansion",
1653                 "rdt.asm-rule-expansion",
1654                 FT_UINT16,
1655                 BASE_DEC,
1656                 NULL,
1657                 0x0,
1658                 NULL, HFILL
1659             }
1660         },
1661         {
1662             &hf_rdt_total_reliable,
1663             {
1664                 "Total reliable",
1665                 "rdt.total-reliable",
1666                 FT_UINT16,
1667                 BASE_DEC,
1668                 NULL,
1669                 0x0,
1670                 NULL, HFILL
1671             }
1672         },
1673         {
1674             &hf_rdt_data,
1675             {
1676                 "Data",
1677                 "rdt.data",
1678                 FT_NONE,
1679                 BASE_NONE,
1680                 NULL,
1681                 0x0,
1682                NULL, HFILL
1683             }
1684         },
1685         {
1686             &hf_rdt_aact_reliable_seqno,
1687             {
1688                 "Reliable sequence number",
1689                 "rdt.reliable-seq-no",
1690                 FT_UINT16,
1691                 BASE_DEC,
1692                 NULL,
1693                 0x0,
1694                 NULL, HFILL
1695             }
1696         },
1697         {
1698             &hf_rdt_brpt_interval,
1699             {
1700                 "Bandwidth report interval",
1701                 "rdt.bwid-report-interval",
1702                 FT_UINT16,
1703                 BASE_DEC,
1704                 NULL,
1705                 0x0,
1706                 NULL, HFILL
1707             }
1708         },
1709         {
1710             &hf_rdt_brpt_bandwidth,
1711             {
1712                 "Bandwidth report bandwidth",
1713                 "rdt.bwid-report-bandwidth",
1714                 FT_UINT32,
1715                 BASE_DEC,
1716                 NULL,
1717                 0x0,
1718                 NULL, HFILL
1719             }
1720         },
1721         {
1722             &hf_rdt_brpt_sequence,
1723             {
1724                 "Bandwidth report sequence",
1725                 "rdt.bwid-report-sequence",
1726                 FT_UINT16,
1727                 BASE_DEC,
1728                 NULL,
1729                 0x0,
1730                 NULL, HFILL
1731             }
1732         },
1733         {
1734             &hf_rdt_rtrp_ts_sec,
1735             {
1736                 "Round trip response timestamp seconds",
1737                 "rdt.rtrp-ts-sec",
1738                 FT_UINT32,
1739                 BASE_DEC,
1740                 NULL,
1741                 0x0,
1742                 NULL, HFILL
1743             }
1744         },
1745         {
1746             &hf_rdt_rtrp_ts_usec,
1747             {
1748                 "Round trip response timestamp microseconds",
1749                 "rdt.rtrp-ts-usec",
1750                 FT_UINT32,
1751                 BASE_DEC,
1752                 NULL,
1753                 0x0,
1754                 NULL, HFILL
1755             }
1756         },
1757         {
1758             &hf_rdt_cong_xmit_mult,
1759             {
1760                 "Congestion transmit multiplier",
1761                 "rdt.cong-xmit-mult",
1762                 FT_UINT32,
1763                 BASE_DEC,
1764                 NULL,
1765                 0x0,
1766                 NULL, HFILL
1767             }
1768         },
1769         {
1770             &hf_rdt_cong_recv_mult,
1771             {
1772                 "Congestion receive multiplier",
1773                 "rdt.cong-recv-mult",
1774                 FT_UINT32,
1775                 BASE_DEC,
1776                 NULL,
1777                 0x0,
1778                 NULL, HFILL
1779             }
1780         },
1781         {
1782             &hf_rdt_stre_need_reliable,
1783             {
1784                 "Need reliable",
1785                 "rdt.stre-need-reliable",
1786                 FT_UINT8,
1787                 BASE_DEC,
1788                 NULL,
1789                 0x80,
1790                 NULL, HFILL
1791             }
1792         },
1793         {
1794             &hf_rdt_stre_stream_id,
1795             {
1796                 "Stream id",
1797                 "rdt.stre-stream-id",
1798                 FT_UINT8,
1799                 BASE_DEC,
1800                 NULL,
1801                 0x7c,
1802                 NULL, HFILL
1803             }
1804         },
1805         {
1806             &hf_rdt_stre_packet_sent,
1807             {
1808                 "Packet sent",
1809                 "rdt.stre-packet-sent",
1810                 FT_UINT8,
1811                 BASE_DEC,
1812                 NULL,
1813                 0x02,
1814                 NULL, HFILL
1815             }
1816         },
1817         {
1818             &hf_rdt_stre_ext_flag,
1819             {
1820                 "Ext flag",
1821                 "rdt.stre-ext-flag",
1822                 FT_UINT8,
1823                 BASE_DEC,
1824                 NULL,
1825                 0x01,
1826                 NULL, HFILL
1827             }
1828         },
1829
1830         {
1831             &hf_rdt_stre_seqno,
1832             {
1833                 "Stream end sequence number",
1834                 "rdt.stre-seqno",
1835                 FT_UINT16,
1836                 BASE_DEC,
1837                 NULL,
1838                 0x0,
1839                 NULL, HFILL
1840             }
1841         },
1842         {
1843             &hf_rdt_stre_dummy_flags1,
1844             {
1845                 "Stream end reason dummy flags1",
1846                 "rdt.stre-reason-dummy-flags1",
1847                 FT_UINT8,
1848                 BASE_HEX,
1849                 NULL,
1850                 0x0,
1851                 NULL, HFILL
1852             }
1853         },
1854         {
1855             &hf_rdt_stre_dummy_type,
1856             {
1857                 "Stream end reason dummy type",
1858                 "rdt.stre-reason-dummy-type",
1859                 FT_UINT16,
1860                 BASE_HEX,
1861                 NULL,
1862                 0x0,
1863                 NULL, HFILL
1864             }
1865         },
1866         {
1867             &hf_rdt_stre_reason_code,
1868             {
1869                 "Stream end reason code",
1870                 "rdt.stre-reason-code",
1871                 FT_UINT32,
1872                 BASE_HEX,
1873                 NULL,
1874                 0x0,
1875                 NULL, HFILL
1876             }
1877         },
1878         {
1879             &hf_rdt_lrpt_server_out_time,
1880             {
1881                 "Latency report server out time",
1882                 "rdt.lrpt-server-out-time",
1883                 FT_UINT32,
1884                 BASE_DEC,
1885                 NULL,
1886                 0x0,
1887                 NULL, HFILL
1888             }
1889         },
1890         {
1891             &hf_rdt_tirq_request_rtt_info,
1892             {
1893                 "Transport info request rtt info flag",
1894                 "rdt.tirq-request-rtt-info",
1895                 FT_UINT8,
1896                 BASE_DEC,
1897                 NULL,
1898                 0x2,
1899                 NULL, HFILL
1900             }
1901         },
1902         {
1903             &hf_rdt_tirq_request_buffer_info,
1904             {
1905                 "Transport info request buffer info flag",
1906                 "rdt.tirq-request-buffer-info",
1907                 FT_UINT8,
1908                 BASE_DEC,
1909                 NULL,
1910                 0x1,
1911                 NULL, HFILL
1912             }
1913         },
1914         {
1915             &hf_rdt_tirq_request_time_msec,
1916             {
1917                 "Transport info request time msec",
1918                 "rdt.tirq-request-time-msec",
1919                 FT_UINT32,
1920                 BASE_DEC,
1921                 NULL,
1922                 0x0,
1923                 NULL, HFILL
1924             }
1925         },
1926         {
1927             &hf_rdt_tirp_has_rtt_info,
1928             {
1929                 "Transport info response has rtt info flag",
1930                 "rdt.tirp-has-rtt-info",
1931                 FT_UINT8,
1932                 BASE_DEC,
1933                 NULL,
1934                 0x4,
1935                 NULL, HFILL
1936             }
1937         },
1938         {
1939             &hf_rdt_tirp_is_delayed,
1940             {
1941                 "Transport info response is delayed",
1942                 "rdt.tirp-is-delayed",
1943                 FT_UINT8,
1944                 BASE_DEC,
1945                 NULL,
1946                 0x2,
1947                 NULL, HFILL
1948             }
1949         },
1950         {
1951             &hf_rdt_tirp_has_buffer_info,
1952             {
1953                 "Transport info response has buffer info",
1954                 "rdt.tirp-has-buffer-info",
1955                 FT_UINT8,
1956                 BASE_DEC,
1957                 NULL,
1958                 0x1,
1959                 NULL, HFILL
1960             }
1961         },
1962         {
1963             &hf_rdt_tirp_request_time_msec,
1964             {
1965                 "Transport info request time msec",
1966                 "rdt.tirp-request-time-msec",
1967                 FT_UINT32,
1968                 BASE_DEC,
1969                 NULL,
1970                 0x0,
1971                 NULL, HFILL
1972             }
1973         },
1974         {
1975             &hf_rdt_tirp_response_time_msec,
1976             {
1977                 "Transport info response time msec",
1978                 "rdt.tirp-response-time-msec",
1979                 FT_UINT32,
1980                 BASE_DEC,
1981                 NULL,
1982                 0x0,
1983                 NULL, HFILL
1984             }
1985         },
1986         {
1987             &hf_rdt_tirp_buffer_info_count,
1988             {
1989                 "Transport info buffer into count",
1990                 "rdt.tirp-buffer-info-count",
1991                 FT_UINT16,
1992                 BASE_DEC,
1993                 NULL,
1994                 0x0,
1995                 NULL, HFILL
1996             }
1997         },
1998         {
1999             &hf_rdt_tirp_buffer_info,
2000             {
2001                 "RDT buffer info",
2002                 "rdt.tirp-buffer-info",
2003                 FT_STRING,
2004                 BASE_NONE,
2005                 NULL,
2006                 0x0,
2007                 NULL, HFILL
2008             }
2009         },
2010         {
2011             &hf_rdt_tirp_buffer_info_stream_id,
2012             {
2013                 "Buffer info stream-id",
2014                 "rdt.tirp-buffer-info-stream-id",
2015                 FT_UINT16,
2016                 BASE_DEC,
2017                 NULL,
2018                 0x0,
2019                 NULL, HFILL
2020             }
2021         },
2022         {
2023             &hf_rdt_tirp_buffer_info_lowest_timestamp,
2024             {
2025                 "Lowest timestamp",
2026                 "rdt.tirp-buffer-info-lowest-timestamp",
2027                 FT_UINT32,
2028                 BASE_DEC,
2029                 NULL,
2030                 0x0,
2031                 NULL, HFILL
2032             }
2033         },
2034         {
2035             &hf_rdt_tirp_buffer_info_highest_timestamp,
2036             {
2037                 "Highest timestamp",
2038                 "rdt.tirp-buffer-info-highest-timestamp",
2039                 FT_UINT32,
2040                 BASE_DEC,
2041                 NULL,
2042                 0x0,
2043                 NULL, HFILL
2044             }
2045         },
2046         {
2047             &hf_rdt_tirp_buffer_info_bytes_buffered,
2048             {
2049                 "Bytes buffered",
2050                 "rdt.tirp-buffer-info-bytes-buffered",
2051                 FT_UINT32,
2052                 BASE_DEC,
2053                 NULL,
2054                 0x0,
2055                 NULL, HFILL
2056             }
2057         },
2058         {
2059             &hf_rdt_bwpp_seqno,
2060             {
2061                 "Bandwidth probing packet seqno",
2062                 "rdt.bwpp-seqno",
2063                 FT_UINT8,
2064                 BASE_DEC,
2065                 NULL,
2066                 0x0,
2067                 NULL, HFILL
2068             }
2069         },
2070         {
2071             &hf_rdt_unk_flags1,
2072             {
2073                 "Unknown packet flags",
2074                 "rdt.unk-flags1",
2075                 FT_UINT8,
2076                 BASE_DEC,
2077                 NULL,
2078                 0x0,
2079                 NULL, HFILL
2080             }
2081         },
2082         {
2083             &hf_rdt_setup,
2084             {
2085                 "Stream setup",
2086                 "rdt.setup",
2087                 FT_STRING,
2088                 BASE_NONE,
2089                 NULL,
2090                 0x0,
2091                 "Stream setup, method and frame number", HFILL
2092             }
2093         },
2094         {
2095             &hf_rdt_setup_frame,
2096             {
2097                 "Setup frame",
2098                 "rdt.setup-frame",
2099                 FT_FRAMENUM,
2100                 BASE_NONE,
2101                 NULL,
2102                 0x0,
2103                 "Frame that set up this stream", HFILL
2104             }
2105         },
2106         {
2107             &hf_rdt_setup_method,
2108             {
2109                 "Setup Method",
2110                 "rdt.setup-method",
2111                 FT_STRING,
2112                 BASE_NONE,
2113                 NULL,
2114                 0x0,
2115                 "Method used to set up this stream", HFILL
2116             }
2117         },
2118         {
2119             &hf_rdt_feature_level,
2120             {
2121                 "RDT feature level",
2122                 "rdt.feature-level",
2123                 FT_INT32,
2124                 BASE_DEC,
2125                 NULL,
2126                 0x0,
2127                 NULL, HFILL
2128             }
2129         },
2130     };
2131
2132     static gint *ett[] =
2133     {
2134         &ett_rdt,
2135         &ett_rdt_packet,
2136         &ett_rdt_setup,
2137         &ett_rdt_data_flags1,
2138         &ett_rdt_data_flags2,
2139         &ett_rdt_aact_flags,
2140         &ett_rdt_ack_flags,
2141         &ett_rdt_latency_report_flags,
2142         &ett_rdt_bandwidth_report_flags,
2143         &ett_rdt_stre_flags,
2144         &ett_rdt_rtt_request_flags,
2145         &ett_rdt_rtt_response_flags,
2146         &ett_rdt_congestion_flags,
2147         &ett_rdt_report_flags,
2148         &ett_rdt_tirq_flags,
2149         &ett_rdt_tirp_flags,
2150         &ett_rdt_tirp_buffer_info,
2151         &ett_rdt_bw_probing_flags
2152     };
2153
2154     module_t *rdt_module;
2155
2156     /* Register protocol and fields */
2157     proto_rdt = proto_register_protocol("Real Data Transport", "RDT", "rdt");
2158     proto_register_field_array(proto_rdt, hf, array_length(hf));
2159     proto_register_subtree_array(ett, array_length(ett));
2160     register_dissector("rdt", dissect_rdt, proto_rdt);
2161
2162     /* Preference settings */
2163     rdt_module = prefs_register_protocol(proto_rdt, proto_reg_handoff_rdt);
2164     prefs_register_bool_preference(rdt_module, "show_setup_info",
2165                                    "Show stream setup information",
2166                                    "Where available, show which protocol and frame caused "
2167                                    "this RDT stream to be created",
2168                                    &global_rdt_show_setup_info);
2169
2170     prefs_register_bool_preference(rdt_module, "register_udp_port",
2171                                    "Register default UDP client port",
2172                                    "Register a client UDP port for RDT traffic",
2173                                    &global_rdt_register_udp_port);
2174
2175     /* TODO: better to specify a range of ports instead? */
2176     prefs_register_uint_preference(rdt_module, "default_udp_port",
2177                                    "Default UDP client port",
2178                                    "Set the UDP port for clients",
2179                                    10, &global_rdt_udp_port);
2180
2181 }
2182
2183 void proto_reg_handoff_rdt(void)
2184 {
2185     static gboolean rdt_prefs_initialized = FALSE;
2186     /* Also store this so can delete registered setting properly */
2187     static gboolean  rdt_register_udp_port;
2188     static guint     rdt_udp_port;
2189
2190     if (!rdt_prefs_initialized)
2191     {
2192         /* Register this dissector as one that can be selected by a
2193            UDP port number. */
2194         rdt_handle = find_dissector("rdt");
2195         dissector_add_handle("udp.port", rdt_handle);
2196         rdt_prefs_initialized = TRUE;
2197     }
2198     else
2199     {
2200         /* Undo any current port registrations */
2201         if (rdt_register_udp_port)
2202         {
2203             dissector_delete_uint("udp.port", rdt_udp_port, rdt_handle);
2204         }
2205     }
2206
2207     /* Remember whether a port is set for next time */
2208     rdt_register_udp_port = global_rdt_register_udp_port;
2209
2210     /* Add any new port registration */
2211     if (global_rdt_register_udp_port)
2212     {
2213         /* Set our port number for future use */
2214         rdt_udp_port = global_rdt_udp_port;
2215
2216         /* And register with this port */
2217         dissector_add_uint("udp.port", global_rdt_udp_port, rdt_handle);
2218     }
2219 }
2220