ANNOUNCEMENT: Live Wireshark University & Allegro Packets online APAC Wireshark Training Session
July 17th, 2024 | 10:00am-11:55am SGT (UTC+8) | Online

Ethereal-dev: Re: [Ethereal-dev] Voip Calls analysis and Graph analysis

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Alejandro Vaquero <alejandrovaquero@xxxxxxxxx>
Date: Tue, 08 Mar 2005 20:08:22 -0700
Hi All,
   find attached a new patch to:
- Automatic dissection of RTP events (RFC2833) set in SDP sessions.
- Add RTP events (RFC2833) to the Voip Graph

Regards
Alejandro

Alejandro Vaquero wrote:

Hi All,
    Find attached a patch to "Voip analysis" to:
- Add a horizontal scrollbar in the "Graph" to scroll the "comments"
- Fix a "state" bug in H323 and SIP calls
- Fix a bug that can make the "graph" to crash, and also clean up the "address" when the window is close

Regards
Alejandro

Alejandro Vaquero wrote:

Hi All,
    Here is another patch for:

voip_calls_dlg.c
Change the "prepare filter" function to be protocol independent. Now it uses the "frame_num"s from the Graph structure to create the filter. This also add support to MGCP and H323 LRQ/LCF filters that were not supported before.

graph_analysis.c:
Change the mouse scroll wheel implementation to make a 3 line step change instead of 1 line.

Regards
Alejandro


Add support to filter MGCP and

Alejandro Vaquero wrote:

Thanks Lars,
Also attached find a patch to graph_analysis.c to add support of mouse scroll wheel and directional keys (Up, down, left, and right) in the Graph Analysis.

Regards
Alejandro

Lars Roland wrote:

Lars Roland schrieb:

Having a short look at the patch, I have to disagree on an implementation detail:

I don't like to have the mgcp dissector allocating a mgcp_info_t structure for each dissection of an mgcp packet without freeing it. This could be considered to be a big memory leak. Instead use a static array of mgcp_info_t structures. You can take the h225 or the q931 dissector as an example of such an implementation.




On Fri, 18 Feb 2005 13:00:00 -0700, Alejandro Vaquero
<alejandrovaquero@xxxxxxxxx> wrote:

Hi All,
find attached a patch to add MGCP calls to the "Voip Analysis". The
implementation is oriented to MGCP Residential Gateways.



checked in along with the changes I've proposed above and an additional check for the presence of the mgcp plugin.

Regards,
Lars

_______________________________________________
Ethereal-dev mailing list
Ethereal-dev@xxxxxxxxxxxx
http://www.ethereal.com/mailman/listinfo/ethereal-dev

------------------------------------------------------------------------

Index: graph_analysis.c
===================================================================
--- graph_analysis.c	(revision 13449)
+++ graph_analysis.c	(working copy)
@@ -38,6 +38,7 @@

/* in /gtk ... */
#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
#include "gtkglobals.h"

#include "dlg_utils.h"
@@ -647,6 +648,63 @@
}

/****************************************************************************/
+static gint scroll_event(GtkWidget *widget, GdkEventButton *event _U_)
+{
+        graph_analysis_data_t *user_data;
+
+        user_data=(graph_analysis_data_t *)OBJECT_GET_DATA(widget, "graph_analysis_data_t");
+
+		/* Up scroll */
+		if (event->state == 0){
+			if (user_data->dlg.first_item == 0) return TRUE;
+			user_data->dlg.first_item--;
+
+		/* Down scroll */
+		} else {
+			if ((user_data->dlg.first_item+user_data->dlg.v_scrollbar_adjustment->page_size+1 == user_data->num_items)) return TRUE;
+			user_data->dlg.first_item++;
+		}
+		dialog_graph_redraw(user_data);
+
+        return TRUE;
+}
+
+/****************************************************************************/
+static gint key_press_event(GtkWidget *widget, GdkEventKey *event _U_)
+{
+        graph_analysis_data_t *user_data;
+
+        user_data=(graph_analysis_data_t *)OBJECT_GET_DATA(widget, "graph_analysis_data_t");
+
+		/* Up arrow */
+		if (event->keyval == GDK_Up){
+			if (user_data->dlg.selected_item == 0) return TRUE;
+			user_data->dlg.selected_item--;
+			if ( (user_data->dlg.selected_item<user_data->dlg.first_item) || (user_data->dlg.selected_item>user_data->dlg.first_item+user_data->dlg.v_scrollbar_adjustment->page_size) )
+				user_data->dlg.first_item = user_data->dlg.selected_item;
+		/* Down arrow */
+		} else if (event->keyval == GDK_Down){
+			if (user_data->dlg.selected_item == user_data->num_items-1) return TRUE;
+			user_data->dlg.selected_item++;
+			if ( (user_data->dlg.selected_item<user_data->dlg.first_item) || (user_data->dlg.selected_item>user_data->dlg.first_item+user_data->dlg.v_scrollbar_adjustment->page_size) )
+				user_data->dlg.first_item = (guint32)user_data->dlg.selected_item-(guint32)user_data->dlg.v_scrollbar_adjustment->page_size;
+		} else if (event->keyval == GDK_Left){
+			if (user_data->dlg.first_node == 0) return TRUE;
+				user_data->dlg.first_node--;
+		} else if (event->keyval == GDK_Right){
+			if ((user_data->dlg.first_node+user_data->dlg.h_scrollbar_adjustment->page_size+1 == user_data->num_nodes)) return TRUE;
+				user_data->dlg.first_node++;
+ } +
+		user_data->dlg.needs_redraw=TRUE;
+		dialog_graph_draw(user_data);
+
+		cf_goto_frame(&cfile, user_data->dlg.items[user_data->dlg.selected_item-user_data->dlg.first_item].frame_num);
+
+        return TRUE;
+}
+
+/****************************************************************************/
static gint expose_event(GtkWidget *widget, GdkEventExpose *event)
{
	graph_analysis_data_t *user_data;
@@ -795,6 +853,8 @@


        user_data->dlg.draw_area=gtk_drawing_area_new();
+		GTK_WIDGET_SET_FLAGS(user_data->dlg.draw_area, GTK_CAN_FOCUS);
+		gtk_widget_grab_focus(user_data->dlg.draw_area);
        SIGNAL_CONNECT(user_data->dlg.draw_area, "destroy", quit, user_data);
        OBJECT_SET_DATA(user_data->dlg.draw_area, "graph_analysis_data_t", user_data);

@@ -807,6 +867,8 @@
		gtk_widget_add_events (user_data->dlg.draw_area,
			 GDK_BUTTON_PRESS_MASK);
		SIGNAL_CONNECT(user_data->dlg.draw_area, "button_press_event", button_press_event, user_data);
+		SIGNAL_CONNECT(user_data->dlg.draw_area, "scroll_event",  scroll_event, user_data);
+		SIGNAL_CONNECT(user_data->dlg.draw_area, "key_press_event",  key_press_event, user_data);

        gtk_widget_show(user_data->dlg.draw_area);
        gtk_box_pack_start(GTK_BOX(vbox), user_data->dlg.draw_area, TRUE, TRUE, 0);
------------------------------------------------------------------------

_______________________________________________
Ethereal-dev mailing list
Ethereal-dev@xxxxxxxxxxxx
http://www.ethereal.com/mailman/listinfo/ethereal-dev
------------------------------------------------------------------------

Index: gtk/voip_calls_dlg.c
===================================================================
--- gtk/voip_calls_dlg.c	(revision 13474)
+++ gtk/voip_calls_dlg.c	(working copy)
@@ -221,12 +221,11 @@
	gchar c;
	GString *filter_string_fwd;
	gchar *filter_prepend;
-	sip_calls_info_t *tmp_sipinfo;
-	isup_calls_info_t *tmp_isupinfo;
-	h323_calls_info_t *tmp_h323info;
-	h245_address_t *h245_add = NULL;
+	gboolean isFirst = TRUE;
	GList* list;

+	graph_analysis_item_t *gai;
+
	if (selected_call_fwd==NULL)
		return;

@@ -242,51 +241,23 @@
	}
		
	filter_string_fwd = g_string_new(filter_prepend);
-	switch(selected_call_fwd->protocol){
-		case VOIP_SIP:
-			tmp_sipinfo = selected_call_fwd->prot_info;
-			g_string_sprintfa(filter_string_fwd,
-			   "(sip.Call-ID == \"%s\") ",
- tmp_sipinfo->call_identifier - );
-			gtk_entry_append_text(GTK_ENTRY(main_display_filter_widget), filter_string_fwd->str);
-			break;
-		case VOIP_ISUP:
-			tmp_isupinfo = selected_call_fwd->prot_info;
-			g_string_sprintfa(filter_string_fwd,
-			   "(isup.cic == %i and frame.number >=%i and frame.number<=%i and mtp3.network_indicator == %i and ((mtp3.dpc == %i) and (mtp3.opc == %i)) or((mtp3.dpc == %i) and (mtp3.opc == %i))) ",
-			   tmp_isupinfo->cic,selected_call_fwd->first_frame_num,
- selected_call_fwd->last_frame_num, - tmp_isupinfo->ni, tmp_isupinfo->dpc, tmp_isupinfo->opc, - tmp_isupinfo->opc, tmp_isupinfo->dpc
-			   );
-			gtk_entry_append_text(GTK_ENTRY(main_display_filter_widget), filter_string_fwd->str);
-			break;
-		case VOIP_H323:
-			tmp_h323info = selected_call_fwd->prot_info;
-			g_string_sprintfa(filter_string_fwd,
-			   "((h225.guid == %x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x || q931.call_ref == %x:%x || q931.call_ref == %x:%x) ",
-			   (guint8)tmp_h323info->guid[0], (guint8)tmp_h323info->guid[1], (guint8)tmp_h323info->guid[2],
-			   (guint8)tmp_h323info->guid[3], (guint8)tmp_h323info->guid[4], (guint8)tmp_h323info->guid[5], (guint8)tmp_h323info->guid[6],
-			   (guint8)tmp_h323info->guid[7], (guint8)tmp_h323info->guid[8], (guint8)tmp_h323info->guid[9], (guint8)tmp_h323info->guid[10],
-			   (guint8)tmp_h323info->guid[11], (guint8)tmp_h323info->guid[12], (guint8)tmp_h323info->guid[13], (guint8)tmp_h323info->guid[14],
-			   (guint8)tmp_h323info->guid[15], (guint8)(tmp_h323info->q931_crv & 0xff), (guint8)((tmp_h323info->q931_crv & 0xff00)>>8)
-			   , (guint8)(tmp_h323info->q931_crv2 & 0xff), (guint8)((tmp_h323info->q931_crv2 & 0xff00)>>8));
+	
+	/* look in the Graph and get all the frame_num for this call */
+	g_string_sprintfa(filter_string_fwd, " (");
+	list = g_list_first(voip_calls_get_info()->graph_analysis->list);
+	while (list)
+	{
+		gai = list->data;
+		if (gai->conv_num == selected_call_fwd->call_num){
+			g_string_sprintfa(filter_string_fwd,"%sframe.number == %d", isFirst?"":" or ", gai->frame_num );
+			isFirst = FALSE;
+		}		
+		list = g_list_next (list);
+	}
+	g_string_sprintfa(filter_string_fwd, ") ");

-			list = g_list_first(tmp_h323info->h245_list);
-			while (list)
-			{
-				h245_add=list->data;
-				g_string_sprintfa(filter_string_fwd,
- " || (ip.addr == %s && tcp.port == %d && h245) ", - ip_to_str((guint8 *)&(h245_add->h245_address)), h245_add->h245_port);
-				list = g_list_next(list);
-			}
-			g_string_sprintfa(filter_string_fwd, ") ");
-			gtk_entry_append_text(GTK_ENTRY(main_display_filter_widget), filter_string_fwd->str);
-			break;
+	gtk_entry_append_text(GTK_ENTRY(main_display_filter_widget), filter_string_fwd->str);

-	}
	g_string_free(filter_string_fwd, TRUE);
}

Index: gtk/graph_analysis.c
===================================================================
--- gtk/graph_analysis.c	(revision 13474)
+++ gtk/graph_analysis.c	(working copy)
@@ -662,12 +662,18 @@
	/* Up scroll */
	if (event->state == 0){
		if (user_data->dlg.first_item == 0) return TRUE;
-		user_data->dlg.first_item--;
+ if (user_data->dlg.first_item < 3) + user_data->dlg.first_item = 0;
+		else
+			user_data->dlg.first_item -= 3;
		
-		/* Down scroll */
+	/* Down scroll */
	} else {
		if ((user_data->dlg.first_item+user_data->dlg.v_scrollbar_adjustment->page_size+1 == user_data->num_items)) return TRUE;
-		user_data->dlg.first_item++;
+ if ((user_data->dlg.first_item+user_data->dlg.v_scrollbar_adjustment->page_size+1) > (user_data->num_items-3)) + user_data->dlg.first_item = user_data->num_items-(guint32)user_data->dlg.v_scrollbar_adjustment->page_size-1;
+		else
+			user_data->dlg.first_item += 3;
	}
	dialog_graph_redraw(user_data);
	
------------------------------------------------------------------------

_______________________________________________
Ethereal-dev mailing list
Ethereal-dev@xxxxxxxxxxxx
http://www.ethereal.com/mailman/listinfo/ethereal-dev
------------------------------------------------------------------------

Index: gtk/graph_analysis.c
===================================================================
--- gtk/graph_analysis.c	(revision 13505)
+++ gtk/graph_analysis.c	(working copy)
@@ -83,6 +83,7 @@
		user_data->nodes[i].type = AT_NONE;
		user_data->nodes[i].len = 0;
		g_free((void *)user_data->nodes[i].data);
+		user_data->nodes[i].data = NULL;
	}
	
	user_data->dlg.first_node=0;
@@ -95,15 +96,31 @@
/* Reset the user_data structure */
static void graph_analysis_init_dlg(graph_analysis_data_t* user_data)
{
+	int i;
+
+	user_data->num_nodes = 0;
+	user_data->num_items = 0;
+	for (i=0; i<MAX_NUM_NODES; i++){
+		user_data->nodes[i].type = AT_NONE;
+		user_data->nodes[i].len = 0;
+		user_data->nodes[i].data = NULL;
+	}
+	
+	user_data->dlg.first_node=0;
+	user_data->dlg.first_item=0;
+	user_data->dlg.left_x_border=0;
+	user_data->dlg.selected_item=0xFFFFFFFF;    /*not item selected */
    /* init dialog_graph */
    user_data->dlg.needs_redraw=TRUE;
    user_data->dlg.draw_area=NULL;
    user_data->dlg.pixmap=NULL;
+	user_data->dlg.draw_area_comments=NULL;
+    user_data->dlg.pixmap_comments=NULL;
    user_data->dlg.h_scrollbar=NULL;
    user_data->dlg.h_scrollbar_adjustment=NULL;
    user_data->dlg.v_scrollbar=NULL;
    user_data->dlg.v_scrollbar_adjustment=NULL;
-    user_data->dlg.pixmap_width=600;
+    user_data->dlg.pixmap_width=350;
    user_data->dlg.pixmap_height=400;
	user_data->dlg.first_node=0;
	user_data->dlg.first_item=0;
@@ -125,8 +142,9 @@
		user_data->nodes[i].type = AT_NONE;
		user_data->nodes[i].len = 0;
		g_free((void *)user_data->nodes[i].data);
+		user_data->nodes[i].data = NULL;
	}
-	g_free(user_data);
+	user_data->dlg.window = NULL;
}


@@ -168,12 +186,12 @@
}

#define MAX_LABEL 50
-#define MAX_COMMENT 60
+#define MAX_COMMENT 100
#define ITEM_HEIGHT 20
#define NODE_WIDTH 100
#define TOP_Y_BORDER 40
#define BOTTOM_Y_BORDER 0
-#define COMMENT_WIDTH 250
+#define COMMENT_WIDTH 400

/****************************************************************************/
static void dialog_graph_draw(graph_analysis_data_t* user_data)
@@ -224,9 +242,17 @@
                           user_data->dlg.draw_area->allocation.width,
                           user_data->dlg.draw_area->allocation.height);

+        gdk_draw_rectangle(user_data->dlg.pixmap_comments,
+                           user_data->dlg.draw_area->style->white_gc,
+                           TRUE,
+                           0, 0,
+                           COMMENT_WIDTH,
+                           user_data->dlg.draw_area->allocation.height);
+
+
		/* Calculate the y border */
        top_y_border=TOP_Y_BORDER;	/* to display the node address */
-        bottom_y_border=BOTTOM_Y_BORDER;
+        bottom_y_border=2;

        draw_height=user_data->dlg.pixmap_height-top_y_border-bottom_y_border;

@@ -305,7 +331,7 @@
        left_x_border=label_width+10;
		user_data->dlg.left_x_border = left_x_border;

-        right_x_border=COMMENT_WIDTH;
+        right_x_border=2;

		/* Calculate the number of nodes to display */
        draw_width=user_data->dlg.pixmap_width-right_x_border-left_x_border;
@@ -404,18 +430,18 @@
#if GTK_MAJOR_VERSION < 2
			label_width=gdk_string_width(small_font, label_string);
			label_height=gdk_string_height(small_font, label_string);
-			gdk_draw_string(user_data->dlg.pixmap,
+			gdk_draw_string(user_data->dlg.pixmap_comments,
                small_font,
-                user_data->dlg.draw_area->style->black_gc,
-                user_data->dlg.pixmap_width-right_x_border+3,
+                user_data->dlg.draw_area_comments->style->black_gc,
+                2,
                top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT/2+label_height/4,
                label_string);
#else
			pango_layout_set_text(small_layout, label_string, -1);
			pango_layout_get_pixel_size(small_layout, &label_width, &label_height);
-	        gdk_draw_layout(user_data->dlg.pixmap,
+	        gdk_draw_layout(user_data->dlg.pixmap_comments,
                user_data->dlg.draw_area->style->black_gc,
-                user_data->dlg.pixmap_width-right_x_border+3,
+                2,
                top_y_border+current_item*ITEM_HEIGHT+ITEM_HEIGHT/2-label_height/2,
                small_layout);
#endif
@@ -586,12 +612,12 @@
				FALSE,
				left_x_border-1,
				(user_data->dlg.selected_item-first_item)*ITEM_HEIGHT+TOP_Y_BORDER,
-				user_data->dlg.pixmap_width-COMMENT_WIDTH-left_x_border+1,
+				user_data->dlg.pixmap_width-left_x_border-right_x_border+1,
				ITEM_HEIGHT);
		}


-
+		/* refresh the draw areas */
        gdk_draw_pixmap(user_data->dlg.draw_area->window,
                        user_data->dlg.draw_area->style->fg_gc[GTK_WIDGET_STATE(user_data->dlg.draw_area)],
                        user_data->dlg.pixmap,
@@ -599,7 +625,14 @@
                        0, 0,
                        user_data->dlg.pixmap_width, user_data->dlg.pixmap_height);

+        gdk_draw_pixmap(user_data->dlg.draw_area_comments->window,
+                        user_data->dlg.draw_area_comments->style->fg_gc[GTK_WIDGET_STATE(user_data->dlg.draw_area_comments)],
+                        user_data->dlg.pixmap_comments,
+                        0, 0,
+                        0, 0,
+                        COMMENT_WIDTH, user_data->dlg.pixmap_height);

+
        /* update the h_scrollbar */
        user_data->dlg.h_scrollbar_adjustment->upper=(gfloat) user_data->num_nodes-1;
        user_data->dlg.h_scrollbar_adjustment->step_increment=1;
@@ -619,7 +652,6 @@

		gtk_adjustment_changed(user_data->dlg.v_scrollbar_adjustment);
        gtk_adjustment_value_changed(user_data->dlg.v_scrollbar_adjustment);
-
}

/****************************************************************************/
@@ -630,19 +662,6 @@
}

/****************************************************************************/
-static gint quit(GtkWidget *widget, GdkEventExpose *event _U_)
-{
-        graph_analysis_data_t *user_data;
-
-        user_data=(graph_analysis_data_t *)OBJECT_GET_DATA(widget, "graph_analysis_data_t");
-
-		user_data->dlg.window = NULL;
-
-		user_data = NULL;
-        return TRUE;
-}
-
-/****************************************************************************/
static gint button_press_event(GtkWidget *widget, GdkEventButton *event _U_)
{
        graph_analysis_data_t *user_data;
@@ -750,6 +769,27 @@
        return FALSE;
}

+/****************************************************************************/
+static gint expose_event_comments(GtkWidget *widget, GdkEventExpose *event)
+{
+	graph_analysis_data_t *user_data;
+
+	user_data=(graph_analysis_data_t *)OBJECT_GET_DATA(widget, "graph_analysis_data_t");
+        if(!user_data){
+                exit(10);
+        }
+
+
+        gdk_draw_pixmap(widget->window,
+                        widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+                        user_data->dlg.pixmap_comments,
+                        event->area.x, event->area.y,
+                        event->area.x, event->area.y,
+                        event->area.width, event->area.height);
+
+        return FALSE;
+}
+
static const GdkColor COLOR_GRAY = {0, 0x7fff, 0x7fff, 0x7fff};

/****************************************************************************/
@@ -830,6 +870,38 @@
}

/****************************************************************************/
+static gint configure_event_comments(GtkWidget *widget, GdkEventConfigure *event _U_)
+{
+        graph_analysis_data_t *user_data;
+
+        user_data=(graph_analysis_data_t *)OBJECT_GET_DATA(widget, "graph_analysis_data_t");
+
+        if(!user_data){
+                exit(10);
+        }
+
+        if(user_data->dlg.pixmap_comments){
+                gdk_pixmap_unref(user_data->dlg.pixmap_comments);
+                user_data->dlg.pixmap_comments=NULL;
+        }
+
+        user_data->dlg.pixmap_comments=gdk_pixmap_new(widget->window,
+                        COMMENT_WIDTH,
+                        widget->allocation.height,
+                        -1);
+
+        gdk_draw_rectangle(user_data->dlg.pixmap_comments,
+                        widget->style->white_gc,
+                        TRUE,
+                        0, 0,
+                        COMMENT_WIDTH,
+                        widget->allocation.height);
+
+		dialog_graph_redraw(user_data);
+        return TRUE;
+}
+
+/****************************************************************************/
static gint h_scrollbar_changed(GtkWidget *widget _U_, gpointer data)
{
    graph_analysis_data_t *user_data=(graph_analysis_data_t *)data;
@@ -869,6 +941,8 @@
{
	    GtkWidget *vbox;
        GtkWidget *hbox;
+		GtkWidget *scroll_window;
+		GtkWidget *viewport;

        hbox=gtk_hbox_new(FALSE, 0);
        gtk_widget_show(hbox);
@@ -876,28 +950,45 @@
        vbox=gtk_vbox_new(FALSE, 0);
        gtk_widget_show(vbox);

+		/* create "comments" draw area */
+        user_data->dlg.draw_area_comments=gtk_drawing_area_new();
+        WIDGET_SET_SIZE(user_data->dlg.draw_area_comments, COMMENT_WIDTH, user_data->dlg.pixmap_height);
+		scroll_window=gtk_scrolled_window_new(NULL, NULL);
+		WIDGET_SET_SIZE(scroll_window, COMMENT_WIDTH/2, user_data->dlg.pixmap_height);
+		gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll_window), GTK_POLICY_ALWAYS, GTK_POLICY_NEVER);
+		viewport = gtk_viewport_new(gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(scroll_window)), gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scroll_window)));
+		gtk_container_add(GTK_CONTAINER(viewport), user_data->dlg.draw_area_comments);
+		gtk_container_add(GTK_CONTAINER(scroll_window), viewport);
+		gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewport), GTK_SHADOW_NONE);
+        OBJECT_SET_DATA(user_data->dlg.draw_area_comments, "graph_analysis_data_t", user_data);
+		gtk_widget_add_events (user_data->dlg.draw_area_comments, GDK_BUTTON_PRESS_MASK);
+		SIGNAL_CONNECT(user_data->dlg.draw_area_comments, "scroll_event",  scroll_event, user_data);

+		/* create main Graph draw area */
        user_data->dlg.draw_area=gtk_drawing_area_new();
		GTK_WIDGET_SET_FLAGS(user_data->dlg.draw_area, GTK_CAN_FOCUS);
		gtk_widget_grab_focus(user_data->dlg.draw_area);
-
-        SIGNAL_CONNECT(user_data->dlg.draw_area, "destroy", quit, user_data);
        OBJECT_SET_DATA(user_data->dlg.draw_area, "graph_analysis_data_t", user_data);
-
        WIDGET_SET_SIZE(user_data->dlg.draw_area, user_data->dlg.pixmap_width, user_data->dlg.pixmap_height);

        /* signals needed to handle backing pixmap */
        SIGNAL_CONNECT(user_data->dlg.draw_area, "expose_event", expose_event, NULL);
        SIGNAL_CONNECT(user_data->dlg.draw_area, "configure_event", configure_event, user_data);
+        /* signals needed to handle backing pixmap comments*/
+        SIGNAL_CONNECT(user_data->dlg.draw_area_comments, "expose_event", expose_event_comments, NULL);
+        SIGNAL_CONNECT(user_data->dlg.draw_area_comments, "configure_event", configure_event_comments, user_data);

-		gtk_widget_add_events (user_data->dlg.draw_area,
-			 GDK_BUTTON_PRESS_MASK);
+		gtk_widget_add_events (user_data->dlg.draw_area, GDK_BUTTON_PRESS_MASK);
		SIGNAL_CONNECT(user_data->dlg.draw_area, "button_press_event", button_press_event, user_data);
		SIGNAL_CONNECT(user_data->dlg.draw_area, "scroll_event",  scroll_event, user_data);
		SIGNAL_CONNECT(user_data->dlg.draw_area, "key_press_event",  key_press_event, user_data);
-		
+
        gtk_widget_show(user_data->dlg.draw_area);
+		gtk_widget_show(user_data->dlg.draw_area_comments);
+		gtk_widget_show(viewport);
+	
        gtk_box_pack_start(GTK_BOX(vbox), user_data->dlg.draw_area, TRUE, TRUE, 0);
+		gtk_widget_show(scroll_window);

        /* create the associated h_scrollbar */
        user_data->dlg.h_scrollbar_adjustment=(GtkAdjustment *)gtk_adjustment_new(0,0,0,0,0,0);
@@ -908,6 +999,8 @@

        gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);

+        gtk_box_pack_start(GTK_BOX(hbox), scroll_window, FALSE, FALSE, 0);
+
       /* create the associated v_scrollbar */
        user_data->dlg.v_scrollbar_adjustment=(GtkAdjustment *)gtk_adjustment_new(0,0,0,0,0,0);
        user_data->dlg.v_scrollbar=gtk_vscrollbar_new(user_data->dlg.v_scrollbar_adjustment);
@@ -944,6 +1037,7 @@
        window_set_cancel_button(user_data->dlg.window, bt_close, window_cancel_button_cb);

        SIGNAL_CONNECT(user_data->dlg.window, "delete_event", window_delete_event_cb, NULL);
+		SIGNAL_CONNECT(user_data->dlg.window, "destroy", on_destroy, user_data);

        gtk_widget_show(user_data->dlg.window);
        window_present(user_data->dlg.window);
Index: gtk/graph_analysis.h
===================================================================
--- gtk/graph_analysis.h	(revision 13505)
+++ gtk/graph_analysis.h	(working copy)
@@ -84,7 +84,9 @@
	gboolean needs_redraw;
	gint selected_row;
    GtkWidget *draw_area;
+	GtkWidget *draw_area_comments;
    GdkPixmap *pixmap;
+    GdkPixmap *pixmap_comments;
    GtkAdjustment *h_scrollbar_adjustment;
    GtkWidget *h_scrollbar;
	GtkWidget *v_scrollbar;
Index: gtk/voip_calls.c
===================================================================
--- gtk/voip_calls.c	(revision 13505)
+++ gtk/voip_calls.c	(working copy)
@@ -10,7 +10,7 @@
 * Copyright 2004, Iskratel, Ltd, Kranj
 * By Miha Jemec <m.jemec@xxxxxxxxxxx>
* - * H323, RTP and Graph Support
+ * H323, RTP, MGCP and Graph Support
 * By Alejandro Vaquero, alejandro.vaquero@xxxxxxxxx
 * Copyright 2005, Verso Technologies Inc.
 *
@@ -548,10 +548,12 @@

			if ((strcmp(pi->request_method,"INVITE")==0)&&(ADDRESSES_EQUAL(&tmp_src,&(strinfo->initial_speaker)))){
				tmp_sipinfo->invite_cseq = pi->tap_cseq_number;
+				strinfo->call_state = VOIP_CALL_SETUP;
				comment = g_strdup_printf("SIP From: %s To:%s", strinfo->from_identity, strinfo->to_identity);
			}
			else if ((strcmp(pi->request_method,"ACK")==0)&&(pi->tap_cseq_number == tmp_sipinfo->invite_cseq)
-				&&(ADDRESSES_EQUAL(&tmp_src,&(strinfo->initial_speaker)))&&(tmp_sipinfo->sip_state==SIP_200_REC)){
+				&&(ADDRESSES_EQUAL(&tmp_src,&(strinfo->initial_speaker)))&&(tmp_sipinfo->sip_state==SIP_200_REC)
+				&&(strinfo->call_state == VOIP_CALL_SETUP)){
				strinfo->call_state = VOIP_IN_CALL;
				comment = g_strdup_printf("SIP Request");
			}
@@ -1245,19 +1247,18 @@
						strinfo->call_state=VOIP_REJECTED;
						tapinfo->rejected_calls++;
					}
+				} else {
+						strinfo->call_state=VOIP_COMPLETED;
+						tapinfo->completed_calls++;
				}
-					else {
-						strinfo->call_state=VOIP_REJECTED;
-						tapinfo->rejected_calls++;
-					}
-					/* get the Q931 Release cause code */
-					if (q931_frame_num == pinfo->fd->num &&
-						q931_cause_value != 0xFF){		
-						comment = g_strdup_printf("H225 Q931 Rel Cause (%i):%s", q931_cause_value, val_to_str(q931_cause_value, q931_cause_code_vals, "<unknown>"));
-					} else {			/* Cause not set */
-						comment = g_strdup("H225 No Q931 Rel Cause");
-					}
-					break;
+				/* get the Q931 Release cause code */
+				if (q931_frame_num == pinfo->fd->num &&
+					q931_cause_value != 0xFF){		
+					comment = g_strdup_printf("H225 Q931 Rel Cause (%i):%s", q931_cause_value, val_to_str(q931_cause_value, q931_cause_code_vals, "<unknown>"));
+				} else {			/* Cause not set */
+					comment = g_strdup("H225 No Q931 Rel Cause");
+				}
+				break;
			case H225_PROGRESS:
			case H225_ALERTING:
			case H225_CALL_PROCEDING:
------------------------------------------------------------------------

_______________________________________________
Ethereal-dev mailing list
Ethereal-dev@xxxxxxxxxxxx
http://www.ethereal.com/mailman/listinfo/ethereal-dev
Index: asn1/h245/h245.cnf
===================================================================
--- asn1/h245/h245.cnf	(revision 13657)
+++ asn1/h245/h245.cnf	(working copy)
@@ -345,7 +345,7 @@
 		src_addr.len=4;
 		src_addr.data=(char *)&ipv4_address;
 
-		rtp_add_address(pinfo, &src_addr, ipv4_port, 0, "H245", pinfo->fd->num);
+		rtp_add_address(pinfo, &src_addr, ipv4_port, 0, "H245", pinfo->fd->num, 0);
 	}
 	if((!pinfo->fd->flags.visited) && rtcp_ipv4_address!=0 && rtcp_ipv4_port!=0 && rtcp_handle){
 		address src_addr;
Index: gtk/voip_calls_dlg.c
===================================================================
--- gtk/voip_calls_dlg.c	(revision 13657)
+++ gtk/voip_calls_dlg.c	(working copy)
@@ -179,6 +179,7 @@
 	remove_tap_listener_q931_calls();
 	remove_tap_listener_sdp_calls();
 	remove_tap_listener_rtp();
+	remove_tap_listener_rtp_event();
 	if (find_tap_id("mgcp")) {
 		remove_tap_listener_mgcp_calls();
 	}
@@ -666,6 +667,7 @@
 	q931_calls_init_tap();
 	sdp_calls_init_tap();
 	rtp_init_tap();
+	rtp_event_init_tap();
 	/* We don't register this tap, if we don't have the mgcp plugin loaded.*/
 	if (find_tap_id("mgcp")) {
 		mgcp_calls_init_tap();
Index: gtk/voip_calls.c
===================================================================
--- gtk/voip_calls.c	(revision 13657)
+++ gtk/voip_calls.c	(working copy)
@@ -10,7 +10,7 @@
  * Copyright 2004, Iskratel, Ltd, Kranj
  * By Miha Jemec <m.jemec@xxxxxxxxxxx>
  * 
- * H323, RTP, MGCP and Graph Support
+ * H323, RTP, RTP Event, MGCP and Graph Support
  * By Alejandro Vaquero, alejandro.vaquero@xxxxxxxxx
  * Copyright 2005, Verso Technologies Inc.
  *
@@ -55,6 +55,7 @@
 #include <epan/dissectors/packet-sdp.h>
 #include <plugins/mgcp/packet-mgcp.h>
 #include <epan/dissectors/packet-rtp.h>
+#include <epan/dissectors/packet-rtp-events.h>
 #include "rtp_pt.h"
 
 #include "alert_box.h"
@@ -87,7 +88,7 @@
 
 /* the one and only global voip_rtp_tapinfo_t structure */
 static voip_rtp_tapinfo_t the_tapinfo_rtp_struct =
-	{0, NULL, 0};
+	{0, NULL, 0, 0};
 
 /****************************************************************************/
 /* when there is a [re]reading of packet's */
@@ -261,7 +262,89 @@
 	return items_changed;
 }
 
+/* XXX just copied from gtk/rpc_stat.c */
+void protect_thread_critical_region(void);
+void unprotect_thread_critical_region(void);
+
 /****************************************************************************/
+/* ***************************TAP for RTP Events*****************************/
+/****************************************************************************/
+
+/****************************************************************************/
+/* whenever a rtp event packet is seen by the tap listener */
+static int 
+rtp_event_packet(void *ptr _U_, packet_info *pinfo, epan_dissect_t *edt _U_, const void *rtp_event_info _U_)
+{
+	const struct _rtp_event_info *pi = rtp_event_info;
+	voip_rtp_tapinfo_t *tapinfo = &the_tapinfo_rtp_struct;
+	voip_rtp_stream_info_t *tmp_listinfo;
+	voip_rtp_stream_info_t *strinfo = NULL;
+	GList* list;
+
+	/* do not consider RTP events packets without a setup frame */
+	if (pi->info_setup_frame_num == 0){
+		return 0;
+	}
+
+	/* check wether we already have a RTP stream with this setup frame in the list */
+	list = g_list_first(tapinfo->list);
+	while (list)
+	{
+		tmp_listinfo=list->data;
+		if ( (tmp_listinfo->setup_frame_number == pi->info_setup_frame_num) 
+			&& (tmp_listinfo->end_stream == FALSE) && (tmp_listinfo->rtp_event == -1)){
+				strinfo = (voip_rtp_stream_info_t*)(list->data);
+				strinfo->rtp_event = pi->info_rtp_evt;
+				break;
+		}
+		list = g_list_next (list);
+	}
+
+
+	return 0;
+}
+
+/****************************************************************************/
+static gboolean have_rtp_event_tap_listener=FALSE;
+
+void
+rtp_event_init_tap(void)
+{
+	GString *error_string;
+
+
+	if(have_rtp_event_tap_listener==FALSE)
+	{
+		error_string = register_tap_listener("rtpevent", &(the_tapinfo_rtp_struct.rtp_event_dummy),
+			NULL,
+			NULL,
+			rtp_event_packet,
+			NULL
+			);
+			
+		if (error_string != NULL) {
+			simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+				      error_string->str);
+			g_string_free(error_string, TRUE);
+			exit(1);
+		}
+		have_rtp_event_tap_listener=TRUE;
+	}
+}
+
+/****************************************************************************/
+
+void
+remove_tap_listener_rtp_event(void)
+{
+	protect_thread_critical_region();
+	remove_tap_listener(&(the_tapinfo_rtp_struct.rtp_event_dummy));
+	unprotect_thread_critical_region();
+
+	have_rtp_event_tap_listener=FALSE;
+}
+
+/****************************************************************************/
 /* ***************************TAP for RTP **********************************/
 /****************************************************************************/
 
@@ -335,6 +418,7 @@
 		strinfo->start_rel_sec = pinfo->fd->rel_secs;
 		strinfo->start_rel_usec = pinfo->fd->rel_usecs;
 		strinfo->setup_frame_number = pi->info_setup_frame_num;
+		strinfo->rtp_event = -1;
 		tapinfo->list = g_list_append(tapinfo->list, strinfo);
 	}
 
@@ -394,7 +478,7 @@
 						new_gai->port_src = rtp_listinfo->src_port;
 						new_gai->port_dst = rtp_listinfo->dest_port;
 						duration = (rtp_listinfo->stop_rel_sec*1000000 + rtp_listinfo->stop_rel_usec) - (rtp_listinfo->start_rel_sec*1000000 + rtp_listinfo->start_rel_usec);
-						new_gai->frame_label = g_strdup_printf("RTP (%s)", val_to_str(rtp_listinfo->pt, rtp_payload_type_short_vals, "%u"));
+						new_gai->frame_label = g_strdup_printf("RTP (%s) %s", val_to_str(rtp_listinfo->pt, rtp_payload_type_short_vals, "%u"), (rtp_listinfo->rtp_event == -1)?"":val_to_str(rtp_listinfo->rtp_event, rtp_event_type_values, "Uknown RTP Event"));
 						new_gai->comment = g_strdup_printf("RTP Num packets:%d  Duration:%d.%03ds ssrc:%d", rtp_listinfo->npackets, duration/1000000,(duration%1000000)/1000, rtp_listinfo->ssrc);
 						new_gai->conv_num = conv_num;
 						new_gai->display=FALSE;
@@ -440,12 +524,6 @@
 	}
 }
 
-
-
-/* XXX just copied from gtk/rpc_stat.c */
-void protect_thread_critical_region(void);
-void unprotect_thread_critical_region(void);
-
 /****************************************************************************/
 void
 remove_tap_listener_rtp(void)
@@ -677,8 +755,8 @@
 	isup_message_type = pi->message_type;
 	isup_cause_value = pi->cause_value;
 	isup_cic = pinfo->circuit_id;
-
 	isup_frame_num = pinfo->fd->num;
+	isup_frame_num = pinfo->fd->num;
 	
 	return 0;
 }
Index: gtk/voip_calls.h
===================================================================
--- gtk/voip_calls.h	(revision 13657)
+++ gtk/voip_calls.h	(working copy)
@@ -180,6 +180,7 @@
 	guint32 start_rel_usec;        /* start stream rel microseconds */
 	guint32 stop_rel_sec;         /* stop stream rel seconds */
 	guint32 stop_rel_usec;        /* stop stream rel microseconds */
+	gint32 rtp_event;
 } voip_rtp_stream_info_t;
 
 /* structure that holds the information about all RTP streams associated with the calls */
@@ -188,6 +189,7 @@
 	int     nstreams;       /* number of rtp streams */
 	GList*  list;			/* list with the rtp streams */
 	int rtp_dummy;
+	int rtp_event_dummy;
 } voip_rtp_tapinfo_t;
 
 /****************************************************************************/
@@ -208,6 +210,7 @@
 void q931_calls_init_tap(void);
 void sdp_calls_init_tap(void);
 void rtp_init_tap(void);
+void rtp_init_tap_event(void);
 void mgcp_calls_init_tap(void);
 
 
@@ -223,6 +226,7 @@
 void remove_tap_listener_q931_calls(void);
 void remove_tap_listener_sdp_calls(void);
 void remove_tap_listener_rtp(void);
+void remove_tap_listener_rtp_event(void);
 void remove_tap_listener_mgcp_calls(void);
 
 /*
Index: plugins/plugin_api_list.c
===================================================================
--- plugins/plugin_api_list.c	(revision 13657)
+++ plugins/plugin_api_list.c	(working copy)
@@ -498,7 +498,7 @@
 
 proto_item *proto_tree_add_debug_text(proto_tree *tree, const char *format, ...);
 
-void rtp_add_address(packet_info *pinfo, address *addr, int port, int other_port, gchar *setup_method, guint32 setup_frame_number);
+void rtp_add_address(packet_info *pinfo, address *addr, int port, int other_port, gchar *setup_method, guint32 setup_frame_number, guint32 rtp_event_pt);
 void rtcp_add_address(packet_info *pinfo, address *addr, int port, int other_port, gchar *setup_method, guint32 setup_frame_number);
 
 GString *register_tap_listener(char *, void *, char *, tap_reset_cb, tap_packet_cb, tap_draw_cb);
Index: plugins/Xplugin_table.h
===================================================================
--- plugins/Xplugin_table.h	(revision 13657)
+++ plugins/Xplugin_table.h	(working copy)
@@ -302,7 +302,7 @@
 typedef gfloat (*addr_tvb_get_letohieee_float) (tvbuff_t *, gint);
 typedef gdouble (*addr_tvb_get_letohieee_double) (tvbuff_t *, gint);
 typedef proto_item *(*addr_proto_tree_add_debug_text) (proto_tree *, const char *, ...);
-typedef void (*addr_rtp_add_address) (packet_info *, address *, int, int, gchar *, guint32);
+typedef void (*addr_rtp_add_address) (packet_info *, address *, int, int, gchar *, guint32, guint32);
 typedef void (*addr_rtcp_add_address) (packet_info *, address *, int, int, gchar *, guint32);
 typedef GString *(*addr_register_tap_listener) (char *, void *, char *, tap_reset_cb, tap_packet_cb, tap_draw_cb);
 typedef const char *(*addr_get_datafile_dir) (void);
Index: epan/dissectors/packet-rtsp.c
===================================================================
--- epan/dissectors/packet-rtsp.c	(revision 13657)
+++ epan/dissectors/packet-rtsp.c	(working copy)
@@ -462,7 +462,7 @@
 	if (rtp_transport)
 	{
 		rtp_add_address(pinfo, &pinfo->dst, c_data_port, s_data_port,
-						"RTSP", pinfo->fd->num);
+						"RTSP", pinfo->fd->num, 0);
 	
 		if (!c_mon_port)
 			return;
Index: epan/dissectors/packet-sdp.c
===================================================================
--- epan/dissectors/packet-sdp.c	(revision 13657)
+++ epan/dissectors/packet-sdp.c	(working copy)
@@ -170,6 +170,7 @@
 	char *media_port[SDP_MAX_RTP_CHANNELS];
 	char *media_proto[SDP_MAX_RTP_CHANNELS];
 	gint8 media_count;
+	guint32 rtp_event_pt;
 } transport_info_t;
 
 /* static functions */
@@ -189,7 +190,7 @@
 static void dissect_sdp_session_attribute(tvbuff_t *tvb, proto_item *ti);
 static void dissect_sdp_media(tvbuff_t *tvb, proto_item *ti,
 			      transport_info_t *transport_info);
-static void dissect_sdp_media_attribute(tvbuff_t *tvb, proto_item *ti);
+static void dissect_sdp_media_attribute(tvbuff_t *tvb, proto_item *ti, transport_info_t *transport_info);
 
 static void
 dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
@@ -227,6 +228,7 @@
 	/* Initialise RTP channel info */
 	transport_info.connection_address=NULL;
 	transport_info.connection_type=NULL;
+	transport_info.rtp_event_pt=0;
 	for (n=0; n < SDP_MAX_RTP_CHANNELS; n++)
 	{
 	    transport_info.media_port[n]=NULL;
@@ -415,7 +417,7 @@
 		    src_addr.data=(char *)&ipaddr;
 		    if(rtp_handle){
 				rtp_add_address(pinfo, &src_addr, port, 0,
-	                "SDP", pinfo->fd->num);
+	                "SDP", pinfo->fd->num, transport_info.rtp_event_pt);
 				set_rtp = TRUE;
 		    }
 		    if(rtcp_handle){
@@ -473,7 +475,7 @@
   } else if ( hf == hf_media ) {
     dissect_sdp_media(tvb,ti,transport_info);
   } else if ( hf == hf_media_attribute ){
-    dissect_sdp_media_attribute(tvb,ti);
+    dissect_sdp_media_attribute(tvb,ti,transport_info);
   }
 }
 
@@ -921,9 +923,12 @@
 
 }
 
-static void dissect_sdp_media_attribute(tvbuff_t *tvb, proto_item * ti){
+static void dissect_sdp_media_attribute(tvbuff_t *tvb, proto_item * ti, transport_info_t *transport_info){
   proto_tree *sdp_media_attribute_tree;
   gint offset, next_offset, tokenlen;
+  guint8 *field_name;
+  guint8 *payload_type;
+  guint8 *encoding_name;
 
   offset = 0;
   next_offset = 0;
@@ -943,11 +948,44 @@
 		      hf_media_attribute_field,
 		      tvb, offset, tokenlen, FALSE);
 
+  field_name = tvb_get_string(tvb, offset, tokenlen);
+
   offset = next_offset + 1;
   proto_tree_add_item(sdp_media_attribute_tree,
 		      hf_media_attribute_value,
 		      tvb, offset, -1, FALSE);
 
+  /* decode the rtpmap to see if it is DynamicPayload for RTP-Events RFC2833 to dissect them automatic */
+  if (strcmp(field_name, "rtpmap") == 0) {
+	next_offset = tvb_find_guint8(tvb,offset,-1,' ');
+	g_free(field_name);
+
+    if(next_offset == -1)
+		return;
+
+    tokenlen = next_offset - offset;
+
+	payload_type = tvb_get_string(tvb, offset, tokenlen);
+
+    offset = next_offset + 1;
+
+    next_offset = tvb_find_guint8(tvb,offset,-1,'/');
+
+    if(next_offset == -1){
+		g_free(payload_type);
+        return;
+    }
+
+    tokenlen = next_offset - offset;
+
+    encoding_name = tvb_get_string(tvb, offset, tokenlen);
+
+    if (strcmp(encoding_name, "telephone-event") == 0)
+		transport_info->rtp_event_pt = atol(payload_type);
+
+    g_free(payload_type);
+    g_free(encoding_name);
+  } else g_free(field_name);
 }
 
 void
Index: epan/dissectors/packet-h245.c
===================================================================
--- epan/dissectors/packet-h245.c	(revision 13657)
+++ epan/dissectors/packet-h245.c	(working copy)
@@ -9866,7 +9866,7 @@
 		src_addr.len=4;
 		src_addr.data=(char *)&ipv4_address;
 
-		rtp_add_address(pinfo, &src_addr, ipv4_port, 0, "H245", pinfo->fd->num);
+		rtp_add_address(pinfo, &src_addr, ipv4_port, 0, "H245", pinfo->fd->num, 0);
 	}
 	if((!pinfo->fd->flags.visited) && rtcp_ipv4_address!=0 && rtcp_ipv4_port!=0 && rtcp_handle){
 		address src_addr;
@@ -12527,7 +12527,7 @@
 		src_addr.len=4;
 		src_addr.data=(char *)&ipv4_address;
 
-		rtp_add_address(pinfo, &src_addr, ipv4_port, 0, "H245", pinfo->fd->num);
+		rtp_add_address(pinfo, &src_addr, ipv4_port, 0, "H245", pinfo->fd->num, 0);
 	}
 	if((!pinfo->fd->flags.visited) && rtcp_ipv4_address!=0 && rtcp_ipv4_port!=0 && rtcp_handle){
 		address src_addr;
Index: epan/dissectors/packet-rtp-events.c
===================================================================
--- epan/dissectors/packet-rtp-events.c	(revision 13657)
+++ epan/dissectors/packet-rtp-events.c	(working copy)
@@ -40,6 +40,9 @@
 #include <stdio.h>
 #include <string.h>
 #include "packet-rtp-events.h"
+#include "packet-rtp.h"
+#include <epan/conversation.h>
+#include <epan/tap.h>
 
 /*  rtp_event_payload_type_value is the value used globally
 	to set the appropriate payload type
@@ -54,6 +57,7 @@
 /* RTP Event Fields */
 
 static int proto_rtp_events          = -1;
+static int rtp_event_tap = -1;
 
 static int hf_rtp_events_event = -1; /* one byte */
 static int hf_rtp_events_end = -1; /* one bit */
@@ -69,12 +73,15 @@
 void
 proto_reg_handoff_rtp_events(void);
 
+static struct _rtp_event_info rtp_event_info;
+
 static void
 dissect_rtp_events( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
 {
 	proto_item *ti            = NULL;
 	proto_tree *rtp_events_tree     = NULL;
 	unsigned int offset       = 0;
+	struct _rtp_conversation_info *p_conv_data = NULL;
 
 	guint8      rtp_evt;
 	guint8      octet;
@@ -91,13 +98,21 @@
 
 	rtp_evt = tvb_get_guint8(tvb, offset );
 
+	/* get tap info */
+	rtp_event_info.info_rtp_evt = rtp_evt;
+
+	p_conv_data = p_get_proto_data(pinfo->fd, proto_get_id_by_filter_name("rtp"));
+	if (p_conv_data)
+		rtp_event_info.info_setup_frame_num = p_conv_data->frame_number;
+	else
+		rtp_event_info.info_setup_frame_num = 0;
+
+
 	if ( check_col( pinfo->cinfo, COL_INFO) )
 	  {
 		col_add_fstr( pinfo->cinfo, COL_INFO,
 		    "Payload type=RTP Event, %s",
 		    val_to_str( rtp_evt, rtp_event_type_values, "Unknown (%u)" ));
-
-
 	  }
 
 	if ( tree )
@@ -121,6 +136,7 @@
 	    }
 
 	  }
+	tap_queue_packet(rtp_event_tap, pinfo, &rtp_event_info);
 }
 
 
@@ -214,6 +230,8 @@
                                     "This is the value of the Payload Type field"
                                     "that specifies RTP Events", 10,
                                     &rtp_event_payload_type_value);
+	register_dissector("rtpevent", dissect_rtp_events, proto_rtp_events);
+	rtp_event_tap = register_tap("rtpevent");
 }
 
 
Index: epan/dissectors/packet-rtp-events.h
===================================================================
--- epan/dissectors/packet-rtp-events.h	(revision 13657)
+++ epan/dissectors/packet-rtp-events.h	(working copy)
@@ -251,3 +251,8 @@
 	{ RTP_NEWMWATTTN,       "New milliwatt tone (1004 Hz)"},
 	{ 0,               NULL },
 };
+
+struct _rtp_event_info {
+	guint8      info_rtp_evt;
+	guint32		info_setup_frame_num; /* the frame num of the packet that set this RTP connection */
+};
\ No newline at end of file
Index: epan/dissectors/packet-skinny.c
===================================================================
--- epan/dissectors/packet-skinny.c	(revision 13657)
+++ epan/dissectors/packet-skinny.c	(working copy)
@@ -1396,7 +1396,7 @@
 	    src_addr.len=4;
 	    src_addr.data=(char *)&ipv4_address;
 	    tvb_memcpy(tvb, (char *)&ipv4_address, offset+16, 4);
-	    rtp_add_address(pinfo, &src_addr, tvb_get_letohl(tvb, offset+20), 0, "Skinny", pinfo->fd->num);
+	    rtp_add_address(pinfo, &src_addr, tvb_get_letohl(tvb, offset+20), 0, "Skinny", pinfo->fd->num, 0);
       }
       break;
 
@@ -1777,7 +1777,7 @@
 	    src_addr.len=4;
 	    src_addr.data=(char *)&ipv4_address;
 	    tvb_memcpy(tvb, (char *)&ipv4_address, offset+20, 4);
-	    rtp_add_address(pinfo, &src_addr, tvb_get_letohl(tvb, offset+24), 0, "Skinny", pinfo->fd->num);
+	    rtp_add_address(pinfo, &src_addr, tvb_get_letohl(tvb, offset+24), 0, "Skinny", pinfo->fd->num, 0);
       }
       break;
 
Index: epan/dissectors/packet-rtp.c
===================================================================
--- epan/dissectors/packet-rtp.c	(revision 13657)
+++ epan/dissectors/packet-rtp.c	(working copy)
@@ -70,6 +70,7 @@
 
 static dissector_handle_t rtp_handle;
 static dissector_handle_t stun_handle;
+static dissector_handle_t rtpevent_handle=NULL;
 
 static int rtp_tap = -1;
 
@@ -238,7 +239,7 @@
 void rtp_add_address(packet_info *pinfo,
                      address *addr, int port,
                      int other_port,
-                     gchar *setup_method, guint32 setup_frame_number)
+                     gchar *setup_method, guint32 setup_frame_number, int rtp_event_pt)
 {
 	address null_addr;
 	conversation_t* p_conv;
@@ -296,6 +297,7 @@
 	strncpy(p_conv_data->method, setup_method, MAX_RTP_SETUP_METHOD_SIZE);
 	p_conv_data->method[MAX_RTP_SETUP_METHOD_SIZE] = '\0';
 	p_conv_data->frame_number = setup_frame_number;
+	p_conv_data->rtp_event_pt = rtp_event_pt;
 }
 
 static void rtp_init( void )
@@ -368,11 +370,25 @@
     unsigned int data_reported_len, unsigned int payload_type )
 {
 	tvbuff_t *newtvb;
+	struct _rtp_conversation_info *p_conv_data = NULL;
 
 	newtvb = tvb_new_subset( tvb, offset, data_len, data_reported_len );
-	if (!dissector_try_port(rtp_pt_dissector_table, payload_type, newtvb,
-	    pinfo, tree))
-		proto_tree_add_item( rtp_tree, hf_rtp_data, newtvb, 0, -1, FALSE );
+
+	/* if this is part of a conv set by a SDP, we know the payload type for dynamic payloads */
+	p_conv_data = p_get_proto_data(pinfo->fd, proto_rtp);
+	if (p_conv_data && (strcmp(p_conv_data->method, "SDP") == 0) ) {
+		if ( (p_conv_data->rtp_event_pt != 0) && (p_conv_data->rtp_event_pt == (guint32)payload_type) )
+		{
+			call_dissector(rtpevent_handle, newtvb, pinfo, tree);
+		} else 
+		{
+			proto_tree_add_item( rtp_tree, hf_rtp_data, newtvb, 0, -1, FALSE );
+		}
+	} else {
+    /* is not part of a conv, use the preference saved value do decode the payload type */
+		if (!dissector_try_port(rtp_pt_dissector_table, payload_type, newtvb, pinfo, tree))
+				proto_tree_add_item( rtp_tree, hf_rtp_data, newtvb, 0, -1, FALSE );
+	}
 }
 
 static struct _rtp_info rtp_info;
@@ -715,6 +731,7 @@
 				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_conv_packet_data->rtp_event_pt = p_conv_data->rtp_event_pt;
 				p_add_proto_data(pinfo->fd, proto_rtp, p_conv_packet_data);
 			}
 		}
@@ -1031,6 +1048,7 @@
 {
 	data_handle = find_dissector("data");
 	stun_handle = find_dissector("stun");
+	rtpevent_handle = find_dissector("rtpevent");
 
 	/*
 	 * Register this dissector as one that can be selected by a
Index: epan/dissectors/packet-rtp.h
===================================================================
--- epan/dissectors/packet-rtp.h	(revision 13657)
+++ epan/dissectors/packet-rtp.h	(working copy)
@@ -58,10 +58,13 @@
 {
 	gchar   method[MAX_RTP_SETUP_METHOD_SIZE + 1];
 	guint32 frame_number;
+	guint32 rtp_event_pt;	/* this is payload type for dynamic RTP events (RFC2833) */
 };
 
 /* Add an RTP conversation with the given details */
 void rtp_add_address(packet_info *pinfo,
                      address *addr, int port,
                      int other_port,
-                     gchar *setup_method, guint32 setup_frame_number);
+                     gchar *setup_method, 
+					 guint32 setup_frame_number,
+					 int rtp_event_pt);