diff --git a/packet-h245.c b/packet-h245.c index 417324dff2..c55977b2e7 100644 --- a/packet-h245.c +++ b/packet-h245.c @@ -6,7 +6,7 @@ * * Maintained by Andreas Sikkema (h323@ramdyne.nl) * - * $Id: packet-h245.c,v 1.47 2004/05/17 20:03:36 sahlberg Exp $ + * $Id: packet-h245.c,v 1.48 2004/06/15 18:26:08 etxrab Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -42,6 +42,8 @@ #include "packet-tpkt.h" #include "packet-per.h" #include "t35.h" +#include "packet-rtp.h" +#include "packet-rtcp.h" static dissector_handle_t rtp_handle=NULL; static dissector_handle_t rtcp_handle=NULL; @@ -14367,17 +14369,12 @@ dissect_h245_mediaChannel(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_t if((!pinfo->fd->flags.visited) && ipv4_address!=0 && ipv4_port!=0 && rtp_handle){ address src_addr; - conversation_t *conv=NULL; src_addr.type=AT_IPv4; src_addr.len=4; src_addr.data=(char *)&ipv4_address; - conv=find_conversation(&src_addr, &src_addr, PT_UDP, ipv4_port, ipv4_port, NO_ADDR_B|NO_PORT_B); - if(!conv){ - conv=conversation_new(&src_addr, &src_addr, PT_UDP, ipv4_port, ipv4_port, NO_ADDR2|NO_PORT2); - conversation_set_dissector(conv, rtp_handle); - } + rtp_add_address(pinfo, (char *)&ipv4_address, ipv4_port, 0, "H245", pinfo->fd->num); } return offset; } @@ -14391,17 +14388,12 @@ dissect_h245_mediaControlChannel(tvbuff_t *tvb, int offset, packet_info *pinfo, if((!pinfo->fd->flags.visited) && ipv4_address!=0 && ipv4_port!=0 && rtcp_handle){ address src_addr; - conversation_t *conv=NULL; src_addr.type=AT_IPv4; src_addr.len=4; src_addr.data=(char *)&ipv4_address; - conv=find_conversation(&src_addr, &src_addr, PT_UDP, ipv4_port, ipv4_port, NO_ADDR_B|NO_PORT_B); - if(!conv){ - conv=conversation_new(&src_addr, &src_addr, PT_UDP, ipv4_port, ipv4_port, NO_ADDR2|NO_PORT2); - conversation_set_dissector(conv, rtcp_handle); - } + rtcp_add_address(pinfo, (char *)&ipv4_address, ipv4_port, 0, "H245", pinfo->fd->num); } return offset; } @@ -17982,7 +17974,7 @@ dissect_h245_signalType(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tre /* XXX this is just wrong. * the definition in the ASN.1 file is : * signalType IA5String (SIZE (1) ^ FROM ("0123456789#*ABCD!")) - * which means the 17 characters are encoded as 8-bit values + * which means the 17 characters are encoded as 8-bit values * between 0x00 and 0x10 * * however, captures from real world applications show that diff --git a/packet-rtcp.c b/packet-rtcp.c index a0e7cd1b0b..de83ccbe75 100644 --- a/packet-rtcp.c +++ b/packet-rtcp.c @@ -1,6 +1,6 @@ /* packet-rtcp.c * - * $Id: packet-rtcp.c,v 1.43 2004/06/01 18:58:04 guy Exp $ + * $Id: packet-rtcp.c,v 1.44 2004/06/15 18:26:08 etxrab Exp $ * * Routines for RTCP dissection * RTCP = Real-time Transport Control Protocol @@ -58,6 +58,9 @@ #endif #include +#include "prefs.h" + + /* Version is the first 2 bits of the first octet*/ #define RTCP_VERSION(octet) ((octet) >> 6) @@ -68,6 +71,8 @@ /* Receiver/ Sender count is the 5 last bits */ #define RTCP_COUNT(octet) ((octet) & 0x1F) +static dissector_handle_t rtcp_handle; + static const value_string rtcp_version_vals[] = { { 0, "Old VAT Version" }, @@ -191,7 +196,7 @@ static int hf_rtcp_fsn = -1; static int hf_rtcp_blp = -1; static int hf_rtcp_padding_count = -1; static int hf_rtcp_padding_data = -1; -static int hf_rtcp_app_PoC1_subtype = -1; +static int hf_rtcp_app_poc1_subtype = -1; static int hf_rtcp_app_poc1_sip_uri = -1; static int hf_rtcp_app_poc1_disp_name = -1; static int hf_rtcp_app_poc1_last_pkt_seq_no = -1; @@ -201,6 +206,12 @@ static int hf_rtcp_app_poc1_reason1_phrase = -1; static int hf_rtcp_app_poc1_reason_code2 = -1; static int hf_rtcp_app_poc1_additionalinfo = -1; +/* RTCP setup fields */ +static int hf_rtcp_setup = -1; +static int hf_rtcp_setup_frame = -1; +static int hf_rtcp_setup_method = -1; + + /* RTCP fields defining a sub tree */ static gint ett_rtcp = -1; static gint ett_ssrc = -1; @@ -209,6 +220,7 @@ static gint ett_ssrc_ext_high = -1; static gint ett_sdes = -1; static gint ett_sdes_item = -1; static gint ett_PoC1 = -1; +static gint ett_rtcp_setup = -1; static address fake_addr; static int heur_init = FALSE; @@ -217,12 +229,23 @@ static gboolean dissect_rtcp_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ); static void dissect_rtcp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ); +static void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); -void rtcp_add_address( packet_info *pinfo, const unsigned char* ip_addr, - int prt ) +/* Preferences bool to control whether or not setup info should be shown */ +static gboolean global_rtcp_show_setup_info = TRUE; + +/* Memory chunk for storing conversation and per-packet info */ +static GMemChunk *rtcp_conversations = NULL; + + +void rtcp_add_address( packet_info *pinfo, + const unsigned char* ip_addr, int port, + int other_port, + gchar *setup_method, guint32 setup_frame_number) { address src_addr; - conversation_t* pconv; + conversation_t* p_conv; + struct _rtcp_conversation_info *p_conv_data = NULL; /* * If this isn't the first time this packet has been processed, @@ -232,43 +255,77 @@ void rtcp_add_address( packet_info *pinfo, const unsigned char* ip_addr, if (pinfo->fd->flags.visited) return; - src_addr.type = AT_IPv4; - src_addr.len = 4; + src_addr.type = pinfo->net_src.type; + src_addr.len = pinfo->net_src.len; src_addr.data = ip_addr; /* * The first time the function is called let the udp dissector * know that we're interested in traffic - */ + * TODO??? + * if ( ! heur_init ) { heur_dissector_add( "udp", dissect_rtcp_heur, proto_rtcp ); heur_init = TRUE; } + */ /* * Check if the ip address and port combination is not * already registered */ - pconv = find_conversation( &src_addr, &fake_addr, PT_UDP, prt, 0, 0 ); + p_conv = find_conversation( &src_addr, &src_addr, PT_UDP, port, other_port, + NO_ADDR_B | (!other_port ? NO_PORT_B : 0)); /* * If not, add - * XXX - use wildcard address and port B? */ - if ( ! pconv ) { - pconv = conversation_new( &src_addr, &fake_addr, PT_UDP, - (guint32) prt, (guint32) 0, 0 ); - conversation_add_proto_data(pconv, proto_rtcp, NULL); - } + if ( ! p_conv ) { + /* Create conversation data */ + p_conv_data = g_mem_chunk_alloc(rtcp_conversations); + /* Check length first time we look at method string */ + strncpy(p_conv_data->method, setup_method, + (strlen(setup_method)+1 <= MAX_RTCP_SETUP_METHOD_SIZE) ? + strlen(setup_method)+1 : + MAX_RTCP_SETUP_METHOD_SIZE); + p_conv_data->method[MAX_RTCP_SETUP_METHOD_SIZE] = '\0'; + p_conv_data->frame_number = setup_frame_number; + + /* Create conversation with this data */ + p_conv = conversation_new( &src_addr, &src_addr, PT_UDP, + (guint32)port, (guint32)port, + NO_ADDR2 | (!other_port ? NO_PORT2 : 0)); + conversation_add_proto_data(p_conv, proto_rtcp, p_conv_data); + + /* Set dissector */ + conversation_set_dissector(p_conv, rtcp_handle); + } + else + { + /* Update existing conversation data */ + p_conv_data = conversation_get_proto_data(p_conv, proto_rtcp); + strcpy(p_conv_data->method, setup_method); + p_conv_data->frame_number = setup_frame_number; + } } -#if 0 static void rtcp_init( void ) { unsigned char* tmp_data; int i; + /* (Re)allocate mem chunk for conversations */ + if (rtcp_conversations) + { + g_mem_chunk_destroy(rtcp_conversations); + } + rtcp_conversations = g_mem_chunk_new("rtcp_conversations", + sizeof(struct _rtcp_conversation_info), + 20 * sizeof(struct _rtcp_conversation_info), + G_ALLOC_ONLY); + + /* Create a fake adddress... */ fake_addr.type = AT_IPv4; fake_addr.len = 4; @@ -279,7 +336,6 @@ static void rtcp_init( void ) } fake_addr.data = tmp_data; } -#endif static gboolean dissect_rtcp_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) @@ -383,7 +439,7 @@ dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree proto_tree *PoC1_tree; proto_item *PoC1_item; - /* XXX If more application types are to be dissected it may be useful to use a table like in packet-sip.c */ + /* XXX If more application types are to be dissected it may be useful to use a table like in packet-sip.c */ static const char app_name_str[] = "PoC1"; @@ -417,7 +473,7 @@ dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree return offset; }else{/* PoC1 Application */ proto_item *item; - item = proto_tree_add_uint( tree, hf_rtcp_app_PoC1_subtype, tvb, offset - 8, 1, rtcp_subtype ); + item = proto_tree_add_uint( tree, hf_rtcp_app_poc1_subtype, tvb, offset - 8, 1, rtcp_subtype ); PROTO_ITEM_SET_GENERATED(item); if (check_col(pinfo->cinfo, COL_INFO)) col_append_fstr(pinfo->cinfo, COL_INFO,"(%s) subtype=%s",ascii_name, @@ -469,7 +525,7 @@ dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree offset = offset + item_len; packet_len = packet_len - item_len; break; - case 3: + case 3: proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_reason_code1, tvb, offset, 1, FALSE ); offset++; packet_len--; @@ -483,13 +539,13 @@ dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree offset = offset + item_len; packet_len = packet_len - item_len; break; - case 4: + case 4: proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_last_pkt_seq_no, tvb, offset, 2, FALSE ); proto_tree_add_text(PoC1_tree, tvb, offset + 2, 2, "Padding 2 bytes"); offset += 4; packet_len-=4; break; - case 6: + case 6: proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_reason_code2, tvb, offset, 2, FALSE ); proto_tree_add_item( PoC1_tree, hf_rtcp_app_poc1_additionalinfo, tvb, offset + 2, 2, FALSE ); offset += 4; @@ -765,6 +821,63 @@ dissect_rtcp_sr( tvbuff_t *tvb, int offset, proto_tree *tree, return offset; } +/* Look for conversation info and display any setup info found */ +void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + /* Conversation and current data */ + conversation_t *p_conv = NULL; + struct _rtcp_conversation_info *p_conv_data = NULL; + + if (!pinfo->fd->flags.visited) + { + /* First time, get info from conversation */ + p_conv = find_conversation(&pinfo->net_src, &pinfo->net_dst, + pinfo->ptype, + pinfo->srcport, pinfo->destport, 0); + if (p_conv) + { + /* Create space for packet info */ + struct _rtcp_conversation_info *p_conv_packet_data; + p_conv_data = conversation_get_proto_data(p_conv, proto_rtcp); + + /* Save this conversation info into packet info */ + p_conv_packet_data = g_mem_chunk_alloc(rtcp_conversations); + strcpy(p_conv_packet_data->method, p_conv_data->method); + p_conv_packet_data->frame_number = p_conv_data->frame_number; + p_add_proto_data(pinfo->fd, proto_rtcp, p_conv_packet_data); + } + } + else + { + /* Otherwise, use stored packet data instead */ + p_conv_data = p_get_proto_data(pinfo->fd, proto_rtcp); + } + + /* Create setup info subtree with summary info. */ + if (p_conv_data) + { + proto_tree *rtcp_setup_tree; + proto_item *ti = proto_tree_add_string_format(tree, hf_rtcp_setup, tvb, 0, 0, + "", + "Stream setup by %s (frame %d)", + p_conv_data->method, + p_conv_data->frame_number); + PROTO_ITEM_SET_GENERATED(ti); + rtcp_setup_tree = proto_item_add_subtree(ti, ett_rtcp_setup); + if (rtcp_setup_tree) + { + /* Add details into subtree */ + proto_item* item = proto_tree_add_uint(rtcp_setup_tree, hf_rtcp_setup_frame, + tvb, 0, 0, p_conv_data->frame_number); + PROTO_ITEM_SET_GENERATED(item); + item = proto_tree_add_string(rtcp_setup_tree, hf_rtcp_setup_method, + tvb, 0, 0, p_conv_data->method); + PROTO_ITEM_SET_GENERATED(item); + } + } +} + + static void dissect_rtcp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) { @@ -817,7 +930,6 @@ dissect_rtcp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) } if ( tree ) { - /* * Check if there are at least 4 bytes left in the frame, * the last 16 bits of those is the length of the current @@ -844,6 +956,14 @@ dissect_rtcp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) ti = proto_tree_add_item(tree, proto_rtcp, tvb, offset, packet_length, FALSE ); rtcp_tree = proto_item_add_subtree( ti, ett_rtcp ); + + /* Conversation setup info */ + if (global_rtcp_show_setup_info) + { + show_setup_info(tvb, pinfo, rtcp_tree); + } + + temp_byte = tvb_get_guint8( tvb, offset ); proto_tree_add_uint( rtcp_tree, hf_rtcp_version, tvb, @@ -1296,7 +1416,7 @@ proto_register_rtcp(void) } }, { - &hf_rtcp_app_PoC1_subtype, + &hf_rtcp_app_poc1_subtype, { "Subtype", "rtcp.app.PoC1.subtype", @@ -1451,6 +1571,43 @@ proto_register_rtcp(void) "", HFILL } }, + { + &hf_rtcp_setup, + { + "Stream setup", + "rtcp.setup", + FT_STRING, + BASE_NONE, + NULL, + 0x0, + "Stream setup, method and frame number", HFILL + } + }, + { + &hf_rtcp_setup_frame, + { + "Setup frame", + "rtcp.setup-frame", + FT_FRAMENUM, + BASE_NONE, + NULL, + 0x0, + "Frame that set up this stream", HFILL + } + }, + { + &hf_rtcp_setup_method, + { + "Setup Method", + "rtcp.setup-method", + FT_STRING, + BASE_NONE, + NULL, + 0x0, + "Method used to set up this stream", HFILL + } + } + }; static gint *ett[] = @@ -1462,8 +1619,10 @@ proto_register_rtcp(void) &ett_sdes, &ett_sdes_item, &ett_PoC1, + &ett_rtcp_setup }; + module_t *rtcp_module; proto_rtcp = proto_register_protocol("Real-time Transport Control Protocol", "RTCP", "rtcp"); @@ -1472,16 +1631,20 @@ proto_register_rtcp(void) register_dissector("rtcp", dissect_rtcp, proto_rtcp); -#if 0 + rtcp_module = prefs_register_protocol(proto_rtcp, NULL); + + prefs_register_bool_preference(rtcp_module, "show_setup_info", + "Show stream setup information", + "Where available, show which protocol and frame caused " + "this RTCP stream to be created", + &global_rtcp_show_setup_info); + register_init_routine( &rtcp_init ); -#endif } void proto_reg_handoff_rtcp(void) { - dissector_handle_t rtcp_handle; - /* * Register this dissector as one that can be selected by a * UDP port number. diff --git a/packet-rtcp.h b/packet-rtcp.h index f596ba4fc2..1e8b217cda 100644 --- a/packet-rtcp.h +++ b/packet-rtcp.h @@ -1,6 +1,6 @@ /* packet-rtcp.h * - * $Id: packet-rtcp.h,v 1.8 2002/08/28 21:00:30 jmayer Exp $ + * $Id: packet-rtcp.h,v 1.9 2004/06/15 18:26:08 etxrab Exp $ * * Routines for RTCP dissection * RTCP = Real-time Transport Control Protocol @@ -27,5 +27,18 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -void rtcp_add_address ( packet_info *pinfo, const unsigned char* ip_addr, int prt ); -void proto_register_rtcp( void ); +/* Info to save in RTCP conversation / packet-info */ +#define MAX_RTCP_SETUP_METHOD_SIZE 8 +struct _rtcp_conversation_info +{ + gchar method[MAX_RTCP_SETUP_METHOD_SIZE]; + guint32 frame_number; +}; + + +/* Add an RTCP conversation with the given details */ +void rtcp_add_address(packet_info *pinfo, + const unsigned char* ip_addr, int port, + int other_port, + gchar *setup_method, guint32 setup_frame_number); + diff --git a/packet-rtp.c b/packet-rtp.c index 7b0ad9eae0..d1ea504281 100644 --- a/packet-rtp.c +++ b/packet-rtp.c @@ -6,7 +6,7 @@ * Copyright 2000, Philips Electronics N.V. * Written by Andreas Sikkema * - * $Id: packet-rtp.c,v 1.48 2004/06/12 08:56:05 guy Exp $ + * $Id: packet-rtp.c,v 1.49 2004/06/15 18:26:08 etxrab Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -66,6 +66,10 @@ #include #include "tap.h" +#include "prefs.h" + +static dissector_handle_t rtp_handle; + static int rtp_tap = -1; static dissector_table_t rtp_pt_dissector_table; @@ -91,10 +95,16 @@ static int hf_rtp_prof_define = -1; static int hf_rtp_length = -1; static int hf_rtp_hdr_ext = -1; +/* RTP setup fields */ +static int hf_rtp_setup = -1; +static int hf_rtp_setup_frame = -1; +static int hf_rtp_setup_method = -1; + /* RTP fields defining a sub tree */ static gint ett_rtp = -1; static gint ett_csrc_list = -1; static gint ett_hdr_ext = -1; +static gint ett_rtp_setup = -1; static dissector_handle_t data_handle; @@ -102,6 +112,13 @@ static gboolean dissect_rtp_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ); static void dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ); +static void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); + +/* Preferences bool to control whether or not setup info should be shown */ +static gboolean global_rtp_show_setup_info = TRUE; + +/* Memory chunk for storing conversation and per-packet info */ +static GMemChunk *rtp_conversations = NULL; /* * Fields in the first octet of the RTP header. @@ -173,11 +190,15 @@ const value_string rtp_payload_type_vals[] = static address fake_addr; static int heur_init = FALSE; -void rtp_add_address( packet_info *pinfo, const unsigned char* ip_addr, - int prt ) +/* Set up an RTP conversation */ +void rtp_add_address(packet_info *pinfo, + const unsigned char* ip_addr, int port, + int other_port, + gchar *setup_method, guint32 setup_frame_number) { address src_addr; - conversation_t* pconv; + conversation_t* p_conv = NULL; + struct _rtp_conversation_info *p_conv_data = NULL; /* * If this isn't the first time this packet has been processed, @@ -187,43 +208,76 @@ void rtp_add_address( packet_info *pinfo, const unsigned char* ip_addr, if (pinfo->fd->flags.visited) return; - src_addr.type = AT_IPv4; - src_addr.len = 4; + src_addr.type = pinfo->net_src.type; + src_addr.len = pinfo->net_src.len; src_addr.data = ip_addr; /* - * The first time the function is called let the tcp dissector + * The first time the function is called let the udp dissector * know that we're interested in traffic - */ + * TODO??? + * if ( ! heur_init ) { heur_dissector_add( "udp", dissect_rtp_heur, proto_rtp ); heur_init = TRUE; } + */ /* - * Check if the ip address an dport combination is not + * Check if the ip address and port combination is not * already registered */ - pconv = find_conversation( &src_addr, &fake_addr, PT_UDP, prt, 0, 0 ); + p_conv = find_conversation( &src_addr, &src_addr, PT_UDP, port, other_port, + NO_ADDR_B | (!other_port ? NO_PORT_B : 0)); /* * If not, add - * XXX - use wildcard address and port B? */ - if ( ! pconv ) { - pconv = conversation_new( &src_addr, &fake_addr, PT_UDP, - (guint32) prt, (guint32) 0, 0 ); - conversation_add_proto_data(pconv, proto_rtp, NULL); - } + if ( ! p_conv ) { + /* Create conversation data */ + p_conv_data = g_mem_chunk_alloc(rtp_conversations); + /* Check length first time we look at method string */ + strncpy(p_conv_data->method, setup_method, + (strlen(setup_method)+1 <= MAX_RTP_SETUP_METHOD_SIZE) ? + strlen(setup_method)+1 : + MAX_RTP_SETUP_METHOD_SIZE); + p_conv_data->method[MAX_RTP_SETUP_METHOD_SIZE] = '\0'; + p_conv_data->frame_number = setup_frame_number; + + /* Create conversation with this data */ + p_conv = conversation_new( &src_addr, &src_addr, PT_UDP, + (guint32)port, (guint32)other_port, + NO_ADDR2 | (!other_port ? NO_PORT2 : 0)); + conversation_add_proto_data(p_conv, proto_rtp, p_conv_data); + + /* Set dissector */ + conversation_set_dissector(p_conv, rtp_handle); + } + else + { + /* Update existing conversation data */ + p_conv_data = conversation_get_proto_data(p_conv, proto_rtp); + strcpy(p_conv_data->method, setup_method); + p_conv_data->frame_number = setup_frame_number; + } } -#if 0 static void rtp_init( void ) { unsigned char* tmp_data; int i; + /* (Re)allocate mem chunk for conversations */ + if (rtp_conversations) + { + g_mem_chunk_destroy(rtp_conversations); + } + rtp_conversations = g_mem_chunk_new("rtp_conversations", + sizeof(struct _rtp_conversation_info), + 20 * sizeof(struct _rtp_conversation_info), + G_ALLOC_ONLY); + /* Create a fake adddress... */ fake_addr.type = AT_IPv4; fake_addr.len = 4; @@ -234,7 +288,6 @@ static void rtp_init( void ) } fake_addr.data = tmp_data; } -#endif static gboolean dissect_rtp_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) @@ -408,8 +461,15 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) marker_set ? ", Mark" : ""); } if ( tree ) { - ti = proto_tree_add_item( tree, proto_rtp, tvb, offset, -1, FALSE ); - rtp_tree = proto_item_add_subtree( ti, ett_rtp ); + /* Create RTP protocol tree */ + ti = proto_tree_add_item(tree, proto_rtp, tvb, offset, -1, FALSE ); + rtp_tree = proto_item_add_subtree(ti, ett_rtp ); + + /* Conversation setup info */ + if (global_rtp_show_setup_info) + { + show_setup_info(tvb, pinfo, rtp_tree); + } proto_tree_add_uint( rtp_tree, hf_rtp_version, tvb, offset, 1, octet1 ); @@ -440,7 +500,7 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) offset += 4; } else { offset += 12; - } + } /* CSRC list*/ if ( csrc_count > 0 ) { if ( tree ) { @@ -573,6 +633,64 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) tap_queue_packet(rtp_tap, pinfo, &rtp_info); } + +/* Look for conversation info and display any setup info found */ +void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + /* Conversation and current data */ + conversation_t *p_conv = NULL; + struct _rtp_conversation_info *p_conv_data = NULL; + + if (!pinfo->fd->flags.visited) + { + /* First time, get info from conversation */ + p_conv = find_conversation(&pinfo->net_src, &pinfo->net_dst, + pinfo->ptype, + pinfo->srcport, pinfo->destport, 0); + if (p_conv) + { + /* Create space for packet info */ + struct _rtp_conversation_info *p_conv_packet_data; + p_conv_data = conversation_get_proto_data(p_conv, proto_rtp); + + /* Save this conversation info into packet info */ + p_conv_packet_data = g_mem_chunk_alloc(rtp_conversations); + strcpy(p_conv_packet_data->method, p_conv_data->method); + p_conv_packet_data->frame_number = p_conv_data->frame_number; + p_add_proto_data(pinfo->fd, proto_rtp, p_conv_packet_data); + } + } + else + { + /* Otherwise, use stored packet data instead */ + p_conv_data = p_get_proto_data(pinfo->fd, proto_rtp); + } + + /* Create setup info subtree with summary info. */ + if (p_conv_data) + { + proto_tree *rtp_setup_tree; + proto_item *ti = proto_tree_add_string_format(tree, hf_rtp_setup, tvb, 0, 0, + "", + "Stream setup by %s (frame %d)", + p_conv_data->method, + p_conv_data->frame_number); + PROTO_ITEM_SET_GENERATED(ti); + rtp_setup_tree = proto_item_add_subtree(ti, ett_rtp_setup); + if (rtp_setup_tree) + { + /* Add details into subtree */ + proto_item* item = proto_tree_add_uint(rtp_setup_tree, hf_rtp_setup_frame, + tvb, 0, 0, p_conv_data->frame_number); + PROTO_ITEM_SET_GENERATED(item); + item = proto_tree_add_string(rtp_setup_tree, hf_rtp_setup_method, + tvb, 0, 0, p_conv_data->method); + PROTO_ITEM_SET_GENERATED(item); + } + } +} + + void proto_register_rtp(void) { @@ -770,15 +888,55 @@ proto_register_rtp(void) "", HFILL } }, -}; + { + &hf_rtp_setup, + { + "Stream setup", + "rtp.setup", + FT_STRING, + BASE_NONE, + NULL, + 0x0, + "Stream setup, method and frame number", HFILL + } + }, + { + &hf_rtp_setup_frame, + { + "Setup frame", + "rtp.setup-frame", + FT_FRAMENUM, + BASE_NONE, + NULL, + 0x0, + "Frame that set up this stream", HFILL + } + }, + { + &hf_rtp_setup_method, + { + "Setup Method", + "rtp.setup-method", + FT_STRING, + BASE_NONE, + NULL, + 0x0, + "Method used to set up this stream", HFILL + } + } + + }; static gint *ett[] = { &ett_rtp, &ett_csrc_list, &ett_hdr_ext, + &ett_rtp_setup }; + module_t *rtp_module; + proto_rtp = proto_register_protocol("Real-Time Transport Protocol", "RTP", "rtp"); @@ -791,16 +949,20 @@ proto_register_rtp(void) rtp_pt_dissector_table = register_dissector_table("rtp.pt", "RTP payload type", FT_UINT8, BASE_DEC); -#if 0 + rtp_module = prefs_register_protocol(proto_rtp, NULL); + + prefs_register_bool_preference(rtp_module, "show_setup_info", + "Show stream setup information", + "Where available, show which protocol and frame caused " + "this RTP stream to be created", + &global_rtp_show_setup_info); + register_init_routine( &rtp_init ); -#endif } void proto_reg_handoff_rtp(void) { - dissector_handle_t rtp_handle; - data_handle = find_dissector("data"); /* diff --git a/packet-rtp.h b/packet-rtp.h index ee5b1bda27..e10b4e08be 100644 --- a/packet-rtp.h +++ b/packet-rtp.h @@ -3,7 +3,7 @@ * Routines for RTP dissection * RTP = Real time Transport Protocol * - * $Id: packet-rtp.h,v 1.11 2004/01/31 09:48:25 guy Exp $ + * $Id: packet-rtp.h,v 1.12 2004/06/15 18:26:08 etxrab Exp $ * * Copyright 2000, Philips Electronics N.V. * Written by Andreas Sikkema @@ -50,5 +50,16 @@ struct _rtp_info { */ }; -void rtp_add_address ( packet_info *pinfo, const unsigned char* ip_addr, int prt ); -void proto_register_rtp( void ); +/* Info to save in RTP conversation / packet-info */ +#define MAX_RTP_SETUP_METHOD_SIZE 8 +struct _rtp_conversation_info +{ + gchar method[MAX_RTP_SETUP_METHOD_SIZE]; + guint32 frame_number; +}; + +/* Add an RTP conversation with the given details */ +void rtp_add_address(packet_info *pinfo, + const unsigned char* ip_addr, int port, + int other_port, + gchar *setup_method, guint32 setup_frame_number); diff --git a/packet-rtsp.c b/packet-rtsp.c index 93e6d561c0..06c9bc4013 100644 --- a/packet-rtsp.c +++ b/packet-rtsp.c @@ -4,7 +4,7 @@ * Jason Lango * Liberally copied from packet-http.c, by Guy Harris * - * $Id: packet-rtsp.c,v 1.64 2004/05/11 10:55:42 guy Exp $ + * $Id: packet-rtsp.c,v 1.65 2004/06/15 18:26:08 etxrab Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -27,7 +27,7 @@ * References: * RTSP is defined in RFC 2326, http://www.ietf.org/rfc/rfc2326.txt?number=2326 * http://www.iana.org/assignments/rsvp-parameters - * + * */ #include "config.h" @@ -266,15 +266,15 @@ typedef enum { static const char *rtsp_methods[] = { "DESCRIBE", - "ANNOUNCE", - "GET_PARAMETER", + "ANNOUNCE", + "GET_PARAMETER", "OPTIONS", - "PAUSE", - "PLAY", - "RECORD", - "REDIRECT", + "PAUSE", + "PLAY", + "RECORD", + "REDIRECT", "SETUP", - "SET_PARAMETER", + "SET_PARAMETER", "TEARDOWN" }; @@ -444,16 +444,14 @@ rtsp_create_conversation(packet_info *pinfo, const guchar *line_begin, */ SET_ADDRESS(&null_addr, pinfo->src.type, 0, NULL); - conv = conversation_new(&pinfo->dst, &null_addr, PT_UDP, c_data_port, - s_data_port, NO_ADDR2 | (!s_data_port ? NO_PORT2 : 0)); - conversation_set_dissector(conv, rtp_handle); + rtp_add_address(pinfo, (char *)&pinfo->dst, c_data_port, s_data_port, + "RTSP", pinfo->fd->num); if (!c_mon_port) return; - conv = conversation_new(&pinfo->dst, &null_addr, PT_UDP, c_mon_port, - s_mon_port, NO_ADDR2 | (!s_mon_port ? NO_PORT2 : 0)); - conversation_set_dissector(conv, rtcp_handle); + rtcp_add_address(pinfo, (char *)&pinfo->dst, c_mon_port, s_mon_port, + "RTSP", pinfo->fd->num); } static const char rtsp_content_length[] = "Content-Length:"; @@ -597,10 +595,10 @@ dissect_rtspmessage(tvbuff_t *tvb, int offset, packet_info *pinfo, else col_add_str(pinfo->cinfo, COL_INFO, format_text(line, first_linelen)); - + else col_set_str(pinfo->cinfo, COL_INFO, "Continuation"); - + } orig_offset = offset; @@ -635,7 +633,7 @@ dissect_rtspmessage(tvbuff_t *tvb, int offset, packet_info *pinfo, return -1; line_end_offset = offset + linelen; /* - * colon_offset may be -1 + * colon_offset may be -1 */ colon_offset = tvb_find_guint8(tvb, offset, linelen, ':'); @@ -766,7 +764,7 @@ dissect_rtspmessage(tvbuff_t *tvb, int offset, packet_info *pinfo, /* * Not a blank line - either a request, a reply, or a header * line. - */ + */ saw_req_resp_or_header = TRUE; if (rtsp_tree) { ti = proto_tree_add_text(rtsp_tree, tvb, offset, @@ -833,13 +831,13 @@ dissect_rtspmessage(tvbuff_t *tvb, int offset, packet_info *pinfo, */ content_length = rtsp_get_content_length(line, linelen); - + } else if (MIME_HDR_MATCHES(rtsp_Session)) { /* * Extract the session string - + */ - + if ( colon_offset != -1 ){ /* * Skip whitespace after the colon. @@ -859,7 +857,7 @@ dissect_rtspmessage(tvbuff_t *tvb, int offset, packet_info *pinfo, value_offset, value_len , tvb_format_text(tvb, value_offset, value_len)); } - + } else if (MIME_HDR_MATCHES(rtsp_X_Vig_Msisdn)) { /* * Extract the X_Vig_Msisdn string @@ -1035,7 +1033,7 @@ process_rtsp_request(tvbuff_t *tvb, int offset, const guchar *data, /* Method name */ proto_tree_add_string(tree, hf_rtsp_method, tvb, offset, strlen(rtsp_methods[ii]), rtsp_methods[ii]); - + /* URL */ url = data; @@ -1125,19 +1123,19 @@ proto_register_rtsp(void) }; static hf_register_info hf[] = { { &hf_rtsp_method, - { "Method", "rtsp.method", FT_STRING, BASE_NONE, NULL, 0, + { "Method", "rtsp.method", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, { &hf_rtsp_url, - { "URL", "rtsp.url", FT_STRING, BASE_NONE, NULL, 0, + { "URL", "rtsp.url", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, { &hf_rtsp_status, - { "Status", "rtsp.status", FT_UINT32, BASE_DEC, NULL, 0, + { "Status", "rtsp.status", FT_UINT32, BASE_DEC, NULL, 0, "", HFILL }}, { &hf_rtsp_session, - { "Session", "rtsp.session", FT_STRING, BASE_NONE, NULL, 0, + { "Session", "rtsp.session", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, { &hf_rtsp_X_Vig_Msisdn, - { "X-Vig-Msisdn", "X_Vig_Msisdn", FT_STRING, BASE_NONE, NULL, 0, + { "X-Vig-Msisdn", "X_Vig_Msisdn", FT_STRING, BASE_NONE, NULL, 0, "", HFILL }}, @@ -1192,10 +1190,10 @@ proto_reg_handoff_rtsp(void) dissector_delete("tcp.port", tcp_alternate_port, rtsp_handle); } /* Set our port number for future use */ - + tcp_port = global_rtsp_tcp_port; tcp_alternate_port = global_rtsp_tcp_alternate_port; - + dissector_add("tcp.port", tcp_port, rtsp_handle); dissector_add("tcp.port", tcp_alternate_port, rtsp_handle); diff --git a/packet-sdp.c b/packet-sdp.c index 69bb46cb20..420ee54075 100644 --- a/packet-sdp.c +++ b/packet-sdp.c @@ -4,7 +4,7 @@ * Jason Lango * Liberally copied from packet-http.c, by Guy Harris * - * $Id: packet-sdp.c,v 1.46 2004/06/01 21:40:41 etxrab Exp $ + * $Id: packet-sdp.c,v 1.47 2004/06/15 18:26:08 etxrab Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -48,7 +48,11 @@ #include #include #include + +#include "packet-rtp.h" #include "rtp_pt.h" +#include "packet-rtcp.h" + static dissector_handle_t rtp_handle=NULL; static dissector_handle_t rtcp_handle=NULL; @@ -187,7 +191,6 @@ dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) char *string; address src_addr; - conversation_t *conv=NULL; transport_info_t transport_info; @@ -380,20 +383,14 @@ dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) src_addr.data=(char *)&ipv4_address; if(rtp_handle){ - conv=find_conversation(&src_addr, &src_addr, PT_UDP, ipv4_port, ipv4_port, NO_ADDR_B|NO_PORT_B); - if(!conv){ - conv=conversation_new(&src_addr, &src_addr, PT_UDP, ipv4_port, ipv4_port, NO_ADDR2|NO_PORT2); - conversation_set_dissector(conv, rtp_handle); - } + rtp_add_address(pinfo, (char *)&ipv4_address, ipv4_port, 0, + "SDP", pinfo->fd->num); } if(rtcp_handle){ - ipv4_port++; - conv=find_conversation(&src_addr, &src_addr, PT_UDP, ipv4_port, ipv4_port, NO_ADDR_B|NO_PORT_B); - if(!conv){ - conv=conversation_new(&src_addr, &src_addr, PT_UDP, ipv4_port, ipv4_port, NO_ADDR2|NO_PORT2); - conversation_set_dissector(conv, rtcp_handle); - } + ipv4_port++; + rtcp_add_address(pinfo, (char *)&ipv4_address, ipv4_port, 0, + "SDP", pinfo->fd->num); } } }