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
39 #include <epan/packet.h>
40 #include <epan/conversation.h>
41 #include <epan/prefs.h>
42 #include <epan/strutil.h>
43 #include <epan/wmem/wmem.h>
45 #include "packet-rdt.h"
47 static dissector_handle_t rdt_handle
;
49 static gint proto_rdt
= -1;
52 static gint hf_rdt_packet
= -1;
55 static gint hf_rdt_len_included
= -1;
57 /* flags1: data packet */
58 static gint hf_rdt_data_flags1
= -1;
59 static gint hf_rdt_data_need_reliable
= -1;
60 static gint hf_rdt_data_stream_id
= -1;
61 static gint hf_rdt_data_is_reliable
= -1;
63 /* flags2: data packet */
64 static gint hf_rdt_data_flags2
= -1;
65 static gint hf_rdt_data_backtoback
= -1;
66 static gint hf_rdt_data_slowdata
= -1;
67 static gint hf_rdt_data_asmrule
= -1;
69 /* flags1: asm action packet */
70 static gint hf_rdt_aact_flags
= -1;
71 static gint hf_rdt_aact_stream_id
= -1;
73 /* flags1: ack packet */
74 static gint hf_rdt_ack_flags
= -1;
75 static gint hf_rdt_ack_lost_high
= -1;
77 /* flags1: latency report packet */
78 static gint hf_rdt_latency_report_flags
= -1;
80 /* flags1: bandwidth report packet */
81 static gint hf_rdt_bandwidth_report_flags
= -1;
83 /* flags1: stream end packet */
84 static gint hf_rdt_stre_flags
= -1;
85 static gint hf_rdt_stre_need_reliable
= -1;
86 static gint hf_rdt_stre_stream_id
= -1;
87 static gint hf_rdt_stre_packet_sent
= -1;
88 static gint hf_rdt_stre_ext_flag
= -1;
90 /* static gint hf_rdt_rtt_request_flags = -1; */
91 /* static gint hf_rdt_rtt_response_flags = -1; */
92 /* static gint hf_rdt_congestion_flags = -1; */
93 static gint hf_rdt_report_flags
= -1;
94 /* static gint hf_rdt_tirq_flags = -1; */
95 static gint hf_rdt_tirp_flags
= -1;
96 static gint hf_rdt_bw_probing_flags
= -1;
98 /* Octets 1-2: sequence number or packet type */
99 static gint hf_rdt_sequence_number
= -1;
100 static gint hf_rdt_packet_type
= -1;
102 /* Only present if length_included */
103 static gint hf_rdt_packet_length
= -1;
105 /* General shared fields */
106 static gint hf_rdt_timestamp
= -1;
107 static gint hf_rdt_stream_id_ex
= -1;
108 static gint hf_rdt_asmrule_ex
= -1;
109 static gint hf_rdt_total_reliable
= -1;
110 static gint hf_rdt_data
= -1;
112 /* Special use fields */
113 static gint hf_rdt_aact_reliable_seqno
= -1;
114 static gint hf_rdt_brpt_interval
= -1;
115 static gint hf_rdt_brpt_bandwidth
= -1;
116 static gint hf_rdt_brpt_sequence
= -1;
117 static gint hf_rdt_rtrp_ts_sec
= -1;
118 static gint hf_rdt_rtrp_ts_usec
= -1;
119 static gint hf_rdt_cong_xmit_mult
= -1;
120 static gint hf_rdt_cong_recv_mult
= -1;
121 static gint hf_rdt_stre_seqno
= -1;
122 static gint hf_rdt_stre_dummy_flags1
= -1;
123 static gint hf_rdt_stre_dummy_type
= -1;
124 static gint hf_rdt_stre_reason_code
= -1;
125 static gint hf_rdt_lrpt_server_out_time
= -1;
126 static gint hf_rdt_tirq_request_rtt_info
= -1;
127 static gint hf_rdt_tirq_request_buffer_info
= -1;
128 static gint hf_rdt_tirq_request_time_msec
= -1;
129 static gint hf_rdt_tirp_has_rtt_info
= -1;
130 static gint hf_rdt_tirp_is_delayed
= -1;
131 static gint hf_rdt_tirp_has_buffer_info
= -1;
132 static gint hf_rdt_tirp_request_time_msec
= -1;
133 static gint hf_rdt_tirp_response_time_msec
= -1;
134 static gint hf_rdt_tirp_buffer_info
= -1;
135 static gint hf_rdt_tirp_buffer_info_count
= -1;
136 static gint hf_rdt_tirp_buffer_info_stream_id
= -1;
137 static gint hf_rdt_tirp_buffer_info_lowest_timestamp
= -1;
138 static gint hf_rdt_tirp_buffer_info_highest_timestamp
= -1;
139 static gint hf_rdt_tirp_buffer_info_bytes_buffered
= -1;
140 static gint hf_rdt_bwpp_seqno
= -1;
141 static gint hf_rdt_unk_flags1
= -1;
143 /* RDT setup fields */
144 static gint hf_rdt_setup
= -1;
145 static gint hf_rdt_setup_frame
= -1;
146 static gint hf_rdt_setup_method
= -1;
147 static gint hf_rdt_feature_level
= -1;
149 /* RDT fields defining a sub tree */
150 static gint ett_rdt
= -1;
151 static gint ett_rdt_packet
= -1;
152 static gint ett_rdt_setup
= -1;
153 static gint ett_rdt_data_flags1
= -1;
154 static gint ett_rdt_data_flags2
= -1;
155 static gint ett_rdt_aact_flags
= -1;
156 static gint ett_rdt_ack_flags
= -1;
157 static gint ett_rdt_latency_report_flags
= -1;
158 static gint ett_rdt_bandwidth_report_flags
= -1;
159 static gint ett_rdt_stre_flags
= -1;
160 static gint ett_rdt_rtt_request_flags
= -1;
161 static gint ett_rdt_rtt_response_flags
= -1;
162 static gint ett_rdt_congestion_flags
= -1;
163 static gint ett_rdt_report_flags
= -1;
164 static gint ett_rdt_tirq_flags
= -1;
165 static gint ett_rdt_tirp_flags
= -1;
166 static gint ett_rdt_tirp_buffer_info
= -1;
167 static gint ett_rdt_bw_probing_flags
= -1;
169 /* Port preference settings */
170 static gboolean global_rdt_register_udp_port
= FALSE
;
171 static guint global_rdt_udp_port
= 6970;
173 void proto_register_rdt(void);
174 void proto_reg_handoff_rdt(void);
176 /* Main dissection function */
177 static void dissect_rdt(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
);
179 /* Parse individual packet types */
180 static guint
dissect_rdt_data_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
);
181 static guint
dissect_rdt_asm_action_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
);
182 static guint
dissect_rdt_bandwidth_report_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
);
183 static guint
dissect_rdt_ack_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
);
184 static guint
dissect_rdt_rtt_request_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
);
185 static guint
dissect_rdt_rtt_response_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
);
186 static guint
dissect_rdt_congestion_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
);
187 static guint
dissect_rdt_stream_end_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
);
188 static guint
dissect_rdt_report_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
);
189 static guint
dissect_rdt_latency_report_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
);
190 static guint
dissect_rdt_transport_info_request_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
);
191 static guint
dissect_rdt_transport_info_response_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
);
192 static guint
dissect_rdt_bw_probing_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
);
193 static guint
dissect_rdt_unknown_control(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
);
195 static void show_setup_info(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
);
197 /* Preferences bool to control whether or not setup info should be shown */
198 static gboolean global_rdt_show_setup_info
= TRUE
;
201 #define RDT_ASMACTIION_PACKET 0xff00
202 #define RDT_BANDWIDTHREPORT_PACKET 0xff01
203 #define RDT_ACK_PACKET 0xff02
204 #define RDT_RTTREQUEST_PACKET 0xff03
205 #define RDT_RTTRESPONSE_PACKET 0xff04
206 #define RDT_CONGESTION_PACKET 0xff05
207 #define RDT_STREAMEND_PACKET 0xff06
208 #define RDT_REPORT_PACKET 0xff07
209 #define RDT_LATENCYREPORT_PACKET 0xff08
210 #define RDT_TRANSPORTINFO_PACKET 0xff09
211 #define RDT_TRANSPORTINFORESPONSE_PACKET 0xff0a
212 #define RDT_BWPROBING_PACKET 0xff0b
214 static const value_string packet_type_vals
[] =
216 { RDT_ASMACTIION_PACKET
, "Asm action" },
217 { RDT_BANDWIDTHREPORT_PACKET
, "Bandwidth report" },
218 { RDT_ACK_PACKET
, "Ack" },
219 { RDT_RTTREQUEST_PACKET
, "RTT request" },
220 { RDT_RTTRESPONSE_PACKET
, "RTT response" },
221 { RDT_CONGESTION_PACKET
, "Congestion" },
222 { RDT_STREAMEND_PACKET
, "Stream end" },
223 { RDT_REPORT_PACKET
, "Report" },
224 { RDT_LATENCYREPORT_PACKET
, "Latency report" },
225 { RDT_TRANSPORTINFO_PACKET
, "Transport info" },
226 { RDT_TRANSPORTINFORESPONSE_PACKET
, "Transport info response" },
227 { RDT_BWPROBING_PACKET
, "BW probing" },
232 /* Set up an RDT conversation */
233 void rdt_add_address(packet_info
*pinfo
,
234 address
*addr
, int port
,
236 const gchar
*setup_method
,
237 gint rdt_feature_level
)
240 conversation_t
* p_conv
;
241 struct _rdt_conversation_info
*p_conv_data
;
243 /* If this isn't the first time this packet has been processed,
244 we've already done this work, so we don't need to do it
246 if (pinfo
->fd
->flags
.visited
)
251 SET_ADDRESS(&null_addr
, AT_NONE
, 0, NULL
);
253 /* Check if the ip address and port combination is not already registered
254 as a conversation. */
255 p_conv
= find_conversation(pinfo
->fd
->num
, addr
, &null_addr
, PT_UDP
, port
, other_port
,
256 NO_ADDR_B
| (!other_port
? NO_PORT_B
: 0));
258 /* If not, create a new conversation. */
259 if ( !p_conv
|| p_conv
->setup_frame
!= pinfo
->fd
->num
)
261 p_conv
= conversation_new(pinfo
->fd
->num
, addr
, &null_addr
, PT_UDP
,
262 (guint32
)port
, (guint32
)other_port
,
263 NO_ADDR2
| (!other_port
? NO_PORT2
: 0));
267 conversation_set_dissector(p_conv
, rdt_handle
);
269 /* Check if the conversation has data associated with it. */
270 p_conv_data
= (struct _rdt_conversation_info
*)conversation_get_proto_data(p_conv
, proto_rdt
);
272 /* If not, add a new data item. */
275 /* Create conversation data */
276 p_conv_data
= wmem_new(wmem_file_scope(), struct _rdt_conversation_info
);
277 conversation_add_proto_data(p_conv
, proto_rdt
, p_conv_data
);
280 /* Update the conversation data. */
281 g_strlcpy(p_conv_data
->method
, setup_method
, MAX_RDT_SETUP_METHOD_SIZE
);
282 p_conv_data
->frame_number
= pinfo
->fd
->num
;
283 p_conv_data
->feature_level
= rdt_feature_level
;
288 /****************************************************************************/
289 /* Main dissection function */
290 /****************************************************************************/
291 static void dissect_rdt(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
293 guint previous_offset
= 0;
296 proto_tree
*rdt_tree
= NULL
;
297 proto_tree
*rdt_packet_tree
;
300 /* Set/clear columns */
301 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "RDT");
302 col_clear(pinfo
->cinfo
, COL_INFO
);
304 /* Create RDT protocol tree */
307 ti
= proto_tree_add_item(tree
, proto_rdt
, tvb
, offset
, -1, ENC_NA
);
308 rdt_tree
= proto_item_add_subtree(ti
, ett_rdt
);
311 /* Conversation setup info */
312 if (global_rdt_show_setup_info
)
314 show_setup_info(tvb
, pinfo
, rdt_tree
);
317 /* Parse all RDT packets found in the frame */
318 while (offset
!= -1 && tvb_length_remaining(tvb
, offset
))
320 /* Every packet type should have at least 3 bytes */
321 tvb_ensure_bytes_exist(tvb
, offset
, 3);
323 /* 2nd & 3rd bytes determine packet type */
324 packet_type
= tvb_get_ntohs(tvb
, offset
+1);
326 /* Add a tree for the next individual packet */
327 ti
= proto_tree_add_string_format(rdt_tree
, hf_rdt_packet
, tvb
, offset
, -1,
330 packet_type
< 0xff00 ? "Data" :
331 val_to_str_const(packet_type
, packet_type_vals
, "Unknown"));
332 rdt_packet_tree
= proto_item_add_subtree(ti
, ett_rdt_packet
);
334 /* Dissect the details of the next packet in this frame */
335 if (packet_type
< 0xff00)
337 offset
= dissect_rdt_data_packet(tvb
, pinfo
, rdt_packet_tree
, offset
);
343 case RDT_ASMACTIION_PACKET
:
344 offset
= dissect_rdt_asm_action_packet(tvb
, pinfo
, rdt_packet_tree
, offset
);
346 case RDT_BANDWIDTHREPORT_PACKET
:
347 offset
= dissect_rdt_bandwidth_report_packet(tvb
, pinfo
, rdt_packet_tree
, offset
);
350 offset
= dissect_rdt_ack_packet(tvb
, pinfo
, rdt_packet_tree
, offset
);
352 case RDT_RTTREQUEST_PACKET
:
353 offset
= dissect_rdt_rtt_request_packet(tvb
, pinfo
, rdt_packet_tree
, offset
);
355 case RDT_RTTRESPONSE_PACKET
:
356 offset
= dissect_rdt_rtt_response_packet(tvb
, pinfo
, rdt_packet_tree
, offset
);
358 case RDT_CONGESTION_PACKET
:
359 offset
= dissect_rdt_congestion_packet(tvb
, pinfo
, rdt_packet_tree
, offset
);
361 case RDT_STREAMEND_PACKET
:
362 offset
= dissect_rdt_stream_end_packet(tvb
, pinfo
, rdt_packet_tree
, offset
);
364 case RDT_REPORT_PACKET
:
365 offset
= dissect_rdt_report_packet(tvb
, pinfo
, rdt_packet_tree
, offset
);
367 case RDT_LATENCYREPORT_PACKET
:
368 offset
= dissect_rdt_latency_report_packet(tvb
, pinfo
, rdt_packet_tree
, offset
);
370 case RDT_TRANSPORTINFO_PACKET
:
371 offset
= dissect_rdt_transport_info_request_packet(tvb
, pinfo
, rdt_packet_tree
, offset
);
373 case RDT_TRANSPORTINFORESPONSE_PACKET
:
374 offset
= dissect_rdt_transport_info_response_packet(tvb
, pinfo
, rdt_packet_tree
, offset
);
376 case RDT_BWPROBING_PACKET
:
377 offset
= dissect_rdt_bw_probing_packet(tvb
, pinfo
, rdt_packet_tree
, offset
);
381 /* Unknown control packet */
382 offset
= dissect_rdt_unknown_control(tvb
, pinfo
, rdt_packet_tree
, offset
);
387 /* Select correct number of bytes for the tree showing this packet */
390 proto_item_set_len(rdt_packet_tree
, offset
-previous_offset
);
392 previous_offset
= offset
;
398 /************************************************/
399 /* Functions to dissect individual packet types */
400 /************************************************/
402 /* Dissect a data packet */
403 guint
dissect_rdt_data_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
)
405 guint start_offset
= offset
;
406 guint16 packet_length
;
408 guint8 length_included_flag
;
409 guint8 need_reliable_flag
;
411 guint16 sequence_number
;
412 guint8 is_reliable_flag
;
415 guint16 asm_rule_number
;
418 proto_tree
*flags_tree1
;
419 proto_tree
*flags_tree2
;
422 /* Flags in first byte */
423 flags1
= tvb_get_guint8(tvb
, offset
);
424 length_included_flag
= (flags1
& 0x80) >> 7;
425 need_reliable_flag
= (flags1
& 0x40) >> 6;
426 stream_id
= (flags1
& 0x3e) >> 1;
427 is_reliable_flag
= flags1
& 0x01;
429 /* Create subtree for flags1 fields */
432 ti
= proto_tree_add_string_format(tree
, hf_rdt_data_flags1
, tvb
, offset
, 1,
434 "Length-included=%u, need-reliable=%u, stream-id=%u, is-reliable=%u",
435 length_included_flag
,
439 flags_tree1
= proto_item_add_subtree(ti
, ett_rdt_data_flags1
);
441 proto_tree_add_item(flags_tree1
, hf_rdt_len_included
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
442 proto_tree_add_item(flags_tree1
, hf_rdt_data_need_reliable
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
443 proto_tree_add_item(flags_tree1
, hf_rdt_data_stream_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
444 proto_tree_add_item(flags_tree1
, hf_rdt_data_is_reliable
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
449 /* Sequence number */
450 sequence_number
= tvb_get_ntohs(tvb
, offset
);
451 proto_tree_add_item(tree
, hf_rdt_sequence_number
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
454 /* Length field is optional */
455 if (length_included_flag
)
457 packet_length
= tvb_get_ntohs(tvb
, offset
);
458 proto_tree_add_item(tree
, hf_rdt_packet_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
461 /* Check that there are as many bytes as reported */
462 tvb_ensure_bytes_exist(tvb
, start_offset
, packet_length
);
466 packet_length
= tvb_length_remaining(tvb
, start_offset
);
470 flags2
= tvb_get_guint8(tvb
, offset
);
471 back_to_back
= (flags2
& 0x80) >> 7;
472 slow_data
= (flags2
& 0x40) >> 6;
473 asm_rule_number
= flags2
& 0x3f;
476 /* Create subtree for flags2 fields */
479 ti
= proto_tree_add_string_format(tree
, hf_rdt_data_flags2
, tvb
, offset
, 1,
481 "Back-to-back=%u, slow-data=%u, asm-rule=%u",
486 /* Create subtree for flags and add fields */
487 flags_tree2
= proto_item_add_subtree(ti
, ett_rdt_data_flags2
);
489 proto_tree_add_item(flags_tree2
, hf_rdt_data_backtoback
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
490 proto_tree_add_item(flags_tree2
, hf_rdt_data_slowdata
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
491 proto_tree_add_item(flags_tree2
, hf_rdt_data_asmrule
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
496 timestamp
= tvb_get_ntohl(tvb
, offset
);
497 proto_tree_add_item(tree
, hf_rdt_timestamp
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
500 /* Stream ID expansion */
503 stream_id
= tvb_get_ntohs(tvb
, offset
);
504 proto_tree_add_item(tree
, hf_rdt_stream_id_ex
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
509 if (need_reliable_flag
)
511 proto_tree_add_item(tree
, hf_rdt_total_reliable
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
515 /* Asm rule number */
516 if (asm_rule_number
== 63)
518 asm_rule_number
= tvb_get_ntohs(tvb
, offset
);
519 proto_tree_add_item(tree
, hf_rdt_asmrule_ex
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
523 col_append_fstr(pinfo
->cinfo
, COL_INFO
,
524 "DATA: stream-id=%02u asm-rule=%02u seq=%05u ts=%05u ",
525 stream_id
, asm_rule_number
, sequence_number
, timestamp
);
527 /* The remaining data is unparsed. */
528 proto_tree_add_item(tree
, hf_rdt_data
, tvb
, offset
, -1, ENC_NA
);
529 offset
+= tvb_length_remaining(tvb
, offset
);
531 if (packet_length
< (offset
- start_offset
) ||
532 packet_length
> tvb_length_remaining(tvb
, start_offset
))
534 proto_tree_add_text(tree
, tvb
, 0, 0, "Packet length invalid");
535 packet_length
= tvb_length_remaining(tvb
, start_offset
);
538 return start_offset
+ packet_length
;
541 /* Dissect an asm-action packet */
542 guint
dissect_rdt_asm_action_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
)
544 guint start_offset
= offset
;
545 guint16 packet_length
;
547 guint8 length_included_flag
;
550 proto_tree
*flags_tree
;
553 /* Flags in first byte */
554 flags1
= tvb_get_guint8(tvb
, offset
);
555 length_included_flag
= (flags1
& 0x80) >> 7;
556 stream_id
= (flags1
& 0x7c) >> 2;
558 /* Create subtree for flags fields */
561 proto_tree_add_item(tree
, proto_rdt
, tvb
, offset
, -1, ENC_NA
);
562 ti
= proto_tree_add_string_format(tree
, hf_rdt_aact_flags
, tvb
, offset
, 1,
564 "Length-included=%u, stream_id=%u",
565 length_included_flag
,
567 flags_tree
= proto_item_add_subtree(ti
, ett_rdt_aact_flags
);
569 proto_tree_add_item(flags_tree
, hf_rdt_len_included
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
570 proto_tree_add_item(flags_tree
, hf_rdt_aact_stream_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
575 proto_tree_add_item(tree
, hf_rdt_packet_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
578 rel_seqno
= tvb_get_ntohs(tvb
, offset
);
579 proto_tree_add_item(tree
, hf_rdt_aact_reliable_seqno
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
582 /* Length field is optional */
583 if (length_included_flag
)
585 packet_length
= tvb_get_ntohs(tvb
, offset
);
586 proto_tree_add_item(tree
, hf_rdt_packet_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
589 /* Check that there are as many bytes as reported */
590 tvb_ensure_bytes_exist(tvb
, start_offset
, packet_length
);
594 packet_length
= tvb_length_remaining(tvb
, start_offset
);
597 /* Stream ID expansion */
600 stream_id
= tvb_get_ntohs(tvb
, offset
);
601 proto_tree_add_item(tree
, hf_rdt_stream_id_ex
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
605 col_append_fstr(pinfo
->cinfo
, COL_INFO
,
606 "ASM-ACTION: stream-id=%02u rel-seqno=%05u ",
607 stream_id
, rel_seqno
);
609 /* The remaining data is unparsed. */
610 proto_tree_add_item(tree
, hf_rdt_data
, tvb
, offset
, -1, ENC_NA
);
612 if (packet_length
< (offset
- start_offset
) ||
613 packet_length
> tvb_length_remaining(tvb
, start_offset
))
615 proto_tree_add_text(tree
, tvb
, 0, 0, "Packet length invalid");
616 packet_length
= tvb_length_remaining(tvb
, start_offset
);
619 return start_offset
+ packet_length
;
622 /* Dissect an bandwidth-report packet */
623 guint
dissect_rdt_bandwidth_report_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
)
625 guint start_offset
= offset
;
626 guint16 packet_length
;
628 guint8 length_included_flag
;
629 proto_tree
*flags_tree
;
632 /* Flags in first byte */
633 flags1
= tvb_get_guint8(tvb
, offset
);
634 length_included_flag
= (flags1
& 0x80) >> 7;
636 /* Create subtree for flags fields */
639 ti
= proto_tree_add_string_format(tree
, hf_rdt_bandwidth_report_flags
, tvb
, offset
, 1,
641 "Length-included=%u",
642 length_included_flag
);
643 flags_tree
= proto_item_add_subtree(ti
, ett_rdt_bandwidth_report_flags
);
645 proto_tree_add_item(flags_tree
, hf_rdt_len_included
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
650 proto_tree_add_item(tree
, hf_rdt_packet_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
653 /* Length field is optional */
654 if (length_included_flag
)
656 packet_length
= tvb_get_ntohs(tvb
, offset
);
657 proto_tree_add_item(tree
, hf_rdt_packet_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
660 /* Check that there are as many bytes as reported */
661 tvb_ensure_bytes_exist(tvb
, start_offset
, packet_length
);
665 packet_length
= tvb_length_remaining(tvb
, start_offset
);
668 proto_tree_add_item(tree
, hf_rdt_brpt_interval
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
670 proto_tree_add_item(tree
, hf_rdt_brpt_bandwidth
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
672 proto_tree_add_item(tree
, hf_rdt_brpt_sequence
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
675 col_append_str(pinfo
->cinfo
, COL_INFO
, "BANDWIDTH-REPORT: ");
677 if (packet_length
< (offset
- start_offset
) ||
678 packet_length
> tvb_length_remaining(tvb
, start_offset
))
680 proto_tree_add_text(tree
, tvb
, 0, 0, "Packet length invalid");
681 packet_length
= tvb_length_remaining(tvb
, start_offset
);
684 return start_offset
+ packet_length
;
687 /* Dissect an ack packet */
688 guint
dissect_rdt_ack_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
)
690 guint start_offset
= offset
;
691 guint16 packet_length
;
693 guint8 length_included_flag
;
694 guint8 lost_high_flag
;
695 proto_tree
*flags_tree
;
698 /* Flags in first byte */
699 flags1
= tvb_get_guint8(tvb
, offset
);
700 length_included_flag
= (flags1
& 0x80) >> 7;
701 lost_high_flag
= (flags1
& 0x40) >> 6;
703 /* Create subtree for flags fields */
706 ti
= proto_tree_add_string_format(tree
, hf_rdt_ack_flags
, tvb
, offset
, 1,
708 "Length-included=%u, lost-high=%u",
709 length_included_flag
,
711 flags_tree
= proto_item_add_subtree(ti
, ett_rdt_ack_flags
);
713 proto_tree_add_item(flags_tree
, hf_rdt_len_included
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
714 proto_tree_add_item(flags_tree
, hf_rdt_ack_lost_high
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
719 proto_tree_add_item(tree
, hf_rdt_packet_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
722 /* Length field is optional */
723 if (length_included_flag
)
725 packet_length
= tvb_get_ntohs(tvb
, offset
);
726 proto_tree_add_item(tree
, hf_rdt_packet_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
729 /* Check that there are as many bytes as reported */
730 tvb_ensure_bytes_exist(tvb
, start_offset
, packet_length
);
734 packet_length
= tvb_length_remaining(tvb
, start_offset
);
737 /* XXX: The remaining data is unparsed. */
738 proto_tree_add_item(tree
, hf_rdt_data
, tvb
, offset
, -1, ENC_NA
);
740 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "ACK: lh=%u ", lost_high_flag
);
742 if (packet_length
< (offset
- start_offset
) ||
743 packet_length
> tvb_length_remaining(tvb
, start_offset
))
745 proto_tree_add_text(tree
, tvb
, 0, 0, "Packet length invalid");
746 packet_length
= tvb_length_remaining(tvb
, start_offset
);
749 return start_offset
+ packet_length
;
752 /* Dissect an att-request packet */
753 guint
dissect_rdt_rtt_request_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
)
755 /* Flags in first byte */
759 proto_tree_add_item(tree
, hf_rdt_packet_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
762 col_append_str(pinfo
->cinfo
, COL_INFO
, "RTT-REQUEST: ");
767 /* Dissect an att-response packet */
768 guint
dissect_rdt_rtt_response_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
)
770 /* Flags in first byte */
774 proto_tree_add_item(tree
, hf_rdt_packet_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
777 proto_tree_add_item(tree
, hf_rdt_rtrp_ts_sec
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
779 proto_tree_add_item(tree
, hf_rdt_rtrp_ts_usec
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
782 col_append_str(pinfo
->cinfo
, COL_INFO
, "RTT-RESPONSE: ");
787 /* Dissect an congestion packet */
788 guint
dissect_rdt_congestion_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
)
790 /* Flags in first byte */
794 proto_tree_add_item(tree
, hf_rdt_packet_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
797 proto_tree_add_item(tree
, hf_rdt_cong_xmit_mult
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
799 proto_tree_add_item(tree
, hf_rdt_cong_recv_mult
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
802 col_append_str(pinfo
->cinfo
, COL_INFO
, "CONGESTION: ");
807 /* Dissect an stream-end packet */
808 guint
dissect_rdt_stream_end_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
)
811 guint8 need_reliable
;
815 proto_tree
*flags_tree
;
818 /* Flags in first byte */
819 flags1
= tvb_get_guint8(tvb
, offset
);
820 need_reliable
= (flags1
& 0x80) >> 7;
821 stream_id
= (flags1
& 0x7c) >> 2;
822 packet_sent
= (flags1
& 0x2) >> 1;
823 ext_flag
= flags1
& 0x1;
825 /* Create subtree for flags fields */
828 ti
= proto_tree_add_string_format(tree
, hf_rdt_stre_flags
, tvb
, offset
, 1,
830 "Need-reliable=%u, stream-id=%u, packet-sent=%u, ext-flag=%u",
835 flags_tree
= proto_item_add_subtree(ti
, ett_rdt_stre_flags
);
837 proto_tree_add_item(flags_tree
, hf_rdt_stre_need_reliable
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
838 proto_tree_add_item(flags_tree
, hf_rdt_stre_stream_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
839 proto_tree_add_item(flags_tree
, hf_rdt_stre_packet_sent
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
840 proto_tree_add_item(flags_tree
, hf_rdt_stre_ext_flag
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
845 proto_tree_add_item(tree
, hf_rdt_packet_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
848 proto_tree_add_item(tree
, hf_rdt_stre_seqno
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
850 proto_tree_add_item(tree
, hf_rdt_timestamp
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
853 /* Stream ID expansion */
856 stream_id
= tvb_get_ntohs(tvb
, offset
);
857 proto_tree_add_item(tree
, hf_rdt_stream_id_ex
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
864 proto_tree_add_item(tree
, hf_rdt_total_reliable
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
870 proto_tree_add_item(tree
, hf_rdt_stre_dummy_flags1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
872 proto_tree_add_item(tree
, hf_rdt_stre_dummy_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
874 proto_tree_add_item(tree
, hf_rdt_stre_reason_code
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
876 /* XXX: Remainder is reason_text */
877 offset
+= tvb_length_remaining(tvb
, offset
);
880 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "STREAM-END: stream-id=%02u ", stream_id
);
885 /* Dissect an report packet */
886 guint
dissect_rdt_report_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
)
888 guint start_offset
= offset
;
889 guint16 packet_length
;
891 guint8 length_included_flag
;
892 proto_tree
*flags_tree
;
895 /* Flags in first byte */
896 flags1
= tvb_get_guint8(tvb
, offset
);
897 length_included_flag
= (flags1
& 0x80) >> 7;
899 /* Create subtree for flags fields */
902 ti
= proto_tree_add_string_format(tree
, hf_rdt_report_flags
, tvb
, offset
, 1,
904 "Length-included=%u",
905 length_included_flag
);
906 flags_tree
= proto_item_add_subtree(ti
, ett_rdt_report_flags
);
908 proto_tree_add_item(flags_tree
, hf_rdt_len_included
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
913 proto_tree_add_item(tree
, hf_rdt_packet_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
916 /* Length field is optional */
917 if (length_included_flag
)
919 packet_length
= tvb_get_ntohs(tvb
, offset
);
920 proto_tree_add_item(tree
, hf_rdt_packet_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
923 /* Check that there are as many bytes as reported */
924 tvb_ensure_bytes_exist(tvb
, start_offset
, packet_length
);
928 packet_length
= tvb_length_remaining(tvb
, start_offset
);
931 col_append_str(pinfo
->cinfo
, COL_INFO
, "REPORT: ");
933 /* The remaining data is unparsed. */
934 proto_tree_add_item(tree
, hf_rdt_data
, tvb
, offset
, -1, ENC_NA
);
936 if (packet_length
< (offset
- start_offset
) ||
937 packet_length
> tvb_length_remaining(tvb
, start_offset
))
939 proto_tree_add_text(tree
, tvb
, 0, 0, "Packet length invalid");
940 packet_length
= tvb_length_remaining(tvb
, start_offset
);
943 return start_offset
+ packet_length
;
946 /* Dissect an latency-report packet */
947 guint
dissect_rdt_latency_report_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
)
949 guint start_offset
= offset
;
950 guint16 packet_length
;
952 guint8 length_included_flag
;
953 guint32 server_out_time
;
954 proto_tree
*flags_tree
;
957 /* Flags in first byte */
958 flags1
= tvb_get_guint8(tvb
, offset
);
959 length_included_flag
= (flags1
& 0x80) >> 7;
961 /* Create subtree for flags fields */
964 ti
= proto_tree_add_string_format(tree
, hf_rdt_latency_report_flags
, tvb
, offset
, 1,
966 "Length-included=%u",
967 length_included_flag
);
968 flags_tree
= proto_item_add_subtree(ti
, ett_rdt_latency_report_flags
);
970 proto_tree_add_item(flags_tree
, hf_rdt_len_included
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
975 proto_tree_add_item(tree
, hf_rdt_packet_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
978 /* Length field is optional */
979 if (length_included_flag
)
981 packet_length
= tvb_get_ntohs(tvb
, offset
);
982 proto_tree_add_item(tree
, hf_rdt_packet_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
985 /* Check that there are as many bytes as reported */
986 tvb_ensure_bytes_exist(tvb
, start_offset
, packet_length
);
990 packet_length
= tvb_length_remaining(tvb
, start_offset
);
993 server_out_time
= tvb_get_ntohl(tvb
, offset
);
994 proto_tree_add_item(tree
, hf_rdt_lrpt_server_out_time
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
997 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "LATENCY-REPORT: t=%u ", server_out_time
);
999 if (packet_length
< (offset
- start_offset
) ||
1000 packet_length
> tvb_length_remaining(tvb
, start_offset
))
1002 proto_tree_add_text(tree
, tvb
, 0, 0, "Packet length invalid");
1003 packet_length
= tvb_length_remaining(tvb
, start_offset
);
1006 return start_offset
+ packet_length
;
1009 /* Dissect a transport-info packet */
1010 guint
dissect_rdt_transport_info_request_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
)
1013 guint8 request_rtt_info_flag
;
1014 guint8 request_buffer_info_flag
;
1015 proto_tree
*flags_tree
;
1018 /* Flags in first byte */
1019 flags1
= tvb_get_guint8(tvb
, offset
);
1020 request_rtt_info_flag
= (flags1
& 0x2) >> 1;
1021 request_buffer_info_flag
= (flags1
& 0x01);
1023 /* Create subtree for flags fields */
1026 ti
= proto_tree_add_string_format(tree
, hf_rdt_ack_flags
, tvb
, offset
, 1,
1028 "Request-rtt-info=%u, request-buffer-info=%u",
1029 request_rtt_info_flag
,
1030 request_buffer_info_flag
);
1031 flags_tree
= proto_item_add_subtree(ti
, ett_rdt_tirq_flags
);
1033 proto_tree_add_item(flags_tree
, hf_rdt_tirq_request_rtt_info
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1034 proto_tree_add_item(flags_tree
, hf_rdt_tirq_request_buffer_info
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1039 proto_tree_add_item(tree
, hf_rdt_packet_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1042 if (request_rtt_info_flag
)
1044 proto_tree_add_item(tree
, hf_rdt_tirq_request_time_msec
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1048 col_append_str(pinfo
->cinfo
, COL_INFO
, "TRANSPORT-INFO-REQUEST: ");
1053 /* Dissect an transport-info-response packet */
1054 guint
dissect_rdt_transport_info_response_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
)
1057 guint8 has_rtt_info
;
1059 guint8 has_buffer_info
;
1060 proto_tree
*flags_tree
;
1063 /* Flags in first byte */
1064 flags1
= tvb_get_guint8(tvb
, offset
);
1065 has_rtt_info
= (flags1
& 0x4) >> 2;
1066 is_delayed
= (flags1
& 0x2) >> 1;
1067 has_buffer_info
= (flags1
& 0x1);
1069 /* Create subtree for flags fields */
1072 ti
= proto_tree_add_string_format(tree
, hf_rdt_tirp_flags
, tvb
, offset
, 1,
1074 "Has-rtt-info=%u, is-delayed=%u, has-buffer-info=%u",
1078 flags_tree
= proto_item_add_subtree(ti
, ett_rdt_tirp_flags
);
1080 proto_tree_add_item(flags_tree
, hf_rdt_tirp_has_rtt_info
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1081 proto_tree_add_item(flags_tree
, hf_rdt_tirp_is_delayed
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1082 proto_tree_add_item(flags_tree
, hf_rdt_tirp_has_buffer_info
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1087 proto_tree_add_item(tree
, hf_rdt_packet_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1093 proto_tree_add_item(tree
, hf_rdt_tirp_request_time_msec
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1098 proto_tree_add_item(tree
, hf_rdt_tirp_response_time_msec
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1104 if (has_buffer_info
)
1108 /* Read number of buffers */
1109 guint16 buffer_info_count
= tvb_get_ntohs(tvb
, offset
);
1110 proto_tree_add_item(tree
, hf_rdt_tirp_buffer_info_count
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1113 for (n
=0; n
< buffer_info_count
; n
++)
1115 proto_tree
*buffer_info_tree
;
1118 /* Each buffer info in a new subtree */
1119 ti2
= proto_tree_add_string_format(tree
, hf_rdt_tirp_buffer_info
, tvb
, offset
, 14,
1123 buffer_info_tree
= proto_item_add_subtree(ti2
, ett_rdt_tirp_buffer_info
);
1125 /* Read individual buffer info */
1126 proto_tree_add_item(buffer_info_tree
, hf_rdt_tirp_buffer_info_stream_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1128 proto_tree_add_item(buffer_info_tree
, hf_rdt_tirp_buffer_info_lowest_timestamp
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1130 proto_tree_add_item(buffer_info_tree
, hf_rdt_tirp_buffer_info_highest_timestamp
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1132 proto_tree_add_item(buffer_info_tree
, hf_rdt_tirp_buffer_info_bytes_buffered
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1137 /* Report what is left */
1138 offset
+= tvb_length_remaining(tvb
, offset
);
1140 col_append_str(pinfo
->cinfo
, COL_INFO
, "RESPONSE: ");
1145 /* Dissect a bw-probing packet */
1146 guint
dissect_rdt_bw_probing_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
)
1148 guint start_offset
= offset
;
1149 guint16 packet_length
;
1151 guint8 length_included_flag
;
1152 proto_tree
*flags_tree
;
1155 /* Flags in first byte */
1156 flags1
= tvb_get_guint8(tvb
, offset
);
1157 length_included_flag
= (flags1
& 0x80) >> 7;
1159 /* Create subtree for flags fields */
1162 ti
= proto_tree_add_string_format(tree
, hf_rdt_bw_probing_flags
, tvb
, offset
, 1,
1164 "Length-included=%u",
1165 length_included_flag
);
1166 flags_tree
= proto_item_add_subtree(ti
, ett_rdt_bw_probing_flags
);
1168 proto_tree_add_item(flags_tree
, hf_rdt_len_included
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1173 proto_tree_add_item(tree
, hf_rdt_packet_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1176 /* Length field is optional */
1177 if (length_included_flag
)
1179 packet_length
= tvb_get_ntohs(tvb
, offset
);
1180 proto_tree_add_item(tree
, hf_rdt_packet_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1183 /* Check that there are as many bytes as reported */
1184 tvb_ensure_bytes_exist(tvb
, start_offset
, packet_length
);
1188 packet_length
= tvb_length_remaining(tvb
, start_offset
);
1191 proto_tree_add_item(tree
, hf_rdt_bwpp_seqno
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1193 proto_tree_add_item(tree
, hf_rdt_timestamp
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1196 col_append_str(pinfo
->cinfo
, COL_INFO
, "BW-PROBING: ");
1198 if (packet_length
< (offset
- start_offset
) ||
1199 packet_length
> tvb_length_remaining(tvb
, start_offset
))
1201 proto_tree_add_text(tree
, tvb
, 0, 0, "Packet length invalid");
1202 packet_length
= tvb_length_remaining(tvb
, start_offset
);
1205 return start_offset
+ packet_length
;
1208 /* Dissect an unknown control packet */
1209 guint
dissect_rdt_unknown_control(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, guint offset
)
1211 /* Flags in first byte */
1212 proto_tree_add_item(tree
, hf_rdt_unk_flags1
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1216 proto_tree_add_item(tree
, hf_rdt_packet_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1219 /* The remaining data is unparsed. */
1220 proto_tree_add_item(tree
, hf_rdt_data
, tvb
, offset
, -1, ENC_NA
);
1221 offset
+= tvb_length_remaining(tvb
, offset
);
1223 col_append_str(pinfo
->cinfo
, COL_INFO
, "UNKNOWN-CTL: ");
1228 /* Look for conversation info and display any setup info found */
1229 static void show_setup_info(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
1231 /* Conversation and current data */
1232 conversation_t
*p_conv
;
1233 struct _rdt_conversation_info
*p_conv_data
;
1235 /* Use existing packet info if available */
1236 p_conv_data
= (struct _rdt_conversation_info
*)p_get_proto_data(pinfo
->fd
, proto_rdt
, 0);
1240 /* First time, get info from conversation */
1241 p_conv
= find_conversation(pinfo
->fd
->num
, &pinfo
->net_dst
, &pinfo
->net_src
,
1243 pinfo
->destport
, pinfo
->srcport
, NO_ADDR_B
);
1246 /* Create space for conversation info */
1247 struct _rdt_conversation_info
*p_conv_packet_data
;
1248 p_conv_data
= (struct _rdt_conversation_info
*)conversation_get_proto_data(p_conv
, proto_rdt
);
1252 /* Save this conversation info into packet info */
1253 p_conv_packet_data
= wmem_new(wmem_file_scope(), struct _rdt_conversation_info
);
1254 g_strlcpy(p_conv_packet_data
->method
, p_conv_data
->method
, MAX_RDT_SETUP_METHOD_SIZE
);
1255 p_conv_packet_data
->frame_number
= p_conv_data
->frame_number
;
1256 p_conv_packet_data
->feature_level
= p_conv_data
->feature_level
;
1257 p_add_proto_data(pinfo
->fd
, proto_rdt
, 0, p_conv_packet_data
);
1262 /* Create setup info subtree with summary info. */
1265 proto_tree
*rdt_setup_tree
;
1266 proto_item
*ti
= proto_tree_add_string_format(tree
, hf_rdt_setup
, tvb
, 0, 0,
1268 "Stream setup by %s (frame %u), feature level %d",
1269 p_conv_data
->method
,
1270 p_conv_data
->frame_number
,
1271 p_conv_data
->feature_level
);
1272 PROTO_ITEM_SET_GENERATED(ti
);
1273 rdt_setup_tree
= proto_item_add_subtree(ti
, ett_rdt_setup
);
1276 /* Add details into subtree */
1277 proto_item
* item
= proto_tree_add_uint(rdt_setup_tree
, hf_rdt_setup_frame
,
1278 tvb
, 0, 0, p_conv_data
->frame_number
);
1279 PROTO_ITEM_SET_GENERATED(item
);
1280 item
= proto_tree_add_string(rdt_setup_tree
, hf_rdt_setup_method
,
1281 tvb
, 0, 0, p_conv_data
->method
);
1282 PROTO_ITEM_SET_GENERATED(item
);
1283 item
= proto_tree_add_int(rdt_setup_tree
, hf_rdt_feature_level
,
1284 tvb
, 0, 0, p_conv_data
->feature_level
);
1285 PROTO_ITEM_SET_GENERATED(item
);
1291 void proto_register_rdt(void)
1293 static hf_register_info hf
[] =
1308 &hf_rdt_data_flags1
,
1320 &hf_rdt_len_included
,
1323 "rdt.length-included",
1332 &hf_rdt_data_need_reliable
,
1335 "rdt.need-reliable",
1344 &hf_rdt_data_stream_id
,
1356 &hf_rdt_data_is_reliable
,
1368 &hf_rdt_data_flags2
,
1376 "RDT data flags2", HFILL
1380 &hf_rdt_data_backtoback
,
1392 &hf_rdt_data_slowdata
,
1404 &hf_rdt_data_asmrule
,
1418 "RDT asm-action flags 1",
1424 "RDT aact flags", HFILL
1428 &hf_rdt_aact_stream_id
,
1440 &hf_rdt_sequence_number
,
1443 "rdt.sequence-number",
1452 &hf_rdt_packet_type
,
1458 VALS(packet_type_vals
),
1476 &hf_rdt_ack_lost_high
,
1488 &hf_rdt_latency_report_flags
,
1490 "RDT latency report flags",
1491 "rdt.latency-report-flags",
1500 &hf_rdt_bandwidth_report_flags
,
1502 "RDT bandwidth report flags",
1503 "rdt.bandwidth-report-flags",
1514 "RDT stream end flags",
1515 "rdt.stream-end-flags",
1525 &hf_rdt_rtt_request_flags
,
1527 "RDT rtt request flags",
1528 "rdt.rtt-request-flags",
1539 &hf_rdt_rtt_response_flags
,
1541 "RDT rtt response flags",
1542 "rdt.rtt-response-flags",
1553 &hf_rdt_congestion_flags
,
1555 "RDT congestion flags",
1556 "rdt.congestion-flags",
1566 &hf_rdt_report_flags
,
1581 "RDT transport info request flags",
1582 "rdt.transport-info-request-flags",
1594 "RDT transport info response flags",
1595 "rdt.transport-info-response-flags",
1604 &hf_rdt_bw_probing_flags
,
1606 "RDT bw probing flags",
1607 "rdt.bw-probing-flags",
1616 &hf_rdt_packet_length
,
1619 "rdt.packet-length",
1640 &hf_rdt_stream_id_ex
,
1642 "Stream-id expansion",
1643 "rdt.stream-id-expansion",
1654 "Asm rule expansion",
1655 "rdt.asm-rule-expansion",
1664 &hf_rdt_total_reliable
,
1667 "rdt.total-reliable",
1688 &hf_rdt_aact_reliable_seqno
,
1690 "Reliable sequence number",
1691 "rdt.reliable-seq-no",
1700 &hf_rdt_brpt_interval
,
1702 "Bandwidth report interval",
1703 "rdt.bwid-report-interval",
1712 &hf_rdt_brpt_bandwidth
,
1714 "Bandwidth report bandwidth",
1715 "rdt.bwid-report-bandwidth",
1724 &hf_rdt_brpt_sequence
,
1726 "Bandwidth report sequence",
1727 "rdt.bwid-report-sequence",
1736 &hf_rdt_rtrp_ts_sec
,
1738 "Round trip response timestamp seconds",
1748 &hf_rdt_rtrp_ts_usec
,
1750 "Round trip response timestamp microseconds",
1760 &hf_rdt_cong_xmit_mult
,
1762 "Congestion transmit multiplier",
1763 "rdt.cong-xmit-mult",
1772 &hf_rdt_cong_recv_mult
,
1774 "Congestion receive multiplier",
1775 "rdt.cong-recv-mult",
1784 &hf_rdt_stre_need_reliable
,
1787 "rdt.stre-need-reliable",
1796 &hf_rdt_stre_stream_id
,
1799 "rdt.stre-stream-id",
1808 &hf_rdt_stre_packet_sent
,
1811 "rdt.stre-packet-sent",
1820 &hf_rdt_stre_ext_flag
,
1823 "rdt.stre-ext-flag",
1835 "Stream end sequence number",
1845 &hf_rdt_stre_dummy_flags1
,
1847 "Stream end reason dummy flags1",
1848 "rdt.stre-reason-dummy-flags1",
1857 &hf_rdt_stre_dummy_type
,
1859 "Stream end reason dummy type",
1860 "rdt.stre-reason-dummy-type",
1869 &hf_rdt_stre_reason_code
,
1871 "Stream end reason code",
1872 "rdt.stre-reason-code",
1881 &hf_rdt_lrpt_server_out_time
,
1883 "Latency report server out time",
1884 "rdt.lrpt-server-out-time",
1893 &hf_rdt_tirq_request_rtt_info
,
1895 "Transport info request rtt info flag",
1896 "rdt.tirq-request-rtt-info",
1905 &hf_rdt_tirq_request_buffer_info
,
1907 "Transport info request buffer info flag",
1908 "rdt.tirq-request-buffer-info",
1917 &hf_rdt_tirq_request_time_msec
,
1919 "Transport info request time msec",
1920 "rdt.tirq-request-time-msec",
1929 &hf_rdt_tirp_has_rtt_info
,
1931 "Transport info response has rtt info flag",
1932 "rdt.tirp-has-rtt-info",
1941 &hf_rdt_tirp_is_delayed
,
1943 "Transport info response is delayed",
1944 "rdt.tirp-is-delayed",
1953 &hf_rdt_tirp_has_buffer_info
,
1955 "Transport info response has buffer info",
1956 "rdt.tirp-has-buffer-info",
1965 &hf_rdt_tirp_request_time_msec
,
1967 "Transport info request time msec",
1968 "rdt.tirp-request-time-msec",
1977 &hf_rdt_tirp_response_time_msec
,
1979 "Transport info response time msec",
1980 "rdt.tirp-response-time-msec",
1989 &hf_rdt_tirp_buffer_info_count
,
1991 "Transport info buffer into count",
1992 "rdt.tirp-buffer-info-count",
2001 &hf_rdt_tirp_buffer_info
,
2004 "rdt.tirp-buffer-info",
2013 &hf_rdt_tirp_buffer_info_stream_id
,
2015 "Buffer info stream-id",
2016 "rdt.tirp-buffer-info-stream-id",
2025 &hf_rdt_tirp_buffer_info_lowest_timestamp
,
2028 "rdt.tirp-buffer-info-lowest-timestamp",
2037 &hf_rdt_tirp_buffer_info_highest_timestamp
,
2039 "Highest timestamp",
2040 "rdt.tirp-buffer-info-highest-timestamp",
2049 &hf_rdt_tirp_buffer_info_bytes_buffered
,
2052 "rdt.tirp-buffer-info-bytes-buffered",
2063 "Bandwidth probing packet seqno",
2075 "Unknown packet flags",
2093 "Stream setup, method and frame number", HFILL
2097 &hf_rdt_setup_frame
,
2105 "Frame that set up this stream", HFILL
2109 &hf_rdt_setup_method
,
2117 "Method used to set up this stream", HFILL
2121 &hf_rdt_feature_level
,
2123 "RDT feature level",
2124 "rdt.feature-level",
2134 static gint
*ett
[] =
2139 &ett_rdt_data_flags1
,
2140 &ett_rdt_data_flags2
,
2141 &ett_rdt_aact_flags
,
2143 &ett_rdt_latency_report_flags
,
2144 &ett_rdt_bandwidth_report_flags
,
2145 &ett_rdt_stre_flags
,
2146 &ett_rdt_rtt_request_flags
,
2147 &ett_rdt_rtt_response_flags
,
2148 &ett_rdt_congestion_flags
,
2149 &ett_rdt_report_flags
,
2150 &ett_rdt_tirq_flags
,
2151 &ett_rdt_tirp_flags
,
2152 &ett_rdt_tirp_buffer_info
,
2153 &ett_rdt_bw_probing_flags
2156 module_t
*rdt_module
;
2158 /* Register protocol and fields */
2159 proto_rdt
= proto_register_protocol("Real Data Transport", "RDT", "rdt");
2160 proto_register_field_array(proto_rdt
, hf
, array_length(hf
));
2161 proto_register_subtree_array(ett
, array_length(ett
));
2162 register_dissector("rdt", dissect_rdt
, proto_rdt
);
2164 /* Preference settings */
2165 rdt_module
= prefs_register_protocol(proto_rdt
, proto_reg_handoff_rdt
);
2166 prefs_register_bool_preference(rdt_module
, "show_setup_info",
2167 "Show stream setup information",
2168 "Where available, show which protocol and frame caused "
2169 "this RDT stream to be created",
2170 &global_rdt_show_setup_info
);
2172 prefs_register_bool_preference(rdt_module
, "register_udp_port",
2173 "Register default UDP client port",
2174 "Register a client UDP port for RDT traffic",
2175 &global_rdt_register_udp_port
);
2177 /* TODO: better to specify a range of ports instead? */
2178 prefs_register_uint_preference(rdt_module
, "default_udp_port",
2179 "Default UDP client port",
2180 "Set the UDP port for clients",
2181 10, &global_rdt_udp_port
);
2185 void proto_reg_handoff_rdt(void)
2187 static gboolean rdt_prefs_initialized
= FALSE
;
2188 /* Also store this so can delete registered setting properly */
2189 static gboolean rdt_register_udp_port
;
2190 static guint rdt_udp_port
;
2192 if (!rdt_prefs_initialized
)
2194 /* Register this dissector as one that can be selected by a
2196 rdt_handle
= find_dissector("rdt");
2197 dissector_add_handle("udp.port", rdt_handle
);
2198 rdt_prefs_initialized
= TRUE
;
2202 /* Undo any current port registrations */
2203 if (rdt_register_udp_port
)
2205 dissector_delete_uint("udp.port", rdt_udp_port
, rdt_handle
);
2209 /* Remember whether a port is set for next time */
2210 rdt_register_udp_port
= global_rdt_register_udp_port
;
2212 /* Add any new port registration */
2213 if (global_rdt_register_udp_port
)
2215 /* Set our port number for future use */
2216 rdt_udp_port
= global_rdt_udp_port
;
2218 /* And register with this port */
2219 dissector_add_uint("udp.port", global_rdt_udp_port
, rdt_handle
);