3 * Routines for RDT dissection
4 * RDT = Real Data Transport
7 * Written by Martin Mathieson and Tom Marshall
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 /* Information sources:
29 * helixcommunity.org sources, in particular
30 * server/protocol/transport/rdt/pub/tngpkt.pm
37 #include <epan/packet.h>
38 #include <epan/conversation.h>
39 #include <epan/prefs.h>
40 #include <epan/strutil.h>
41 #include <epan/wmem/wmem.h>
43 #include "packet-rdt.h"
45 static dissector_handle_t rdt_handle;
47 static gint proto_rdt = -1;
50 static gint hf_rdt_packet = -1;
53 static gint hf_rdt_len_included = -1;
55 /* flags1: data packet */
56 static gint hf_rdt_data_flags1 = -1;
57 static gint hf_rdt_data_need_reliable = -1;
58 static gint hf_rdt_data_stream_id = -1;
59 static gint hf_rdt_data_is_reliable = -1;
61 /* flags2: data packet */
62 static gint hf_rdt_data_flags2 = -1;
63 static gint hf_rdt_data_backtoback = -1;
64 static gint hf_rdt_data_slowdata = -1;
65 static gint hf_rdt_data_asmrule = -1;
67 /* flags1: asm action packet */
68 static gint hf_rdt_aact_flags = -1;
69 static gint hf_rdt_aact_stream_id = -1;
71 /* flags1: ack packet */
72 static gint hf_rdt_ack_flags = -1;
73 static gint hf_rdt_ack_lost_high = -1;
75 /* flags1: latency report packet */
76 static gint hf_rdt_latency_report_flags = -1;
78 /* flags1: bandwidth report packet */
79 static gint hf_rdt_bandwidth_report_flags = -1;
81 /* flags1: stream end packet */
82 static gint hf_rdt_stre_flags = -1;
83 static gint hf_rdt_stre_need_reliable = -1;
84 static gint hf_rdt_stre_stream_id = -1;
85 static gint hf_rdt_stre_packet_sent = -1;
86 static gint hf_rdt_stre_ext_flag = -1;
88 /* static gint hf_rdt_rtt_request_flags = -1; */
89 /* static gint hf_rdt_rtt_response_flags = -1; */
90 /* static gint hf_rdt_congestion_flags = -1; */
91 static gint hf_rdt_report_flags = -1;
92 /* static gint hf_rdt_tirq_flags = -1; */
93 static gint hf_rdt_tirp_flags = -1;
94 static gint hf_rdt_bw_probing_flags = -1;
96 /* Octets 1-2: sequence number or packet type */
97 static gint hf_rdt_sequence_number = -1;
98 static gint hf_rdt_packet_type = -1;
100 /* Only present if length_included */
101 static gint hf_rdt_packet_length = -1;
103 /* General shared fields */
104 static gint hf_rdt_timestamp = -1;
105 static gint hf_rdt_stream_id_ex = -1;
106 static gint hf_rdt_asmrule_ex = -1;
107 static gint hf_rdt_total_reliable = -1;
108 static gint hf_rdt_data = -1;
110 /* Special use fields */
111 static gint hf_rdt_aact_reliable_seqno = -1;
112 static gint hf_rdt_brpt_interval = -1;
113 static gint hf_rdt_brpt_bandwidth = -1;
114 static gint hf_rdt_brpt_sequence = -1;
115 static gint hf_rdt_rtrp_ts_sec = -1;
116 static gint hf_rdt_rtrp_ts_usec = -1;
117 static gint hf_rdt_cong_xmit_mult = -1;
118 static gint hf_rdt_cong_recv_mult = -1;
119 static gint hf_rdt_stre_seqno = -1;
120 static gint hf_rdt_stre_dummy_flags1 = -1;
121 static gint hf_rdt_stre_dummy_type = -1;
122 static gint hf_rdt_stre_reason_code = -1;
123 static gint hf_rdt_lrpt_server_out_time = -1;
124 static gint hf_rdt_tirq_request_rtt_info = -1;
125 static gint hf_rdt_tirq_request_buffer_info = -1;
126 static gint hf_rdt_tirq_request_time_msec = -1;
127 static gint hf_rdt_tirp_has_rtt_info = -1;
128 static gint hf_rdt_tirp_is_delayed = -1;
129 static gint hf_rdt_tirp_has_buffer_info = -1;
130 static gint hf_rdt_tirp_request_time_msec = -1;
131 static gint hf_rdt_tirp_response_time_msec = -1;
132 static gint hf_rdt_tirp_buffer_info = -1;
133 static gint hf_rdt_tirp_buffer_info_count = -1;
134 static gint hf_rdt_tirp_buffer_info_stream_id = -1;
135 static gint hf_rdt_tirp_buffer_info_lowest_timestamp = -1;
136 static gint hf_rdt_tirp_buffer_info_highest_timestamp = -1;
137 static gint hf_rdt_tirp_buffer_info_bytes_buffered = -1;
138 static gint hf_rdt_bwpp_seqno = -1;
139 static gint hf_rdt_unk_flags1 = -1;
141 /* RDT setup fields */
142 static gint hf_rdt_setup = -1;
143 static gint hf_rdt_setup_frame = -1;
144 static gint hf_rdt_setup_method = -1;
145 static gint hf_rdt_feature_level = -1;
147 /* RDT fields defining a sub tree */
148 static gint ett_rdt = -1;
149 static gint ett_rdt_packet = -1;
150 static gint ett_rdt_setup = -1;
151 static gint ett_rdt_data_flags1 = -1;
152 static gint ett_rdt_data_flags2 = -1;
153 static gint ett_rdt_aact_flags = -1;
154 static gint ett_rdt_ack_flags = -1;
155 static gint ett_rdt_latency_report_flags = -1;
156 static gint ett_rdt_bandwidth_report_flags = -1;
157 static gint ett_rdt_stre_flags = -1;
158 static gint ett_rdt_rtt_request_flags = -1;
159 static gint ett_rdt_rtt_response_flags = -1;
160 static gint ett_rdt_congestion_flags = -1;
161 static gint ett_rdt_report_flags = -1;
162 static gint ett_rdt_tirq_flags = -1;
163 static gint ett_rdt_tirp_flags = -1;
164 static gint ett_rdt_tirp_buffer_info = -1;
165 static gint ett_rdt_bw_probing_flags = -1;
167 /* Port preference settings */
168 static gboolean global_rdt_register_udp_port = FALSE;
169 static guint global_rdt_udp_port = 6970;
171 void proto_register_rdt(void);
172 void proto_reg_handoff_rdt(void);
174 /* Main dissection function */
175 static void dissect_rdt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
177 /* Parse individual packet types */
178 static guint dissect_rdt_data_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
179 static guint dissect_rdt_asm_action_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
180 static guint dissect_rdt_bandwidth_report_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
181 static guint dissect_rdt_ack_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
182 static guint dissect_rdt_rtt_request_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
183 static guint dissect_rdt_rtt_response_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
184 static guint dissect_rdt_congestion_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
185 static guint dissect_rdt_stream_end_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
186 static guint dissect_rdt_report_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
187 static guint dissect_rdt_latency_report_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
188 static guint dissect_rdt_transport_info_request_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
189 static guint dissect_rdt_transport_info_response_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
190 static guint dissect_rdt_bw_probing_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
191 static guint dissect_rdt_unknown_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
193 static void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
195 /* Preferences bool to control whether or not setup info should be shown */
196 static gboolean global_rdt_show_setup_info = TRUE;
199 #define RDT_ASMACTIION_PACKET 0xff00
200 #define RDT_BANDWIDTHREPORT_PACKET 0xff01
201 #define RDT_ACK_PACKET 0xff02
202 #define RDT_RTTREQUEST_PACKET 0xff03
203 #define RDT_RTTRESPONSE_PACKET 0xff04
204 #define RDT_CONGESTION_PACKET 0xff05
205 #define RDT_STREAMEND_PACKET 0xff06
206 #define RDT_REPORT_PACKET 0xff07
207 #define RDT_LATENCYREPORT_PACKET 0xff08
208 #define RDT_TRANSPORTINFO_PACKET 0xff09
209 #define RDT_TRANSPORTINFORESPONSE_PACKET 0xff0a
210 #define RDT_BWPROBING_PACKET 0xff0b
212 static const value_string packet_type_vals[] =
214 { RDT_ASMACTIION_PACKET, "Asm action" },
215 { RDT_BANDWIDTHREPORT_PACKET, "Bandwidth report" },
216 { RDT_ACK_PACKET, "Ack" },
217 { RDT_RTTREQUEST_PACKET, "RTT request" },
218 { RDT_RTTRESPONSE_PACKET, "RTT response" },
219 { RDT_CONGESTION_PACKET, "Congestion" },
220 { RDT_STREAMEND_PACKET, "Stream end" },
221 { RDT_REPORT_PACKET, "Report" },
222 { RDT_LATENCYREPORT_PACKET, "Latency report" },
223 { RDT_TRANSPORTINFO_PACKET, "Transport info" },
224 { RDT_TRANSPORTINFORESPONSE_PACKET, "Transport info response" },
225 { RDT_BWPROBING_PACKET, "BW probing" },
230 /* Set up an RDT conversation */
231 void rdt_add_address(packet_info *pinfo,
232 address *addr, int port,
234 const gchar *setup_method,
235 gint rdt_feature_level)
238 conversation_t* p_conv;
239 struct _rdt_conversation_info *p_conv_data;
241 /* If this isn't the first time this packet has been processed,
242 we've already done this work, so we don't need to do it
244 if (pinfo->fd->flags.visited)
249 SET_ADDRESS(&null_addr, AT_NONE, 0, NULL);
251 /* Check if the ip address and port combination is not already registered
252 as a conversation. */
253 p_conv = find_conversation(pinfo->fd->num, addr, &null_addr, PT_UDP, port, other_port,
254 NO_ADDR_B | (!other_port ? NO_PORT_B : 0));
256 /* If not, create a new conversation. */
257 if ( !p_conv || p_conv->setup_frame != pinfo->fd->num)
259 p_conv = conversation_new(pinfo->fd->num, addr, &null_addr, PT_UDP,
260 (guint32)port, (guint32)other_port,
261 NO_ADDR2 | (!other_port ? NO_PORT2 : 0));
265 conversation_set_dissector(p_conv, rdt_handle);
267 /* Check if the conversation has data associated with it. */
268 p_conv_data = (struct _rdt_conversation_info *)conversation_get_proto_data(p_conv, proto_rdt);
270 /* If not, add a new data item. */
273 /* Create conversation data */
274 p_conv_data = wmem_new(wmem_file_scope(), struct _rdt_conversation_info);
275 conversation_add_proto_data(p_conv, proto_rdt, p_conv_data);
278 /* Update the conversation data. */
279 g_strlcpy(p_conv_data->method, setup_method, MAX_RDT_SETUP_METHOD_SIZE);
280 p_conv_data->frame_number = pinfo->fd->num;
281 p_conv_data->feature_level = rdt_feature_level;
286 /****************************************************************************/
287 /* Main dissection function */
288 /****************************************************************************/
289 static void dissect_rdt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
291 guint previous_offset = 0;
294 proto_tree *rdt_tree = NULL;
295 proto_tree *rdt_packet_tree;
298 /* Set/clear columns */
299 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RDT");
300 col_clear(pinfo->cinfo, COL_INFO);
302 /* Create RDT protocol tree */
305 ti = proto_tree_add_item(tree, proto_rdt, tvb, offset, -1, ENC_NA);
306 rdt_tree = proto_item_add_subtree(ti, ett_rdt);
309 /* Conversation setup info */
310 if (global_rdt_show_setup_info)
312 show_setup_info(tvb, pinfo, rdt_tree);
315 /* Parse all RDT packets found in the frame */
316 while (offset != -1 && tvb_length_remaining(tvb, offset))
318 /* Every packet type should have at least 3 bytes */
319 tvb_ensure_bytes_exist(tvb, offset, 3);
321 /* 2nd & 3rd bytes determine packet type */
322 packet_type = tvb_get_ntohs(tvb, offset+1);
324 /* Add a tree for the next individual packet */
325 ti = proto_tree_add_string_format(rdt_tree, hf_rdt_packet, tvb, offset, -1,
328 packet_type < 0xff00 ? "Data" :
329 val_to_str_const(packet_type, packet_type_vals, "Unknown"));
330 rdt_packet_tree = proto_item_add_subtree(ti, ett_rdt_packet);
332 /* Dissect the details of the next packet in this frame */
333 if (packet_type < 0xff00)
335 offset = dissect_rdt_data_packet(tvb, pinfo, rdt_packet_tree, offset);
341 case RDT_ASMACTIION_PACKET:
342 offset = dissect_rdt_asm_action_packet(tvb, pinfo, rdt_packet_tree, offset);
344 case RDT_BANDWIDTHREPORT_PACKET:
345 offset = dissect_rdt_bandwidth_report_packet(tvb, pinfo, rdt_packet_tree, offset);
348 offset = dissect_rdt_ack_packet(tvb, pinfo, rdt_packet_tree, offset);
350 case RDT_RTTREQUEST_PACKET:
351 offset = dissect_rdt_rtt_request_packet(tvb, pinfo, rdt_packet_tree, offset);
353 case RDT_RTTRESPONSE_PACKET:
354 offset = dissect_rdt_rtt_response_packet(tvb, pinfo, rdt_packet_tree, offset);
356 case RDT_CONGESTION_PACKET:
357 offset = dissect_rdt_congestion_packet(tvb, pinfo, rdt_packet_tree, offset);
359 case RDT_STREAMEND_PACKET:
360 offset = dissect_rdt_stream_end_packet(tvb, pinfo, rdt_packet_tree, offset);
362 case RDT_REPORT_PACKET:
363 offset = dissect_rdt_report_packet(tvb, pinfo, rdt_packet_tree, offset);
365 case RDT_LATENCYREPORT_PACKET:
366 offset = dissect_rdt_latency_report_packet(tvb, pinfo, rdt_packet_tree, offset);
368 case RDT_TRANSPORTINFO_PACKET:
369 offset = dissect_rdt_transport_info_request_packet(tvb, pinfo, rdt_packet_tree, offset);
371 case RDT_TRANSPORTINFORESPONSE_PACKET:
372 offset = dissect_rdt_transport_info_response_packet(tvb, pinfo, rdt_packet_tree, offset);
374 case RDT_BWPROBING_PACKET:
375 offset = dissect_rdt_bw_probing_packet(tvb, pinfo, rdt_packet_tree, offset);
379 /* Unknown control packet */
380 offset = dissect_rdt_unknown_control(tvb, pinfo, rdt_packet_tree, offset);
385 /* Select correct number of bytes for the tree showing this packet */
388 proto_item_set_len(rdt_packet_tree, offset-previous_offset);
390 previous_offset = offset;
396 /************************************************/
397 /* Functions to dissect individual packet types */
398 /************************************************/
400 /* Dissect a data packet */
401 guint dissect_rdt_data_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
403 guint start_offset = offset;
404 guint16 packet_length;
406 guint8 length_included_flag;
407 guint8 need_reliable_flag;
409 guint16 sequence_number;
410 guint8 is_reliable_flag;
413 guint16 asm_rule_number;
416 proto_tree *flags_tree1;
417 proto_tree *flags_tree2;
420 /* Flags in first byte */
421 flags1 = tvb_get_guint8(tvb, offset);
422 length_included_flag = (flags1 & 0x80) >> 7;
423 need_reliable_flag = (flags1 & 0x40) >> 6;
424 stream_id = (flags1 & 0x3e) >> 1;
425 is_reliable_flag = flags1 & 0x01;
427 /* Create subtree for flags1 fields */
430 ti = proto_tree_add_string_format(tree, hf_rdt_data_flags1, tvb, offset, 1,
432 "Length-included=%u, need-reliable=%u, stream-id=%u, is-reliable=%u",
433 length_included_flag,
437 flags_tree1 = proto_item_add_subtree(ti, ett_rdt_data_flags1);
439 proto_tree_add_item(flags_tree1, hf_rdt_len_included, tvb, offset, 1, ENC_BIG_ENDIAN);
440 proto_tree_add_item(flags_tree1, hf_rdt_data_need_reliable, tvb, offset, 1, ENC_BIG_ENDIAN);
441 proto_tree_add_item(flags_tree1, hf_rdt_data_stream_id, tvb, offset, 1, ENC_BIG_ENDIAN);
442 proto_tree_add_item(flags_tree1, hf_rdt_data_is_reliable, tvb, offset, 1, ENC_BIG_ENDIAN);
447 /* Sequence number */
448 sequence_number = tvb_get_ntohs(tvb, offset);
449 proto_tree_add_item(tree, hf_rdt_sequence_number, tvb, offset, 2, ENC_BIG_ENDIAN);
452 /* Length field is optional */
453 if (length_included_flag)
455 packet_length = tvb_get_ntohs(tvb, offset);
456 proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, ENC_BIG_ENDIAN);
459 /* Check that there are as many bytes as reported */
460 tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
464 packet_length = tvb_length_remaining(tvb, start_offset);
468 flags2 = tvb_get_guint8(tvb, offset);
469 back_to_back = (flags2 & 0x80) >> 7;
470 slow_data = (flags2 & 0x40) >> 6;
471 asm_rule_number = flags2 & 0x3f;
474 /* Create subtree for flags2 fields */
477 ti = proto_tree_add_string_format(tree, hf_rdt_data_flags2, tvb, offset, 1,
479 "Back-to-back=%u, slow-data=%u, asm-rule=%u",
484 /* Create subtree for flags and add fields */
485 flags_tree2 = proto_item_add_subtree(ti, ett_rdt_data_flags2);
487 proto_tree_add_item(flags_tree2, hf_rdt_data_backtoback, tvb, offset, 1, ENC_BIG_ENDIAN);
488 proto_tree_add_item(flags_tree2, hf_rdt_data_slowdata, tvb, offset, 1, ENC_BIG_ENDIAN);
489 proto_tree_add_item(flags_tree2, hf_rdt_data_asmrule, tvb, offset, 1, ENC_BIG_ENDIAN);
494 timestamp = tvb_get_ntohl(tvb, offset);
495 proto_tree_add_item(tree, hf_rdt_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
498 /* Stream ID expansion */
501 stream_id = tvb_get_ntohs(tvb, offset);
502 proto_tree_add_item(tree, hf_rdt_stream_id_ex, tvb, offset, 2, ENC_BIG_ENDIAN);
507 if (need_reliable_flag)
509 proto_tree_add_item(tree, hf_rdt_total_reliable, tvb, offset, 2, ENC_BIG_ENDIAN);
513 /* Asm rule number */
514 if (asm_rule_number == 63)
516 asm_rule_number = tvb_get_ntohs(tvb, offset);
517 proto_tree_add_item(tree, hf_rdt_asmrule_ex, tvb, offset, 2, ENC_BIG_ENDIAN);
521 col_append_fstr(pinfo->cinfo, COL_INFO,
522 "DATA: stream-id=%02u asm-rule=%02u seq=%05u ts=%05u ",
523 stream_id, asm_rule_number, sequence_number, timestamp);
525 /* The remaining data is unparsed. */
526 proto_tree_add_item(tree, hf_rdt_data, tvb, offset, -1, ENC_NA);
527 offset += tvb_length_remaining(tvb, offset);
529 if (packet_length < (offset - start_offset) ||
530 packet_length > tvb_length_remaining(tvb, start_offset))
532 proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
533 packet_length = tvb_length_remaining(tvb, start_offset);
536 return start_offset + packet_length;
539 /* Dissect an asm-action packet */
540 guint dissect_rdt_asm_action_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
542 guint start_offset = offset;
543 guint16 packet_length;
545 guint8 length_included_flag;
548 proto_tree *flags_tree;
551 /* Flags in first byte */
552 flags1 = tvb_get_guint8(tvb, offset);
553 length_included_flag = (flags1 & 0x80) >> 7;
554 stream_id = (flags1 & 0x7c) >> 2;
556 /* Create subtree for flags fields */
559 proto_tree_add_item(tree, proto_rdt, tvb, offset, -1, ENC_NA);
560 ti = proto_tree_add_string_format(tree, hf_rdt_aact_flags, tvb, offset, 1,
562 "Length-included=%u, stream_id=%u",
563 length_included_flag,
565 flags_tree = proto_item_add_subtree(ti, ett_rdt_aact_flags);
567 proto_tree_add_item(flags_tree, hf_rdt_len_included, tvb, offset, 1, ENC_BIG_ENDIAN);
568 proto_tree_add_item(flags_tree, hf_rdt_aact_stream_id, tvb, offset, 1, ENC_BIG_ENDIAN);
573 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
576 rel_seqno = tvb_get_ntohs(tvb, offset);
577 proto_tree_add_item(tree, hf_rdt_aact_reliable_seqno, tvb, offset, 2, ENC_BIG_ENDIAN);
580 /* Length field is optional */
581 if (length_included_flag)
583 packet_length = tvb_get_ntohs(tvb, offset);
584 proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, ENC_BIG_ENDIAN);
587 /* Check that there are as many bytes as reported */
588 tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
592 packet_length = tvb_length_remaining(tvb, start_offset);
595 /* Stream ID expansion */
598 stream_id = tvb_get_ntohs(tvb, offset);
599 proto_tree_add_item(tree, hf_rdt_stream_id_ex, tvb, offset, 2, ENC_BIG_ENDIAN);
603 col_append_fstr(pinfo->cinfo, COL_INFO,
604 "ASM-ACTION: stream-id=%02u rel-seqno=%05u ",
605 stream_id, rel_seqno);
607 /* The remaining data is unparsed. */
608 proto_tree_add_item(tree, hf_rdt_data, tvb, offset, -1, ENC_NA);
610 if (packet_length < (offset - start_offset) ||
611 packet_length > tvb_length_remaining(tvb, start_offset))
613 proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
614 packet_length = tvb_length_remaining(tvb, start_offset);
617 return start_offset + packet_length;
620 /* Dissect an bandwidth-report packet */
621 guint dissect_rdt_bandwidth_report_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
623 guint start_offset = offset;
624 guint16 packet_length;
626 guint8 length_included_flag;
627 proto_tree *flags_tree;
630 /* Flags in first byte */
631 flags1 = tvb_get_guint8(tvb, offset);
632 length_included_flag = (flags1 & 0x80) >> 7;
634 /* Create subtree for flags fields */
637 ti = proto_tree_add_string_format(tree, hf_rdt_bandwidth_report_flags, tvb, offset, 1,
639 "Length-included=%u",
640 length_included_flag);
641 flags_tree = proto_item_add_subtree(ti, ett_rdt_bandwidth_report_flags);
643 proto_tree_add_item(flags_tree, hf_rdt_len_included, tvb, offset, 1, ENC_BIG_ENDIAN);
648 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
651 /* Length field is optional */
652 if (length_included_flag)
654 packet_length = tvb_get_ntohs(tvb, offset);
655 proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, ENC_BIG_ENDIAN);
658 /* Check that there are as many bytes as reported */
659 tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
663 packet_length = tvb_length_remaining(tvb, start_offset);
666 proto_tree_add_item(tree, hf_rdt_brpt_interval, tvb, offset, 2, ENC_BIG_ENDIAN);
668 proto_tree_add_item(tree, hf_rdt_brpt_bandwidth, tvb, offset, 4, ENC_BIG_ENDIAN);
670 proto_tree_add_item(tree, hf_rdt_brpt_sequence, tvb, offset, 1, ENC_BIG_ENDIAN);
673 col_append_str(pinfo->cinfo, COL_INFO, "BANDWIDTH-REPORT: ");
675 if (packet_length < (offset - start_offset) ||
676 packet_length > tvb_length_remaining(tvb, start_offset))
678 proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
679 packet_length = tvb_length_remaining(tvb, start_offset);
682 return start_offset + packet_length;
685 /* Dissect an ack packet */
686 guint dissect_rdt_ack_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
688 guint start_offset = offset;
689 guint16 packet_length;
691 guint8 length_included_flag;
692 guint8 lost_high_flag;
693 proto_tree *flags_tree;
696 /* Flags in first byte */
697 flags1 = tvb_get_guint8(tvb, offset);
698 length_included_flag = (flags1 & 0x80) >> 7;
699 lost_high_flag = (flags1 & 0x40) >> 6;
701 /* Create subtree for flags fields */
704 ti = proto_tree_add_string_format(tree, hf_rdt_ack_flags, tvb, offset, 1,
706 "Length-included=%u, lost-high=%u",
707 length_included_flag,
709 flags_tree = proto_item_add_subtree(ti, ett_rdt_ack_flags);
711 proto_tree_add_item(flags_tree, hf_rdt_len_included, tvb, offset, 1, ENC_BIG_ENDIAN);
712 proto_tree_add_item(flags_tree, hf_rdt_ack_lost_high, tvb, offset, 1, ENC_BIG_ENDIAN);
717 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
720 /* Length field is optional */
721 if (length_included_flag)
723 packet_length = tvb_get_ntohs(tvb, offset);
724 proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, ENC_BIG_ENDIAN);
727 /* Check that there are as many bytes as reported */
728 tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
732 packet_length = tvb_length_remaining(tvb, start_offset);
735 /* XXX: The remaining data is unparsed. */
736 proto_tree_add_item(tree, hf_rdt_data, tvb, offset, -1, ENC_NA);
738 col_append_fstr(pinfo->cinfo, COL_INFO, "ACK: lh=%u ", lost_high_flag);
740 if (packet_length < (offset - start_offset) ||
741 packet_length > tvb_length_remaining(tvb, start_offset))
743 proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
744 packet_length = tvb_length_remaining(tvb, start_offset);
747 return start_offset + packet_length;
750 /* Dissect an att-request packet */
751 guint dissect_rdt_rtt_request_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
753 /* Flags in first byte */
757 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
760 col_append_str(pinfo->cinfo, COL_INFO, "RTT-REQUEST: ");
765 /* Dissect an att-response packet */
766 guint dissect_rdt_rtt_response_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
768 /* Flags in first byte */
772 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
775 proto_tree_add_item(tree, hf_rdt_rtrp_ts_sec, tvb, offset, 4, ENC_BIG_ENDIAN);
777 proto_tree_add_item(tree, hf_rdt_rtrp_ts_usec, tvb, offset, 4, ENC_BIG_ENDIAN);
780 col_append_str(pinfo->cinfo, COL_INFO, "RTT-RESPONSE: ");
785 /* Dissect an congestion packet */
786 guint dissect_rdt_congestion_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
788 /* Flags in first byte */
792 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
795 proto_tree_add_item(tree, hf_rdt_cong_xmit_mult, tvb, offset, 4, ENC_BIG_ENDIAN);
797 proto_tree_add_item(tree, hf_rdt_cong_recv_mult, tvb, offset, 4, ENC_BIG_ENDIAN);
800 col_append_str(pinfo->cinfo, COL_INFO, "CONGESTION: ");
805 /* Dissect an stream-end packet */
806 guint dissect_rdt_stream_end_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
809 guint8 need_reliable;
813 proto_tree *flags_tree;
816 /* Flags in first byte */
817 flags1 = tvb_get_guint8(tvb, offset);
818 need_reliable = (flags1 & 0x80) >> 7;
819 stream_id = (flags1 & 0x7c) >> 2;
820 packet_sent = (flags1 & 0x2) >> 1;
821 ext_flag = flags1 & 0x1;
823 /* Create subtree for flags fields */
826 ti = proto_tree_add_string_format(tree, hf_rdt_stre_flags, tvb, offset, 1,
828 "Need-reliable=%u, stream-id=%u, packet-sent=%u, ext-flag=%u",
833 flags_tree = proto_item_add_subtree(ti, ett_rdt_stre_flags);
835 proto_tree_add_item(flags_tree, hf_rdt_stre_need_reliable, tvb, offset, 1, ENC_BIG_ENDIAN);
836 proto_tree_add_item(flags_tree, hf_rdt_stre_stream_id, tvb, offset, 1, ENC_BIG_ENDIAN);
837 proto_tree_add_item(flags_tree, hf_rdt_stre_packet_sent, tvb, offset, 1, ENC_BIG_ENDIAN);
838 proto_tree_add_item(flags_tree, hf_rdt_stre_ext_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
843 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
846 proto_tree_add_item(tree, hf_rdt_stre_seqno, tvb, offset, 2, ENC_BIG_ENDIAN);
848 proto_tree_add_item(tree, hf_rdt_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
851 /* Stream ID expansion */
854 stream_id = tvb_get_ntohs(tvb, offset);
855 proto_tree_add_item(tree, hf_rdt_stream_id_ex, tvb, offset, 2, ENC_BIG_ENDIAN);
862 proto_tree_add_item(tree, hf_rdt_total_reliable, tvb, offset, 2, ENC_BIG_ENDIAN);
868 proto_tree_add_item(tree, hf_rdt_stre_dummy_flags1, tvb, offset, 1, ENC_BIG_ENDIAN);
870 proto_tree_add_item(tree, hf_rdt_stre_dummy_type, tvb, offset, 2, ENC_BIG_ENDIAN);
872 proto_tree_add_item(tree, hf_rdt_stre_reason_code, tvb, offset, 4, ENC_BIG_ENDIAN);
874 /* XXX: Remainder is reason_text */
875 offset += tvb_length_remaining(tvb, offset);
878 col_append_fstr(pinfo->cinfo, COL_INFO, "STREAM-END: stream-id=%02u ", stream_id);
883 /* Dissect an report packet */
884 guint dissect_rdt_report_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
886 guint start_offset = offset;
887 guint16 packet_length;
889 guint8 length_included_flag;
890 proto_tree *flags_tree;
893 /* Flags in first byte */
894 flags1 = tvb_get_guint8(tvb, offset);
895 length_included_flag = (flags1 & 0x80) >> 7;
897 /* Create subtree for flags fields */
900 ti = proto_tree_add_string_format(tree, hf_rdt_report_flags, tvb, offset, 1,
902 "Length-included=%u",
903 length_included_flag);
904 flags_tree = proto_item_add_subtree(ti, ett_rdt_report_flags);
906 proto_tree_add_item(flags_tree, hf_rdt_len_included, tvb, offset, 1, ENC_BIG_ENDIAN);
911 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
914 /* Length field is optional */
915 if (length_included_flag)
917 packet_length = tvb_get_ntohs(tvb, offset);
918 proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, ENC_BIG_ENDIAN);
921 /* Check that there are as many bytes as reported */
922 tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
926 packet_length = tvb_length_remaining(tvb, start_offset);
929 col_append_str(pinfo->cinfo, COL_INFO, "REPORT: ");
931 /* The remaining data is unparsed. */
932 proto_tree_add_item(tree, hf_rdt_data, tvb, offset, -1, ENC_NA);
934 if (packet_length < (offset - start_offset) ||
935 packet_length > tvb_length_remaining(tvb, start_offset))
937 proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
938 packet_length = tvb_length_remaining(tvb, start_offset);
941 return start_offset + packet_length;
944 /* Dissect an latency-report packet */
945 guint dissect_rdt_latency_report_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
947 guint start_offset = offset;
948 guint16 packet_length;
950 guint8 length_included_flag;
951 guint32 server_out_time;
952 proto_tree *flags_tree;
955 /* Flags in first byte */
956 flags1 = tvb_get_guint8(tvb, offset);
957 length_included_flag = (flags1 & 0x80) >> 7;
959 /* Create subtree for flags fields */
962 ti = proto_tree_add_string_format(tree, hf_rdt_latency_report_flags, tvb, offset, 1,
964 "Length-included=%u",
965 length_included_flag);
966 flags_tree = proto_item_add_subtree(ti, ett_rdt_latency_report_flags);
968 proto_tree_add_item(flags_tree, hf_rdt_len_included, tvb, offset, 1, ENC_BIG_ENDIAN);
973 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
976 /* Length field is optional */
977 if (length_included_flag)
979 packet_length = tvb_get_ntohs(tvb, offset);
980 proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, ENC_BIG_ENDIAN);
983 /* Check that there are as many bytes as reported */
984 tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
988 packet_length = tvb_length_remaining(tvb, start_offset);
991 server_out_time = tvb_get_ntohl(tvb, offset);
992 proto_tree_add_item(tree, hf_rdt_lrpt_server_out_time, tvb, offset, 4, ENC_BIG_ENDIAN);
995 col_append_fstr(pinfo->cinfo, COL_INFO, "LATENCY-REPORT: t=%u ", server_out_time);
997 if (packet_length < (offset - start_offset) ||
998 packet_length > tvb_length_remaining(tvb, start_offset))
1000 proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
1001 packet_length = tvb_length_remaining(tvb, start_offset);
1004 return start_offset + packet_length;
1007 /* Dissect a transport-info packet */
1008 guint dissect_rdt_transport_info_request_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
1011 guint8 request_rtt_info_flag;
1012 guint8 request_buffer_info_flag;
1013 proto_tree *flags_tree;
1016 /* Flags in first byte */
1017 flags1 = tvb_get_guint8(tvb, offset);
1018 request_rtt_info_flag = (flags1 & 0x2) >> 1;
1019 request_buffer_info_flag = (flags1 & 0x01);
1021 /* Create subtree for flags fields */
1024 ti = proto_tree_add_string_format(tree, hf_rdt_ack_flags, tvb, offset, 1,
1026 "Request-rtt-info=%u, request-buffer-info=%u",
1027 request_rtt_info_flag,
1028 request_buffer_info_flag);
1029 flags_tree = proto_item_add_subtree(ti, ett_rdt_tirq_flags);
1031 proto_tree_add_item(flags_tree, hf_rdt_tirq_request_rtt_info, tvb, offset, 1, ENC_BIG_ENDIAN);
1032 proto_tree_add_item(flags_tree, hf_rdt_tirq_request_buffer_info, tvb, offset, 1, ENC_BIG_ENDIAN);
1037 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
1040 if (request_rtt_info_flag)
1042 proto_tree_add_item(tree, hf_rdt_tirq_request_time_msec, tvb, offset, 4, ENC_BIG_ENDIAN);
1046 col_append_str(pinfo->cinfo, COL_INFO, "TRANSPORT-INFO-REQUEST: ");
1051 /* Dissect an transport-info-response packet */
1052 guint dissect_rdt_transport_info_response_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
1055 guint8 has_rtt_info;
1057 guint8 has_buffer_info;
1058 proto_tree *flags_tree;
1061 /* Flags in first byte */
1062 flags1 = tvb_get_guint8(tvb, offset);
1063 has_rtt_info = (flags1 & 0x4) >> 2;
1064 is_delayed = (flags1 & 0x2) >> 1;
1065 has_buffer_info = (flags1 & 0x1);
1067 /* Create subtree for flags fields */
1070 ti = proto_tree_add_string_format(tree, hf_rdt_tirp_flags, tvb, offset, 1,
1072 "Has-rtt-info=%u, is-delayed=%u, has-buffer-info=%u",
1076 flags_tree = proto_item_add_subtree(ti, ett_rdt_tirp_flags);
1078 proto_tree_add_item(flags_tree, hf_rdt_tirp_has_rtt_info, tvb, offset, 1, ENC_BIG_ENDIAN);
1079 proto_tree_add_item(flags_tree, hf_rdt_tirp_is_delayed, tvb, offset, 1, ENC_BIG_ENDIAN);
1080 proto_tree_add_item(flags_tree, hf_rdt_tirp_has_buffer_info, tvb, offset, 1, ENC_BIG_ENDIAN);
1085 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
1091 proto_tree_add_item(tree, hf_rdt_tirp_request_time_msec, tvb, offset, 4, ENC_BIG_ENDIAN);
1096 proto_tree_add_item(tree, hf_rdt_tirp_response_time_msec, tvb, offset, 4, ENC_BIG_ENDIAN);
1102 if (has_buffer_info)
1106 /* Read number of buffers */
1107 guint16 buffer_info_count = tvb_get_ntohs(tvb, offset);
1108 proto_tree_add_item(tree, hf_rdt_tirp_buffer_info_count, tvb, offset, 2, ENC_BIG_ENDIAN);
1111 for (n=0; n < buffer_info_count; n++)
1113 proto_tree *buffer_info_tree;
1116 /* Each buffer info in a new subtree */
1117 ti2 = proto_tree_add_string_format(tree, hf_rdt_tirp_buffer_info, tvb, offset, 14,
1121 buffer_info_tree = proto_item_add_subtree(ti2, ett_rdt_tirp_buffer_info);
1123 /* Read individual buffer info */
1124 proto_tree_add_item(buffer_info_tree, hf_rdt_tirp_buffer_info_stream_id, tvb, offset, 2, ENC_BIG_ENDIAN);
1126 proto_tree_add_item(buffer_info_tree, hf_rdt_tirp_buffer_info_lowest_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
1128 proto_tree_add_item(buffer_info_tree, hf_rdt_tirp_buffer_info_highest_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
1130 proto_tree_add_item(buffer_info_tree, hf_rdt_tirp_buffer_info_bytes_buffered, tvb, offset, 4, ENC_BIG_ENDIAN);
1135 /* Report what is left */
1136 offset += tvb_length_remaining(tvb, offset);
1138 col_append_str(pinfo->cinfo, COL_INFO, "RESPONSE: ");
1143 /* Dissect a bw-probing packet */
1144 guint dissect_rdt_bw_probing_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
1146 guint start_offset = offset;
1147 guint16 packet_length;
1149 guint8 length_included_flag;
1150 proto_tree *flags_tree;
1153 /* Flags in first byte */
1154 flags1 = tvb_get_guint8(tvb, offset);
1155 length_included_flag = (flags1 & 0x80) >> 7;
1157 /* Create subtree for flags fields */
1160 ti = proto_tree_add_string_format(tree, hf_rdt_bw_probing_flags, tvb, offset, 1,
1162 "Length-included=%u",
1163 length_included_flag);
1164 flags_tree = proto_item_add_subtree(ti, ett_rdt_bw_probing_flags);
1166 proto_tree_add_item(flags_tree, hf_rdt_len_included, tvb, offset, 1, ENC_BIG_ENDIAN);
1171 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
1174 /* Length field is optional */
1175 if (length_included_flag)
1177 packet_length = tvb_get_ntohs(tvb, offset);
1178 proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, ENC_BIG_ENDIAN);
1181 /* Check that there are as many bytes as reported */
1182 tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
1186 packet_length = tvb_length_remaining(tvb, start_offset);
1189 proto_tree_add_item(tree, hf_rdt_bwpp_seqno, tvb, offset, 1, ENC_BIG_ENDIAN);
1191 proto_tree_add_item(tree, hf_rdt_timestamp, tvb, offset, 1, ENC_BIG_ENDIAN);
1194 col_append_str(pinfo->cinfo, COL_INFO, "BW-PROBING: ");
1196 if (packet_length < (offset - start_offset) ||
1197 packet_length > tvb_length_remaining(tvb, start_offset))
1199 proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
1200 packet_length = tvb_length_remaining(tvb, start_offset);
1203 return start_offset + packet_length;
1206 /* Dissect an unknown control packet */
1207 guint dissect_rdt_unknown_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
1209 /* Flags in first byte */
1210 proto_tree_add_item(tree, hf_rdt_unk_flags1, tvb, offset, 1, ENC_BIG_ENDIAN);
1214 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, ENC_BIG_ENDIAN);
1217 /* The remaining data is unparsed. */
1218 proto_tree_add_item(tree, hf_rdt_data, tvb, offset, -1, ENC_NA);
1219 offset += tvb_length_remaining(tvb, offset);
1221 col_append_str(pinfo->cinfo, COL_INFO, "UNKNOWN-CTL: ");
1226 /* Look for conversation info and display any setup info found */
1227 static void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1229 /* Conversation and current data */
1230 conversation_t *p_conv;
1231 struct _rdt_conversation_info *p_conv_data;
1233 /* Use existing packet info if available */
1234 p_conv_data = (struct _rdt_conversation_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_rdt, 0);
1238 /* First time, get info from conversation */
1239 p_conv = find_conversation(pinfo->fd->num, &pinfo->net_dst, &pinfo->net_src,
1241 pinfo->destport, pinfo->srcport, NO_ADDR_B);
1244 /* Create space for conversation info */
1245 struct _rdt_conversation_info *p_conv_packet_data;
1246 p_conv_data = (struct _rdt_conversation_info *)conversation_get_proto_data(p_conv, proto_rdt);
1250 /* Save this conversation info into packet info */
1251 p_conv_packet_data = wmem_new(wmem_file_scope(), struct _rdt_conversation_info);
1252 g_strlcpy(p_conv_packet_data->method, p_conv_data->method, MAX_RDT_SETUP_METHOD_SIZE);
1253 p_conv_packet_data->frame_number = p_conv_data->frame_number;
1254 p_conv_packet_data->feature_level = p_conv_data->feature_level;
1255 p_add_proto_data(wmem_file_scope(), pinfo, proto_rdt, 0, p_conv_packet_data);
1260 /* Create setup info subtree with summary info. */
1263 proto_tree *rdt_setup_tree;
1264 proto_item *ti = proto_tree_add_string_format(tree, hf_rdt_setup, tvb, 0, 0,
1266 "Stream setup by %s (frame %u), feature level %d",
1267 p_conv_data->method,
1268 p_conv_data->frame_number,
1269 p_conv_data->feature_level);
1270 PROTO_ITEM_SET_GENERATED(ti);
1271 rdt_setup_tree = proto_item_add_subtree(ti, ett_rdt_setup);
1274 /* Add details into subtree */
1275 proto_item* item = proto_tree_add_uint(rdt_setup_tree, hf_rdt_setup_frame,
1276 tvb, 0, 0, p_conv_data->frame_number);
1277 PROTO_ITEM_SET_GENERATED(item);
1278 item = proto_tree_add_string(rdt_setup_tree, hf_rdt_setup_method,
1279 tvb, 0, 0, p_conv_data->method);
1280 PROTO_ITEM_SET_GENERATED(item);
1281 item = proto_tree_add_int(rdt_setup_tree, hf_rdt_feature_level,
1282 tvb, 0, 0, p_conv_data->feature_level);
1283 PROTO_ITEM_SET_GENERATED(item);
1289 void proto_register_rdt(void)
1291 static hf_register_info hf[] =
1306 &hf_rdt_data_flags1,
1318 &hf_rdt_len_included,
1321 "rdt.length-included",
1330 &hf_rdt_data_need_reliable,
1333 "rdt.need-reliable",
1342 &hf_rdt_data_stream_id,
1354 &hf_rdt_data_is_reliable,
1366 &hf_rdt_data_flags2,
1374 "RDT data flags2", HFILL
1378 &hf_rdt_data_backtoback,
1390 &hf_rdt_data_slowdata,
1402 &hf_rdt_data_asmrule,
1416 "RDT asm-action flags 1",
1422 "RDT aact flags", HFILL
1426 &hf_rdt_aact_stream_id,
1438 &hf_rdt_sequence_number,
1441 "rdt.sequence-number",
1450 &hf_rdt_packet_type,
1456 VALS(packet_type_vals),
1474 &hf_rdt_ack_lost_high,
1486 &hf_rdt_latency_report_flags,
1488 "RDT latency report flags",
1489 "rdt.latency-report-flags",
1498 &hf_rdt_bandwidth_report_flags,
1500 "RDT bandwidth report flags",
1501 "rdt.bandwidth-report-flags",
1512 "RDT stream end flags",
1513 "rdt.stream-end-flags",
1523 &hf_rdt_rtt_request_flags,
1525 "RDT rtt request flags",
1526 "rdt.rtt-request-flags",
1537 &hf_rdt_rtt_response_flags,
1539 "RDT rtt response flags",
1540 "rdt.rtt-response-flags",
1551 &hf_rdt_congestion_flags,
1553 "RDT congestion flags",
1554 "rdt.congestion-flags",
1564 &hf_rdt_report_flags,
1579 "RDT transport info request flags",
1580 "rdt.transport-info-request-flags",
1592 "RDT transport info response flags",
1593 "rdt.transport-info-response-flags",
1602 &hf_rdt_bw_probing_flags,
1604 "RDT bw probing flags",
1605 "rdt.bw-probing-flags",
1614 &hf_rdt_packet_length,
1617 "rdt.packet-length",
1638 &hf_rdt_stream_id_ex,
1640 "Stream-id expansion",
1641 "rdt.stream-id-expansion",
1652 "Asm rule expansion",
1653 "rdt.asm-rule-expansion",
1662 &hf_rdt_total_reliable,
1665 "rdt.total-reliable",
1686 &hf_rdt_aact_reliable_seqno,
1688 "Reliable sequence number",
1689 "rdt.reliable-seq-no",
1698 &hf_rdt_brpt_interval,
1700 "Bandwidth report interval",
1701 "rdt.bwid-report-interval",
1710 &hf_rdt_brpt_bandwidth,
1712 "Bandwidth report bandwidth",
1713 "rdt.bwid-report-bandwidth",
1722 &hf_rdt_brpt_sequence,
1724 "Bandwidth report sequence",
1725 "rdt.bwid-report-sequence",
1734 &hf_rdt_rtrp_ts_sec,
1736 "Round trip response timestamp seconds",
1746 &hf_rdt_rtrp_ts_usec,
1748 "Round trip response timestamp microseconds",
1758 &hf_rdt_cong_xmit_mult,
1760 "Congestion transmit multiplier",
1761 "rdt.cong-xmit-mult",
1770 &hf_rdt_cong_recv_mult,
1772 "Congestion receive multiplier",
1773 "rdt.cong-recv-mult",
1782 &hf_rdt_stre_need_reliable,
1785 "rdt.stre-need-reliable",
1794 &hf_rdt_stre_stream_id,
1797 "rdt.stre-stream-id",
1806 &hf_rdt_stre_packet_sent,
1809 "rdt.stre-packet-sent",
1818 &hf_rdt_stre_ext_flag,
1821 "rdt.stre-ext-flag",
1833 "Stream end sequence number",
1843 &hf_rdt_stre_dummy_flags1,
1845 "Stream end reason dummy flags1",
1846 "rdt.stre-reason-dummy-flags1",
1855 &hf_rdt_stre_dummy_type,
1857 "Stream end reason dummy type",
1858 "rdt.stre-reason-dummy-type",
1867 &hf_rdt_stre_reason_code,
1869 "Stream end reason code",
1870 "rdt.stre-reason-code",
1879 &hf_rdt_lrpt_server_out_time,
1881 "Latency report server out time",
1882 "rdt.lrpt-server-out-time",
1891 &hf_rdt_tirq_request_rtt_info,
1893 "Transport info request rtt info flag",
1894 "rdt.tirq-request-rtt-info",
1903 &hf_rdt_tirq_request_buffer_info,
1905 "Transport info request buffer info flag",
1906 "rdt.tirq-request-buffer-info",
1915 &hf_rdt_tirq_request_time_msec,
1917 "Transport info request time msec",
1918 "rdt.tirq-request-time-msec",
1927 &hf_rdt_tirp_has_rtt_info,
1929 "Transport info response has rtt info flag",
1930 "rdt.tirp-has-rtt-info",
1939 &hf_rdt_tirp_is_delayed,
1941 "Transport info response is delayed",
1942 "rdt.tirp-is-delayed",
1951 &hf_rdt_tirp_has_buffer_info,
1953 "Transport info response has buffer info",
1954 "rdt.tirp-has-buffer-info",
1963 &hf_rdt_tirp_request_time_msec,
1965 "Transport info request time msec",
1966 "rdt.tirp-request-time-msec",
1975 &hf_rdt_tirp_response_time_msec,
1977 "Transport info response time msec",
1978 "rdt.tirp-response-time-msec",
1987 &hf_rdt_tirp_buffer_info_count,
1989 "Transport info buffer into count",
1990 "rdt.tirp-buffer-info-count",
1999 &hf_rdt_tirp_buffer_info,
2002 "rdt.tirp-buffer-info",
2011 &hf_rdt_tirp_buffer_info_stream_id,
2013 "Buffer info stream-id",
2014 "rdt.tirp-buffer-info-stream-id",
2023 &hf_rdt_tirp_buffer_info_lowest_timestamp,
2026 "rdt.tirp-buffer-info-lowest-timestamp",
2035 &hf_rdt_tirp_buffer_info_highest_timestamp,
2037 "Highest timestamp",
2038 "rdt.tirp-buffer-info-highest-timestamp",
2047 &hf_rdt_tirp_buffer_info_bytes_buffered,
2050 "rdt.tirp-buffer-info-bytes-buffered",
2061 "Bandwidth probing packet seqno",
2073 "Unknown packet flags",
2091 "Stream setup, method and frame number", HFILL
2095 &hf_rdt_setup_frame,
2103 "Frame that set up this stream", HFILL
2107 &hf_rdt_setup_method,
2115 "Method used to set up this stream", HFILL
2119 &hf_rdt_feature_level,
2121 "RDT feature level",
2122 "rdt.feature-level",
2132 static gint *ett[] =
2137 &ett_rdt_data_flags1,
2138 &ett_rdt_data_flags2,
2139 &ett_rdt_aact_flags,
2141 &ett_rdt_latency_report_flags,
2142 &ett_rdt_bandwidth_report_flags,
2143 &ett_rdt_stre_flags,
2144 &ett_rdt_rtt_request_flags,
2145 &ett_rdt_rtt_response_flags,
2146 &ett_rdt_congestion_flags,
2147 &ett_rdt_report_flags,
2148 &ett_rdt_tirq_flags,
2149 &ett_rdt_tirp_flags,
2150 &ett_rdt_tirp_buffer_info,
2151 &ett_rdt_bw_probing_flags
2154 module_t *rdt_module;
2156 /* Register protocol and fields */
2157 proto_rdt = proto_register_protocol("Real Data Transport", "RDT", "rdt");
2158 proto_register_field_array(proto_rdt, hf, array_length(hf));
2159 proto_register_subtree_array(ett, array_length(ett));
2160 register_dissector("rdt", dissect_rdt, proto_rdt);
2162 /* Preference settings */
2163 rdt_module = prefs_register_protocol(proto_rdt, proto_reg_handoff_rdt);
2164 prefs_register_bool_preference(rdt_module, "show_setup_info",
2165 "Show stream setup information",
2166 "Where available, show which protocol and frame caused "
2167 "this RDT stream to be created",
2168 &global_rdt_show_setup_info);
2170 prefs_register_bool_preference(rdt_module, "register_udp_port",
2171 "Register default UDP client port",
2172 "Register a client UDP port for RDT traffic",
2173 &global_rdt_register_udp_port);
2175 /* TODO: better to specify a range of ports instead? */
2176 prefs_register_uint_preference(rdt_module, "default_udp_port",
2177 "Default UDP client port",
2178 "Set the UDP port for clients",
2179 10, &global_rdt_udp_port);
2183 void proto_reg_handoff_rdt(void)
2185 static gboolean rdt_prefs_initialized = FALSE;
2186 /* Also store this so can delete registered setting properly */
2187 static gboolean rdt_register_udp_port;
2188 static guint rdt_udp_port;
2190 if (!rdt_prefs_initialized)
2192 /* Register this dissector as one that can be selected by a
2194 rdt_handle = find_dissector("rdt");
2195 dissector_add_handle("udp.port", rdt_handle);
2196 rdt_prefs_initialized = TRUE;
2200 /* Undo any current port registrations */
2201 if (rdt_register_udp_port)
2203 dissector_delete_uint("udp.port", rdt_udp_port, rdt_handle);
2207 /* Remember whether a port is set for next time */
2208 rdt_register_udp_port = global_rdt_register_udp_port;
2210 /* Add any new port registration */
2211 if (global_rdt_register_udp_port)
2213 /* Set our port number for future use */
2214 rdt_udp_port = global_rdt_udp_port;
2216 /* And register with this port */
2217 dissector_add_uint("udp.port", global_rdt_udp_port, rdt_handle);