3 * Routines for RDT dissection
4 * RDT = Real Data Transport
7 * Written by Martin Mathieson and Tom Marshall
11 * Wireshark - Network traffic analyzer
12 * By Gerald Combs <gerald@wireshark.org>
13 * Copyright 1998 Gerald Combs
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.
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.
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.
30 /* Information sources:
31 * helixcommunity.org sources, in particular
32 * server/protocol/transport/rdt/pub/tngpkt.pm
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>
47 #include "packet-rdt.h"
49 static dissector_handle_t rdt_handle;
51 static gint proto_rdt = -1;
54 static gint hf_rdt_packet = -1;
57 static gint hf_rdt_len_included = -1;
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;
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;
71 /* flags1: asm action packet */
72 static gint hf_rdt_aact_flags = -1;
73 static gint hf_rdt_aact_stream_id = -1;
75 /* flags1: ack packet */
76 static gint hf_rdt_ack_flags = -1;
77 static gint hf_rdt_ack_lost_high = -1;
79 /* flags1: latency report packet */
80 static gint hf_rdt_latency_report_flags = -1;
82 /* flags1: bandwidth report packet */
83 static gint hf_rdt_bandwidth_report_flags = -1;
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;
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;
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;
104 /* Only present if length_included */
105 static gint hf_rdt_packet_length = -1;
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;
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;
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;
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;
171 /* Port preference settings */
172 static gboolean global_rdt_register_udp_port = FALSE;
173 static guint global_rdt_udp_port = 6970;
175 void proto_register_rdt(void);
176 void proto_reg_handoff_rdt(void);
178 /* Main dissection function */
179 static void dissect_rdt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
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);
197 static void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
199 /* Preferences bool to control whether or not setup info should be shown */
200 static gboolean global_rdt_show_setup_info = TRUE;
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
216 static const value_string packet_type_vals[] =
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" },
234 /* Set up an RDT conversation */
235 void rdt_add_address(packet_info *pinfo,
236 address *addr, int port,
238 const gchar *setup_method,
239 gint rdt_feature_level)
242 conversation_t* p_conv;
243 struct _rdt_conversation_info *p_conv_data;
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
248 if (pinfo->fd->flags.visited)
253 SET_ADDRESS(&null_addr, AT_NONE, 0, NULL);
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));
260 /* If not, create a new conversation. */
261 if ( !p_conv || p_conv->setup_frame != pinfo->fd->num)
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));
269 conversation_set_dissector(p_conv, rdt_handle);
271 /* Check if the conversation has data associated with it. */
272 p_conv_data = conversation_get_proto_data(p_conv, proto_rdt);
274 /* If not, add a new data item. */
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);
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;
290 /****************************************************************************/
291 /* Main dissection function */
292 /****************************************************************************/
293 static void dissect_rdt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
295 guint previous_offset = 0;
298 proto_tree *rdt_tree = NULL;
299 proto_tree *rdt_packet_tree;
302 /* Set/clear columns */
303 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RDT");
304 col_clear(pinfo->cinfo, COL_INFO);
306 /* Create RDT protocol tree */
309 ti = proto_tree_add_item(tree, proto_rdt, tvb, offset, -1, ENC_NA);
310 rdt_tree = proto_item_add_subtree(ti, ett_rdt);
313 /* Conversation setup info */
314 if (global_rdt_show_setup_info)
316 show_setup_info(tvb, pinfo, rdt_tree);
319 /* Parse all RDT packets found in the frame */
320 while (offset != -1 && tvb_length_remaining(tvb, offset))
322 /* Every packet type should have at least 3 bytes */
323 tvb_ensure_bytes_exist(tvb, offset, 3);
325 /* 2nd & 3rd bytes determine packet type */
326 packet_type = tvb_get_ntohs(tvb, offset+1);
328 /* Add a tree for the next individual packet */
329 ti = proto_tree_add_string_format(rdt_tree, hf_rdt_packet, tvb, offset, -1,
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);
336 /* Dissect the details of the next packet in this frame */
337 if (packet_type < 0xff00)
339 offset = dissect_rdt_data_packet(tvb, pinfo, rdt_packet_tree, offset);
345 case RDT_ASMACTIION_PACKET:
346 offset = dissect_rdt_asm_action_packet(tvb, pinfo, rdt_packet_tree, offset);
348 case RDT_BANDWIDTHREPORT_PACKET:
349 offset = dissect_rdt_bandwidth_report_packet(tvb, pinfo, rdt_packet_tree, offset);
352 offset = dissect_rdt_ack_packet(tvb, pinfo, rdt_packet_tree, offset);
354 case RDT_RTTREQUEST_PACKET:
355 offset = dissect_rdt_rtt_request_packet(tvb, pinfo, rdt_packet_tree, offset);
357 case RDT_RTTRESPONSE_PACKET:
358 offset = dissect_rdt_rtt_response_packet(tvb, pinfo, rdt_packet_tree, offset);
360 case RDT_CONGESTION_PACKET:
361 offset = dissect_rdt_congestion_packet(tvb, pinfo, rdt_packet_tree, offset);
363 case RDT_STREAMEND_PACKET:
364 offset = dissect_rdt_stream_end_packet(tvb, pinfo, rdt_packet_tree, offset);
366 case RDT_REPORT_PACKET:
367 offset = dissect_rdt_report_packet(tvb, pinfo, rdt_packet_tree, offset);
369 case RDT_LATENCYREPORT_PACKET:
370 offset = dissect_rdt_latency_report_packet(tvb, pinfo, rdt_packet_tree, offset);
372 case RDT_TRANSPORTINFO_PACKET:
373 offset = dissect_rdt_transport_info_request_packet(tvb, pinfo, rdt_packet_tree, offset);
375 case RDT_TRANSPORTINFORESPONSE_PACKET:
376 offset = dissect_rdt_transport_info_response_packet(tvb, pinfo, rdt_packet_tree, offset);
378 case RDT_BWPROBING_PACKET:
379 offset = dissect_rdt_bw_probing_packet(tvb, pinfo, rdt_packet_tree, offset);
383 /* Unknown control packet */
384 offset = dissect_rdt_unknown_control(tvb, pinfo, rdt_packet_tree, offset);
389 /* Select correct number of bytes for the tree showing this packet */
392 proto_item_set_len(rdt_packet_tree, offset-previous_offset);
394 previous_offset = offset;
400 /************************************************/
401 /* Functions to dissect individual packet types */
402 /************************************************/
404 /* Dissect a data packet */
405 guint dissect_rdt_data_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
407 guint start_offset = offset;
408 guint16 packet_length;
410 guint8 length_included_flag;
411 guint8 need_reliable_flag;
413 guint16 sequence_number;
414 guint8 is_reliable_flag;
417 guint16 asm_rule_number;
420 proto_tree *flags_tree1;
421 proto_tree *flags_tree2;
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;
431 /* Create subtree for flags1 fields */
434 ti = proto_tree_add_string_format(tree, hf_rdt_data_flags1, tvb, offset, 1,
436 "Length-included=%u, need-reliable=%u, stream-id=%u, is-reliable=%u",
437 length_included_flag,
441 flags_tree1 = proto_item_add_subtree(ti, ett_rdt_data_flags1);
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);
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);
456 /* Length field is optional */
457 if (length_included_flag)
459 packet_length = tvb_get_ntohs(tvb, offset);
460 proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, ENC_BIG_ENDIAN);
463 /* Check that there are as many bytes as reported */
464 tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
468 packet_length = tvb_length_remaining(tvb, start_offset);
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;
478 /* Create subtree for flags2 fields */
481 ti = proto_tree_add_string_format(tree, hf_rdt_data_flags2, tvb, offset, 1,
483 "Back-to-back=%u, slow-data=%u, asm-rule=%u",
488 /* Create subtree for flags and add fields */
489 flags_tree2 = proto_item_add_subtree(ti, ett_rdt_data_flags2);
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);
498 timestamp = tvb_get_ntohl(tvb, offset);
499 proto_tree_add_item(tree, hf_rdt_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
502 /* Stream ID expansion */
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);
511 if (need_reliable_flag)
513 proto_tree_add_item(tree, hf_rdt_total_reliable, tvb, offset, 2, ENC_BIG_ENDIAN);
517 /* Asm rule number */
518 if (asm_rule_number == 63)
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);
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);
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);
533 if (packet_length < (offset - start_offset) ||
534 packet_length > tvb_length_remaining(tvb, start_offset))
536 proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
537 packet_length = tvb_length_remaining(tvb, start_offset);
540 return start_offset + packet_length;
543 /* Dissect an asm-action packet */
544 guint dissect_rdt_asm_action_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
546 guint start_offset = offset;
547 guint16 packet_length;
549 guint8 length_included_flag;
552 proto_tree *flags_tree;
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;
560 /* Create subtree for flags fields */
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,
566 "Length-included=%u, stream_id=%u",
567 length_included_flag,
569 flags_tree = proto_item_add_subtree(ti, ett_rdt_aact_flags);
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);
577 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
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);
584 /* Length field is optional */
585 if (length_included_flag)
587 packet_length = tvb_get_ntohs(tvb, offset);
588 proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, ENC_BIG_ENDIAN);
591 /* Check that there are as many bytes as reported */
592 tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
596 packet_length = tvb_length_remaining(tvb, start_offset);
599 /* Stream ID expansion */
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);
607 col_append_fstr(pinfo->cinfo, COL_INFO,
608 "ASM-ACTION: stream-id=%02u rel-seqno=%05u ",
609 stream_id, rel_seqno);
611 /* The remaining data is unparsed. */
612 proto_tree_add_item(tree, hf_rdt_data, tvb, offset, -1, ENC_NA);
614 if (packet_length < (offset - start_offset) ||
615 packet_length > tvb_length_remaining(tvb, start_offset))
617 proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
618 packet_length = tvb_length_remaining(tvb, start_offset);
621 return start_offset + packet_length;
624 /* Dissect an bandwidth-report packet */
625 guint dissect_rdt_bandwidth_report_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
627 guint start_offset = offset;
628 guint16 packet_length;
630 guint8 length_included_flag;
631 proto_tree *flags_tree;
634 /* Flags in first byte */
635 flags1 = tvb_get_guint8(tvb, offset);
636 length_included_flag = (flags1 & 0x80) >> 7;
638 /* Create subtree for flags fields */
641 ti = proto_tree_add_string_format(tree, hf_rdt_bandwidth_report_flags, tvb, offset, 1,
643 "Length-included=%u",
644 length_included_flag);
645 flags_tree = proto_item_add_subtree(ti, ett_rdt_bandwidth_report_flags);
647 proto_tree_add_item(flags_tree, hf_rdt_len_included, tvb, offset, 1, ENC_BIG_ENDIAN);
652 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
655 /* Length field is optional */
656 if (length_included_flag)
658 packet_length = tvb_get_ntohs(tvb, offset);
659 proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, ENC_BIG_ENDIAN);
662 /* Check that there are as many bytes as reported */
663 tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
667 packet_length = tvb_length_remaining(tvb, start_offset);
670 proto_tree_add_item(tree, hf_rdt_brpt_interval, tvb, offset, 2, ENC_BIG_ENDIAN);
672 proto_tree_add_item(tree, hf_rdt_brpt_bandwidth, tvb, offset, 4, ENC_BIG_ENDIAN);
674 proto_tree_add_item(tree, hf_rdt_brpt_sequence, tvb, offset, 1, ENC_BIG_ENDIAN);
677 col_append_str(pinfo->cinfo, COL_INFO, "BANDWIDTH-REPORT: ");
679 if (packet_length < (offset - start_offset) ||
680 packet_length > tvb_length_remaining(tvb, start_offset))
682 proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
683 packet_length = tvb_length_remaining(tvb, start_offset);
686 return start_offset + packet_length;
689 /* Dissect an ack packet */
690 guint dissect_rdt_ack_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
692 guint start_offset = offset;
693 guint16 packet_length;
695 guint8 length_included_flag;
696 guint8 lost_high_flag;
697 proto_tree *flags_tree;
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;
705 /* Create subtree for flags fields */
708 ti = proto_tree_add_string_format(tree, hf_rdt_ack_flags, tvb, offset, 1,
710 "Length-included=%u, lost-high=%u",
711 length_included_flag,
713 flags_tree = proto_item_add_subtree(ti, ett_rdt_ack_flags);
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);
721 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
724 /* Length field is optional */
725 if (length_included_flag)
727 packet_length = tvb_get_ntohs(tvb, offset);
728 proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, ENC_BIG_ENDIAN);
731 /* Check that there are as many bytes as reported */
732 tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
736 packet_length = tvb_length_remaining(tvb, start_offset);
739 /* XXX: The remaining data is unparsed. */
740 proto_tree_add_item(tree, hf_rdt_data, tvb, offset, -1, ENC_NA);
742 col_append_fstr(pinfo->cinfo, COL_INFO, "ACK: lh=%u ", lost_high_flag);
744 if (packet_length < (offset - start_offset) ||
745 packet_length > tvb_length_remaining(tvb, start_offset))
747 proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
748 packet_length = tvb_length_remaining(tvb, start_offset);
751 return start_offset + packet_length;
754 /* Dissect an att-request packet */
755 guint dissect_rdt_rtt_request_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
757 /* Flags in first byte */
761 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
764 col_append_str(pinfo->cinfo, COL_INFO, "RTT-REQUEST: ");
769 /* Dissect an att-response packet */
770 guint dissect_rdt_rtt_response_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
772 /* Flags in first byte */
776 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
779 proto_tree_add_item(tree, hf_rdt_rtrp_ts_sec, tvb, offset, 4, ENC_BIG_ENDIAN);
781 proto_tree_add_item(tree, hf_rdt_rtrp_ts_usec, tvb, offset, 4, ENC_BIG_ENDIAN);
784 col_append_str(pinfo->cinfo, COL_INFO, "RTT-RESPONSE: ");
789 /* Dissect an congestion packet */
790 guint dissect_rdt_congestion_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
792 /* Flags in first byte */
796 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
799 proto_tree_add_item(tree, hf_rdt_cong_xmit_mult, tvb, offset, 4, ENC_BIG_ENDIAN);
801 proto_tree_add_item(tree, hf_rdt_cong_recv_mult, tvb, offset, 4, ENC_BIG_ENDIAN);
804 col_append_str(pinfo->cinfo, COL_INFO, "CONGESTION: ");
809 /* Dissect an stream-end packet */
810 guint dissect_rdt_stream_end_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
813 guint8 need_reliable;
817 proto_tree *flags_tree;
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;
827 /* Create subtree for flags fields */
830 ti = proto_tree_add_string_format(tree, hf_rdt_stre_flags, tvb, offset, 1,
832 "Need-reliable=%u, stream-id=%u, packet-sent=%u, ext-flag=%u",
837 flags_tree = proto_item_add_subtree(ti, ett_rdt_stre_flags);
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);
847 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
850 proto_tree_add_item(tree, hf_rdt_stre_seqno, tvb, offset, 2, ENC_BIG_ENDIAN);
852 proto_tree_add_item(tree, hf_rdt_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
855 /* Stream ID expansion */
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);
866 proto_tree_add_item(tree, hf_rdt_total_reliable, tvb, offset, 2, ENC_BIG_ENDIAN);
872 proto_tree_add_item(tree, hf_rdt_stre_dummy_flags1, tvb, offset, 1, ENC_BIG_ENDIAN);
874 proto_tree_add_item(tree, hf_rdt_stre_dummy_type, tvb, offset, 2, ENC_BIG_ENDIAN);
876 proto_tree_add_item(tree, hf_rdt_stre_reason_code, tvb, offset, 4, ENC_BIG_ENDIAN);
878 /* XXX: Remainder is reason_text */
879 offset += tvb_length_remaining(tvb, offset);
882 col_append_fstr(pinfo->cinfo, COL_INFO, "STREAM-END: stream-id=%02u ", stream_id);
887 /* Dissect an report packet */
888 guint dissect_rdt_report_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
890 guint start_offset = offset;
891 guint16 packet_length;
893 guint8 length_included_flag;
894 proto_tree *flags_tree;
897 /* Flags in first byte */
898 flags1 = tvb_get_guint8(tvb, offset);
899 length_included_flag = (flags1 & 0x80) >> 7;
901 /* Create subtree for flags fields */
904 ti = proto_tree_add_string_format(tree, hf_rdt_report_flags, tvb, offset, 1,
906 "Length-included=%u",
907 length_included_flag);
908 flags_tree = proto_item_add_subtree(ti, ett_rdt_report_flags);
910 proto_tree_add_item(flags_tree, hf_rdt_len_included, tvb, offset, 1, ENC_BIG_ENDIAN);
915 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
918 /* Length field is optional */
919 if (length_included_flag)
921 packet_length = tvb_get_ntohs(tvb, offset);
922 proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, ENC_BIG_ENDIAN);
925 /* Check that there are as many bytes as reported */
926 tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
930 packet_length = tvb_length_remaining(tvb, start_offset);
933 col_append_str(pinfo->cinfo, COL_INFO, "REPORT: ");
935 /* The remaining data is unparsed. */
936 proto_tree_add_item(tree, hf_rdt_data, tvb, offset, -1, ENC_NA);
938 if (packet_length < (offset - start_offset) ||
939 packet_length > tvb_length_remaining(tvb, start_offset))
941 proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
942 packet_length = tvb_length_remaining(tvb, start_offset);
945 return start_offset + packet_length;
948 /* Dissect an latency-report packet */
949 guint dissect_rdt_latency_report_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
951 guint start_offset = offset;
952 guint16 packet_length;
954 guint8 length_included_flag;
955 guint32 server_out_time;
956 proto_tree *flags_tree;
959 /* Flags in first byte */
960 flags1 = tvb_get_guint8(tvb, offset);
961 length_included_flag = (flags1 & 0x80) >> 7;
963 /* Create subtree for flags fields */
966 ti = proto_tree_add_string_format(tree, hf_rdt_latency_report_flags, tvb, offset, 1,
968 "Length-included=%u",
969 length_included_flag);
970 flags_tree = proto_item_add_subtree(ti, ett_rdt_latency_report_flags);
972 proto_tree_add_item(flags_tree, hf_rdt_len_included, tvb, offset, 1, ENC_BIG_ENDIAN);
977 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
980 /* Length field is optional */
981 if (length_included_flag)
983 packet_length = tvb_get_ntohs(tvb, offset);
984 proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, ENC_BIG_ENDIAN);
987 /* Check that there are as many bytes as reported */
988 tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
992 packet_length = tvb_length_remaining(tvb, start_offset);
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);
999 col_append_fstr(pinfo->cinfo, COL_INFO, "LATENCY-REPORT: t=%u ", server_out_time);
1001 if (packet_length < (offset - start_offset) ||
1002 packet_length > tvb_length_remaining(tvb, start_offset))
1004 proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
1005 packet_length = tvb_length_remaining(tvb, start_offset);
1008 return start_offset + packet_length;
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)
1015 guint8 request_rtt_info_flag;
1016 guint8 request_buffer_info_flag;
1017 proto_tree *flags_tree;
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);
1025 /* Create subtree for flags fields */
1028 ti = proto_tree_add_string_format(tree, hf_rdt_ack_flags, tvb, offset, 1,
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);
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);
1041 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
1044 if (request_rtt_info_flag)
1046 proto_tree_add_item(tree, hf_rdt_tirq_request_time_msec, tvb, offset, 4, ENC_BIG_ENDIAN);
1050 col_append_str(pinfo->cinfo, COL_INFO, "TRANSPORT-INFO-REQUEST: ");
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)
1059 guint8 has_rtt_info;
1061 guint8 has_buffer_info;
1062 proto_tree *flags_tree;
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);
1071 /* Create subtree for flags fields */
1074 ti = proto_tree_add_string_format(tree, hf_rdt_tirp_flags, tvb, offset, 1,
1076 "Has-rtt-info=%u, is-delayed=%u, has-buffer-info=%u",
1080 flags_tree = proto_item_add_subtree(ti, ett_rdt_tirp_flags);
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);
1089 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
1095 proto_tree_add_item(tree, hf_rdt_tirp_request_time_msec, tvb, offset, 4, ENC_BIG_ENDIAN);
1100 proto_tree_add_item(tree, hf_rdt_tirp_response_time_msec, tvb, offset, 4, ENC_BIG_ENDIAN);
1106 if (has_buffer_info)
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);
1115 for (n=0; n < buffer_info_count; n++)
1117 proto_tree *buffer_info_tree;
1120 /* Each buffer info in a new subtree */
1121 ti2 = proto_tree_add_string_format(tree, hf_rdt_tirp_buffer_info, tvb, offset, 14,
1125 buffer_info_tree = proto_item_add_subtree(ti2, ett_rdt_tirp_buffer_info);
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);
1130 proto_tree_add_item(buffer_info_tree, hf_rdt_tirp_buffer_info_lowest_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
1132 proto_tree_add_item(buffer_info_tree, hf_rdt_tirp_buffer_info_highest_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
1134 proto_tree_add_item(buffer_info_tree, hf_rdt_tirp_buffer_info_bytes_buffered, tvb, offset, 4, ENC_BIG_ENDIAN);
1139 /* Report what is left */
1140 offset += tvb_length_remaining(tvb, offset);
1142 col_append_str(pinfo->cinfo, COL_INFO, "RESPONSE: ");
1147 /* Dissect a bw-probing packet */
1148 guint dissect_rdt_bw_probing_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
1150 guint start_offset = offset;
1151 guint16 packet_length;
1153 guint8 length_included_flag;
1154 proto_tree *flags_tree;
1157 /* Flags in first byte */
1158 flags1 = tvb_get_guint8(tvb, offset);
1159 length_included_flag = (flags1 & 0x80) >> 7;
1161 /* Create subtree for flags fields */
1164 ti = proto_tree_add_string_format(tree, hf_rdt_bw_probing_flags, tvb, offset, 1,
1166 "Length-included=%u",
1167 length_included_flag);
1168 flags_tree = proto_item_add_subtree(ti, ett_rdt_bw_probing_flags);
1170 proto_tree_add_item(flags_tree, hf_rdt_len_included, tvb, offset, 1, ENC_BIG_ENDIAN);
1175 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
1178 /* Length field is optional */
1179 if (length_included_flag)
1181 packet_length = tvb_get_ntohs(tvb, offset);
1182 proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, ENC_BIG_ENDIAN);
1185 /* Check that there are as many bytes as reported */
1186 tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
1190 packet_length = tvb_length_remaining(tvb, start_offset);
1193 proto_tree_add_item(tree, hf_rdt_bwpp_seqno, tvb, offset, 1, ENC_BIG_ENDIAN);
1195 proto_tree_add_item(tree, hf_rdt_timestamp, tvb, offset, 1, ENC_BIG_ENDIAN);
1198 col_append_str(pinfo->cinfo, COL_INFO, "BW-PROBING: ");
1200 if (packet_length < (offset - start_offset) ||
1201 packet_length > tvb_length_remaining(tvb, start_offset))
1203 proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
1204 packet_length = tvb_length_remaining(tvb, start_offset);
1207 return start_offset + packet_length;
1210 /* Dissect an unknown control packet */
1211 guint dissect_rdt_unknown_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
1213 /* Flags in first byte */
1214 proto_tree_add_item(tree, hf_rdt_unk_flags1, tvb, offset, 1, ENC_BIG_ENDIAN);
1218 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
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);
1225 col_append_str(pinfo->cinfo, COL_INFO, "UNKNOWN-CTL: ");
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)
1233 /* Conversation and current data */
1234 conversation_t *p_conv;
1235 struct _rdt_conversation_info *p_conv_data;
1237 /* Use existing packet info if available */
1238 p_conv_data = p_get_proto_data(pinfo->fd, proto_rdt);
1242 /* First time, get info from conversation */
1243 p_conv = find_conversation(pinfo->fd->num, &pinfo->net_dst, &pinfo->net_src,
1245 pinfo->destport, pinfo->srcport, NO_ADDR_B);
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);
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);
1264 /* Create setup info subtree with summary info. */
1267 proto_tree *rdt_setup_tree;
1268 proto_item *ti = proto_tree_add_string_format(tree, hf_rdt_setup, tvb, 0, 0,
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);
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);
1293 void proto_register_rdt(void)
1295 static hf_register_info hf[] =
1310 &hf_rdt_data_flags1,
1322 &hf_rdt_len_included,
1325 "rdt.length-included",
1334 &hf_rdt_data_need_reliable,
1337 "rdt.need-reliable",
1346 &hf_rdt_data_stream_id,
1358 &hf_rdt_data_is_reliable,
1370 &hf_rdt_data_flags2,
1378 "RDT data flags2", HFILL
1382 &hf_rdt_data_backtoback,
1394 &hf_rdt_data_slowdata,
1406 &hf_rdt_data_asmrule,
1420 "RDT asm-action flags 1",
1426 "RDT aact flags", HFILL
1430 &hf_rdt_aact_stream_id,
1442 &hf_rdt_sequence_number,
1445 "rdt.sequence-number",
1454 &hf_rdt_packet_type,
1460 VALS(packet_type_vals),
1478 &hf_rdt_ack_lost_high,
1490 &hf_rdt_latency_report_flags,
1492 "RDT latency report flags",
1493 "rdt.latency-report-flags",
1502 &hf_rdt_bandwidth_report_flags,
1504 "RDT bandwidth report flags",
1505 "rdt.bandwidth-report-flags",
1516 "RDT stream end flags",
1517 "rdt.stream-end-flags",
1526 &hf_rdt_rtt_request_flags,
1528 "RDT rtt request flags",
1529 "rdt.rtt-request-flags",
1538 &hf_rdt_rtt_response_flags,
1540 "RDT rtt response flags",
1541 "rdt.rtt-response-flags",
1550 &hf_rdt_congestion_flags,
1552 "RDT congestion flags",
1553 "rdt.congestion-flags",
1562 &hf_rdt_report_flags,
1576 "RDT transport info request flags",
1577 "rdt.transport-info-request-flags",
1588 "RDT transport info response flags",
1589 "rdt.transport-info-response-flags",
1598 &hf_rdt_bw_probing_flags,
1600 "RDT bw probing flags",
1601 "rdt.bw-probing-flags",
1610 &hf_rdt_packet_length,
1613 "rdt.packet-length",
1634 &hf_rdt_stream_id_ex,
1636 "Stream-id expansion",
1637 "rdt.stream-id-expansion",
1648 "Asm rule expansion",
1649 "rdt.asm-rule-expansion",
1658 &hf_rdt_total_reliable,
1661 "rdt.total-reliable",
1682 &hf_rdt_aact_reliable_seqno,
1684 "Reliable sequence number",
1685 "rdt.reliable-seq-no",
1694 &hf_rdt_brpt_interval,
1696 "Bandwidth report interval",
1697 "rdt.bwid-report-interval",
1706 &hf_rdt_brpt_bandwidth,
1708 "Bandwidth report bandwidth",
1709 "rdt.bwid-report-bandwidth",
1718 &hf_rdt_brpt_sequence,
1720 "Bandwidth report sequence",
1721 "rdt.bwid-report-sequence",
1730 &hf_rdt_rtrp_ts_sec,
1732 "Round trip response timestamp seconds",
1742 &hf_rdt_rtrp_ts_usec,
1744 "Round trip response timestamp microseconds",
1754 &hf_rdt_cong_xmit_mult,
1756 "Congestion transmit multiplier",
1757 "rdt.cong-xmit-mult",
1766 &hf_rdt_cong_recv_mult,
1768 "Congestion receive multiplier",
1769 "rdt.cong-recv-mult",
1778 &hf_rdt_stre_need_reliable,
1781 "rdt.stre-need-reliable",
1790 &hf_rdt_stre_stream_id,
1793 "rdt.stre-stream-id",
1802 &hf_rdt_stre_packet_sent,
1805 "rdt.stre-packet-sent",
1814 &hf_rdt_stre_ext_flag,
1817 "rdt.stre-ext-flag",
1829 "Stream end sequence number",
1839 &hf_rdt_stre_dummy_flags1,
1841 "Stream end reason dummy flags1",
1842 "rdt.stre-reason-dummy-flags1",
1851 &hf_rdt_stre_dummy_type,
1853 "Stream end reason dummy type",
1854 "rdt.stre-reason-dummy-type",
1863 &hf_rdt_stre_reason_code,
1865 "Stream end reason code",
1866 "rdt.stre-reason-code",
1875 &hf_rdt_lrpt_server_out_time,
1877 "Latency report server out time",
1878 "rdt.lrpt-server-out-time",
1887 &hf_rdt_tirq_request_rtt_info,
1889 "Transport info request rtt info flag",
1890 "rdt.tirq-request-rtt-info",
1899 &hf_rdt_tirq_request_buffer_info,
1901 "Transport info request buffer info flag",
1902 "rdt.tirq-request-buffer-info",
1911 &hf_rdt_tirq_request_time_msec,
1913 "Transport info request time msec",
1914 "rdt.tirq-request-time-msec",
1923 &hf_rdt_tirp_has_rtt_info,
1925 "Transport info response has rtt info flag",
1926 "rdt.tirp-has-rtt-info",
1935 &hf_rdt_tirp_is_delayed,
1937 "Transport info response is delayed",
1938 "rdt.tirp-is-delayed",
1947 &hf_rdt_tirp_has_buffer_info,
1949 "Transport info response has buffer info",
1950 "rdt.tirp-has-buffer-info",
1959 &hf_rdt_tirp_request_time_msec,
1961 "Transport info request time msec",
1962 "rdt.tirp-request-time-msec",
1971 &hf_rdt_tirp_response_time_msec,
1973 "Transport info response time msec",
1974 "rdt.tirp-response-time-msec",
1983 &hf_rdt_tirp_buffer_info_count,
1985 "Transport info buffer into count",
1986 "rdt.tirp-buffer-info-count",
1995 &hf_rdt_tirp_buffer_info,
1998 "rdt.tirp-buffer-info",
2007 &hf_rdt_tirp_buffer_info_stream_id,
2009 "Buffer info stream-id",
2010 "rdt.tirp-buffer-info-stream-id",
2019 &hf_rdt_tirp_buffer_info_lowest_timestamp,
2022 "rdt.tirp-buffer-info-lowest-timestamp",
2031 &hf_rdt_tirp_buffer_info_highest_timestamp,
2033 "Highest timestamp",
2034 "rdt.tirp-buffer-info-highest-timestamp",
2043 &hf_rdt_tirp_buffer_info_bytes_buffered,
2046 "rdt.tirp-buffer-info-bytes-buffered",
2057 "Bandwidth probing packet seqno",
2069 "Unknown packet flags",
2087 "Stream setup, method and frame number", HFILL
2091 &hf_rdt_setup_frame,
2099 "Frame that set up this stream", HFILL
2103 &hf_rdt_setup_method,
2111 "Method used to set up this stream", HFILL
2115 &hf_rdt_feature_level,
2117 "RDT feature level",
2118 "rdt.feature-level",
2128 static gint *ett[] =
2133 &ett_rdt_data_flags1,
2134 &ett_rdt_data_flags2,
2135 &ett_rdt_aact_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
2150 module_t *rdt_module;
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);
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);
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);
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);
2179 void proto_reg_handoff_rdt(void)
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;
2186 if (!rdt_prefs_initialized)
2188 /* Register this dissector as one that can be selected by a
2190 rdt_handle = find_dissector("rdt");
2191 dissector_add_handle("udp.port", rdt_handle);
2192 rdt_prefs_initialized = TRUE;
2196 /* Undo any current port registrations */
2197 if (rdt_register_udp_port)
2199 dissector_delete_uint("udp.port", rdt_udp_port, rdt_handle);
2203 /* Remember whether a port is set for next time */
2204 rdt_register_udp_port = global_rdt_register_udp_port;
2206 /* Add any new port registration */
2207 if (global_rdt_register_udp_port)
2209 /* Set our port number for future use */
2210 rdt_udp_port = global_rdt_udp_port;
2212 /* And register with this port */
2213 dissector_add_uint("udp.port", global_rdt_udp_port, rdt_handle);