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