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