3 * Routines for RTP dissection
4 * RTP = Real time Transport Protocol
6 * Copyright 2000, Philips Electronics N.V.
7 * Written by Andreas Sikkema <h323@ramdyne.nl>
11 * Ethereal - Network traffic analyzer
12 * By Gerald Combs <gerald@ethereal.com>
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.
31 * This dissector tries to dissect the RTP protocol according to Annex A
32 * of ITU-T Recommendation H.225.0 (02/98) or RFC 1889
34 * RTP traffic is handled by an even UDP portnumber. This can be any
35 * port number, but there is a registered port available, port 5004
36 * See Annex B of ITU-T Recommendation H.225.0, section B.7
38 * This doesn't dissect older versions of RTP, such as:
40 * the vat protocol ("version 0") - see
42 * ftp://ftp.ee.lbl.gov/conferencing/vat/alpha-test/vatsrc-4.0b2.tar.gz
44 * and look in "session-vat.cc" if you want to write a dissector
45 * (have fun - there aren't any nice header files showing the packet
48 * version 1, as documented in
50 * ftp://gaia.cs.umass.edu/pub/hgschulz/rtp/draft-ietf-avt-rtp-04.txt
59 #include <epan/packet.h>
64 #include "packet-rtp.h"
65 #include <epan/rtp_pt.h>
66 #include <epan/conversation.h>
69 #include <epan/prefs.h>
70 #include <epan/emem.h>
72 static dissector_handle_t rtp_handle;
73 static dissector_handle_t stun_handle;
75 static int rtp_tap = -1;
77 static dissector_table_t rtp_pt_dissector_table;
78 static dissector_table_t rtp_dyn_pt_dissector_table;
80 /* RTP header fields */
81 static int proto_rtp = -1;
82 static int hf_rtp_version = -1;
83 static int hf_rtp_padding = -1;
84 static int hf_rtp_extension = -1;
85 static int hf_rtp_csrc_count = -1;
86 static int hf_rtp_marker = -1;
87 static int hf_rtp_payload_type = -1;
88 static int hf_rtp_seq_nr = -1;
89 static int hf_rtp_timestamp = -1;
90 static int hf_rtp_ssrc = -1;
91 static int hf_rtp_csrc_item = -1;
92 static int hf_rtp_data = -1;
93 static int hf_rtp_padding_data = -1;
94 static int hf_rtp_padding_count= -1;
96 /* RTP header extension fields */
97 static int hf_rtp_prof_define = -1;
98 static int hf_rtp_length = -1;
99 static int hf_rtp_hdr_ext = -1;
101 /* RTP setup fields */
102 static int hf_rtp_setup = -1;
103 static int hf_rtp_setup_frame = -1;
104 static int hf_rtp_setup_method = -1;
106 /* RTP fields defining a sub tree */
107 static gint ett_rtp = -1;
108 static gint ett_csrc_list = -1;
109 static gint ett_hdr_ext = -1;
110 static gint ett_rtp_setup = -1;
113 #define RTP0_INVALID 0
116 static enum_val_t rtp_version0_types[] = {
117 { "invalid", "Invalid RTP packets", RTP0_INVALID },
118 { "stun", "STUN packets", RTP0_STUN },
121 static guint global_rtp_version0_type = 0;
123 static dissector_handle_t data_handle;
125 static gboolean dissect_rtp_heur( tvbuff_t *tvb, packet_info *pinfo,
127 static void dissect_rtp( tvbuff_t *tvb, packet_info *pinfo,
129 static void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
130 static void get_conv_info(packet_info *pinfo, struct _rtp_info *rtp_info);
132 /* Preferences bool to control whether or not setup info should be shown */
133 static gboolean global_rtp_show_setup_info = TRUE;
135 /* Try heuristic RTP decode */
136 static gboolean global_rtp_heur = FALSE;
139 * Fields in the first octet of the RTP header.
142 /* Version is the first 2 bits of the first octet*/
143 #define RTP_VERSION(octet) ((octet) >> 6)
145 /* Padding is the third bit; No need to shift, because true is any value
147 #define RTP_PADDING(octet) ((octet) & 0x20)
149 /* Extension bit is the fourth bit */
150 #define RTP_EXTENSION(octet) ((octet) & 0x10)
152 /* CSRC count is the last four bits */
153 #define RTP_CSRC_COUNT(octet) ((octet) & 0xF)
155 static const value_string rtp_version_vals[] =
157 { 0, "Old VAT Version" },
158 { 1, "First Draft Version" },
159 { 2, "RFC 1889 Version" },
164 * Fields in the second octet of the RTP header.
167 /* Marker is the first bit of the second octet */
168 #define RTP_MARKER(octet) ((octet) & 0x80)
170 /* Payload type is the last 7 bits */
171 #define RTP_PAYLOAD_TYPE(octet) ((octet) & 0x7F)
173 const value_string rtp_payload_type_vals[] =
175 { PT_PCMU, "ITU-T G.711 PCMU" },
176 { PT_1016, "USA Federal Standard FS-1016" },
177 { PT_G721, "ITU-T G.721" },
178 { PT_GSM, "GSM 06.10" },
179 { PT_G723, "ITU-T G.723" },
180 { PT_DVI4_8000, "DVI4 8000 samples/s" },
181 { PT_DVI4_16000, "DVI4 16000 samples/s" },
182 { PT_LPC, "Experimental linear predictive encoding from Xerox PARC" },
183 { PT_PCMA, "ITU-T G.711 PCMA" },
184 { PT_G722, "ITU-T G.722" },
185 { PT_L16_STEREO, "16-bit uncompressed audio, stereo" },
186 { PT_L16_MONO, "16-bit uncompressed audio, monaural" },
187 { PT_QCELP, "Qualcomm Code Excited Linear Predictive coding" },
188 { PT_CN, "Comfort noise" },
189 { PT_MPA, "MPEG-I/II Audio"},
190 { PT_G728, "ITU-T G.728" },
191 { PT_DVI4_11025, "DVI4 11025 samples/s" },
192 { PT_DVI4_22050, "DVI4 22050 samples/s" },
193 { PT_G729, "ITU-T G.729" },
194 { PT_CN_OLD, "Comfort noise (old)" },
195 { PT_CELB, "Sun CellB video encoding" },
196 { PT_JPEG, "JPEG-compressed video" },
197 { PT_NV, "'nv' program" },
198 { PT_H261, "ITU-T H.261" },
199 { PT_MPV, "MPEG-I/II Video"},
200 { PT_MP2T, "MPEG-II transport streams"},
201 { PT_H263, "ITU-T H.263" },
205 const value_string rtp_payload_type_short_vals[] =
207 { PT_PCMU, "g711U" },
208 { PT_1016, "fs-1016" },
212 { PT_DVI4_8000, "DVI4 8k" },
213 { PT_DVI4_16000, "DVI4 16k" },
214 { PT_LPC, "Exp. from Xerox PARC" },
215 { PT_PCMA, "g711A" },
217 { PT_L16_STEREO, "16-bit audio, stereo" },
218 { PT_L16_MONO, "16-bit audio, monaural" },
219 { PT_QCELP, "Qualcomm" },
221 { PT_MPA, "MPEG-I/II Audio"},
223 { PT_DVI4_11025, "DVI4 11k" },
224 { PT_DVI4_22050, "DVI4 22k" },
226 { PT_CN_OLD, "CN(old)" },
227 { PT_CELB, "CellB" },
231 { PT_MPV, "MPEG-I/II Video"},
232 { PT_MP2T, "MPEG-II streams"},
238 rtp_free_hash_dyn_payload(GHashTable *rtp_dyn_payload)
240 if (rtp_dyn_payload == NULL) return;
241 g_hash_table_destroy(rtp_dyn_payload);
242 rtp_dyn_payload = NULL;
245 /* Set up an RTP conversation */
246 void rtp_add_address(packet_info *pinfo,
247 address *addr, int port,
249 const gchar *setup_method, guint32 setup_frame_number, GHashTable *rtp_dyn_payload)
252 conversation_t* p_conv;
253 struct _rtp_conversation_info *p_conv_data = NULL;
256 * If this isn't the first time this packet has been processed,
257 * we've already done this work, so we don't need to do it
260 if (pinfo->fd->flags.visited)
265 SET_ADDRESS(&null_addr, AT_NONE, 0, NULL);
268 * Check if the ip address and port combination is not
269 * already registered as a conversation.
271 p_conv = find_conversation( setup_frame_number, addr, &null_addr, PT_UDP, port, other_port,
272 NO_ADDR_B | (!other_port ? NO_PORT_B : 0));
275 * If not, create a new conversation.
277 if ( !p_conv || p_conv->setup_frame != setup_frame_number) {
278 p_conv = conversation_new( setup_frame_number, addr, &null_addr, PT_UDP,
279 (guint32)port, (guint32)other_port,
280 NO_ADDR2 | (!other_port ? NO_PORT2 : 0));
284 conversation_set_dissector(p_conv, rtp_handle);
287 * Check if the conversation has data associated with it.
289 p_conv_data = conversation_get_proto_data(p_conv, proto_rtp);
292 * If not, add a new data item.
294 if ( ! p_conv_data ) {
295 /* Create conversation data */
296 p_conv_data = se_alloc(sizeof(struct _rtp_conversation_info));
297 p_conv_data->rtp_dyn_payload = NULL;
299 conversation_add_proto_data(p_conv, proto_rtp, p_conv_data);
303 * Update the conversation data.
305 /* Free the hash if already exists */
306 rtp_free_hash_dyn_payload(p_conv_data->rtp_dyn_payload);
308 strncpy(p_conv_data->method, setup_method, MAX_RTP_SETUP_METHOD_SIZE);
309 p_conv_data->method[MAX_RTP_SETUP_METHOD_SIZE] = '\0';
310 p_conv_data->frame_number = setup_frame_number;
311 p_conv_data->rtp_dyn_payload = rtp_dyn_payload;
315 dissect_rtp_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
317 guint8 octet1, octet2;
318 unsigned int version;
319 unsigned int payload_type;
320 unsigned int offset = 0;
322 /* This is a heuristic dissector, which means we get all the UDP
323 * traffic not sent to a known dissector and not claimed by
324 * a heuristic dissector called before us!
327 if (! global_rtp_heur)
330 /* Get the fields in the first octet */
331 octet1 = tvb_get_guint8( tvb, offset );
332 version = RTP_VERSION( octet1 );
335 switch (global_rtp_version0_type) {
337 call_dissector(stun_handle, tvb, pinfo, tree);
342 return FALSE; /* Unknown or unsupported version */
344 } else if (version != 2) {
345 /* Unknown or unsupported version */
349 /* Get the fields in the second octet */
350 octet2 = tvb_get_guint8( tvb, offset + 1 );
351 payload_type = RTP_PAYLOAD_TYPE( octet2 );
352 /* if (payload_type == PT_PCMU ||
353 * payload_type == PT_PCMA)
354 * payload_type == PT_G729)
356 if (payload_type <= PT_H263) {
357 dissect_rtp( tvb, pinfo, tree );
366 dissect_rtp_data( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
367 proto_tree *rtp_tree, int offset, unsigned int data_len,
368 unsigned int data_reported_len, unsigned int payload_type )
371 struct _rtp_conversation_info *p_conv_data = NULL;
372 gboolean found_match = FALSE;
374 newtvb = tvb_new_subset( tvb, offset, data_len, data_reported_len );
376 /* if the payload type is dynamic (96 to 127), we check if the conv is set and we look for the pt definition */
377 if ( (payload_type >=96) && (payload_type <=127) ) {
378 p_conv_data = p_get_proto_data(pinfo->fd, proto_rtp);
379 if (p_conv_data && p_conv_data->rtp_dyn_payload) {
380 gchar *payload_type_str = NULL;
381 payload_type_str = g_hash_table_lookup(p_conv_data->rtp_dyn_payload, &payload_type);
382 if (payload_type_str)
383 found_match = dissector_try_string(rtp_dyn_pt_dissector_table,
384 payload_type_str, newtvb, pinfo, tree);
387 /* if we don't found, it is static OR could be set static from the preferences */
388 if (found_match == FALSE)
389 if (!dissector_try_port(rtp_pt_dissector_table, payload_type, newtvb, pinfo, tree))
390 proto_tree_add_item( rtp_tree, hf_rtp_data, newtvb, 0, -1, FALSE );
395 dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
397 proto_item *ti = NULL;
398 proto_tree *rtp_tree = NULL;
399 proto_tree *rtp_csrc_tree = NULL;
400 guint8 octet1, octet2;
401 unsigned int version;
402 gboolean padding_set;
403 gboolean extension_set;
404 unsigned int csrc_count;
406 unsigned int payload_type;
407 gchar *payload_type_str = NULL;
409 unsigned int hdr_extension= 0;
410 unsigned int padding_count;
411 gint length, reported_length;
413 unsigned int offset = 0;
418 struct _rtp_conversation_info *p_conv_data = NULL;
420 /* Can tap up to 4 RTP packets within same packet */
421 static struct _rtp_info rtp_info_arr[4];
422 static int rtp_info_current=0;
423 struct _rtp_info *rtp_info;
426 if (rtp_info_current==4) {
429 rtp_info = &rtp_info_arr[rtp_info_current];
431 /* Get the fields in the first octet */
432 octet1 = tvb_get_guint8( tvb, offset );
433 version = RTP_VERSION( octet1 );
436 switch (global_rtp_version0_type) {
438 call_dissector(stun_handle, tvb, pinfo, tree);
443 ; /* Unknown or unsupported version (let it fall through */
447 /* fill in the rtp_info structure */
448 rtp_info->info_version = version;
451 * Unknown or unsupported version.
453 if ( check_col( pinfo->cinfo, COL_PROTOCOL ) ) {
454 col_set_str( pinfo->cinfo, COL_PROTOCOL, "RTP" );
457 if ( check_col( pinfo->cinfo, COL_INFO) ) {
458 col_add_fstr( pinfo->cinfo, COL_INFO,
459 "Unknown RTP version %u", version);
463 ti = proto_tree_add_item( tree, proto_rtp, tvb, offset, -1, FALSE );
464 rtp_tree = proto_item_add_subtree( ti, ett_rtp );
466 proto_tree_add_uint( rtp_tree, hf_rtp_version, tvb,
472 padding_set = RTP_PADDING( octet1 );
473 extension_set = RTP_EXTENSION( octet1 );
474 csrc_count = RTP_CSRC_COUNT( octet1 );
476 /* Get the fields in the second octet */
477 octet2 = tvb_get_guint8( tvb, offset + 1 );
478 marker_set = RTP_MARKER( octet2 );
479 payload_type = RTP_PAYLOAD_TYPE( octet2 );
481 /* Get the subsequent fields */
482 seq_num = tvb_get_ntohs( tvb, offset + 2 );
483 timestamp = tvb_get_ntohl( tvb, offset + 4 );
484 sync_src = tvb_get_ntohl( tvb, offset + 8 );
486 /* fill in the rtp_info structure */
487 rtp_info->info_padding_set = padding_set;
488 rtp_info->info_padding_count = 0;
489 rtp_info->info_marker_set = marker_set;
490 rtp_info->info_payload_type = payload_type;
491 rtp_info->info_seq_num = seq_num;
492 rtp_info->info_timestamp = timestamp;
493 rtp_info->info_sync_src = sync_src;
494 rtp_info->info_setup_frame_num = 0;
495 rtp_info->info_payload_type_str = NULL;
498 * Do we have all the data?
500 length = tvb_length_remaining(tvb, offset);
501 reported_length = tvb_reported_length_remaining(tvb, offset);
502 if (reported_length >= 0 && length >= reported_length) {
506 rtp_info->info_all_data_present = TRUE;
507 rtp_info->info_data_len = reported_length;
510 * Save the pointer to raw rtp data (header + payload incl.
512 * That should be safe because the "epan_dissect_t"
513 * constructed for the packet has not yet been freed when
514 * the taps are called.
515 * (Destroying the "epan_dissect_t" will end up freeing
516 * all the tvbuffs and hence invalidating pointers to
518 * See "add_packet_to_packet_list()" for details.
520 rtp_info->info_data = tvb_get_ptr(tvb, 0, -1);
523 * No - packet was cut short at capture time.
525 rtp_info->info_all_data_present = FALSE;
526 rtp_info->info_data_len = 0;
527 rtp_info->info_data = NULL;
530 /* Look for conv and add to the frame if found */
531 get_conv_info(pinfo, rtp_info);
533 if ( check_col( pinfo->cinfo, COL_PROTOCOL ) ) {
534 col_set_str( pinfo->cinfo, COL_PROTOCOL, "RTP" );
537 /* if it is dynamic payload, let use the conv data to see if it is defined */
538 if ( (payload_type>95) && (payload_type<128) ) {
539 /* Use existing packet info if available */
540 p_conv_data = p_get_proto_data(pinfo->fd, proto_rtp);
541 if (p_conv_data && p_conv_data->rtp_dyn_payload){
542 payload_type_str = g_hash_table_lookup(p_conv_data->rtp_dyn_payload, &payload_type);
543 rtp_info->info_payload_type_str = payload_type_str;
547 if ( check_col( pinfo->cinfo, COL_INFO) ) {
548 col_add_fstr( pinfo->cinfo, COL_INFO,
549 "Payload type=%s, SSRC=%u, Seq=%u, Time=%u%s",
550 payload_type_str ? payload_type_str : val_to_str( payload_type, rtp_payload_type_vals,"Unknown (%u)" ),
554 marker_set ? ", Mark" : "");
560 /* Create RTP protocol tree */
561 ti = proto_tree_add_item(tree, proto_rtp, tvb, offset, -1, FALSE );
562 rtp_tree = proto_item_add_subtree(ti, ett_rtp );
564 /* Conversation setup info */
565 if (global_rtp_show_setup_info)
567 show_setup_info(tvb, pinfo, rtp_tree);
570 proto_tree_add_uint( rtp_tree, hf_rtp_version, tvb,
572 proto_tree_add_boolean( rtp_tree, hf_rtp_padding, tvb,
574 proto_tree_add_boolean( rtp_tree, hf_rtp_extension, tvb,
576 proto_tree_add_uint( rtp_tree, hf_rtp_csrc_count, tvb,
580 proto_tree_add_boolean( rtp_tree, hf_rtp_marker, tvb, offset,
583 item = proto_tree_add_uint_format( rtp_tree, hf_rtp_payload_type, tvb,
584 offset, 1, octet2, "Payload type: %s (%u)",
585 payload_type_str ? payload_type_str : val_to_str( payload_type, rtp_payload_type_vals,"Unknown"),
590 /* Sequence number 16 bits (2 octets) */
591 proto_tree_add_uint( rtp_tree, hf_rtp_seq_nr, tvb, offset, 2, seq_num );
594 /* Timestamp 32 bits (4 octets) */
595 proto_tree_add_uint( rtp_tree, hf_rtp_timestamp, tvb, offset, 4, timestamp );
598 /* Synchronization source identifier 32 bits (4 octets) */
599 proto_tree_add_uint( rtp_tree, hf_rtp_ssrc, tvb, offset, 4, sync_src );
605 if ( csrc_count > 0 ) {
607 ti = proto_tree_add_text(rtp_tree, tvb, offset, csrc_count * 4, "Contributing Source identifiers");
608 rtp_csrc_tree = proto_item_add_subtree( ti, ett_csrc_list );
610 for (i = 0; i < csrc_count; i++ ) {
611 csrc_item = tvb_get_ntohl( tvb, offset );
612 if ( tree ) proto_tree_add_uint_format( rtp_csrc_tree,
613 hf_rtp_csrc_item, tvb, offset, 4,
621 /* Optional RTP header extension */
622 if ( extension_set ) {
623 /* Defined by profile field is 16 bits (2 octets) */
624 if ( tree ) proto_tree_add_uint( rtp_tree, hf_rtp_prof_define, tvb, offset, 2, tvb_get_ntohs( tvb, offset ) );
627 hdr_extension = tvb_get_ntohs( tvb, offset );
628 if ( tree ) proto_tree_add_uint( rtp_tree, hf_rtp_length, tvb,
629 offset, 2, hdr_extension);
631 if ( hdr_extension > 0 ) {
633 ti = proto_tree_add_text(rtp_tree, tvb, offset, csrc_count * 4, "Header extensions");
634 /* I'm re-using the old tree variable here
635 from the CSRC list!*/
636 rtp_csrc_tree = proto_item_add_subtree( ti,
639 for (i = 0; i < hdr_extension; i++ ) {
640 if ( tree ) proto_tree_add_uint( rtp_csrc_tree, hf_rtp_hdr_ext, tvb, offset, 4, tvb_get_ntohl( tvb, offset ) );
648 * This RTP frame has padding - find it.
650 * The padding count is found in the LAST octet of
651 * the packet; it contains the number of octets
652 * that can be ignored at the end of the packet.
654 if (tvb_length(tvb) < tvb_reported_length(tvb)) {
656 * We don't *have* the last octet of the
657 * packet, so we can't get the padding
660 * Put an indication of that into the
661 * tree, and just put in a raw data
664 if ( tree ) proto_tree_add_text(rtp_tree, tvb, 0, 0,
665 "Frame has padding, but not all the frame data was captured");
666 call_dissector(data_handle,
667 tvb_new_subset(tvb, offset, -1, -1),
672 padding_count = tvb_get_guint8( tvb,
673 tvb_reported_length( tvb ) - 1 );
675 tvb_reported_length_remaining( tvb, offset ) - padding_count;
677 rtp_info->info_payload_offset = offset;
678 rtp_info->info_payload_len = tvb_length_remaining(tvb, offset);
679 rtp_info->info_padding_count = padding_count;
683 * There's data left over when you take out
684 * the padding; dissect it.
686 dissect_rtp_data( tvb, pinfo, tree, rtp_tree,
692 } else if (data_len < 0) {
694 * The padding count is bigger than the
695 * amount of RTP payload in the packet!
696 * Clip the padding count.
698 * XXX - put an item in the tree to indicate
699 * that the padding count is bogus?
702 tvb_reported_length_remaining(tvb, offset);
704 if (padding_count > 1) {
706 * There's more than one byte of padding;
707 * show all but the last byte as padding
710 if ( tree ) proto_tree_add_item( rtp_tree, hf_rtp_padding_data,
711 tvb, offset, padding_count - 1, FALSE );
712 offset += padding_count - 1;
715 * Show the last byte in the PDU as the padding
718 if ( tree ) proto_tree_add_item( rtp_tree, hf_rtp_padding_count,
719 tvb, offset, 1, FALSE );
725 dissect_rtp_data( tvb, pinfo, tree, rtp_tree, offset,
726 tvb_length_remaining( tvb, offset ),
727 tvb_reported_length_remaining( tvb, offset ),
729 rtp_info->info_payload_offset = offset;
730 rtp_info->info_payload_len = tvb_length_remaining(tvb, offset);
732 if (!pinfo->in_error_pkt)
733 tap_queue_packet(rtp_tap, pinfo, rtp_info);
736 /* Look for conversation info */
737 static void get_conv_info(packet_info *pinfo, struct _rtp_info *rtp_info)
739 /* Conversation and current data */
740 conversation_t *p_conv = NULL;
741 struct _rtp_conversation_info *p_conv_data = NULL;
743 /* Use existing packet info if available */
744 p_conv_data = p_get_proto_data(pinfo->fd, proto_rtp);
748 /* First time, get info from conversation */
749 p_conv = find_conversation(pinfo->fd->num, &pinfo->net_dst, &pinfo->net_src,
751 pinfo->destport, pinfo->srcport, NO_ADDR_B);
754 /* Create space for packet info */
755 struct _rtp_conversation_info *p_conv_packet_data;
756 p_conv_data = conversation_get_proto_data(p_conv, proto_rtp);
759 /* Save this conversation info into packet info */
760 p_conv_packet_data = se_alloc(sizeof(struct _rtp_conversation_info));
761 g_snprintf(p_conv_packet_data->method, MAX_RTP_SETUP_METHOD_SIZE, "%s", p_conv_data->method);
762 p_conv_packet_data->method[MAX_RTP_SETUP_METHOD_SIZE]=0;
763 p_conv_packet_data->frame_number = p_conv_data->frame_number;
764 p_conv_packet_data->rtp_dyn_payload = p_conv_data->rtp_dyn_payload;
765 p_add_proto_data(pinfo->fd, proto_rtp, p_conv_packet_data);
769 if (p_conv_data) rtp_info->info_setup_frame_num = p_conv_data->frame_number;
773 /* Display setup info */
774 static void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
776 /* Conversation and current data */
777 struct _rtp_conversation_info *p_conv_data = NULL;
778 proto_tree *rtp_setup_tree;
781 /* Use existing packet info if available */
782 p_conv_data = p_get_proto_data(pinfo->fd, proto_rtp);
784 if (!p_conv_data) return;
786 /* Create setup info subtree with summary info. */
787 ti = proto_tree_add_string_format(tree, hf_rtp_setup, tvb, 0, 0,
789 "Stream setup by %s (frame %u)",
791 p_conv_data->frame_number);
792 PROTO_ITEM_SET_GENERATED(ti);
793 rtp_setup_tree = proto_item_add_subtree(ti, ett_rtp_setup);
796 /* Add details into subtree */
797 proto_item* item = proto_tree_add_uint(rtp_setup_tree, hf_rtp_setup_frame,
798 tvb, 0, 0, p_conv_data->frame_number);
799 PROTO_ITEM_SET_GENERATED(item);
800 item = proto_tree_add_string(rtp_setup_tree, hf_rtp_setup_method,
801 tvb, 0, 0, p_conv_data->method);
802 PROTO_ITEM_SET_GENERATED(item);
808 proto_register_rtp(void)
810 static hf_register_info hf[] =
819 VALS(rtp_version_vals),
851 "Contributing source identifiers count",
873 &hf_rtp_payload_type,
911 "Synchronization Source identifier",
923 "Defined by profile",
981 &hf_rtp_padding_data,
993 &hf_rtp_padding_count,
1013 "Stream setup, method and frame number", HFILL
1017 &hf_rtp_setup_frame,
1025 "Frame that set up this stream", HFILL
1029 &hf_rtp_setup_method,
1037 "Method used to set up this stream", HFILL
1043 static gint *ett[] =
1051 module_t *rtp_module;
1054 proto_rtp = proto_register_protocol("Real-Time Transport Protocol",
1056 proto_register_field_array(proto_rtp, hf, array_length(hf));
1057 proto_register_subtree_array(ett, array_length(ett));
1059 register_dissector("rtp", dissect_rtp, proto_rtp);
1061 rtp_tap = register_tap("rtp");
1063 rtp_pt_dissector_table = register_dissector_table("rtp.pt",
1064 "RTP payload type", FT_UINT8, BASE_DEC);
1065 rtp_dyn_pt_dissector_table = register_dissector_table("rtp_dyn_payload_type",
1066 "Dynamic RTP payload type", FT_STRING, BASE_NONE);
1069 rtp_module = prefs_register_protocol(proto_rtp, NULL);
1071 prefs_register_bool_preference(rtp_module, "show_setup_info",
1072 "Show stream setup information",
1073 "Where available, show which protocol and frame caused "
1074 "this RTP stream to be created",
1075 &global_rtp_show_setup_info);
1077 prefs_register_bool_preference(rtp_module, "heuristic_rtp",
1078 "Try to decode RTP outside of conversations",
1079 "If call control SIP/H323/RTSP/.. messages are missing in the trace, "
1080 "RTP isn't decoded without this",
1083 prefs_register_enum_preference(rtp_module, "version0_type",
1084 "Treat RTP version 0 packets as",
1085 "If an RTP version 0 packet is encountered, it can be treated as an invalid packet or a STUN packet",
1086 &global_rtp_version0_type,
1087 rtp_version0_types, FALSE);
1091 proto_reg_handoff_rtp(void)
1093 data_handle = find_dissector("data");
1094 stun_handle = find_dissector("stun");
1096 * Register this dissector as one that can be selected by a
1099 rtp_handle = find_dissector("rtp");
1100 dissector_add_handle("udp.port", rtp_handle);
1102 heur_dissector_add( "udp", dissect_rtp_heur, proto_rtp);