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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 /* Information sources:
31 * helixcommunity.org sources, in particular
32 * server/protocol/transport/rdt/pub/tngpkt.pm
43 #include <epan/packet.h>
44 #include <epan/conversation.h>
45 #include <epan/prefs.h>
46 #include <epan/emem.h>
48 #include "packet-rdt.h"
50 static dissector_handle_t rdt_handle;
52 static gint proto_rdt = -1;
55 static gint hf_rdt_packet = -1;
58 static gint hf_rdt_len_included = -1;
60 /* flags1: data packet */
61 static gint hf_rdt_data_flags1 = -1;
62 static gint hf_rdt_data_need_reliable = -1;
63 static gint hf_rdt_data_stream_id = -1;
64 static gint hf_rdt_data_is_reliable = -1;
66 /* flags2: data packet */
67 static gint hf_rdt_data_flags2 = -1;
68 static gint hf_rdt_data_backtoback = -1;
69 static gint hf_rdt_data_slowdata = -1;
70 static gint hf_rdt_data_asmrule = -1;
72 /* flags1: asm action packet */
73 static gint hf_rdt_aact_flags = -1;
74 static gint hf_rdt_aact_stream_id = -1;
76 /* flags1: ack packet */
77 static gint hf_rdt_ack_flags = -1;
78 static gint hf_rdt_ack_lost_high = -1;
80 /* flags1: latency report packet */
81 static gint hf_rdt_latency_report_flags = -1;
83 /* flags1: bandwidth report packet */
84 static gint hf_rdt_bandwidth_report_flags = -1;
86 /* flags1: stream end packet */
87 static gint hf_rdt_stre_flags = -1;
88 static gint hf_rdt_stre_need_reliable = -1;
89 static gint hf_rdt_stre_stream_id = -1;
90 static gint hf_rdt_stre_packet_sent = -1;
91 static gint hf_rdt_stre_ext_flag = -1;
93 static gint hf_rdt_rtt_request_flags = -1;
94 static gint hf_rdt_rtt_response_flags = -1;
95 static gint hf_rdt_congestion_flags = -1;
96 static gint hf_rdt_report_flags = -1;
97 static gint hf_rdt_tirq_flags = -1;
98 static gint hf_rdt_tirp_flags = -1;
99 static gint hf_rdt_bw_probing_flags = -1;
101 /* Octets 1-2: sequence number or packet type */
102 static gint hf_rdt_sequence_number = -1;
103 static gint hf_rdt_packet_type = -1;
105 /* Only present if length_included */
106 static gint hf_rdt_packet_length = -1;
108 /* General shared fields */
109 static gint hf_rdt_timestamp = -1;
110 static gint hf_rdt_stream_id_ex = -1;
111 static gint hf_rdt_asmrule_ex = -1;
112 static gint hf_rdt_total_reliable = -1;
113 static gint hf_rdt_data = -1;
115 /* Special use fields */
116 static gint hf_rdt_aact_reliable_seqno = -1;
117 static gint hf_rdt_brpt_interval = -1;
118 static gint hf_rdt_brpt_bandwidth = -1;
119 static gint hf_rdt_brpt_sequence = -1;
120 static gint hf_rdt_rtrp_ts_sec = -1;
121 static gint hf_rdt_rtrp_ts_usec = -1;
122 static gint hf_rdt_cong_xmit_mult = -1;
123 static gint hf_rdt_cong_recv_mult = -1;
124 static gint hf_rdt_stre_seqno = -1;
125 static gint hf_rdt_stre_dummy_flags1 = -1;
126 static gint hf_rdt_stre_dummy_type = -1;
127 static gint hf_rdt_stre_reason_code = -1;
128 static gint hf_rdt_lrpt_server_out_time = -1;
129 static gint hf_rdt_tirq_request_rtt_info = -1;
130 static gint hf_rdt_tirq_request_buffer_info = -1;
131 static gint hf_rdt_tirq_request_time_msec = -1;
132 static gint hf_rdt_tirp_has_rtt_info = -1;
133 static gint hf_rdt_tirp_is_delayed = -1;
134 static gint hf_rdt_tirp_has_buffer_info = -1;
135 static gint hf_rdt_tirp_request_time_msec = -1;
136 static gint hf_rdt_tirp_response_time_msec = -1;
137 static gint hf_rdt_tirp_buffer_info = -1;
138 static gint hf_rdt_tirp_buffer_info_count = -1;
139 static gint hf_rdt_tirp_buffer_info_stream_id = -1;
140 static gint hf_rdt_tirp_buffer_info_lowest_timestamp = -1;
141 static gint hf_rdt_tirp_buffer_info_highest_timestamp = -1;
142 static gint hf_rdt_tirp_buffer_info_bytes_buffered = -1;
143 static gint hf_rdt_bwpp_seqno = -1;
144 static gint hf_rdt_unk_flags1 = -1;
146 /* RDT setup fields */
147 static gint hf_rdt_setup = -1;
148 static gint hf_rdt_setup_frame = -1;
149 static gint hf_rdt_setup_method = -1;
150 static gint hf_rdt_feature_level = -1;
152 /* RDT fields defining a sub tree */
153 static gint ett_rdt = -1;
154 static gint ett_rdt_packet = -1;
155 static gint ett_rdt_setup = -1;
156 static gint ett_rdt_data_flags1 = -1;
157 static gint ett_rdt_data_flags2 = -1;
158 static gint ett_rdt_aact_flags = -1;
159 static gint ett_rdt_ack_flags = -1;
160 static gint ett_rdt_latency_report_flags = -1;
161 static gint ett_rdt_bandwidth_report_flags = -1;
162 static gint ett_rdt_stre_flags = -1;
163 static gint ett_rdt_rtt_request_flags = -1;
164 static gint ett_rdt_rtt_response_flags = -1;
165 static gint ett_rdt_congestion_flags = -1;
166 static gint ett_rdt_report_flags = -1;
167 static gint ett_rdt_tirq_flags = -1;
168 static gint ett_rdt_tirp_flags = -1;
169 static gint ett_rdt_tirp_buffer_info = -1;
170 static gint ett_rdt_bw_probing_flags = -1;
172 /* Port preference settings */
173 static gboolean global_rdt_register_udp_port = FALSE;
174 static guint global_rdt_udp_port = 6970;
176 /* Also store this so can delete registered setting properly */
177 static gboolean rdt_register_udp_port = FALSE;
178 static guint rdt_udp_port = 0;
181 void proto_reg_handoff_rdt(void);
183 /* Main dissection function */
184 static void dissect_rdt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
186 /* Parse individual packet types */
187 static guint dissect_rdt_data_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
188 static guint dissect_rdt_asm_action_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
189 static guint dissect_rdt_bandwidth_report_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
190 static guint dissect_rdt_ack_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
191 static guint dissect_rdt_rtt_request_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
192 static guint dissect_rdt_rtt_response_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
193 static guint dissect_rdt_congestion_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
194 static guint dissect_rdt_stream_end_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
195 static guint dissect_rdt_report_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
196 static guint dissect_rdt_latency_report_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
197 static guint dissect_rdt_transport_info_request_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
198 static guint dissect_rdt_transport_info_response_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
199 static guint dissect_rdt_bw_probing_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
200 static guint dissect_rdt_unknown_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset);
202 static void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
204 /* Preferences bool to control whether or not setup info should be shown */
205 static gboolean global_rdt_show_setup_info = TRUE;
208 #define RDT_ASMACTIION_PACKET 0xff00
209 #define RDT_BANDWIDTHREPORT_PACKET 0xff01
210 #define RDT_ACK_PACKET 0xff02
211 #define RDT_RTTREQUEST_PACKET 0xff03
212 #define RDT_RTTRESPONSE_PACKET 0xff04
213 #define RDT_CONGESTION_PACKET 0xff05
214 #define RDT_STREAMEND_PACKET 0xff06
215 #define RDT_REPORT_PACKET 0xff07
216 #define RDT_LATENCYREPORT_PACKET 0xff08
217 #define RDT_TRANSPORTINFO_PACKET 0xff09
218 #define RDT_TRANSPORTINFORESPONSE_PACKET 0xff0a
219 #define RDT_BWPROBING_PACKET 0xff0b
221 static const value_string packet_type_vals[] =
223 { RDT_ASMACTIION_PACKET, "Asm action" },
224 { RDT_BANDWIDTHREPORT_PACKET, "Bandwith report" },
225 { RDT_ACK_PACKET, "Ack" },
226 { RDT_RTTREQUEST_PACKET, "RTT request" },
227 { RDT_RTTRESPONSE_PACKET, "RTT response" },
228 { RDT_CONGESTION_PACKET, "Congestion" },
229 { RDT_STREAMEND_PACKET, "Stream end" },
230 { RDT_REPORT_PACKET, "Report" },
231 { RDT_LATENCYREPORT_PACKET, "Latency report" },
232 { RDT_TRANSPORTINFO_PACKET, "Transport info" },
233 { RDT_TRANSPORTINFORESPONSE_PACKET, "Transport info response" },
234 { RDT_BWPROBING_PACKET, "BW probing" },
239 /* Set up an RDT conversation */
240 void rdt_add_address(packet_info *pinfo,
241 address *addr, int port,
243 const gchar *setup_method,
244 gint rdt_feature_level)
247 conversation_t* p_conv;
248 struct _rdt_conversation_info *p_conv_data = NULL;
250 /* If this isn't the first time this packet has been processed,
251 we've already done this work, so we don't need to do it
253 if (pinfo->fd->flags.visited)
258 SET_ADDRESS(&null_addr, AT_NONE, 0, NULL);
260 /* Check if the ip address and port combination is not already registered
261 as a conversation. */
262 p_conv = find_conversation(pinfo->fd->num, addr, &null_addr, PT_UDP, port, other_port,
263 NO_ADDR_B | (!other_port ? NO_PORT_B : 0));
265 /* If not, create a new conversation. */
266 if ( !p_conv || p_conv->setup_frame != pinfo->fd->num)
268 p_conv = conversation_new(pinfo->fd->num, addr, &null_addr, PT_UDP,
269 (guint32)port, (guint32)other_port,
270 NO_ADDR2 | (!other_port ? NO_PORT2 : 0));
274 conversation_set_dissector(p_conv, rdt_handle);
276 /* Check if the conversation has data associated with it. */
277 p_conv_data = conversation_get_proto_data(p_conv, proto_rdt);
279 /* If not, add a new data item. */
282 /* Create conversation data */
283 p_conv_data = se_alloc(sizeof(struct _rdt_conversation_info));
284 conversation_add_proto_data(p_conv, proto_rdt, p_conv_data);
287 /* Update the conversation data. */
288 strncpy(p_conv_data->method, setup_method, MAX_RDT_SETUP_METHOD_SIZE);
289 p_conv_data->method[MAX_RDT_SETUP_METHOD_SIZE] = '\0';
290 p_conv_data->frame_number = pinfo->fd->num;
291 p_conv_data->feature_level = rdt_feature_level;
296 /****************************************************************************/
297 /* Main dissection function */
298 /****************************************************************************/
299 static void dissect_rdt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
301 guint previous_offset = 0;
303 proto_item *ti = NULL;
304 proto_tree *rdt_tree = NULL;
305 proto_tree *rdt_packet_tree = NULL;
308 /* Set/clear columns */
309 if (check_col(pinfo->cinfo, COL_PROTOCOL))
311 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RDT");
313 if (check_col(pinfo->cinfo, COL_INFO))
315 col_clear(pinfo->cinfo, COL_INFO);
318 /* Create RDT protocol tree */
321 ti = proto_tree_add_item(tree, proto_rdt, tvb, offset, -1, FALSE);
322 rdt_tree = proto_item_add_subtree(ti, ett_rdt);
325 /* Conversation setup info */
326 if (global_rdt_show_setup_info)
328 show_setup_info(tvb, pinfo, rdt_tree);
331 /* Parse all RDT packets found in the frame */
332 while (offset != -1 && tvb_length_remaining(tvb, offset))
334 /* Every packet type should have at least 3 bytes */
335 tvb_ensure_bytes_exist(tvb, offset, 3);
337 /* 2nd & 3rd bytes determine packet type */
338 packet_type = tvb_get_ntohs(tvb, offset+1);
340 /* Add a tree for the next individual packet */
341 ti = proto_tree_add_string_format(rdt_tree, hf_rdt_packet, tvb, offset, -1,
344 packet_type < 0xff00 ? "Data" :
345 val_to_str(packet_type, packet_type_vals, "Unknown"));
346 rdt_packet_tree = proto_item_add_subtree(ti, ett_rdt_packet);
348 /* Dissect the details of the next packet in this frame */
349 if (packet_type < 0xff00)
351 offset = dissect_rdt_data_packet(tvb, pinfo, rdt_packet_tree, offset);
357 case RDT_ASMACTIION_PACKET:
358 offset = dissect_rdt_asm_action_packet(tvb, pinfo, rdt_packet_tree, offset);
360 case RDT_BANDWIDTHREPORT_PACKET:
361 offset = dissect_rdt_bandwidth_report_packet(tvb, pinfo, rdt_packet_tree, offset);
364 offset = dissect_rdt_ack_packet(tvb, pinfo, rdt_packet_tree, offset);
366 case RDT_RTTREQUEST_PACKET:
367 offset = dissect_rdt_rtt_request_packet(tvb, pinfo, rdt_packet_tree, offset);
369 case RDT_RTTRESPONSE_PACKET:
370 offset = dissect_rdt_rtt_response_packet(tvb, pinfo, rdt_packet_tree, offset);
372 case RDT_CONGESTION_PACKET:
373 offset = dissect_rdt_congestion_packet(tvb, pinfo, rdt_packet_tree, offset);
375 case RDT_STREAMEND_PACKET:
376 offset = dissect_rdt_stream_end_packet(tvb, pinfo, rdt_packet_tree, offset);
378 case RDT_REPORT_PACKET:
379 offset = dissect_rdt_report_packet(tvb, pinfo, rdt_packet_tree, offset);
381 case RDT_LATENCYREPORT_PACKET:
382 offset = dissect_rdt_latency_report_packet(tvb, pinfo, rdt_packet_tree, offset);
384 case RDT_TRANSPORTINFO_PACKET:
385 offset = dissect_rdt_transport_info_request_packet(tvb, pinfo, rdt_packet_tree, offset);
387 case RDT_TRANSPORTINFORESPONSE_PACKET:
388 offset = dissect_rdt_transport_info_response_packet(tvb, pinfo, rdt_packet_tree, offset);
390 case RDT_BWPROBING_PACKET:
391 offset = dissect_rdt_bw_probing_packet(tvb, pinfo, rdt_packet_tree, offset);
395 /* Unknown control packet */
396 offset = dissect_rdt_unknown_control(tvb, pinfo, rdt_packet_tree, offset);
401 /* Select correct number of bytes for the tree showing this packet */
404 proto_item_set_len(rdt_packet_tree, offset-previous_offset);
406 previous_offset = offset;
412 /************************************************/
413 /* Functions to dissect individual packet types */
414 /************************************************/
416 /* Dissect a data packet */
417 guint dissect_rdt_data_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
419 guint start_offset = offset;
420 guint16 packet_length;
422 guint8 length_included_flag;
423 guint8 need_reliable_flag;
425 guint16 sequence_number;
426 guint8 is_reliable_flag;
429 guint16 asm_rule_number;
432 proto_tree *flags_tree1 = NULL;
433 proto_tree *flags_tree2 = NULL;
434 proto_item *ti = NULL;
436 /* Flags in first byte */
437 flags1 = tvb_get_guint8(tvb, offset);
438 length_included_flag = (flags1 & 0x80) >> 7;
439 need_reliable_flag = (flags1 & 0x40) >> 6;
440 stream_id = (flags1 & 0x3e) >> 1;
441 is_reliable_flag = flags1 & 0x01;
443 /* Create subtree for flags1 fields */
446 ti = proto_tree_add_string_format(tree, hf_rdt_data_flags1, tvb, offset, 1,
448 "Length-included=%u, need-reliable=%u, stream-id=%u, is-reliable=%u",
449 length_included_flag,
453 flags_tree1 = proto_item_add_subtree(ti, ett_rdt_data_flags1);
455 proto_tree_add_item(flags_tree1, hf_rdt_len_included, tvb, offset, 1, FALSE);
456 proto_tree_add_item(flags_tree1, hf_rdt_data_need_reliable, tvb, offset, 1, FALSE);
457 proto_tree_add_item(flags_tree1, hf_rdt_data_stream_id, tvb, offset, 1, FALSE);
458 proto_tree_add_item(flags_tree1, hf_rdt_data_is_reliable, tvb, offset, 1, FALSE);
463 /* Sequence number */
464 sequence_number = tvb_get_ntohs(tvb, offset);
465 proto_tree_add_item(tree, hf_rdt_sequence_number, tvb, offset, 2, FALSE);
468 /* Length field is optional */
469 if (length_included_flag)
471 packet_length = tvb_get_ntohs(tvb, offset);
472 proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, FALSE);
475 /* Check that there are as many bytes as reported */
476 tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
480 packet_length = tvb_length_remaining(tvb, start_offset);
484 flags2 = tvb_get_guint8(tvb, offset);
485 back_to_back = (flags2 & 0x80) >> 7;
486 slow_data = (flags2 & 0x40) >> 6;
487 asm_rule_number = flags2 & 0x3f;
490 /* Create subtree for flags2 fields */
493 ti = proto_tree_add_string_format(tree, hf_rdt_data_flags2, tvb, offset, 1,
495 "Back-to-back=%u, slow-data=%u, asm-rule=%u",
500 /* Create subtree for flags and add fields */
501 flags_tree2 = proto_item_add_subtree(ti, ett_rdt_data_flags2);
503 proto_tree_add_item(flags_tree2, hf_rdt_data_backtoback, tvb, offset, 1, FALSE);
504 proto_tree_add_item(flags_tree2, hf_rdt_data_slowdata, tvb, offset, 1, FALSE);
505 proto_tree_add_item(flags_tree2, hf_rdt_data_asmrule, tvb, offset, 1, FALSE);
510 timestamp = tvb_get_ntohl(tvb, offset);
511 proto_tree_add_item(tree, hf_rdt_timestamp, tvb, offset, 4, FALSE);
514 /* Stream ID expansion */
517 stream_id = tvb_get_ntohs(tvb, offset);
518 proto_tree_add_item(tree, hf_rdt_stream_id_ex, tvb, offset, 2, FALSE);
523 if (need_reliable_flag)
525 proto_tree_add_item(tree, hf_rdt_total_reliable, tvb, offset, 2, FALSE);
529 /* Asm rule number */
530 if (asm_rule_number == 63)
532 asm_rule_number = tvb_get_ntohs(tvb, offset);
533 proto_tree_add_item(tree, hf_rdt_asmrule_ex, tvb, offset, 2, FALSE);
537 if (check_col(pinfo->cinfo, COL_PROTOCOL))
539 col_append_fstr(pinfo->cinfo, COL_INFO,
540 "DATA: stream-id=%02u asm-rule=%02u seq=%05u ts=%05u ",
541 stream_id, asm_rule_number, sequence_number, timestamp);
544 /* The remaining data is unparsed. */
545 proto_tree_add_item(tree, hf_rdt_data, tvb, offset, -1, FALSE);
546 offset += tvb_length_remaining(tvb, offset);
548 if (packet_length < (offset - start_offset) ||
549 packet_length > tvb_length_remaining(tvb, start_offset))
551 proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
552 packet_length = tvb_length_remaining(tvb, start_offset);
555 return start_offset + packet_length;
558 /* Dissect an asm-action packet */
559 guint dissect_rdt_asm_action_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
561 guint start_offset = offset;
562 guint16 packet_length;
564 guint8 length_included_flag;
567 proto_tree *flags_tree = NULL;
568 proto_item *ti = NULL;
570 /* Flags in first byte */
571 flags1 = tvb_get_guint8(tvb, offset);
572 length_included_flag = (flags1 & 0x80) >> 7;
573 stream_id = (flags1 & 0x7c) >> 2;
575 /* Create subtree for flags fields */
578 ti = proto_tree_add_item(tree, proto_rdt, tvb, offset, -1, FALSE);
579 ti = proto_tree_add_string_format(tree, hf_rdt_aact_flags, tvb, offset, 1,
581 "Length-included=%u, stream_id=%u",
582 length_included_flag,
584 flags_tree = proto_item_add_subtree(ti, ett_rdt_aact_flags);
586 proto_tree_add_item(flags_tree, hf_rdt_len_included, tvb, offset, 1, FALSE);
587 proto_tree_add_item(flags_tree, hf_rdt_aact_stream_id, tvb, offset, 1, FALSE);
592 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, FALSE);
595 rel_seqno = tvb_get_ntohs(tvb, offset);
596 proto_tree_add_item(tree, hf_rdt_aact_reliable_seqno, tvb, offset, 2, FALSE);
599 /* Length field is optional */
600 if (length_included_flag)
602 packet_length = tvb_get_ntohs(tvb, offset);
603 proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, FALSE);
606 /* Check that there are as many bytes as reported */
607 tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
611 packet_length = tvb_length_remaining(tvb, start_offset);
614 /* Stream ID expansion */
617 stream_id = tvb_get_ntohs(tvb, offset);
618 proto_tree_add_item(tree, hf_rdt_stream_id_ex, tvb, offset, 2, FALSE);
622 if (check_col(pinfo->cinfo, COL_PROTOCOL))
624 col_append_fstr(pinfo->cinfo, COL_INFO,
625 "ASM-ACTION: stream-id=%02u rel-seqno=%05u ",
626 stream_id, rel_seqno);
629 /* The remaining data is unparsed. */
630 proto_tree_add_item(tree, hf_rdt_data, tvb, offset, -1, FALSE);
632 if (packet_length < (offset - start_offset) ||
633 packet_length > tvb_length_remaining(tvb, start_offset))
635 proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
636 packet_length = tvb_length_remaining(tvb, start_offset);
639 return start_offset + packet_length;
642 /* Dissect an bandwidth-report packet */
643 guint dissect_rdt_bandwidth_report_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
645 guint start_offset = offset;
646 guint16 packet_length;
648 guint8 length_included_flag;
649 proto_tree *flags_tree = NULL;
650 proto_item *ti = NULL;
652 /* Flags in first byte */
653 flags1 = tvb_get_guint8(tvb, offset);
654 length_included_flag = (flags1 & 0x80) >> 7;
656 /* Create subtree for flags fields */
659 ti = proto_tree_add_string_format(tree, hf_rdt_bandwidth_report_flags, tvb, offset, 1,
661 "Length-included=%u",
662 length_included_flag);
663 flags_tree = proto_item_add_subtree(ti, ett_rdt_bandwidth_report_flags);
665 proto_tree_add_item(flags_tree, hf_rdt_len_included, tvb, offset, 1, FALSE);
670 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, FALSE);
673 /* Length field is optional */
674 if (length_included_flag)
676 packet_length = tvb_get_ntohs(tvb, offset);
677 proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, FALSE);
680 /* Check that there are as many bytes as reported */
681 tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
685 packet_length = tvb_length_remaining(tvb, start_offset);
688 proto_tree_add_item(tree, hf_rdt_brpt_interval, tvb, offset, 2, FALSE);
690 proto_tree_add_item(tree, hf_rdt_brpt_bandwidth, tvb, offset, 4, FALSE);
692 proto_tree_add_item(tree, hf_rdt_brpt_sequence, tvb, offset, 1, FALSE);
695 if (check_col(pinfo->cinfo, COL_PROTOCOL))
697 col_append_str(pinfo->cinfo, COL_INFO, "BANDWIDTH-REPORT: ");
700 if (packet_length < (offset - start_offset) ||
701 packet_length > tvb_length_remaining(tvb, start_offset))
703 proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
704 packet_length = tvb_length_remaining(tvb, start_offset);
707 return start_offset + packet_length;
710 /* Dissect an ack packet */
711 guint dissect_rdt_ack_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
713 guint start_offset = offset;
714 guint16 packet_length;
716 guint8 length_included_flag;
717 guint8 lost_high_flag;
718 proto_tree *flags_tree = NULL;
719 proto_item *ti = NULL;
721 /* Flags in first byte */
722 flags1 = tvb_get_guint8(tvb, offset);
723 length_included_flag = (flags1 & 0x80) >> 7;
724 lost_high_flag = (flags1 & 0x40) >> 6;
726 /* Create subtree for flags fields */
729 ti = proto_tree_add_string_format(tree, hf_rdt_ack_flags, tvb, offset, 1,
731 "Length-included=%u, lost-high=%u",
732 length_included_flag,
734 flags_tree = proto_item_add_subtree(ti, ett_rdt_ack_flags);
736 proto_tree_add_item(flags_tree, hf_rdt_len_included, tvb, offset, 1, FALSE);
737 proto_tree_add_item(flags_tree, hf_rdt_ack_lost_high, tvb, offset, 1, FALSE);
742 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, FALSE);
745 /* Length field is optional */
746 if (length_included_flag)
748 packet_length = tvb_get_ntohs(tvb, offset);
749 proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, FALSE);
752 /* Check that there are as many bytes as reported */
753 tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
757 packet_length = tvb_length_remaining(tvb, start_offset);
760 /* XXX: The remaining data is unparsed. */
761 proto_tree_add_item(tree, hf_rdt_data, tvb, offset, -1, FALSE);
763 if (check_col(pinfo->cinfo, COL_PROTOCOL))
765 col_append_fstr(pinfo->cinfo, COL_INFO, "ACK: lh=%u ", lost_high_flag);
768 if (packet_length < (offset - start_offset) ||
769 packet_length > tvb_length_remaining(tvb, start_offset))
771 proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
772 packet_length = tvb_length_remaining(tvb, start_offset);
775 return start_offset + packet_length;
778 /* Dissect an att-request packet */
779 guint dissect_rdt_rtt_request_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
783 /* Flags in first byte */
784 flags1 = tvb_get_guint8(tvb, offset);
788 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, FALSE);
791 if (check_col(pinfo->cinfo, COL_PROTOCOL))
793 col_append_str(pinfo->cinfo, COL_INFO, "RTT-REQUEST: ");
799 /* Dissect an att-response packet */
800 guint dissect_rdt_rtt_response_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
804 /* Flags in first byte */
805 flags1 = tvb_get_guint8(tvb, offset);
809 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, FALSE);
812 proto_tree_add_item(tree, hf_rdt_rtrp_ts_sec, tvb, offset, 4, FALSE);
814 proto_tree_add_item(tree, hf_rdt_rtrp_ts_usec, tvb, offset, 4, FALSE);
817 if (check_col(pinfo->cinfo, COL_PROTOCOL))
819 col_append_str(pinfo->cinfo, COL_INFO, "RTT-RESPONSE: ");
825 /* Dissect an congestion packet */
826 guint dissect_rdt_congestion_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
830 /* Flags in first byte */
831 flags1 = tvb_get_guint8(tvb, offset);
835 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, FALSE);
838 proto_tree_add_item(tree, hf_rdt_cong_xmit_mult, tvb, offset, 4, FALSE);
840 proto_tree_add_item(tree, hf_rdt_cong_recv_mult, tvb, offset, 4, FALSE);
843 if (check_col(pinfo->cinfo, COL_PROTOCOL))
845 col_append_str(pinfo->cinfo, COL_INFO, "CONGESTION: ");
851 /* Dissect an stream-end packet */
852 guint dissect_rdt_stream_end_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
855 guint8 need_reliable;
859 proto_tree *flags_tree = NULL;
860 proto_item *ti = NULL;
862 /* Flags in first byte */
863 flags1 = tvb_get_guint8(tvb, offset);
864 need_reliable = (flags1 & 0x80) >> 7;
865 stream_id = (flags1 & 0x7c) >> 2;
866 packet_sent = (flags1 & 0x2) >> 1;
867 ext_flag = flags1 & 0x1;
869 /* Create subtree for flags fields */
872 ti = proto_tree_add_string_format(tree, hf_rdt_stre_flags, tvb, offset, 1,
874 "Need-reliable=%u, stream-id=%u, packet-sent=%u, ext-flag=%u",
879 flags_tree = proto_item_add_subtree(ti, ett_rdt_stre_flags);
881 proto_tree_add_item(flags_tree, hf_rdt_stre_need_reliable, tvb, offset, 1, FALSE);
882 proto_tree_add_item(flags_tree, hf_rdt_stre_stream_id, tvb, offset, 1, FALSE);
883 proto_tree_add_item(flags_tree, hf_rdt_stre_packet_sent, tvb, offset, 1, FALSE);
884 proto_tree_add_item(flags_tree, hf_rdt_stre_ext_flag, tvb, offset, 1, FALSE);
889 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, FALSE);
892 proto_tree_add_item(tree, hf_rdt_stre_seqno, tvb, offset, 2, FALSE);
894 proto_tree_add_item(tree, hf_rdt_timestamp, tvb, offset, 4, FALSE);
897 /* Stream ID expansion */
900 stream_id = tvb_get_ntohs(tvb, offset);
901 proto_tree_add_item(tree, hf_rdt_stream_id_ex, tvb, offset, 2, FALSE);
908 proto_tree_add_item(tree, hf_rdt_total_reliable, tvb, offset, 2, FALSE);
914 proto_tree_add_item(tree, hf_rdt_stre_dummy_flags1, tvb, offset, 1, FALSE);
916 proto_tree_add_item(tree, hf_rdt_stre_dummy_type, tvb, offset, 2, FALSE);
918 proto_tree_add_item(tree, hf_rdt_stre_reason_code, tvb, offset, 4, FALSE);
920 /* XXX: Remainder is reason_text */
921 offset += tvb_length_remaining(tvb, offset);
924 if (check_col(pinfo->cinfo, COL_PROTOCOL))
926 col_append_fstr(pinfo->cinfo, COL_INFO, "STREAM-END: stream-id=%02u ", stream_id);
932 /* Dissect an report packet */
933 guint dissect_rdt_report_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
935 guint start_offset = offset;
936 guint16 packet_length;
938 guint8 length_included_flag;
939 proto_tree *flags_tree = NULL;
940 proto_item *ti = NULL;
942 /* Flags in first byte */
943 flags1 = tvb_get_guint8(tvb, offset);
944 length_included_flag = (flags1 & 0x80) >> 7;
946 /* Create subtree for flags fields */
949 ti = proto_tree_add_string_format(tree, hf_rdt_report_flags, tvb, offset, 1,
951 "Length-included=%u",
952 length_included_flag);
953 flags_tree = proto_item_add_subtree(ti, ett_rdt_report_flags);
955 proto_tree_add_item(flags_tree, hf_rdt_len_included, tvb, offset, 1, FALSE);
960 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, FALSE);
963 /* Length field is optional */
964 if (length_included_flag)
966 packet_length = tvb_get_ntohs(tvb, offset);
967 proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, FALSE);
970 /* Check that there are as many bytes as reported */
971 tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
975 packet_length = tvb_length_remaining(tvb, start_offset);
978 if (check_col(pinfo->cinfo, COL_PROTOCOL))
980 col_append_str(pinfo->cinfo, COL_INFO, "REPORT: ");
983 /* The remaining data is unparsed. */
984 proto_tree_add_item(tree, hf_rdt_data, tvb, offset, -1, FALSE);
986 if (packet_length < (offset - start_offset) ||
987 packet_length > tvb_length_remaining(tvb, start_offset))
989 proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
990 packet_length = tvb_length_remaining(tvb, start_offset);
993 return start_offset + packet_length;
996 /* Dissect an latency-report packet */
997 guint dissect_rdt_latency_report_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
999 guint start_offset = offset;
1000 guint16 packet_length;
1002 guint8 length_included_flag;
1003 guint32 server_out_time;
1004 proto_tree *flags_tree = NULL;
1005 proto_item *ti = NULL;
1007 /* Flags in first byte */
1008 flags1 = tvb_get_guint8(tvb, offset);
1009 length_included_flag = (flags1 & 0x80) >> 7;
1011 /* Create subtree for flags fields */
1014 ti = proto_tree_add_string_format(tree, hf_rdt_latency_report_flags, tvb, offset, 1,
1016 "Length-included=%u",
1017 length_included_flag);
1018 flags_tree = proto_item_add_subtree(ti, ett_rdt_latency_report_flags);
1020 proto_tree_add_item(flags_tree, hf_rdt_len_included, tvb, offset, 1, FALSE);
1025 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, FALSE);
1028 /* Length field is optional */
1029 if (length_included_flag)
1031 packet_length = tvb_get_ntohs(tvb, offset);
1032 proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, FALSE);
1035 /* Check that there are as many bytes as reported */
1036 tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
1040 packet_length = tvb_length_remaining(tvb, start_offset);
1043 server_out_time = tvb_get_ntohl(tvb, offset);
1044 proto_tree_add_item(tree, hf_rdt_lrpt_server_out_time, tvb, offset, 4, FALSE);
1047 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1049 col_append_fstr(pinfo->cinfo, COL_INFO, "LATENCY-REPORT: t=%u ", server_out_time);
1052 if (packet_length < (offset - start_offset) ||
1053 packet_length > tvb_length_remaining(tvb, start_offset))
1055 proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
1056 packet_length = tvb_length_remaining(tvb, start_offset);
1059 return start_offset + packet_length;
1062 /* Dissect a transport-info packet */
1063 guint dissect_rdt_transport_info_request_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
1066 guint8 request_rtt_info_flag;
1067 guint8 request_buffer_info_flag;
1068 guint32 request_time_msec;
1069 proto_tree *flags_tree = NULL;
1070 proto_item *ti = NULL;
1072 /* Flags in first byte */
1073 flags1 = tvb_get_guint8(tvb, offset);
1074 request_rtt_info_flag = (flags1 & 0x2) >> 1;
1075 request_buffer_info_flag = (flags1 & 0x01);
1077 /* Create subtree for flags fields */
1080 ti = proto_tree_add_string_format(tree, hf_rdt_ack_flags, tvb, offset, 1,
1082 "Request-rtt-info=%u, request-buffer-info=%u",
1083 request_rtt_info_flag,
1084 request_buffer_info_flag);
1085 flags_tree = proto_item_add_subtree(ti, ett_rdt_tirq_flags);
1087 proto_tree_add_item(flags_tree, hf_rdt_tirq_request_rtt_info, tvb, offset, 1, FALSE);
1088 proto_tree_add_item(flags_tree, hf_rdt_tirq_request_buffer_info, tvb, offset, 1, FALSE);
1093 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, FALSE);
1096 if (request_rtt_info_flag)
1098 request_time_msec = tvb_get_ntohl(tvb, offset);
1099 proto_tree_add_item(tree, hf_rdt_tirq_request_time_msec, tvb, offset, 4, FALSE);
1103 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1105 col_append_str(pinfo->cinfo, COL_INFO, "TRANSPORT-INFO-REQUEST: ");
1111 /* Dissect an transport-info-response packet */
1112 guint dissect_rdt_transport_info_response_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
1115 guint8 has_rtt_info;
1117 guint8 has_buffer_info;
1118 guint32 request_time_msec;
1119 guint32 response_time_msec;
1120 proto_tree *flags_tree = NULL;
1121 proto_item *ti = NULL;
1123 /* Flags in first byte */
1124 flags1 = tvb_get_guint8(tvb, offset);
1125 has_rtt_info = (flags1 & 0x4) >> 2;
1126 is_delayed = (flags1 & 0x2) >> 1;
1127 has_buffer_info = (flags1 & 0x1);
1129 /* Create subtree for flags fields */
1132 ti = proto_tree_add_string_format(tree, hf_rdt_tirp_flags, tvb, offset, 1,
1134 "Has-rtt-info=%u, is-delayed=%u, has-buffer-info=%u",
1138 flags_tree = proto_item_add_subtree(ti, ett_rdt_tirp_flags);
1140 proto_tree_add_item(flags_tree, hf_rdt_tirp_has_rtt_info, tvb, offset, 1, FALSE);
1141 proto_tree_add_item(flags_tree, hf_rdt_tirp_is_delayed, tvb, offset, 1, FALSE);
1142 proto_tree_add_item(flags_tree, hf_rdt_tirp_has_buffer_info, tvb, offset, 1, FALSE);
1147 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, FALSE);
1153 request_time_msec = tvb_get_ntohl(tvb, offset);
1154 proto_tree_add_item(tree, hf_rdt_tirp_request_time_msec, tvb, offset, 4, FALSE);
1159 response_time_msec = tvb_get_ntohl(tvb, offset);
1160 proto_tree_add_item(tree, hf_rdt_tirp_response_time_msec, tvb, offset, 4, FALSE);
1166 if (has_buffer_info)
1170 /* Read number of buffers */
1171 guint16 buffer_info_count = tvb_get_ntohs(tvb, offset);
1172 proto_tree_add_item(tree, hf_rdt_tirp_buffer_info_count, tvb, offset, 2, FALSE);
1175 for (n=0; n < buffer_info_count; n++)
1177 proto_tree *buffer_info_tree = NULL;
1178 proto_item *ti = NULL;
1180 /* Each buffer info in a new subtree */
1181 ti = proto_tree_add_string_format(tree, hf_rdt_tirp_buffer_info, tvb, offset, 14,
1185 buffer_info_tree = proto_item_add_subtree(ti, ett_rdt_tirp_buffer_info);
1187 /* Read individual buffer info */
1188 proto_tree_add_item(buffer_info_tree, hf_rdt_tirp_buffer_info_stream_id, tvb, offset, 2, FALSE);
1190 proto_tree_add_item(buffer_info_tree, hf_rdt_tirp_buffer_info_lowest_timestamp, tvb, offset, 4, FALSE);
1192 proto_tree_add_item(buffer_info_tree, hf_rdt_tirp_buffer_info_highest_timestamp, tvb, offset, 4, FALSE);
1194 proto_tree_add_item(buffer_info_tree, hf_rdt_tirp_buffer_info_bytes_buffered, tvb, offset, 4, FALSE);
1199 /* Report what is left */
1200 offset += tvb_length_remaining(tvb, offset);
1202 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1204 col_append_str(pinfo->cinfo, COL_INFO, "RESPONSE: ");
1210 /* Dissect a bw-probing packet */
1211 guint dissect_rdt_bw_probing_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
1213 guint start_offset = offset;
1214 guint16 packet_length;
1216 guint8 length_included_flag;
1217 proto_tree *flags_tree = NULL;
1218 proto_item *ti = NULL;
1220 /* Flags in first byte */
1221 flags1 = tvb_get_guint8(tvb, offset);
1222 length_included_flag = (flags1 & 0x80) >> 7;
1224 /* Create subtree for flags fields */
1227 ti = proto_tree_add_string_format(tree, hf_rdt_bw_probing_flags, tvb, offset, 1,
1229 "Length-included=%u",
1230 length_included_flag);
1231 flags_tree = proto_item_add_subtree(ti, ett_rdt_bw_probing_flags);
1233 proto_tree_add_item(flags_tree, hf_rdt_len_included, tvb, offset, 1, FALSE);
1238 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, FALSE);
1241 /* Length field is optional */
1242 if (length_included_flag)
1244 packet_length = tvb_get_ntohs(tvb, offset);
1245 proto_tree_add_item(tree, hf_rdt_packet_length, tvb, offset, 2, FALSE);
1248 /* Check that there are as many bytes as reported */
1249 tvb_ensure_bytes_exist(tvb, start_offset, packet_length);
1253 packet_length = tvb_length_remaining(tvb, start_offset);
1256 proto_tree_add_item(tree, hf_rdt_bwpp_seqno, tvb, offset, 1, FALSE);
1258 proto_tree_add_item(tree, hf_rdt_timestamp, tvb, offset, 1, FALSE);
1261 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1263 col_append_str(pinfo->cinfo, COL_INFO, "BW-PROBING: ");
1266 if (packet_length < (offset - start_offset) ||
1267 packet_length > tvb_length_remaining(tvb, start_offset))
1269 proto_tree_add_text(tree, tvb, 0, 0, "Packet length invalid");
1270 packet_length = tvb_length_remaining(tvb, start_offset);
1273 return start_offset + packet_length;
1276 /* Dissect an unknown control packet */
1277 guint dissect_rdt_unknown_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
1281 /* Flags in first byte */
1282 flags1 = tvb_get_guint8(tvb, offset);
1283 proto_tree_add_item(tree, hf_rdt_unk_flags1, tvb, offset, 1, FALSE);
1287 proto_tree_add_item(tree, hf_rdt_packet_type, tvb, offset, 2, FALSE);
1290 /* The remaining data is unparsed. */
1291 proto_tree_add_item(tree, hf_rdt_data, tvb, offset, -1, FALSE);
1292 offset += tvb_length_remaining(tvb, offset);
1294 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1296 col_append_str(pinfo->cinfo, COL_INFO, "UNKNOWN-CTL: ");
1302 /* Look for conversation info and display any setup info found */
1303 static void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1305 /* Conversation and current data */
1306 conversation_t *p_conv = NULL;
1307 struct _rdt_conversation_info *p_conv_data = NULL;
1309 /* Use existing packet info if available */
1310 p_conv_data = p_get_proto_data(pinfo->fd, proto_rdt);
1314 /* First time, get info from conversation */
1315 p_conv = find_conversation(pinfo->fd->num, &pinfo->net_dst, &pinfo->net_src,
1317 pinfo->destport, pinfo->srcport, NO_ADDR_B);
1320 /* Create space for conversation info */
1321 struct _rdt_conversation_info *p_conv_packet_data;
1322 p_conv_data = conversation_get_proto_data(p_conv, proto_rdt);
1326 /* Save this conversation info into packet info */
1327 p_conv_packet_data = se_alloc(sizeof(struct _rdt_conversation_info));
1328 g_snprintf(p_conv_packet_data->method, MAX_RDT_SETUP_METHOD_SIZE, "%s", p_conv_data->method);
1329 p_conv_packet_data->method[MAX_RDT_SETUP_METHOD_SIZE]=0;
1330 p_conv_packet_data->frame_number = p_conv_data->frame_number;
1331 p_conv_packet_data->feature_level = p_conv_data->feature_level;
1332 p_add_proto_data(pinfo->fd, proto_rdt, p_conv_packet_data);
1337 /* Create setup info subtree with summary info. */
1340 proto_tree *rdt_setup_tree;
1341 proto_item *ti = proto_tree_add_string_format(tree, hf_rdt_setup, tvb, 0, 0,
1343 "Stream setup by %s (frame %u), feature level %d",
1344 p_conv_data->method,
1345 p_conv_data->frame_number,
1346 p_conv_data->feature_level);
1347 PROTO_ITEM_SET_GENERATED(ti);
1348 rdt_setup_tree = proto_item_add_subtree(ti, ett_rdt_setup);
1351 /* Add details into subtree */
1352 proto_item* item = proto_tree_add_uint(rdt_setup_tree, hf_rdt_setup_frame,
1353 tvb, 0, 0, p_conv_data->frame_number);
1354 PROTO_ITEM_SET_GENERATED(item);
1355 item = proto_tree_add_string(rdt_setup_tree, hf_rdt_setup_method,
1356 tvb, 0, 0, p_conv_data->method);
1357 PROTO_ITEM_SET_GENERATED(item);
1358 item = proto_tree_add_int(rdt_setup_tree, hf_rdt_feature_level,
1359 tvb, 0, 0, p_conv_data->feature_level);
1360 PROTO_ITEM_SET_GENERATED(item);
1366 void proto_register_rdt(void)
1368 static hf_register_info hf[] =
1383 &hf_rdt_data_flags1,
1391 "RDT data flags 1", HFILL
1395 &hf_rdt_len_included,
1398 "rdt.length-included",
1407 &hf_rdt_data_need_reliable,
1410 "rdt.need-reliable",
1419 &hf_rdt_data_stream_id,
1431 &hf_rdt_data_is_reliable,
1443 &hf_rdt_data_flags2,
1451 "RDT data flags2", HFILL
1455 &hf_rdt_data_backtoback,
1467 &hf_rdt_data_slowdata,
1479 &hf_rdt_data_asmrule,
1493 "RDT asm-action flags 1",
1499 "RDT aact flags", HFILL
1503 &hf_rdt_aact_stream_id,
1515 &hf_rdt_sequence_number,
1518 "rdt.sequence-number",
1527 &hf_rdt_packet_type,
1533 VALS(packet_type_vals),
1535 "Packet type", HFILL
1547 "RDT ack flags", HFILL
1551 &hf_rdt_ack_lost_high,
1563 &hf_rdt_latency_report_flags,
1565 "RDT latency report flags",
1566 "rdt.latency-report-flags",
1571 "RDT latency report flags", HFILL
1575 &hf_rdt_bandwidth_report_flags,
1577 "RDT bandwidth report flags",
1578 "rdt.bandwidth-report-flags",
1583 "RDT bandwidth report flags", HFILL
1589 "RDT stream end flags",
1590 "rdt.stream-end-flags",
1595 "RDT stream end flags", HFILL
1599 &hf_rdt_rtt_request_flags,
1601 "RDT rtt request flags",
1602 "rdt.rtt-request-flags",
1607 "RDT RTT request flags", HFILL
1611 &hf_rdt_rtt_response_flags,
1613 "RDT rtt response flags",
1614 "rdt.rtt-response-flags",
1619 "RDT RTT response flags", HFILL
1623 &hf_rdt_congestion_flags,
1625 "RDT congestion flags",
1626 "rdt.congestion-flags",
1631 "RDT congestion flags", HFILL
1635 &hf_rdt_report_flags,
1643 "RDT report flags", HFILL
1649 "RDT transport info request flags",
1650 "rdt.transport-info-request-flags",
1655 "RDT transport info request flags", HFILL
1661 "RDT transport info response flags",
1662 "rdt.transport-info-response-flags",
1667 "RDT transport info response flags", HFILL
1671 &hf_rdt_bw_probing_flags,
1673 "RDT bw probing flags",
1674 "rdt.bw-probing-flags",
1679 "RDT bw probing flags", HFILL
1683 &hf_rdt_packet_length,
1686 "rdt.packet-length",
1707 &hf_rdt_stream_id_ex,
1709 "Stream-id expansion",
1710 "rdt.stream-id-expansion",
1715 "Stream-id expansion", HFILL
1721 "Asm rule expansion",
1722 "rdt.asm-rule-expansion",
1727 "Asm rule expansion", HFILL
1731 &hf_rdt_total_reliable,
1734 "rdt.total-reliable",
1739 "Total reliable", HFILL
1755 &hf_rdt_aact_reliable_seqno,
1757 "Reliable sequence number",
1758 "rdt.reliable-seq-no",
1767 &hf_rdt_brpt_interval,
1769 "Bandwidth report interval",
1770 "rdt.bwid-report-interval",
1779 &hf_rdt_brpt_bandwidth,
1781 "Bandwidth report bandwidth",
1782 "rdt.bwid-report-bandwidth",
1791 &hf_rdt_brpt_sequence,
1793 "Bandwidth report sequence",
1794 "rdt.bwid-report-sequence",
1803 &hf_rdt_rtrp_ts_sec,
1805 "Round trip response timestamp seconds",
1815 &hf_rdt_rtrp_ts_usec,
1817 "Round trip response timestamp microseconds",
1827 &hf_rdt_cong_xmit_mult,
1829 "Congestion transmit multiplier",
1830 "rdt.cong-xmit-mult",
1839 &hf_rdt_cong_recv_mult,
1841 "Congestion receive multiplier",
1842 "rdt.cong-recv-mult",
1851 &hf_rdt_stre_need_reliable,
1854 "rdt.stre-need-reliable",
1863 &hf_rdt_stre_stream_id,
1866 "rdt.stre-stream-id",
1875 &hf_rdt_stre_packet_sent,
1878 "rdt.stre-packet-sent",
1887 &hf_rdt_stre_ext_flag,
1890 "rdt.stre-ext-flag",
1902 "Stream end sequence number",
1912 &hf_rdt_stre_dummy_flags1,
1914 "Stream end reason dummy flags1",
1915 "rdt.stre-reason-dummy-flags1",
1924 &hf_rdt_stre_dummy_type,
1926 "Stream end reason dummy type",
1927 "rdt.stre-reason-dummy-type",
1936 &hf_rdt_stre_reason_code,
1938 "Stream end reason code",
1939 "rdt.stre-reason-code",
1948 &hf_rdt_lrpt_server_out_time,
1950 "Latency report server out time",
1951 "rdt.lrpt-server-out-time",
1960 &hf_rdt_tirq_request_rtt_info,
1962 "Transport info request rtt info flag",
1963 "rdt.tirq-request-rtt-info",
1972 &hf_rdt_tirq_request_buffer_info,
1974 "Transport info request buffer info flag",
1975 "rdt.tirq-request-buffer-info",
1984 &hf_rdt_tirq_request_time_msec,
1986 "Transport info request time msec",
1987 "rdt.tirq-request-time-msec",
1996 &hf_rdt_tirp_has_rtt_info,
1998 "Transport info response has rtt info flag",
1999 "rdt.tirp-has-rtt-info",
2008 &hf_rdt_tirp_is_delayed,
2010 "Transport info response is delayed",
2011 "rdt.tirp-is-delayed",
2020 &hf_rdt_tirp_has_buffer_info,
2022 "Transport info response has buffer info",
2023 "rdt.tirp-has-buffer-info",
2032 &hf_rdt_tirp_request_time_msec,
2034 "Transport info request time msec",
2035 "rdt.tirp-request-time-msec",
2044 &hf_rdt_tirp_response_time_msec,
2046 "Transport info response time msec",
2047 "rdt.tirp-response-time-msec",
2056 &hf_rdt_tirp_buffer_info_count,
2058 "Transport info buffer into count",
2059 "rdt.tirp-buffer-info-count",
2068 &hf_rdt_tirp_buffer_info,
2071 "rdt.tirp-buffer-info",
2076 "RDT buffer info", HFILL
2080 &hf_rdt_tirp_buffer_info_stream_id,
2082 "Buffer info stream-id",
2083 "rdt.tirp-buffer-info-stream-id",
2092 &hf_rdt_tirp_buffer_info_lowest_timestamp,
2095 "rdt.tirp-buffer-info-lowest-timestamp",
2104 &hf_rdt_tirp_buffer_info_highest_timestamp,
2106 "Highest timestamp",
2107 "rdt.tirp-buffer-info-highest-timestamp",
2116 &hf_rdt_tirp_buffer_info_bytes_buffered,
2119 "rdt.tirp-buffer-info-bytes-buffered",
2130 "Bandwidth probing packet seqno",
2142 "Unknown packet flags",
2160 "Stream setup, method and frame number", HFILL
2164 &hf_rdt_setup_frame,
2172 "Frame that set up this stream", HFILL
2176 &hf_rdt_setup_method,
2184 "Method used to set up this stream", HFILL
2188 &hf_rdt_feature_level,
2190 "RDT feature level",
2191 "rdt.feature-level",
2201 static gint *ett[] =
2206 &ett_rdt_data_flags1,
2207 &ett_rdt_data_flags2,
2208 &ett_rdt_aact_flags,
2210 &ett_rdt_latency_report_flags,
2211 &ett_rdt_bandwidth_report_flags,
2212 &ett_rdt_stre_flags,
2213 &ett_rdt_rtt_request_flags,
2214 &ett_rdt_rtt_response_flags,
2215 &ett_rdt_congestion_flags,
2216 &ett_rdt_report_flags,
2217 &ett_rdt_tirq_flags,
2218 &ett_rdt_tirp_flags,
2219 &ett_rdt_tirp_buffer_info,
2220 &ett_rdt_bw_probing_flags
2223 module_t *rdt_module;
2225 /* Register protocol and fields */
2226 proto_rdt = proto_register_protocol("Real Data Transport", "RDT", "rdt");
2227 proto_register_field_array(proto_rdt, hf, array_length(hf));
2228 proto_register_subtree_array(ett, array_length(ett));
2229 register_dissector("rdt", dissect_rdt, proto_rdt);
2231 /* Preference settings */
2232 rdt_module = prefs_register_protocol(proto_rdt, proto_reg_handoff_rdt);
2233 prefs_register_bool_preference(rdt_module, "show_setup_info",
2234 "Show stream setup information",
2235 "Where available, show which protocol and frame caused "
2236 "this RDT stream to be created",
2237 &global_rdt_show_setup_info);
2239 prefs_register_bool_preference(rdt_module, "register_udp_port",
2240 "Register default UDP client port",
2241 "Register a client UDP port for RDT traffic",
2242 &global_rdt_register_udp_port);
2244 /* TODO: better to specify a range of ports instead? */
2245 prefs_register_uint_preference(rdt_module, "default_udp_port",
2246 "Default UDP client port",
2247 "Set the UDP port for clients",
2248 10, &global_rdt_udp_port);
2252 void proto_reg_handoff_rdt(void)
2254 static int rdt_prefs_initialized = FALSE;
2256 /* Register this dissector as one that can be selected by a
2258 rdt_handle = find_dissector("rdt");
2259 dissector_add_handle("udp.port", rdt_handle);
2262 if (!rdt_prefs_initialized)
2264 rdt_prefs_initialized = TRUE;
2268 /* Undo any current port registrations */
2269 if (rdt_register_udp_port || global_rdt_register_udp_port)
2271 dissector_delete("udp.port", rdt_udp_port, rdt_handle);
2275 /* Remember whether a port is set for next time */
2276 rdt_register_udp_port = global_rdt_register_udp_port;
2278 /* Add any new port registration */
2279 if (global_rdt_register_udp_port)
2281 /* Set our port number for future use */
2282 rdt_udp_port = global_rdt_udp_port;
2284 /* And register with this port */
2285 dissector_add("udp.port", global_rdt_udp_port, rdt_handle);