From 2e0b11edbf38629e266f4f92ef3ca561edcf9053 Mon Sep 17 00:00:00 2001 From: Anders Broman Date: Thu, 30 Sep 2004 18:09:09 +0000 Subject: From Lars Roland: Having a closer look at the new and very useful H323 Call Analysis feature, I have found some bugs and unnecessarily complicated code for managing the registration of the tap listeners. So I decided to rewrite this part of the source code. This part of the code is much smaller now. Unnecessary and wrong calls of register_ethereal_tap() and register_tap_listener_xxx() have been removed or replaced. I also fixed a bug with RAS Messages. svn path=/trunk/; revision=12149 --- gtk/Makefile.common | 2 +- gtk/h323_analysis.c | 1107 +++++++++++++++++++++-------------------- gtk/h323_conversations.c | 792 ++++++++++++++--------------- gtk/h323_conversations.h | 248 +++++----- gtk/h323_conversations_dlg.c | 1122 +++++++++++++++++++++--------------------- 5 files changed, 1620 insertions(+), 1651 deletions(-) (limited to 'gtk') diff --git a/gtk/Makefile.common b/gtk/Makefile.common index 2fde48f31f..379e3f4273 100644 --- a/gtk/Makefile.common +++ b/gtk/Makefile.common @@ -53,6 +53,7 @@ ETHEREAL_GTK_SRC = \ goto_dlg.c \ gtk_stat_util.c \ gui_prefs.c \ + h323_analysis.c \ h323_conversations.c \ help_dlg.c \ hostlist_table.c \ @@ -104,7 +105,6 @@ ETHEREAL_TAP_SRC = \ gsm_map_summary.c \ h225_counter.c \ h225_ras_srt.c \ - h323_analysis.c \ h323_conversations_dlg.c \ hostlist_eth.c \ hostlist_fc.c \ diff --git a/gtk/h323_analysis.c b/gtk/h323_analysis.c index 2197a6386d..6fd300e8ec 100644 --- a/gtk/h323_analysis.c +++ b/gtk/h323_analysis.c @@ -1,554 +1,553 @@ -/* h323_analysis.c - * H323 analysis addition for ethereal - * - * Copyright 2004, Iskratel, Ltd, Kranj - * By Miha Jemec - * - * Ethereal - Network traffic analyzer - * By Gerald Combs - * Copyright 1998 Gerald Combs - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/*do not define this symbol. will be added soon*/ -/*#define USE_CONVERSATION_GRAPH 1*/ - -#include "h323_analysis.h" -#include "h323_conversations.h" -#include "h323_conversations_dlg.h" - -#include -#include - -#include "globals.h" - -#include "util.h" -#include -#include "register.h" - -#include -#include - -/* in /gtk ... */ -#include "dlg_utils.h" -#include "ui_util.h" -#include "alert_box.h" -#include "simple_dialog.h" -#include "tap_menu.h" -#include "main.h" -#include "progress_dlg.h" -#include "compat_macros.h" - -#include - -/****************************************************************************/ -/* structure that holds general information about the connection */ -typedef struct _user_data_t { - /* tap associated data*/ - guint32 ip_src; - guint16 port_src; - guint32 ip_dst; - guint16 port_dst; - guint32 ip_src_h245; - guint16 port_src_h245; - - GtkWidget *window; - GtkCList *clist1; - GtkWidget *label_stats; - GtkCList *selected_clist1; - gint selected_row; - -} user_data_t; - -/* Column titles. */ -static gchar *titles[7] = { - "Packet", - "Time", - "Delay", - " Side A", - "Direction", - " Side B", - "Comment" -}; - -typedef const guint8 * ip_addr_p; - -static gint32 last_sec = 0, last_usec = 0; - - -/****************************************************************************/ -/* TAP FUNCTIONS */ - -/****************************************************************************/ -/* when there is a [re]reading of packet's */ -static void -h225_reset(void *user_data_arg _U_) -{ - last_sec = 0; - last_usec = 0; - return; -} - -/****************************************************************************/ -/* here we can redraw the output */ -/* not used yet */ -static void h225_draw(void *prs _U_) -{ - return; -} - - -static const GdkColor COLOR_DEFAULT = {0, 0xffff, 0xffff, 0xffff}; -static const GdkColor COLOR_ERROR = {0, 0xffff, 0xbfff, 0xbfff}; -static const GdkColor COLOR_WARNING = {0, 0xffff, 0xdfff, 0xbfff}; -static const GdkColor COLOR_CN = {0, 0xbfff, 0xbfff, 0xffff}; - -/****************************************************************************/ -/* append a line to clist1 */ -static void add_to_clist1(GtkCList *clist1, guint32 number, gchar *time, - double delay, gchar *sideA, gboolean direction, gchar *sideB, - gchar *comment, GdkColor *color) -{ - guint added_row; - gchar *data[7]; - gchar field[7][32]; - - data[0]=&field[0][0]; - data[1]=&field[1][0]; - data[2]=&field[2][0]; - data[3]=&field[3][0]; - data[4]=&field[4][0]; - data[5]=&field[5][0]; - data[6]=&field[6][0]; - - g_snprintf(field[0], 32, "%u", number); - g_snprintf(field[1], 32, "%s", time); - g_snprintf(field[2], 32, "%f", delay); - g_snprintf(field[3], 32, "%s", sideA); - g_snprintf(field[4], 20, "%s", direction? "---->" : "<----"); - g_snprintf(field[5], 32, "%s", sideB); - g_snprintf(field[6], 32, "%s", comment); - - added_row = gtk_clist_append(GTK_CLIST(clist1), data); - gtk_clist_set_row_data(GTK_CLIST(clist1), added_row, GUINT_TO_POINTER(number)); - gtk_clist_set_background(GTK_CLIST(clist1), added_row, color); -} - - -/****************************************************************************/ -/* whenever a h225 packet is seen by the tap listener */ -static int h225_packet(void *user_data_arg, packet_info *pinfo, epan_dissect_t *edt _U_, void *h225info_arg) -{ - user_data_t *user_data = user_data_arg; - h225_packet_info *h225ptr_info = h225info_arg; - GdkColor color = COLOR_DEFAULT; - - gchar timeStr[32]; - gchar message[32]; - guint32 src, dst; - double delay; - gint32 delay_sec, delay_usec; - - /* time since beginning of capture */ - g_snprintf(timeStr, sizeof(timeStr), "%d.%06d", pinfo->fd->rel_secs, pinfo->fd->rel_usecs); - - /* time since previous packet seen in tap listener */ - delay_sec = pinfo->fd->rel_secs - last_sec; - delay_usec = pinfo->fd->rel_usecs - last_usec; - - delay = (double)delay_sec + ((double)delay_usec)/1000000; - - last_sec = pinfo->fd->rel_secs; - last_usec = pinfo->fd->rel_usecs; - - switch (h225ptr_info->cs_type) { - - case H225_SETUP: - g_snprintf(message, sizeof(message),"H225 Setup"); - break; - case H225_CALL_PROCEDING: - g_snprintf(message, sizeof(message),"H225 Call Proceding"); - break; - case H225_ALERTING: - g_snprintf(message, sizeof(message),"H225 Alerting"); - break; - case H225_CONNECT: - g_snprintf(message, sizeof(message),"H225 Connect"); - break; - case H225_RELEASE_COMPLET: - g_snprintf(message, sizeof(message),"H225 Release Complet"); - break; - case H225_OTHER: - g_snprintf(message, sizeof(message),"H225 Other"); - } - - g_memmove(&src, pinfo->src.data, 4); - g_memmove(&dst, pinfo->dst.data, 4); - - if (src == user_data->ip_src) - add_to_clist1(user_data->clist1,pinfo->fd->num,timeStr,delay,message, 1, "", "", &color); - else - add_to_clist1(user_data->clist1, pinfo->fd->num, timeStr,delay, "", 0, message, "", &color); - - return 0; -} - - -/****************************************************************************/ -/* whenever a h245 packet is seen by the tap listener */ -static int h245_packet(void *user_data_arg, packet_info *pinfo, epan_dissect_t *edt _U_, void *h245info_arg) -{ - - user_data_t *user_data = user_data_arg; - h245_packet_info *h245ptr_info = h245info_arg; - GdkColor color = COLOR_DEFAULT; - - gchar timeStr[32]; - gchar message[32]; - guint32 src, dst; - double delay; - gint32 delay_sec, delay_usec; - - /* time since beginning of capture */ - g_snprintf(timeStr, sizeof(timeStr), "%d.%06d", pinfo->fd->rel_secs, pinfo->fd->rel_usecs); - - /* time since previous packet seen in tap listener */ - delay_sec = pinfo->fd->rel_secs - last_sec; - delay_usec = pinfo->fd->rel_usecs - last_usec; - - delay = (double)delay_sec + ((double)delay_usec)/1000000; - - last_sec = pinfo->fd->rel_secs; - last_usec = pinfo->fd->rel_usecs; - - switch (h245ptr_info->msg_type) { - - case H245_TermCapSet: - g_snprintf(message, sizeof(message),"H245 TermCapSet"); - break; - case H245_TermCapSetAck: - g_snprintf(message, sizeof(message),"H245_TermCapSetAck"); - break; - case H245_TermCapSetRjc: - g_snprintf(message, sizeof(message),"H245_TermCapSetRjc"); - break; - case H245_TermCapSetRls: - g_snprintf(message, sizeof(message),"H245_TermCapSetRls"); - break; - case H245_OpenLogChn: - g_snprintf(message, sizeof(message),"H245_OpenLogChn"); - break; - case H245_OpenLogChnCnf: - g_snprintf(message, sizeof(message),"H245_OpenLogChnCnf"); - break; - case H245_OpenLogChnAck: - g_snprintf(message, sizeof(message),"H245_OpenLogChnAck"); - break; - case H245_OpenLogChnRjc: - g_snprintf(message, sizeof(message),"H245_OpenLogChnRjc"); - break; - case H245_CloseLogChn: - g_snprintf(message, sizeof(message),"H245_CloseLogChn"); - break; - case H245_CloseLogChnAck: - g_snprintf(message, sizeof(message),"H245_CloseLogChnAck"); - break; - case H245_MastSlvDet: - g_snprintf(message, sizeof(message),"H245_MastSlvDet"); - break; - case H245_MastSlvDetAck: - g_snprintf(message, sizeof(message),"H245_MastSlvDetAck"); - break; - case H245_MastSlvDetRjc: - g_snprintf(message, sizeof(message),"H245_MastSlvDetRjc"); - break; - case H245_MastSlvDetRls: - g_snprintf(message, sizeof(message),"H245_MastSlvDetRls"); - break; - case H245_OTHER: - g_snprintf(message, sizeof(message),"H225 Other"); - } - - g_memmove(&src, pinfo->src.data, 4); - g_memmove(&dst, pinfo->dst.data, 4); - - if (src == user_data->ip_src) - add_to_clist1(user_data->clist1,pinfo->fd->num,timeStr,delay,message, 1, "", "", &color); - else - add_to_clist1(user_data->clist1, pinfo->fd->num, timeStr,delay, "", 0, message, "", &color); - - return 0; -} - - -/**************** Callbacks *************************************************/ -/****************************************************************************/ -/* XXX just copied from gtk/rpc_stat.c */ -void protect_thread_critical_region(void); -void unprotect_thread_critical_region(void); - - -/****************************************************************************/ -/* close the dialog window and remove the tap listener */ -static void on_destroy(GtkWidget *win _U_, user_data_t *user_data _U_) -{ - g_free(user_data); -} - -/****************************************************************************/ -static void on_clist_select_row(GtkCList *clist1 _U_, - gint row _U_, - gint column _U_, - GdkEvent *event _U_, - user_data_t *user_data _U_) -{ - user_data->selected_clist1 = clist1; - user_data->selected_row = row; -} - -/****************************************************************************/ -static void on_goto_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_) -{ - guint fnumber; - - if (user_data->selected_clist1!=NULL) { - fnumber = GPOINTER_TO_UINT(gtk_clist_get_row_data( - GTK_CLIST(user_data->selected_clist1), user_data->selected_row) ); - goto_frame(&cfile, fnumber); - } -} - - -/****************************************************************************/ -/* re-dissects all packets */ -static void on_refresh_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_) -{ - gchar filter_text_h225[256]; - gchar filter_text_h245[256]; - /*gchar filter_text_rtp[256];*/ - dfilter_t *sfcode; - GString *error_string; - - /* clear the dialog box clists */ - gtk_clist_clear(GTK_CLIST(user_data->clist1)); - - /* try to compile the filter for h225 */ - g_snprintf(filter_text_h225,sizeof(filter_text_h225), - "h225 && (( ip.src==%s && tcp.srcport==%u && ip.dst==%s && tcp.dstport==%u ) || ( ip.src==%s && tcp.srcport==%u && ip.dst==%s && tcp.dstport==%u ))", - ip_to_str((ip_addr_p)&(user_data->ip_src)), - user_data->port_src, - ip_to_str((ip_addr_p)&(user_data->ip_dst)), - user_data->port_dst, - ip_to_str((ip_addr_p)&(user_data->ip_dst)), - user_data->port_dst, - ip_to_str((ip_addr_p)&(user_data->ip_src)), - user_data->port_src - ); - - if (!dfilter_compile(filter_text_h225, &sfcode)) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, dfilter_error_msg); - return; - } - - /* try to compile the filter for h245 */ - g_snprintf(filter_text_h245,sizeof(filter_text_h245), - "h245 && (( ip.src==%s && tcp.srcport==%u ) || ( ip.dst==%s && tcp.dstport==%u ))", - ip_to_str((ip_addr_p)&(user_data->ip_src_h245)), - user_data->port_src_h245, - ip_to_str((ip_addr_p)&(user_data->ip_src_h245)), - user_data->port_src_h245 - ); - - if (!dfilter_compile(filter_text_h245, &sfcode)) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, dfilter_error_msg); - return; - } - - /* register tap h225 listener */ - error_string = register_tap_listener("h225", user_data, filter_text_h225, - h225_reset, h225_packet, h225_draw); - if (error_string != NULL) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, error_string->str); - g_string_free(error_string, TRUE); - return; - } - - /* register tap h245 listener */ - error_string = register_tap_listener("h245", user_data, filter_text_h245, - NULL, h245_packet, NULL); - if (error_string != NULL) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, error_string->str); - g_string_free(error_string, TRUE); - return; - } - - /* retap all packets */ - retap_packets(&cfile); - - /* remove tap listener again */ - protect_thread_critical_region(); - remove_tap_listener(user_data); - remove_tap_listener(user_data); - unprotect_thread_critical_region(); - -} - - -/************************************************************************************/ -/************** Create the dialog box with all widgets ******************************/ -void create_h225_dialog(user_data_t* user_data) -{ - GtkWidget *window = NULL; - GtkWidget *clist_h225; - GtkWidget *label_stats; - - GtkWidget *main_vb; - GtkWidget *label; - GtkWidget *scrolled_window; - GtkWidget *box4, *goto_bt, *close_bt, *refresh_bt; - - gchar label_forward[150]; - - gchar str_ip_src[16]; - gchar str_ip_dst[16]; - - window = window_new(GTK_WINDOW_TOPLEVEL, "Ethereal: H.323 VoIP Analysis"); - gtk_window_set_default_size(GTK_WINDOW(window), 700, 350); - - /* Container for each row of widgets */ - main_vb = gtk_vbox_new(FALSE, 2); - gtk_container_add(GTK_CONTAINER(window), main_vb); - gtk_container_set_border_width(GTK_CONTAINER(main_vb), 2); - gtk_widget_show(main_vb); - - strcpy(str_ip_src, ip_to_str((ip_addr_p)&user_data->ip_src)); - strcpy(str_ip_dst, ip_to_str((ip_addr_p)&user_data->ip_dst)); - - g_snprintf(label_forward, 149, - "\nAnalysing H.323 Call between %s port %u (Side A) and %s port %u (Side B)\n", - str_ip_src, user_data->port_src, str_ip_dst, user_data->port_dst); - - /* label */ - label = gtk_label_new(label_forward); - gtk_box_pack_start (GTK_BOX (main_vb), label, FALSE, FALSE, 0); - - /* scrolled window */ - scrolled_window = scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), - GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); - gtk_box_pack_start (GTK_BOX (main_vb), scrolled_window, TRUE, TRUE, 0); - - /* place for some statistics */ - /*label_stats = gtk_label_new("\n");*/ - /*gtk_box_pack_start(GTK_BOX(main_vb), label_stats, FALSE, FALSE, 0);*/ - - /* packet clist */ - clist_h225 = gtk_clist_new_with_titles(7, titles); - gtk_container_add(GTK_CONTAINER(scrolled_window), clist_h225); - gtk_widget_show(clist_h225); - SIGNAL_CONNECT(clist_h225, "select_row", on_clist_select_row, user_data); - - /* column widths and justification */ - gtk_clist_set_column_width(GTK_CLIST(clist_h225), 0, 45); - gtk_clist_set_column_width(GTK_CLIST(clist_h225), 1, 90); - gtk_clist_set_column_width(GTK_CLIST(clist_h225), 2, 90); - gtk_clist_set_column_width(GTK_CLIST(clist_h225), 3, 140); - gtk_clist_set_column_width(GTK_CLIST(clist_h225), 4, 60); - gtk_clist_set_column_width(GTK_CLIST(clist_h225), 5, 140); - gtk_clist_set_column_justification(GTK_CLIST(clist_h225), 0, GTK_JUSTIFY_CENTER); - gtk_clist_set_column_justification(GTK_CLIST(clist_h225), 1, GTK_JUSTIFY_CENTER); - gtk_clist_set_column_justification(GTK_CLIST(clist_h225), 2, GTK_JUSTIFY_CENTER); - gtk_clist_set_column_justification(GTK_CLIST(clist_h225), 3, GTK_JUSTIFY_LEFT); - gtk_clist_set_column_justification(GTK_CLIST(clist_h225), 4, GTK_JUSTIFY_CENTER); - gtk_clist_set_column_justification(GTK_CLIST(clist_h225), 5, GTK_JUSTIFY_LEFT); - gtk_clist_set_column_justification(GTK_CLIST(clist_h225), 6, GTK_JUSTIFY_CENTER); - - gtk_widget_show(scrolled_window); - - /* buttons */ - box4 = gtk_hbutton_box_new(); - gtk_box_pack_start(GTK_BOX(main_vb), box4, FALSE, FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER(box4), 10); - gtk_button_box_set_layout(GTK_BUTTON_BOX (box4), GTK_BUTTONBOX_END); - gtk_button_box_set_spacing(GTK_BUTTON_BOX (box4), 10); - gtk_button_box_set_child_ipadding(GTK_BUTTON_BOX (box4), 4, 0); - gtk_widget_show(box4); - - refresh_bt = BUTTON_NEW_FROM_STOCK(GTK_STOCK_REFRESH); - gtk_container_add(GTK_CONTAINER(box4), refresh_bt); - gtk_widget_show(refresh_bt); - SIGNAL_CONNECT(refresh_bt, "clicked", on_refresh_bt_clicked, user_data); - - goto_bt = BUTTON_NEW_FROM_STOCK(GTK_STOCK_JUMP_TO); - gtk_container_add(GTK_CONTAINER(box4), goto_bt); - gtk_widget_show(goto_bt); - SIGNAL_CONNECT(goto_bt, "clicked", on_goto_bt_clicked, user_data); - - close_bt = BUTTON_NEW_FROM_STOCK(GTK_STOCK_CLOSE); - gtk_container_add(GTK_CONTAINER(box4), close_bt); - GTK_WIDGET_SET_FLAGS(close_bt, GTK_CAN_DEFAULT); - gtk_widget_show(close_bt); - window_set_cancel_button(window, close_bt, window_cancel_button_cb); - - SIGNAL_CONNECT(window, "delete_event", window_delete_event_cb, NULL); - SIGNAL_CONNECT(window, "destroy", on_destroy, user_data); - - gtk_widget_show_all(window); - window_present(window); - - /* some widget references need to be saved for outside use */ - user_data->window = window; - user_data->clist1 = GTK_CLIST(clist_h225); - user_data->label_stats = label; - user_data->selected_clist1 = GTK_CLIST(clist_h225); - user_data->selected_row = 0; -} - - -/****************************************************************************/ -void h323_analysis( - guint32 ip_src, - guint16 port_src, - guint32 ip_dst, - guint16 port_dst, - guint32 ip_src_h245, - guint16 port_src_h245 - ) -{ - user_data_t *user_data; - - /* init */ - user_data = g_malloc(sizeof(user_data_t)); - - user_data->ip_src = ip_src; - user_data->port_src = port_src; - user_data->ip_dst = ip_dst; - user_data->port_dst = port_dst; - user_data->ip_src_h245 = ip_src_h245; - user_data->port_src_h245 = port_src_h245; - - /* create the dialog box */ - create_h225_dialog(user_data); - - /* proceed as if the Refresh button would have been pressed */ - on_refresh_bt_clicked(NULL, user_data); -} - - +/* h323_analysis.c + * H323 analysis addition for ethereal + * + * Copyright 2004, Iskratel, Ltd, Kranj + * By Miha Jemec + * + * Ethereal - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/*do not define this symbol. will be added soon*/ +/*#define USE_CONVERSATION_GRAPH 1*/ + +#include "h323_analysis.h" +#include "h323_conversations.h" +#include "h323_conversations_dlg.h" + +#include +#include + +#include "globals.h" + +#include "util.h" +#include + +#include +#include + +/* in /gtk ... */ +#include "dlg_utils.h" +#include "ui_util.h" +#include "alert_box.h" +#include "simple_dialog.h" +#include "tap_menu.h" +#include "main.h" +#include "progress_dlg.h" +#include "compat_macros.h" + +#include + +/****************************************************************************/ +/* structure that holds general information about the connection */ +typedef struct _user_data_t { + /* tap associated data*/ + guint32 ip_src; + guint16 port_src; + guint32 ip_dst; + guint16 port_dst; + guint32 ip_src_h245; + guint16 port_src_h245; + + GtkWidget *window; + GtkCList *clist1; + GtkWidget *label_stats; + GtkCList *selected_clist1; + gint selected_row; + +} user_data_t; + +/* Column titles. */ +static gchar *titles[7] = { + "Packet", + "Time", + "Delay", + " Side A", + "Direction", + " Side B", + "Comment" +}; + +typedef const guint8 * ip_addr_p; + +static gint32 last_sec = 0, last_usec = 0; + + +/****************************************************************************/ +/* TAP FUNCTIONS */ + +/****************************************************************************/ +/* when there is a [re]reading of packet's */ +static void +h225_reset(void *user_data_arg _U_) +{ + last_sec = 0; + last_usec = 0; + return; +} + +/****************************************************************************/ +/* here we can redraw the output */ +/* not used yet */ +static void h225_draw(void *prs _U_) +{ + return; +} + + +static const GdkColor COLOR_DEFAULT = {0, 0xffff, 0xffff, 0xffff}; +static const GdkColor COLOR_ERROR = {0, 0xffff, 0xbfff, 0xbfff}; +static const GdkColor COLOR_WARNING = {0, 0xffff, 0xdfff, 0xbfff}; +static const GdkColor COLOR_CN = {0, 0xbfff, 0xbfff, 0xffff}; + +/****************************************************************************/ +/* append a line to clist1 */ +static void add_to_clist1(GtkCList *clist1, guint32 number, gchar *time, + double delay, gchar *sideA, gboolean direction, gchar *sideB, + gchar *comment, GdkColor *color) +{ + guint added_row; + gchar *data[7]; + gchar field[7][32]; + + data[0]=&field[0][0]; + data[1]=&field[1][0]; + data[2]=&field[2][0]; + data[3]=&field[3][0]; + data[4]=&field[4][0]; + data[5]=&field[5][0]; + data[6]=&field[6][0]; + + g_snprintf(field[0], 32, "%u", number); + g_snprintf(field[1], 32, "%s", time); + g_snprintf(field[2], 32, "%f", delay); + g_snprintf(field[3], 32, "%s", sideA); + g_snprintf(field[4], 20, "%s", direction? "---->" : "<----"); + g_snprintf(field[5], 32, "%s", sideB); + g_snprintf(field[6], 32, "%s", comment); + + added_row = gtk_clist_append(GTK_CLIST(clist1), data); + gtk_clist_set_row_data(GTK_CLIST(clist1), added_row, GUINT_TO_POINTER(number)); + gtk_clist_set_background(GTK_CLIST(clist1), added_row, color); +} + + +/****************************************************************************/ +/* whenever a h225 packet is seen by the tap listener */ +static int h225_packet(void *user_data_arg, packet_info *pinfo, epan_dissect_t *edt _U_, void *h225info_arg) +{ + user_data_t *user_data = user_data_arg; + h225_packet_info *h225ptr_info = h225info_arg; + GdkColor color = COLOR_DEFAULT; + + gchar timeStr[32]; + gchar message[32]; + guint32 src, dst; + double delay; + gint32 delay_sec, delay_usec; + + /* time since beginning of capture */ + g_snprintf(timeStr, sizeof(timeStr), "%d.%06d", pinfo->fd->rel_secs, pinfo->fd->rel_usecs); + + /* time since previous packet seen in tap listener */ + delay_sec = pinfo->fd->rel_secs - last_sec; + delay_usec = pinfo->fd->rel_usecs - last_usec; + + delay = (double)delay_sec + ((double)delay_usec)/1000000; + + last_sec = pinfo->fd->rel_secs; + last_usec = pinfo->fd->rel_usecs; + + switch (h225ptr_info->cs_type) { + + case H225_SETUP: + g_snprintf(message, sizeof(message),"H225 Setup"); + break; + case H225_CALL_PROCEDING: + g_snprintf(message, sizeof(message),"H225 Call Proceding"); + break; + case H225_ALERTING: + g_snprintf(message, sizeof(message),"H225 Alerting"); + break; + case H225_CONNECT: + g_snprintf(message, sizeof(message),"H225 Connect"); + break; + case H225_RELEASE_COMPLET: + g_snprintf(message, sizeof(message),"H225 Release Complet"); + break; + case H225_OTHER: + g_snprintf(message, sizeof(message),"H225 Other"); + } + + g_memmove(&src, pinfo->src.data, 4); + g_memmove(&dst, pinfo->dst.data, 4); + + if (src == user_data->ip_src) + add_to_clist1(user_data->clist1,pinfo->fd->num,timeStr,delay,message, 1, "", "", &color); + else + add_to_clist1(user_data->clist1, pinfo->fd->num, timeStr,delay, "", 0, message, "", &color); + + return 0; +} + + +/****************************************************************************/ +/* whenever a h245 packet is seen by the tap listener */ +static int h245_packet(void *user_data_arg, packet_info *pinfo, epan_dissect_t *edt _U_, void *h245info_arg) +{ + + user_data_t *user_data = user_data_arg; + h245_packet_info *h245ptr_info = h245info_arg; + GdkColor color = COLOR_DEFAULT; + + gchar timeStr[32]; + gchar message[32]; + guint32 src, dst; + double delay; + gint32 delay_sec, delay_usec; + + /* time since beginning of capture */ + g_snprintf(timeStr, sizeof(timeStr), "%d.%06d", pinfo->fd->rel_secs, pinfo->fd->rel_usecs); + + /* time since previous packet seen in tap listener */ + delay_sec = pinfo->fd->rel_secs - last_sec; + delay_usec = pinfo->fd->rel_usecs - last_usec; + + delay = (double)delay_sec + ((double)delay_usec)/1000000; + + last_sec = pinfo->fd->rel_secs; + last_usec = pinfo->fd->rel_usecs; + + switch (h245ptr_info->msg_type) { + + case H245_TermCapSet: + g_snprintf(message, sizeof(message),"H245 TermCapSet"); + break; + case H245_TermCapSetAck: + g_snprintf(message, sizeof(message),"H245_TermCapSetAck"); + break; + case H245_TermCapSetRjc: + g_snprintf(message, sizeof(message),"H245_TermCapSetRjc"); + break; + case H245_TermCapSetRls: + g_snprintf(message, sizeof(message),"H245_TermCapSetRls"); + break; + case H245_OpenLogChn: + g_snprintf(message, sizeof(message),"H245_OpenLogChn"); + break; + case H245_OpenLogChnCnf: + g_snprintf(message, sizeof(message),"H245_OpenLogChnCnf"); + break; + case H245_OpenLogChnAck: + g_snprintf(message, sizeof(message),"H245_OpenLogChnAck"); + break; + case H245_OpenLogChnRjc: + g_snprintf(message, sizeof(message),"H245_OpenLogChnRjc"); + break; + case H245_CloseLogChn: + g_snprintf(message, sizeof(message),"H245_CloseLogChn"); + break; + case H245_CloseLogChnAck: + g_snprintf(message, sizeof(message),"H245_CloseLogChnAck"); + break; + case H245_MastSlvDet: + g_snprintf(message, sizeof(message),"H245_MastSlvDet"); + break; + case H245_MastSlvDetAck: + g_snprintf(message, sizeof(message),"H245_MastSlvDetAck"); + break; + case H245_MastSlvDetRjc: + g_snprintf(message, sizeof(message),"H245_MastSlvDetRjc"); + break; + case H245_MastSlvDetRls: + g_snprintf(message, sizeof(message),"H245_MastSlvDetRls"); + break; + case H245_OTHER: + g_snprintf(message, sizeof(message),"H225 Other"); + } + + g_memmove(&src, pinfo->src.data, 4); + g_memmove(&dst, pinfo->dst.data, 4); + + if (src == user_data->ip_src) + add_to_clist1(user_data->clist1,pinfo->fd->num,timeStr,delay,message, 1, "", "", &color); + else + add_to_clist1(user_data->clist1, pinfo->fd->num, timeStr,delay, "", 0, message, "", &color); + + return 0; +} + + +/**************** Callbacks *************************************************/ +/****************************************************************************/ +/* XXX just copied from gtk/rpc_stat.c */ +void protect_thread_critical_region(void); +void unprotect_thread_critical_region(void); + + +/****************************************************************************/ +/* close the dialog window and remove the tap listener */ +static void on_destroy(GtkWidget *win _U_, user_data_t *user_data _U_) +{ + g_free(user_data); +} + +/****************************************************************************/ +static void on_clist_select_row(GtkCList *clist1 _U_, + gint row _U_, + gint column _U_, + GdkEvent *event _U_, + user_data_t *user_data _U_) +{ + user_data->selected_clist1 = clist1; + user_data->selected_row = row; +} + +/****************************************************************************/ +static void on_goto_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_) +{ + guint fnumber; + + if (user_data->selected_clist1!=NULL) { + fnumber = GPOINTER_TO_UINT(gtk_clist_get_row_data( + GTK_CLIST(user_data->selected_clist1), user_data->selected_row) ); + goto_frame(&cfile, fnumber); + } +} + + +/****************************************************************************/ +/* re-dissects all packets */ +static void on_refresh_bt_clicked(GtkWidget *bt _U_, user_data_t *user_data _U_) +{ + gchar filter_text_h225[256]; + gchar filter_text_h245[256]; + /*gchar filter_text_rtp[256];*/ + dfilter_t *sfcode; + GString *error_string; + + /* clear the dialog box clists */ + gtk_clist_clear(GTK_CLIST(user_data->clist1)); + + /* try to compile the filter for h225 */ + g_snprintf(filter_text_h225,sizeof(filter_text_h225), + "h225 && (( ip.src==%s && tcp.srcport==%u && ip.dst==%s && tcp.dstport==%u ) || ( ip.src==%s && tcp.srcport==%u && ip.dst==%s && tcp.dstport==%u ))", + ip_to_str((ip_addr_p)&(user_data->ip_src)), + user_data->port_src, + ip_to_str((ip_addr_p)&(user_data->ip_dst)), + user_data->port_dst, + ip_to_str((ip_addr_p)&(user_data->ip_dst)), + user_data->port_dst, + ip_to_str((ip_addr_p)&(user_data->ip_src)), + user_data->port_src + ); + + if (!dfilter_compile(filter_text_h225, &sfcode)) { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, dfilter_error_msg); + return; + } + + /* try to compile the filter for h245 */ + g_snprintf(filter_text_h245,sizeof(filter_text_h245), + "h245 && (( ip.src==%s && tcp.srcport==%u ) || ( ip.dst==%s && tcp.dstport==%u ))", + ip_to_str((ip_addr_p)&(user_data->ip_src_h245)), + user_data->port_src_h245, + ip_to_str((ip_addr_p)&(user_data->ip_src_h245)), + user_data->port_src_h245 + ); + + if (!dfilter_compile(filter_text_h245, &sfcode)) { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, dfilter_error_msg); + return; + } + + /* register tap h225 listener */ + error_string = register_tap_listener("h225", user_data, filter_text_h225, + h225_reset, h225_packet, h225_draw); + if (error_string != NULL) { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, error_string->str); + g_string_free(error_string, TRUE); + return; + } + + /* register tap h245 listener */ + error_string = register_tap_listener("h245", user_data, filter_text_h245, + NULL, h245_packet, NULL); + if (error_string != NULL) { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, error_string->str); + g_string_free(error_string, TRUE); + return; + } + + /* retap all packets */ + retap_packets(&cfile); + + /* remove tap listener again */ + protect_thread_critical_region(); + remove_tap_listener(user_data); + remove_tap_listener(user_data); + unprotect_thread_critical_region(); + +} + + +/************************************************************************************/ +/************** Create the dialog box with all widgets ******************************/ +void create_h225_dialog(user_data_t* user_data) +{ + GtkWidget *window = NULL; + GtkWidget *clist_h225; + GtkWidget *label_stats; + + GtkWidget *main_vb; + GtkWidget *label; + GtkWidget *scrolled_window; + GtkWidget *box4, *goto_bt, *close_bt, *refresh_bt; + + gchar label_forward[150]; + + gchar str_ip_src[16]; + gchar str_ip_dst[16]; + + window = window_new(GTK_WINDOW_TOPLEVEL, "Ethereal: H.323 VoIP Analysis"); + gtk_window_set_default_size(GTK_WINDOW(window), 700, 350); + + /* Container for each row of widgets */ + main_vb = gtk_vbox_new(FALSE, 2); + gtk_container_add(GTK_CONTAINER(window), main_vb); + gtk_container_set_border_width(GTK_CONTAINER(main_vb), 2); + gtk_widget_show(main_vb); + + strcpy(str_ip_src, ip_to_str((ip_addr_p)&user_data->ip_src)); + strcpy(str_ip_dst, ip_to_str((ip_addr_p)&user_data->ip_dst)); + + g_snprintf(label_forward, 149, + "\nAnalysing H.323 Call between %s port %u (Side A) and %s port %u (Side B)\n", + str_ip_src, user_data->port_src, str_ip_dst, user_data->port_dst); + + /* label */ + label = gtk_label_new(label_forward); + gtk_box_pack_start (GTK_BOX (main_vb), label, FALSE, FALSE, 0); + + /* scrolled window */ + scrolled_window = scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), + GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); + gtk_box_pack_start (GTK_BOX (main_vb), scrolled_window, TRUE, TRUE, 0); + + /* place for some statistics */ + /*label_stats = gtk_label_new("\n");*/ + /*gtk_box_pack_start(GTK_BOX(main_vb), label_stats, FALSE, FALSE, 0);*/ + + /* packet clist */ + clist_h225 = gtk_clist_new_with_titles(7, titles); + gtk_container_add(GTK_CONTAINER(scrolled_window), clist_h225); + gtk_widget_show(clist_h225); + SIGNAL_CONNECT(clist_h225, "select_row", on_clist_select_row, user_data); + + /* column widths and justification */ + gtk_clist_set_column_width(GTK_CLIST(clist_h225), 0, 45); + gtk_clist_set_column_width(GTK_CLIST(clist_h225), 1, 90); + gtk_clist_set_column_width(GTK_CLIST(clist_h225), 2, 90); + gtk_clist_set_column_width(GTK_CLIST(clist_h225), 3, 140); + gtk_clist_set_column_width(GTK_CLIST(clist_h225), 4, 60); + gtk_clist_set_column_width(GTK_CLIST(clist_h225), 5, 140); + gtk_clist_set_column_justification(GTK_CLIST(clist_h225), 0, GTK_JUSTIFY_CENTER); + gtk_clist_set_column_justification(GTK_CLIST(clist_h225), 1, GTK_JUSTIFY_CENTER); + gtk_clist_set_column_justification(GTK_CLIST(clist_h225), 2, GTK_JUSTIFY_CENTER); + gtk_clist_set_column_justification(GTK_CLIST(clist_h225), 3, GTK_JUSTIFY_LEFT); + gtk_clist_set_column_justification(GTK_CLIST(clist_h225), 4, GTK_JUSTIFY_CENTER); + gtk_clist_set_column_justification(GTK_CLIST(clist_h225), 5, GTK_JUSTIFY_LEFT); + gtk_clist_set_column_justification(GTK_CLIST(clist_h225), 6, GTK_JUSTIFY_CENTER); + + gtk_widget_show(scrolled_window); + + /* buttons */ + box4 = gtk_hbutton_box_new(); + gtk_box_pack_start(GTK_BOX(main_vb), box4, FALSE, FALSE, 0); + gtk_container_set_border_width(GTK_CONTAINER(box4), 10); + gtk_button_box_set_layout(GTK_BUTTON_BOX (box4), GTK_BUTTONBOX_END); + gtk_button_box_set_spacing(GTK_BUTTON_BOX (box4), 10); + gtk_button_box_set_child_ipadding(GTK_BUTTON_BOX (box4), 4, 0); + gtk_widget_show(box4); + + refresh_bt = BUTTON_NEW_FROM_STOCK(GTK_STOCK_REFRESH); + gtk_container_add(GTK_CONTAINER(box4), refresh_bt); + gtk_widget_show(refresh_bt); + SIGNAL_CONNECT(refresh_bt, "clicked", on_refresh_bt_clicked, user_data); + + goto_bt = BUTTON_NEW_FROM_STOCK(GTK_STOCK_JUMP_TO); + gtk_container_add(GTK_CONTAINER(box4), goto_bt); + gtk_widget_show(goto_bt); + SIGNAL_CONNECT(goto_bt, "clicked", on_goto_bt_clicked, user_data); + + close_bt = BUTTON_NEW_FROM_STOCK(GTK_STOCK_CLOSE); + gtk_container_add(GTK_CONTAINER(box4), close_bt); + GTK_WIDGET_SET_FLAGS(close_bt, GTK_CAN_DEFAULT); + gtk_widget_show(close_bt); + window_set_cancel_button(window, close_bt, window_cancel_button_cb); + + SIGNAL_CONNECT(window, "delete_event", window_delete_event_cb, NULL); + SIGNAL_CONNECT(window, "destroy", on_destroy, user_data); + + gtk_widget_show_all(window); + window_present(window); + + /* some widget references need to be saved for outside use */ + user_data->window = window; + user_data->clist1 = GTK_CLIST(clist_h225); + user_data->label_stats = label; + user_data->selected_clist1 = GTK_CLIST(clist_h225); + user_data->selected_row = 0; +} + + +/****************************************************************************/ +void h323_analysis( + guint32 ip_src, + guint16 port_src, + guint32 ip_dst, + guint16 port_dst, + guint32 ip_src_h245, + guint16 port_src_h245 + ) +{ + user_data_t *user_data; + + /* init */ + user_data = g_malloc(sizeof(user_data_t)); + + user_data->ip_src = ip_src; + user_data->port_src = port_src; + user_data->ip_dst = ip_dst; + user_data->port_dst = port_dst; + user_data->ip_src_h245 = ip_src_h245; + user_data->port_src_h245 = port_src_h245; + + /* create the dialog box */ + create_h225_dialog(user_data); + + /* proceed as if the Refresh button would have been pressed */ + on_refresh_bt_clicked(NULL, user_data); +} + + diff --git a/gtk/h323_conversations.c b/gtk/h323_conversations.c index 807e6a3194..15c212eee3 100644 --- a/gtk/h323_conversations.c +++ b/gtk/h323_conversations.c @@ -1,413 +1,379 @@ -/* h323_conversations.c - * H323 conversations summary addition for ethereal - * - * Copyright 2004, Iskratel, Ltd, Kranj - * By Miha Jemec - * - * based on rtp_stream.c - * Copyright 2003, Alcatel Business Systems - * By Lars Ruoff - * - * Ethereal - Network traffic analyzer - * By Gerald Combs - * Copyright 1998 Gerald Combs - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "h323_conversations.h" -#include "h323_conversations_dlg.h" - -#include "globals.h" - -#include -#include "register.h" -#include -#include - -#include "alert_box.h" -#include "simple_dialog.h" - -#ifdef HAVE_FCNTL_H -#include -#endif - -#ifdef HAVE_SYS_TYPES_H -# include -#endif - -#include - -/****************************************************************************/ -/* the one and only global h323conversations_tapinfo_t structure */ -static h323conversations_tapinfo_t the_tapinfo_struct = - {0, NULL, 0, NULL, 0, FALSE, FALSE, 0, 0, 0}; - -/****************************************************************************/ -/* GCompareFunc style comparison function for _h323_conversations_info */ -gint h323_conversations_info_cmp(gconstpointer aa, gconstpointer bb) -{ - const struct _h323_conversations_info* a = aa; - const struct _h323_conversations_info* b = bb; - - if (a==b) - return 0; - if (a==NULL || b==NULL) - return 1; - if ((a->src_addr == b->src_addr) - && (a->src_port == b->src_port) - && (a->dest_addr == b->dest_addr) - && (a->dest_port == b->dest_port) - ) - return 0; - else if ((a->src_addr == b->dest_addr) - && (a->src_port == b->dest_port) - && (a->dest_addr == b->src_addr) - && (a->dest_port == b->src_port) - ) - return 0; - else - return 1; -} - - -/****************************************************************************/ -/* when there is a [re]reading of packet's */ -void h225conversations_reset(h323conversations_tapinfo_t *tapinfo) -{ - GList* list; - - /* free the data items first */ - list = g_list_first(tapinfo->strinfo_list); - while (list) - { - g_free(list->data); - list = g_list_next(list); - } - g_list_free(tapinfo->strinfo_list); - tapinfo->strinfo_list = NULL; - tapinfo->nconversationss = 0; - tapinfo->npackets = 0; - tapinfo->setup_packets = 0; - tapinfo->completed_calls = 0; - tapinfo->rejected_calls = 0; - - ++(tapinfo->launch_count); - - return; -} - -/****************************************************************************/ -/* redraw the output */ -void h225conversations_draw(h323conversations_tapinfo_t *tapinfo _U_) -{ -/* XXX: see h323conversations_on_update in h323_conversationss_dlg.c for comments - gtk_signal_emit_by_name(top_level, "signal_h225conversations_update"); -*/ - h323conversations_dlg_update(the_tapinfo_struct.strinfo_list); - return; -} - - - -/****************************************************************************/ -/* whenever a H225 packet is seen by the tap listener */ -int h225conversations_packet(h323conversations_tapinfo_t *tapinfo _U_, packet_info *pinfo, epan_dissect_t *edt _U_, void *h225info) -{ - h323_conversations_info_t tmp_strinfo; - h323_conversations_info_t *strinfo = NULL; - GList* list; - - h225_packet_info *pi = h225info; - - /* gather infos on the conversations this packet is part of */ - g_memmove(&(tmp_strinfo.src_addr), pinfo->src.data, 4); - tmp_strinfo.src_port = pinfo->srcport; - g_memmove(&(tmp_strinfo.dest_addr), pinfo->dst.data, 4); - tmp_strinfo.dest_port = pinfo->destport; - - /* check wether we already have a conversations with these parameters in the list */ - list = g_list_first(tapinfo->strinfo_list); - while (list) - { - if (h323_conversations_info_cmp(&tmp_strinfo, (h323_conversations_info_t*)(list->data))==0) - { - strinfo = (h323_conversations_info_t*)(list->data); /*found!*/ - break; - } - list = g_list_next(list); - } - - /* not in the list? then create a new entry */ - if (!strinfo) { - tmp_strinfo.call_state = UNKNOWN; - tmp_strinfo.npackets = 0; - tmp_strinfo.h245packets = 0; - tmp_strinfo.first_frame_num = pinfo->fd->num; - tmp_strinfo.faststart = pi->is_faststart; - tmp_strinfo.is_h245 = pi->is_h245; - tmp_strinfo.h245address = pi->h245_address; - tmp_strinfo.h245port = pi->h245_port; - strinfo = g_malloc(sizeof(h323_conversations_info_t)); - *strinfo = tmp_strinfo; /* memberwise copy of struct */ - tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo); - - } - /* ok, there is an entry, but is it also an entry for h.245 address. - * h.245 address can be provided in connect message, but entry for this conversation - * already exists at this point */ - else if (pi->is_h245) { - strinfo->is_h245 = pi->is_h245; - strinfo->h245address = pi->h245_address; - strinfo->h245port = pi->h245_port; - } - - /* we check the faststart again in the connect message, if there is no - * faststart field in connect message, we asume, there is no faststart */ - if ((pi->cs_type == H225_CONNECT) && (pi->is_faststart == 0)) - strinfo->faststart = 0; - - /* in the list or not in the list, we want the status */ - /* we have four states: CALL SETUP, IN_CALL, COMPLETED, REJECTED - * CALL_SETUP: if the setup, call proceding, alerting, - * IN_CALL: connect - * COMPLETED: release complete after connect - * REJECTED: release complete without connect - */ - switch (pi->cs_type) { - - case H225_SETUP: - strinfo->call_state = CALL_SETUP; - ++(tapinfo->setup_packets); - break; - case H225_CALL_PROCEDING: - strinfo->call_state = CALL_SETUP; - break; - case H225_ALERTING: - strinfo->call_state = CALL_SETUP; - break; - case H225_CONNECT: - strinfo->call_state = IN_CALL; - break; - case H225_RELEASE_COMPLET: - if (strinfo->call_state == IN_CALL) { - strinfo->call_state = COMPLETED; - ++(tapinfo->completed_calls); - } - else if (strinfo->call_state == CALL_SETUP) { - strinfo->call_state = REJECTED; - ++(tapinfo->rejected_calls); - } - else if (strinfo->call_state == COMPLETED) - strinfo->call_state = COMPLETED; - else if (strinfo->call_state == REJECTED) - strinfo->call_state = REJECTED; - else - strinfo->call_state = UNKNOWN; - case H225_OTHER: - ; - } - - /* increment the packets counter for this conversations */ - ++(strinfo->npackets); - - /* increment the packets counter of all conversationss */ - ++(tapinfo->npackets); - - return 1; /* refresh output */ -} - -/****************************************************************************/ -/* scan for h323 conversationss */ -void h323conversations_scan(void) -{ - gboolean was_h225_registered = the_tapinfo_struct.is_h225_registered; - gboolean was_h245_registered = the_tapinfo_struct.is_h245_registered; - - if (!the_tapinfo_struct.is_h225_registered) - register_tap_listener_h225_conversations(); - if (!the_tapinfo_struct.is_h245_registered) - register_tap_listener_h245_conversations(); - - retap_packets(&cfile); - - if (!was_h225_registered) - remove_tap_listener_h225_conversations(); - if (!was_h245_registered) - remove_tap_listener_h245_conversations(); -} - - -/****************************************************************************/ -const h323conversations_tapinfo_t* h323conversations_get_info(void) -{ - return &the_tapinfo_struct; -} - - -/****************************************************************************/ -/* TAP INTERFACE */ -/****************************************************************************/ - -/****************************************************************************/ -static void -h225conversations_init_tap(char *dummy _U_) -{ - /* XXX: never called? */ -} - - -/* XXX just copied from gtk/rpc_stat.c */ -void protect_thread_critical_region(void); -void unprotect_thread_critical_region(void); - -/****************************************************************************/ -void -remove_tap_listener_h225_conversations(void) -{ - if (the_tapinfo_struct.is_h225_registered) { - protect_thread_critical_region(); - remove_tap_listener(&the_tapinfo_struct); - unprotect_thread_critical_region(); - - the_tapinfo_struct.is_h225_registered = FALSE; - } -} - - -/****************************************************************************/ -void -register_tap_listener_h225_conversations(void) -{ - GString *error_string; - - if (!the_tapinfo_struct.is_h225_registered) { - register_ethereal_tap("h225", h225conversations_init_tap); - - error_string = register_tap_listener("h225", &the_tapinfo_struct, - NULL, - (void*)h225conversations_reset, (void*)h225conversations_packet, (void*)h225conversations_draw); - - if (error_string != NULL) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - error_string->str); - g_string_free(error_string, TRUE); - exit(1); - } - - the_tapinfo_struct.is_h225_registered = TRUE; - } -} - - - -/****************************************************************************/ -/* ***************************TAP for h245 **********************************/ -/****************************************************************************/ - -/****************************************************************************/ -/* redraw the output */ -void h245conversations_draw(h323conversations_tapinfo_t *tapinfo _U_) -{ - h323conversations_dlg_update(the_tapinfo_struct.strinfo_list); - return; -} - -/****************************************************************************/ -/* whenever a H245 packet is seen by the tap listener */ -int h245conversations_packet(h323conversations_tapinfo_t *tapinfo _U_, packet_info *pinfo, epan_dissect_t *edt _U_, void *h245info _U_) -{ - GList* list; - struct _h323_conversations_info* a; - guint32 src, dst; - guint16 srcp, dstp; - - /* check wether this packet is a part of any H323 conversation in the list*/ - list = g_list_first(tapinfo->strinfo_list); - while (list) - { - a = (h323_conversations_info_t*)(list->data); - g_memmove(&src, pinfo->src.data, 4); - g_memmove(&dst, pinfo->dst.data, 4); - //src = *(pinfo->src.data); - //dst = *(pinfo->dst.data); - srcp = pinfo->srcport; - dstp = pinfo->destport; - if ( ((a->h245address == src) && (a->h245port == srcp) ) || - ( (a->h245address == dst) && (a->h245port == dstp)) ) { - /* in the list? increment packet number */ - ++(a->h245packets); - break; - } - list = g_list_next(list); - } - - return 1; /* refresh output */ -} - -/****************************************************************************/ -static void -h245conversations_init_tap(char *dummy _U_) -{ - /* XXX: never called? */ -} - -/****************************************************************************/ -void -remove_tap_listener_h245_conversations(void) -{ - if (the_tapinfo_struct.is_h245_registered) { - protect_thread_critical_region(); - remove_tap_listener(&the_tapinfo_struct); - unprotect_thread_critical_region(); - - the_tapinfo_struct.is_h245_registered = FALSE; - } -} - - -/****************************************************************************/ -void -register_tap_listener_h245_conversations(void) -{ - GString *error_string; - if (!the_tapinfo_struct.is_h245_registered) { - register_ethereal_tap("h245", h245conversations_init_tap); - - error_string = register_tap_listener("h245", &the_tapinfo_struct, - NULL, - (void*)h245conversations_reset, (void*)h245conversations_packet, (void*)h245conversations_draw); - - if (error_string != NULL) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - error_string->str); - g_string_free(error_string, TRUE); - exit(1); - } - - the_tapinfo_struct.is_h245_registered = TRUE; - } -} - - -void h245conversations_reset(h323conversations_tapinfo_t *tapinfo _U_) -{ - return; -} - +/* h323_conversations.c + * H323 conversations summary addition for ethereal + * + * Copyright 2004, Iskratel, Ltd, Kranj + * By Miha Jemec + * + * based on rtp_stream.c + * Copyright 2003, Alcatel Business Systems + * By Lars Ruoff + * + * Ethereal - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "h323_conversations.h" +#include "h323_conversations_dlg.h" + +#include "globals.h" + +#include +#include +#include + +#include "alert_box.h" +#include "simple_dialog.h" + +#ifdef HAVE_FCNTL_H +#include +#endif + +#ifdef HAVE_SYS_TYPES_H +# include +#endif + +#include + +/****************************************************************************/ +/* the one and only global h323conversations_tapinfo_t structure */ +static h323conversations_tapinfo_t the_tapinfo_struct = + {0, NULL, 0, NULL, 0, 0, 0, 0}; + +/****************************************************************************/ +/* GCompareFunc style comparison function for _h323_conversations_info */ +gint h323_conversations_info_cmp(gconstpointer aa, gconstpointer bb) +{ + const struct _h323_conversations_info* a = aa; + const struct _h323_conversations_info* b = bb; + + if (a==b) + return 0; + if (a==NULL || b==NULL) + return 1; + if ((a->src_addr == b->src_addr) + && (a->src_port == b->src_port) + && (a->dest_addr == b->dest_addr) + && (a->dest_port == b->dest_port) + ) + return 0; + else if ((a->src_addr == b->dest_addr) + && (a->src_port == b->dest_port) + && (a->dest_addr == b->src_addr) + && (a->dest_port == b->src_port) + ) + return 0; + else + return 1; +} + + +/****************************************************************************/ +/* when there is a [re]reading of packet's */ +void h225conversations_reset(h323conversations_tapinfo_t *tapinfo) +{ + GList* list; + + /* free the data items first */ + list = g_list_first(tapinfo->strinfo_list); + while (list) + { + g_free(list->data); + list = g_list_next(list); + } + g_list_free(tapinfo->strinfo_list); + tapinfo->strinfo_list = NULL; + tapinfo->nconversationss = 0; + tapinfo->npackets = 0; + tapinfo->setup_packets = 0; + tapinfo->completed_calls = 0; + tapinfo->rejected_calls = 0; + + ++(tapinfo->launch_count); + + return; +} + +/****************************************************************************/ +/* redraw the output */ +void h225conversations_draw(h323conversations_tapinfo_t *tapinfo _U_) +{ +/* XXX: see h323conversations_on_update in h323_conversationss_dlg.c for comments + gtk_signal_emit_by_name(top_level, "signal_h225conversations_update"); +*/ + h323conversations_dlg_update(the_tapinfo_struct.strinfo_list); + return; +} + + + +/****************************************************************************/ +/* whenever a H225 packet is seen by the tap listener */ +int h225conversations_packet(h323conversations_tapinfo_t *tapinfo _U_, packet_info *pinfo, epan_dissect_t *edt _U_, void *h225info) +{ + h323_conversations_info_t tmp_strinfo; + h323_conversations_info_t *strinfo = NULL; + GList* list; + + h225_packet_info *pi = h225info; + + /* TODO: evaluate RAS Messages. Just ignore them for now*/ + if(pi->msg_type==H225_RAS) + return 0; + + /* gather infos on the conversations this packet is part of */ + g_memmove(&(tmp_strinfo.src_addr), pinfo->src.data, 4); + tmp_strinfo.src_port = pinfo->srcport; + g_memmove(&(tmp_strinfo.dest_addr), pinfo->dst.data, 4); + tmp_strinfo.dest_port = pinfo->destport; + + /* check wether we already have a conversations with these parameters in the list */ + list = g_list_first(tapinfo->strinfo_list); + while (list) + { + if (h323_conversations_info_cmp(&tmp_strinfo, (h323_conversations_info_t*)(list->data))==0) + { + strinfo = (h323_conversations_info_t*)(list->data); /*found!*/ + break; + } + list = g_list_next(list); + } + + /* not in the list? then create a new entry */ + if (!strinfo) { + tmp_strinfo.call_state = UNKNOWN; + tmp_strinfo.npackets = 0; + tmp_strinfo.h245packets = 0; + tmp_strinfo.first_frame_num = pinfo->fd->num; + tmp_strinfo.faststart = pi->is_faststart; + tmp_strinfo.is_h245 = pi->is_h245; + tmp_strinfo.h245address = pi->h245_address; + tmp_strinfo.h245port = pi->h245_port; + strinfo = g_malloc(sizeof(h323_conversations_info_t)); + *strinfo = tmp_strinfo; /* memberwise copy of struct */ + tapinfo->strinfo_list = g_list_append(tapinfo->strinfo_list, strinfo); + + } + /* ok, there is an entry, but is it also an entry for h.245 address. + * h.245 address can be provided in connect message, but entry for this conversation + * already exists at this point */ + else if (pi->is_h245) { + strinfo->is_h245 = pi->is_h245; + strinfo->h245address = pi->h245_address; + strinfo->h245port = pi->h245_port; + } + + /* we check the faststart again in the connect message, if there is no + * faststart field in connect message, we asume, there is no faststart */ + if ((pi->cs_type == H225_CONNECT) && (pi->is_faststart == 0)) + strinfo->faststart = 0; + + /* in the list or not in the list, we want the status */ + /* we have four states: CALL SETUP, IN_CALL, COMPLETED, REJECTED + * CALL_SETUP: if the setup, call proceding, alerting, + * IN_CALL: connect + * COMPLETED: release complete after connect + * REJECTED: release complete without connect + */ + switch (pi->cs_type) { + + case H225_SETUP: + strinfo->call_state = CALL_SETUP; + ++(tapinfo->setup_packets); + break; + case H225_CALL_PROCEDING: + strinfo->call_state = CALL_SETUP; + break; + case H225_ALERTING: + strinfo->call_state = CALL_SETUP; + break; + case H225_CONNECT: + strinfo->call_state = IN_CALL; + break; + case H225_RELEASE_COMPLET: + if (strinfo->call_state == IN_CALL) { + strinfo->call_state = COMPLETED; + ++(tapinfo->completed_calls); + } + else if (strinfo->call_state == CALL_SETUP) { + strinfo->call_state = REJECTED; + ++(tapinfo->rejected_calls); + } + else if (strinfo->call_state == COMPLETED) + strinfo->call_state = COMPLETED; + else if (strinfo->call_state == REJECTED) + strinfo->call_state = REJECTED; + else + strinfo->call_state = UNKNOWN; + case H225_OTHER: + ; + } + + /* increment the packets counter for this conversations */ + ++(strinfo->npackets); + + /* increment the packets counter of all conversationss */ + ++(tapinfo->npackets); + + return 1; /* refresh output */ +} + + +/****************************************************************************/ +const h323conversations_tapinfo_t* h323conversations_get_info(void) +{ + return &the_tapinfo_struct; +} + + +/****************************************************************************/ +/* TAP INTERFACE */ +/****************************************************************************/ +static gboolean have_h225_tap_listener=FALSE; +/****************************************************************************/ +void +h225conversations_init_tap(void) +{ + GString *error_string; + + h225conversations_reset(&the_tapinfo_struct); + + if(have_h225_tap_listener==FALSE) + { + /* don't register tap listener, if we have it already */ + error_string = register_tap_listener("h225", &the_tapinfo_struct, NULL, + (void*)h225conversations_reset, (void*)h225conversations_packet, (void*)h225conversations_draw); + + if (error_string != NULL) { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, + error_string->str); + g_string_free(error_string, TRUE); + exit(1); + } + have_h225_tap_listener=TRUE; + } +} + + +/* XXX just copied from gtk/rpc_stat.c */ +void protect_thread_critical_region(void); +void unprotect_thread_critical_region(void); + +/****************************************************************************/ +void +remove_tap_listener_h225_conversations(void) +{ + protect_thread_critical_region(); + remove_tap_listener(&the_tapinfo_struct); + unprotect_thread_critical_region(); + + have_h225_tap_listener=FALSE; +} + + +/****************************************************************************/ +/* ***************************TAP for h245 **********************************/ +/****************************************************************************/ + +/****************************************************************************/ +/* redraw the output */ +void h245conversations_draw(h323conversations_tapinfo_t *tapinfo _U_) +{ + h323conversations_dlg_update(the_tapinfo_struct.strinfo_list); + return; +} + +/****************************************************************************/ +/* whenever a H245 packet is seen by the tap listener */ +int h245conversations_packet(h323conversations_tapinfo_t *tapinfo _U_, packet_info *pinfo, epan_dissect_t *edt _U_, void *h245info _U_) +{ + GList* list; + struct _h323_conversations_info* a; + guint32 src, dst; + guint16 srcp, dstp; + + /* check wether this packet is a part of any H323 conversation in the list*/ + list = g_list_first(tapinfo->strinfo_list); + while (list) + { + a = (h323_conversations_info_t*)(list->data); + g_memmove(&src, pinfo->src.data, 4); + g_memmove(&dst, pinfo->dst.data, 4); + //src = *(pinfo->src.data); + //dst = *(pinfo->dst.data); + srcp = pinfo->srcport; + dstp = pinfo->destport; + if ( ((a->h245address == src) && (a->h245port == srcp) ) || + ( (a->h245address == dst) && (a->h245port == dstp)) ) { + /* in the list? increment packet number */ + ++(a->h245packets); + break; + } + list = g_list_next(list); + } + + return 1; /* refresh output */ +} + +/****************************************************************************/ +static gboolean have_h245_tap_listener=FALSE; + +void +h245conversations_init_tap(void) +{ + GString *error_string; + + if(have_h245_tap_listener==FALSE) + { + /* don't register tap listener, if we have it already */ + error_string = register_tap_listener("h245", &the_tapinfo_struct, + NULL, + (void*)h245conversations_reset, (void*)h245conversations_packet, (void*)h245conversations_draw); + + if (error_string != NULL) { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, + error_string->str); + g_string_free(error_string, TRUE); + exit(1); + } + have_h245_tap_listener=TRUE; + } +} + +/****************************************************************************/ +void +remove_tap_listener_h245_conversations(void) +{ + protect_thread_critical_region(); + remove_tap_listener(&the_tapinfo_struct); + unprotect_thread_critical_region(); + + have_h245_tap_listener=FALSE; +} + + +/****************************************************************************/ + +void h245conversations_reset(h323conversations_tapinfo_t *tapinfo _U_) +{ + return; +} + diff --git a/gtk/h323_conversations.h b/gtk/h323_conversations.h index f280d450db..783832a3c9 100644 --- a/gtk/h323_conversations.h +++ b/gtk/h323_conversations.h @@ -1,128 +1,120 @@ -/* h323_conversations.h - * H323 conversations summary addition for ethereal - * - * Copyright 2004, Iskratel, Ltd, Kranj - * By Miha Jemec - * - * based on rtp_stream.h - * Copyright 2003, Alcatel Business Systems - * By Lars Ruoff - * - * Ethereal - Network traffic analyzer - * By Gerald Combs - * Copyright 1998 Gerald Combs - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef H323_STREAM_H_INCLUDED -#define H323_STREAM_H_INCLUDED - -#include -#include - -/****************************************************************************/ -/* defines h323 state */ -typedef enum _h323_call_state { - CALL_SETUP, - IN_CALL, - COMPLETED, - REJECTED, - UNKNOWN -} h323_call_state; - -/* defines an h323 conversation */ -typedef struct _h323_conversations_info { - h323_call_state call_state; - guint32 src_addr; - guint16 src_port; - guint32 dest_addr; - guint16 dest_port; - guint8 pt; - guint32 npackets; - gboolean faststart; - /* if there are also h245 messages */ - gboolean is_h245; - guint32 h245packets; - guint32 h245address; - guint16 h245port; - - guint32 first_frame_num; /* frame number of first frame */ - -} h323_conversations_info_t; - -/* structure that holds the information about all detected conversationss */ -/* struct holding all information of the tap */ -typedef struct _h323conversations_tapinfo { - int nconversationss; /* number of conversationss in the list */ - GList* strinfo_list; /* list with all conversationss */ - int npackets; /* total number of h323 packets of all conversationss */ - h323_conversations_info_t* filter_conversations_fwd; /* used as filter in some tap modes */ - guint32 launch_count; /* number of times the tap has been run */ - gboolean is_h225_registered; /* if the tap listener is currently registered or not */ - gboolean is_h245_registered; /* if the tap listener is currently registered or not */ - int setup_packets; - int completed_calls; - int rejected_calls; -} h323conversations_tapinfo_t; - - -/****************************************************************************/ -/* INTERFACE */ - -/* -* Registers the h323_conversationss tap listener (if not already done). -* From that point on, the H323 conversationss list will be updated with every redissection. -* This function is also the entry point for the initialization routine of the tap system. -* So whenever h323_conversations.c is added to the list of ETHEREAL_TAP_SRCs, the tap will be registered on startup. -* If not, it will be registered on demand by the h323_conversationss and h323_analysis functions that need it. -*/ -void register_tap_listener_h225_conversations(void); -void register_tap_listener_h245_conversations(void); - -/* -* Removes the h323_conversationss tap listener (if not already done) -* From that point on, the H323 conversationss list won't be updated any more. -*/ -void remove_tap_listener_h225_conversations(void); -void remove_tap_listener_h245_conversations(void); - -/* -* Retrieves a constant reference to the unique info structure of the h323_conversationss tap listener. -* The user should not modify the data pointed to. -*/ -const h323conversations_tapinfo_t* h323conversations_get_info(void); - -/* -* Cleans up memory of h323 conversationss tap. -*/ -void h225conversations_reset(h323conversations_tapinfo_t *tapinfo); -void h245conversations_reset(h323conversations_tapinfo_t *tapinfo); - -/* -* Scans all packets for H225 conversationss and updates the H225 conversationss list. -* (redissects all packets) -*/ -void h323conversations_scan(void); - -/* -* Marks all packets belonging to conversations. -* (can be NULL) -* (redissects all packets) -*/ -void h323conversations_mark(h323_conversations_info_t* conversations_fwd); - - -#endif /*H323_STREAM_H_INCLUDED*/ +/* h323_conversations.h + * H323 conversations summary addition for ethereal + * + * Copyright 2004, Iskratel, Ltd, Kranj + * By Miha Jemec + * + * based on rtp_stream.h + * Copyright 2003, Alcatel Business Systems + * By Lars Ruoff + * + * Ethereal - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef H323_STREAM_H_INCLUDED +#define H323_STREAM_H_INCLUDED + +#include +#include + +/****************************************************************************/ +/* defines h323 state */ +typedef enum _h323_call_state { + CALL_SETUP, + IN_CALL, + COMPLETED, + REJECTED, + UNKNOWN +} h323_call_state; + +/* defines an h323 conversation */ +typedef struct _h323_conversations_info { + h323_call_state call_state; + guint32 src_addr; + guint16 src_port; + guint32 dest_addr; + guint16 dest_port; + guint8 pt; + guint32 npackets; + gboolean faststart; + /* if there are also h245 messages */ + gboolean is_h245; + guint32 h245packets; + guint32 h245address; + guint16 h245port; + + guint32 first_frame_num; /* frame number of first frame */ + +} h323_conversations_info_t; + +/* structure that holds the information about all detected conversationss */ +/* struct holding all information of the tap */ +typedef struct _h323conversations_tapinfo { + int nconversationss; /* number of conversationss in the list */ + GList* strinfo_list; /* list with all conversationss */ + int npackets; /* total number of h323 packets of all conversationss */ + h323_conversations_info_t* filter_conversations_fwd; /* used as filter in some tap modes */ + guint32 launch_count; /* number of times the tap has been run */ + int setup_packets; + int completed_calls; + int rejected_calls; +} h323conversations_tapinfo_t; + + +/****************************************************************************/ +/* INTERFACE */ + +/* +* Registers the h323_conversationss tap listener (if not already done). +* From that point on, the H323 conversationss list will be updated with every redissection. +* This function is also the entry point for the initialization routine of the tap system. +* So whenever h323_conversations.c is added to the list of ETHEREAL_TAP_SRCs, the tap will be registered on startup. +* If not, it will be registered on demand by the h323_conversationss and h323_analysis functions that need it. +*/ +void h225conversations_init_tap(void); +void h245conversations_init_tap(void); + +/* +* Removes the h323_conversationss tap listener (if not already done) +* From that point on, the H323 conversationss list won't be updated any more. +*/ +void remove_tap_listener_h225_conversations(void); +void remove_tap_listener_h245_conversations(void); + +/* +* Retrieves a constant reference to the unique info structure of the h323_conversationss tap listener. +* The user should not modify the data pointed to. +*/ +const h323conversations_tapinfo_t* h323conversations_get_info(void); + +/* +* Cleans up memory of h323 conversationss tap. +*/ +void h225conversations_reset(h323conversations_tapinfo_t *tapinfo); +void h245conversations_reset(h323conversations_tapinfo_t *tapinfo); + +/* +* Marks all packets belonging to conversations. +* (can be NULL) +* (redissects all packets) +*/ +void h323conversations_mark(h323_conversations_info_t* conversations_fwd); + + +#endif /*H323_STREAM_H_INCLUDED*/ diff --git a/gtk/h323_conversations_dlg.c b/gtk/h323_conversations_dlg.c index e6e0ffd492..22c62d9ca2 100644 --- a/gtk/h323_conversations_dlg.c +++ b/gtk/h323_conversations_dlg.c @@ -1,555 +1,567 @@ -/* h323_conversations_dlg.c - * H323 conversations summary addition for ethereal - * - * Copyright 2004, Iskratel, Ltd, Kranj - * By Miha Jemec - * - * based on rtp_stream_dlg.c - * Copyright 2003, Alcatel Business Systems - * By Lars Ruoff - * - * Ethereal - Network traffic analyzer - * By Gerald Combs - * Copyright 1998 Gerald Combs - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "h323_conversations_dlg.h" -#include "h323_conversations.h" -#include "h323_analysis.h" - -#include "globals.h" -#include "epan/filesystem.h" - -#include "tap_menu.h" -#include "dlg_utils.h" -#include "ui_util.h" -#include "compat_macros.h" -#include "gtkglobals.h" - -#include "image/clist_ascend.xpm" -#include "image/clist_descend.xpm" - -#include - - -typedef const guint8 * ip_addr_p; - -static const gchar FWD_LABEL_TEXT[] = "Select one conversation with left mouse button\n"; - -/****************************************************************************/ -/* pointer to the one and only dialog window */ -static GtkWidget *h323_conversations_dlg = NULL; - -static GtkWidget *clist = NULL; -static GtkWidget *top_label = NULL; -static GtkWidget *status_label = NULL; -static GtkWidget *label_fwd = NULL; - -static h323_conversations_info_t* selected_conversations_fwd = NULL; /* current selection */ -static GList *last_list = NULL; - -static guint32 conversationss_nb = 0; /* number of displayed conversationss */ - -/****************************************************************************/ -/* append a line to clist */ -static void add_to_clist(h323_conversations_info_t* strinfo) -{ - gchar label_text[256]; - gint added_row; - gchar *data[8]; - gchar field[8][30]; - - data[0]=&field[0][0]; - data[1]=&field[1][0]; - data[2]=&field[2][0]; - data[3]=&field[3][0]; - data[4]=&field[4][0]; - data[5]=&field[5][0]; - data[6]=&field[6][0]; - data[7]=&field[7][0]; - - g_snprintf(field[0], 20, "%s", ip_to_str((const guint8*)&(strinfo->src_addr))); - g_snprintf(field[1], 20, "%u", strinfo->src_port); - g_snprintf(field[2], 20, "%s", ip_to_str((const guint8*)&(strinfo->dest_addr))); - g_snprintf(field[3], 20, "%u", strinfo->dest_port); - g_snprintf(field[4], 20, "%s", strinfo->faststart? "TRUE":"FALSE"); - g_snprintf(field[5], 20, "%u", strinfo->npackets); - g_snprintf(field[6], 20, "%u", strinfo->h245packets); - - switch (strinfo->call_state) { - - case (CALL_SETUP): - g_snprintf(field[7], 20, "%s", "CALL SETUP"); - break; - case (IN_CALL): - g_snprintf(field[7], 20, "%s", "IN CALL"); - break; - case (COMPLETED): - g_snprintf(field[7], 20, "%s", "COMPLETED"); - break; - case (REJECTED): - g_snprintf(field[7], 20, "%s", "REJECTED"); - break; - case (UNKNOWN): - g_snprintf(field[7], 20, "%s", "UNKNOWN"); - } - - added_row = gtk_clist_append(GTK_CLIST(clist), data); - - /* set data pointer of last row to point to user data for that row */ - gtk_clist_set_row_data(GTK_CLIST(clist), added_row, strinfo); - - /* Update the top label with the number of detected conversationss */ - sprintf(label_text, - "Detected %d H323 Conversations. Choose one for analysis", - ++conversationss_nb); - gtk_label_set(GTK_LABEL(top_label), label_text); - - /* Update the status label with the number of total messages */ - sprintf(label_text, - "Total Setup packets: %d Completed calls: %d Rejected calls: %d\n", - h323conversations_get_info()->setup_packets, - h323conversations_get_info()->completed_calls, - h323conversations_get_info()->rejected_calls); - gtk_label_set(GTK_LABEL(status_label), label_text); -} - - -/****************************************************************************/ -/* CALLBACKS */ -/****************************************************************************/ -static void -h323conversations_on_destroy (GtkObject *object _U_, - gpointer user_data _U_) -{ - /* Remove the conversations tap listener */ - remove_tap_listener_h225_conversations(); - remove_tap_listener_h245_conversations(); - - /* Clean up memory used by conversations tap */ - h225conversations_reset((h323conversations_tapinfo_t*) h323conversations_get_info()); - - /* Note that we no longer have a "H.323 Conversations" dialog box. */ - h323_conversations_dlg = NULL; -} - - -/****************************************************************************/ -static void -h323conversations_on_unselect (GtkButton *button _U_, - gpointer user_data _U_) -{ - selected_conversations_fwd = NULL; - gtk_clist_unselect_all(GTK_CLIST(clist)); - gtk_label_set_text(GTK_LABEL(label_fwd), FWD_LABEL_TEXT); -} - - -/****************************************************************************/ -static void -h323conversations_on_filter (GtkButton *button _U_, - gpointer user_data _U_) -{ - gchar *filter_string = NULL; - gchar *filter_string_fwd = NULL; - - if (selected_conversations_fwd==NULL) - return; - - /* if also address for h245 packets is known */ - else if (selected_conversations_fwd->is_h245) { - filter_string_fwd = g_strdup_printf( - "((ip.addr==%s && tcp.port==%u && ip.addr==%s && tcp.port==%u) and h225) or ((ip.addr==%s && tcp.port==%u) and h245)", - ip_to_str((const guint8*)&(selected_conversations_fwd->src_addr)), - selected_conversations_fwd->src_port, - ip_to_str((const guint8*)&(selected_conversations_fwd->dest_addr)), - selected_conversations_fwd->dest_port, - ip_to_str((const guint8*)&(selected_conversations_fwd->h245address)), - selected_conversations_fwd->h245port); - } - /* else filter only h225 packets */ - else { - filter_string_fwd = g_strdup_printf( - "(ip.addr==%s && tcp.port==%u && ip.addr==%s && tcp.port==%u) and h225", - ip_to_str((const guint8*)&(selected_conversations_fwd->src_addr)), - selected_conversations_fwd->src_port, - ip_to_str((const guint8*)&(selected_conversations_fwd->dest_addr)), - selected_conversations_fwd->dest_port); - } - - filter_string = filter_string_fwd; - - gtk_entry_set_text(GTK_ENTRY(main_display_filter_widget), filter_string); - g_free(filter_string); -/* - main_filter_packets(&cfile, filter_string, FALSE); - h323conversations_dlg_update(h323conversations_get_info()->strinfo_list); -*/ -} - - -/****************************************************************************/ -static void -h323conversations_on_analyse (GtkButton *button _U_, - gpointer user_data _U_) -{ - guint32 ip_src = 0; - guint16 port_src = 0; - guint32 ip_dst = 0; - guint16 port_dst = 0; - guint32 ip_src_h245 = 0; - guint16 port_src_h245 = 0; - - if (selected_conversations_fwd) { - ip_src = selected_conversations_fwd->src_addr; - port_src = selected_conversations_fwd->src_port; - ip_dst = selected_conversations_fwd->dest_addr; - port_dst = selected_conversations_fwd->dest_port; - ip_src_h245 = selected_conversations_fwd->h245address; - port_src_h245 = selected_conversations_fwd->h245port; - } - - h323_analysis( - ip_src, - port_src, - ip_dst, - port_dst, - ip_src_h245, - port_src_h245 - ); -} - - -/****************************************************************************/ -/* when the user selects a row in the conversations list */ -static void -h323conversations_on_select_row(GtkCList *clist, - gint row _U_, - gint column _U_, - GdkEventButton *event _U_, - gpointer user_data _U_) -{ - gchar label_text[80]; - - selected_conversations_fwd = gtk_clist_get_row_data(GTK_CLIST(clist), row); - g_snprintf(label_text, 80, "Conversation: %s:%u <---> %s:%u\n", - ip_to_str((ip_addr_p)&selected_conversations_fwd->src_addr), - selected_conversations_fwd->src_port, - ip_to_str((ip_addr_p)&selected_conversations_fwd->dest_addr), - selected_conversations_fwd->dest_port - ); - gtk_label_set_text(GTK_LABEL(label_fwd), label_text); - -/* - gtk_widget_set_sensitive(save_bt, TRUE); - gtk_widget_set_sensitive(filter_bt, TRUE); - gtk_widget_set_sensitive(mark_bt, TRUE); -*/ - /* TODO: activate other buttons when implemented */ -} - - -/****************************************************************************/ -#define NUM_COLS 8 - -typedef struct column_arrows { - GtkWidget *table; - GtkWidget *ascend_pm; - GtkWidget *descend_pm; -} column_arrows; - - -/****************************************************************************/ -static void -h323conversations_click_column_cb(GtkCList *clist, gint column, gpointer data) -{ - column_arrows *col_arrows = (column_arrows *) data; - int i; - - gtk_clist_freeze(clist); - - for (i=0; isort_column) { - if (clist->sort_type == GTK_SORT_ASCENDING) { - clist->sort_type = GTK_SORT_DESCENDING; - gtk_widget_show(col_arrows[column].descend_pm); - } else { - clist->sort_type = GTK_SORT_ASCENDING; - gtk_widget_show(col_arrows[column].ascend_pm); - } - } else { - clist->sort_type = GTK_SORT_ASCENDING; - gtk_widget_show(col_arrows[column].ascend_pm); - gtk_clist_set_sort_column(clist, column); - } - gtk_clist_thaw(clist); - - gtk_clist_sort(clist); -} - - -/****************************************************************************/ -static gint -h323conversations_sort_column(GtkCList *clist, gconstpointer ptr1, gconstpointer ptr2) -{ - char *text1 = NULL; - char *text2 = NULL; - int i1, i2; - - const GtkCListRow *row1 = (const GtkCListRow *) ptr1; - const GtkCListRow *row2 = (const GtkCListRow *) ptr2; - - text1 = GTK_CELL_TEXT (row1->cell[clist->sort_column])->text; - text2 = GTK_CELL_TEXT (row2->cell[clist->sort_column])->text; - - switch(clist->sort_column){ - case 0: - case 2: - case 5: - case 7: - return strcmp (text1, text2); - case 1: - case 3: - case 4: - case 6: - i1=atoi(text1); - i2=atoi(text2); - return i1-i2; - } - g_assert_not_reached(); - return 0; -} - - -/****************************************************************************/ -/* INTERFACE */ -/****************************************************************************/ - -static void h323conversations_dlg_create (void) -{ - GtkWidget *h323conversations_dlg_w; - GtkWidget *main_vb; - GtkWidget *scrolledwindow; - GtkWidget *hbuttonbox; - GtkWidget *bt_unselect; - GtkWidget *bt_filter; - GtkWidget *bt_analyse; - GtkWidget *bt_close; - - gchar *titles[8] = {"Side A IP addr", "Side B port", "Side B IP addr", "Side B port", "Faststart", "H225 pkts", "H245 pkts", "Status"}; - column_arrows *col_arrows; - GtkWidget *column_lb; - int i; - - h323conversations_dlg_w = dlg_window_new("Ethereal: H.323 Conversations"); - gtk_window_set_default_size(GTK_WINDOW(h323conversations_dlg_w), 700, 300); - - main_vb = gtk_vbox_new (FALSE, 0); - gtk_container_add(GTK_CONTAINER(h323conversations_dlg_w), main_vb); - gtk_container_set_border_width (GTK_CONTAINER (main_vb), 12); - - top_label = gtk_label_new ("Detected 0 H.323 Conversations. Choose one conversation for analysis"); - gtk_box_pack_start (GTK_BOX (main_vb), top_label, FALSE, FALSE, 8); - - scrolledwindow = scrolled_window_new (NULL, NULL); - gtk_box_pack_start (GTK_BOX (main_vb), scrolledwindow, TRUE, TRUE, 0); - - clist = gtk_clist_new (NUM_COLS); - gtk_container_add (GTK_CONTAINER (scrolledwindow), clist); - - gtk_clist_set_column_width (GTK_CLIST (clist), 0, 100); - gtk_clist_set_column_width (GTK_CLIST (clist), 1, 70); - gtk_clist_set_column_width (GTK_CLIST (clist), 2, 100); - gtk_clist_set_column_width (GTK_CLIST (clist), 3, 70); - gtk_clist_set_column_width (GTK_CLIST (clist), 4, 60); - gtk_clist_set_column_width (GTK_CLIST (clist), 5, 60); - gtk_clist_set_column_width (GTK_CLIST (clist), 6, 60); - gtk_clist_set_column_width (GTK_CLIST (clist), 7, 100); - - gtk_clist_set_column_justification(GTK_CLIST(clist), 0, GTK_JUSTIFY_CENTER); - gtk_clist_set_column_justification(GTK_CLIST(clist), 1, GTK_JUSTIFY_CENTER); - gtk_clist_set_column_justification(GTK_CLIST(clist), 2, GTK_JUSTIFY_CENTER); - gtk_clist_set_column_justification(GTK_CLIST(clist), 3, GTK_JUSTIFY_CENTER); - gtk_clist_set_column_justification(GTK_CLIST(clist), 4, GTK_JUSTIFY_CENTER); - gtk_clist_set_column_justification(GTK_CLIST(clist), 5, GTK_JUSTIFY_CENTER); - gtk_clist_set_column_justification(GTK_CLIST(clist), 6, GTK_JUSTIFY_CENTER); - gtk_clist_set_column_justification(GTK_CLIST(clist), 7, GTK_JUSTIFY_CENTER); - - gtk_clist_column_titles_show (GTK_CLIST (clist)); - - gtk_clist_set_compare_func(GTK_CLIST(clist), h323conversations_sort_column); - gtk_clist_set_sort_column(GTK_CLIST(clist), 0); - gtk_clist_set_sort_type(GTK_CLIST(clist), GTK_SORT_ASCENDING); - - gtk_widget_show(h323conversations_dlg_w); - - /* sort by column feature */ - col_arrows = (column_arrows *) g_malloc(sizeof(column_arrows) * NUM_COLS); - - for (i=0; isetup_packets, - h323conversations_get_info()->completed_calls, - h323conversations_get_info()->rejected_calls); - gtk_label_set(GTK_LABEL(status_label), label_text); - - list = g_list_first(list); - while (list) - { - add_to_clist((h323_conversations_info_t*)(list->data)); - list = g_list_next(list); - } - - h323conversations_on_unselect(NULL, NULL); - } - - last_list = list; -} - - -/****************************************************************************/ -/* update the contents of the dialog box clist */ -/* list: pointer to list of h323_conversations_info_t* */ -void h323conversations_dlg_show(GList *list) -{ - if (h323_conversations_dlg != NULL) { - /* There's already a dialog box; reactivate it. */ - reactivate_window(h323_conversations_dlg); - /* Another list since last call? */ - if (list != last_list) { - h323conversations_dlg_update(list); - } - } - else { - /* Create and show the dialog box */ - h323conversations_dlg_create(); - h323conversations_dlg_update(list); - } -} - - -/****************************************************************************/ -/* entry point when called via the GTK menu */ -void h323conversations_launch(GtkWidget *w _U_, gpointer data _U_) -{ - /* Register the tap listener */ - register_tap_listener_h225_conversations(); - register_tap_listener_h245_conversations(); - - /* Scan for H323 conversations conversationss (redissect all packets) */ - h323conversations_scan(); - - /* Show the dialog box with the list of conversationss */ - h323conversations_dlg_show(h323conversations_get_info()->strinfo_list); - - /* Tap listener will be removed and cleaned up in h323conversations_on_destroy */ -} - -/****************************************************************************/ -void -register_tap_listener_h323_conversations_dlg(void) -{ - register_tap_menu_item("H.323/Show All H323 Conversations...", REGISTER_TAP_GROUP_NONE, - h323conversations_launch, NULL, NULL, NULL); -} +/* h323_conversations_dlg.c + * H323 conversations summary addition for ethereal + * + * Copyright 2004, Iskratel, Ltd, Kranj + * By Miha Jemec + * + * based on rtp_stream_dlg.c + * Copyright 2003, Alcatel Business Systems + * By Lars Ruoff + * + * Ethereal - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "register.h" + +#include "h323_conversations_dlg.h" +#include "h323_conversations.h" +#include "h323_analysis.h" + +#include "globals.h" +#include "epan/filesystem.h" + +#include "tap_menu.h" +#include "dlg_utils.h" +#include "ui_util.h" +#include "compat_macros.h" +#include "gtkglobals.h" + +#include "image/clist_ascend.xpm" +#include "image/clist_descend.xpm" + +#include + + +typedef const guint8 * ip_addr_p; + +static const gchar FWD_LABEL_TEXT[] = "Select one conversation with left mouse button\n"; + +/****************************************************************************/ +/* pointer to the one and only dialog window */ +static GtkWidget *h323_conversations_dlg = NULL; + +static GtkWidget *clist = NULL; +static GtkWidget *top_label = NULL; +static GtkWidget *status_label = NULL; +static GtkWidget *label_fwd = NULL; + +static h323_conversations_info_t* selected_conversations_fwd = NULL; /* current selection */ +static GList *last_list = NULL; + +static guint32 conversationss_nb = 0; /* number of displayed conversationss */ + +/****************************************************************************/ +/* append a line to clist */ +static void add_to_clist(h323_conversations_info_t* strinfo) +{ + gchar label_text[256]; + gint added_row; + gchar *data[8]; + gchar field[8][30]; + + data[0]=&field[0][0]; + data[1]=&field[1][0]; + data[2]=&field[2][0]; + data[3]=&field[3][0]; + data[4]=&field[4][0]; + data[5]=&field[5][0]; + data[6]=&field[6][0]; + data[7]=&field[7][0]; + + g_snprintf(field[0], 20, "%s", ip_to_str((const guint8*)&(strinfo->src_addr))); + g_snprintf(field[1], 20, "%u", strinfo->src_port); + g_snprintf(field[2], 20, "%s", ip_to_str((const guint8*)&(strinfo->dest_addr))); + g_snprintf(field[3], 20, "%u", strinfo->dest_port); + g_snprintf(field[4], 20, "%s", strinfo->faststart? "TRUE":"FALSE"); + g_snprintf(field[5], 20, "%u", strinfo->npackets); + g_snprintf(field[6], 20, "%u", strinfo->h245packets); + + switch (strinfo->call_state) { + + case (CALL_SETUP): + g_snprintf(field[7], 20, "%s", "CALL SETUP"); + break; + case (IN_CALL): + g_snprintf(field[7], 20, "%s", "IN CALL"); + break; + case (COMPLETED): + g_snprintf(field[7], 20, "%s", "COMPLETED"); + break; + case (REJECTED): + g_snprintf(field[7], 20, "%s", "REJECTED"); + break; + case (UNKNOWN): + g_snprintf(field[7], 20, "%s", "UNKNOWN"); + } + + added_row = gtk_clist_append(GTK_CLIST(clist), data); + + /* set data pointer of last row to point to user data for that row */ + gtk_clist_set_row_data(GTK_CLIST(clist), added_row, strinfo); + + /* Update the top label with the number of detected conversationss */ + sprintf(label_text, + "Detected %d H323 Conversations. Choose one for analysis", + ++conversationss_nb); + gtk_label_set(GTK_LABEL(top_label), label_text); + + /* Update the status label with the number of total messages */ + sprintf(label_text, + "Total Setup packets: %d Completed calls: %d Rejected calls: %d\n", + h323conversations_get_info()->setup_packets, + h323conversations_get_info()->completed_calls, + h323conversations_get_info()->rejected_calls); + gtk_label_set(GTK_LABEL(status_label), label_text); +} + + +/****************************************************************************/ +/* CALLBACKS */ +/****************************************************************************/ +static void +h323conversations_on_destroy (GtkObject *object _U_, + gpointer user_data _U_) +{ + /* Remove the conversations tap listener */ + remove_tap_listener_h225_conversations(); + remove_tap_listener_h245_conversations(); + + /* Clean up memory used by conversations tap */ + h225conversations_reset((h323conversations_tapinfo_t*) h323conversations_get_info()); + + /* Note that we no longer have a "H.323 Conversations" dialog box. */ + h323_conversations_dlg = NULL; +} + + +/****************************************************************************/ +static void +h323conversations_on_unselect (GtkButton *button _U_, + gpointer user_data _U_) +{ + selected_conversations_fwd = NULL; + gtk_clist_unselect_all(GTK_CLIST(clist)); + gtk_label_set_text(GTK_LABEL(label_fwd), FWD_LABEL_TEXT); +} + + +/****************************************************************************/ +static void +h323conversations_on_filter (GtkButton *button _U_, + gpointer user_data _U_) +{ + gchar *filter_string = NULL; + gchar *filter_string_fwd = NULL; + + if (selected_conversations_fwd==NULL) + return; + + /* if also address for h245 packets is known */ + else if (selected_conversations_fwd->is_h245) { + filter_string_fwd = g_strdup_printf( + "((ip.addr==%s && tcp.port==%u && ip.addr==%s && tcp.port==%u) and h225) or ((ip.addr==%s && tcp.port==%u) and h245)", + ip_to_str((const guint8*)&(selected_conversations_fwd->src_addr)), + selected_conversations_fwd->src_port, + ip_to_str((const guint8*)&(selected_conversations_fwd->dest_addr)), + selected_conversations_fwd->dest_port, + ip_to_str((const guint8*)&(selected_conversations_fwd->h245address)), + selected_conversations_fwd->h245port); + } + /* else filter only h225 packets */ + else { + filter_string_fwd = g_strdup_printf( + "(ip.addr==%s && tcp.port==%u && ip.addr==%s && tcp.port==%u) and h225", + ip_to_str((const guint8*)&(selected_conversations_fwd->src_addr)), + selected_conversations_fwd->src_port, + ip_to_str((const guint8*)&(selected_conversations_fwd->dest_addr)), + selected_conversations_fwd->dest_port); + } + + filter_string = filter_string_fwd; + + gtk_entry_set_text(GTK_ENTRY(main_display_filter_widget), filter_string); + g_free(filter_string); +/* + main_filter_packets(&cfile, filter_string, FALSE); + h323conversations_dlg_update(h323conversations_get_info()->strinfo_list); +*/ +} + + +/****************************************************************************/ +static void +h323conversations_on_analyse (GtkButton *button _U_, + gpointer user_data _U_) +{ + guint32 ip_src = 0; + guint16 port_src = 0; + guint32 ip_dst = 0; + guint16 port_dst = 0; + guint32 ip_src_h245 = 0; + guint16 port_src_h245 = 0; + + if (selected_conversations_fwd) { + ip_src = selected_conversations_fwd->src_addr; + port_src = selected_conversations_fwd->src_port; + ip_dst = selected_conversations_fwd->dest_addr; + port_dst = selected_conversations_fwd->dest_port; + ip_src_h245 = selected_conversations_fwd->h245address; + port_src_h245 = selected_conversations_fwd->h245port; + } + + h323_analysis( + ip_src, + port_src, + ip_dst, + port_dst, + ip_src_h245, + port_src_h245 + ); +} + + +/****************************************************************************/ +/* when the user selects a row in the conversations list */ +static void +h323conversations_on_select_row(GtkCList *clist, + gint row _U_, + gint column _U_, + GdkEventButton *event _U_, + gpointer user_data _U_) +{ + gchar label_text[80]; + + selected_conversations_fwd = gtk_clist_get_row_data(GTK_CLIST(clist), row); + g_snprintf(label_text, 80, "Conversation: %s:%u <---> %s:%u\n", + ip_to_str((ip_addr_p)&selected_conversations_fwd->src_addr), + selected_conversations_fwd->src_port, + ip_to_str((ip_addr_p)&selected_conversations_fwd->dest_addr), + selected_conversations_fwd->dest_port + ); + gtk_label_set_text(GTK_LABEL(label_fwd), label_text); + +/* + gtk_widget_set_sensitive(save_bt, TRUE); + gtk_widget_set_sensitive(filter_bt, TRUE); + gtk_widget_set_sensitive(mark_bt, TRUE); +*/ + /* TODO: activate other buttons when implemented */ +} + + +/****************************************************************************/ +#define NUM_COLS 8 + +typedef struct column_arrows { + GtkWidget *table; + GtkWidget *ascend_pm; + GtkWidget *descend_pm; +} column_arrows; + + +/****************************************************************************/ +static void +h323conversations_click_column_cb(GtkCList *clist, gint column, gpointer data) +{ + column_arrows *col_arrows = (column_arrows *) data; + int i; + + gtk_clist_freeze(clist); + + for (i=0; isort_column) { + if (clist->sort_type == GTK_SORT_ASCENDING) { + clist->sort_type = GTK_SORT_DESCENDING; + gtk_widget_show(col_arrows[column].descend_pm); + } else { + clist->sort_type = GTK_SORT_ASCENDING; + gtk_widget_show(col_arrows[column].ascend_pm); + } + } else { + clist->sort_type = GTK_SORT_ASCENDING; + gtk_widget_show(col_arrows[column].ascend_pm); + gtk_clist_set_sort_column(clist, column); + } + gtk_clist_thaw(clist); + + gtk_clist_sort(clist); +} + + +/****************************************************************************/ +static gint +h323conversations_sort_column(GtkCList *clist, gconstpointer ptr1, gconstpointer ptr2) +{ + char *text1 = NULL; + char *text2 = NULL; + int i1, i2; + + const GtkCListRow *row1 = (const GtkCListRow *) ptr1; + const GtkCListRow *row2 = (const GtkCListRow *) ptr2; + + text1 = GTK_CELL_TEXT (row1->cell[clist->sort_column])->text; + text2 = GTK_CELL_TEXT (row2->cell[clist->sort_column])->text; + + switch(clist->sort_column){ + case 0: + case 2: + case 5: + case 7: + return strcmp (text1, text2); + case 1: + case 3: + case 4: + case 6: + i1=atoi(text1); + i2=atoi(text2); + return i1-i2; + } + g_assert_not_reached(); + return 0; +} + + +/****************************************************************************/ +/* INTERFACE */ +/****************************************************************************/ + +static void h323conversations_dlg_create (void) +{ + GtkWidget *h323conversations_dlg_w; + GtkWidget *main_vb; + GtkWidget *scrolledwindow; + GtkWidget *hbuttonbox; + GtkWidget *bt_unselect; + GtkWidget *bt_filter; + GtkWidget *bt_analyse; + GtkWidget *bt_close; + + gchar *titles[8] = {"Side A IP addr", "Side B port", "Side B IP addr", "Side B port", "Faststart", "H225 pkts", "H245 pkts", "Status"}; + column_arrows *col_arrows; + GtkWidget *column_lb; + int i; + + h323conversations_dlg_w = dlg_window_new("Ethereal: H.323 Conversations"); + gtk_window_set_default_size(GTK_WINDOW(h323conversations_dlg_w), 700, 300); + + main_vb = gtk_vbox_new (FALSE, 0); + gtk_container_add(GTK_CONTAINER(h323conversations_dlg_w), main_vb); + gtk_container_set_border_width (GTK_CONTAINER (main_vb), 12); + + top_label = gtk_label_new ("Detected 0 H.323 Conversations. Choose one conversation for analysis"); + gtk_box_pack_start (GTK_BOX (main_vb), top_label, FALSE, FALSE, 8); + + scrolledwindow = scrolled_window_new (NULL, NULL); + gtk_box_pack_start (GTK_BOX (main_vb), scrolledwindow, TRUE, TRUE, 0); + + clist = gtk_clist_new (NUM_COLS); + gtk_container_add (GTK_CONTAINER (scrolledwindow), clist); + + gtk_clist_set_column_width (GTK_CLIST (clist), 0, 100); + gtk_clist_set_column_width (GTK_CLIST (clist), 1, 70); + gtk_clist_set_column_width (GTK_CLIST (clist), 2, 100); + gtk_clist_set_column_width (GTK_CLIST (clist), 3, 70); + gtk_clist_set_column_width (GTK_CLIST (clist), 4, 60); + gtk_clist_set_column_width (GTK_CLIST (clist), 5, 60); + gtk_clist_set_column_width (GTK_CLIST (clist), 6, 60); + gtk_clist_set_column_width (GTK_CLIST (clist), 7, 100); + + gtk_clist_set_column_justification(GTK_CLIST(clist), 0, GTK_JUSTIFY_CENTER); + gtk_clist_set_column_justification(GTK_CLIST(clist), 1, GTK_JUSTIFY_CENTER); + gtk_clist_set_column_justification(GTK_CLIST(clist), 2, GTK_JUSTIFY_CENTER); + gtk_clist_set_column_justification(GTK_CLIST(clist), 3, GTK_JUSTIFY_CENTER); + gtk_clist_set_column_justification(GTK_CLIST(clist), 4, GTK_JUSTIFY_CENTER); + gtk_clist_set_column_justification(GTK_CLIST(clist), 5, GTK_JUSTIFY_CENTER); + gtk_clist_set_column_justification(GTK_CLIST(clist), 6, GTK_JUSTIFY_CENTER); + gtk_clist_set_column_justification(GTK_CLIST(clist), 7, GTK_JUSTIFY_CENTER); + + gtk_clist_column_titles_show (GTK_CLIST (clist)); + + gtk_clist_set_compare_func(GTK_CLIST(clist), h323conversations_sort_column); + gtk_clist_set_sort_column(GTK_CLIST(clist), 0); + gtk_clist_set_sort_type(GTK_CLIST(clist), GTK_SORT_ASCENDING); + + gtk_widget_show(h323conversations_dlg_w); + + /* sort by column feature */ + col_arrows = (column_arrows *) g_malloc(sizeof(column_arrows) * NUM_COLS); + + for (i=0; isetup_packets, + h323conversations_get_info()->completed_calls, + h323conversations_get_info()->rejected_calls); + gtk_label_set(GTK_LABEL(status_label), label_text); + + list = g_list_first(list); + while (list) + { + add_to_clist((h323_conversations_info_t*)(list->data)); + list = g_list_next(list); + } + + h323conversations_on_unselect(NULL, NULL); + } + + last_list = list; +} + + +/****************************************************************************/ +/* update the contents of the dialog box clist */ +/* list: pointer to list of h323_conversations_info_t* */ +void h323conversations_dlg_show(GList *list) +{ + if (h323_conversations_dlg != NULL) { + /* There's already a dialog box; reactivate it. */ + reactivate_window(h323_conversations_dlg); + /* Another list since last call? */ + if (list != last_list) { + h323conversations_dlg_update(list); + } + } + else { + /* Create and show the dialog box */ + h323conversations_dlg_create(); + h323conversations_dlg_update(list); + } +} + +/* init function for tap */ +static void +h323conversations_init_tap(char *dummy _U_) +{ + /* Register the tap listener */ + h225conversations_init_tap(); + h245conversations_init_tap(); + + /* Scan for H323 conversations conversationss (redissect all packets) */ + retap_packets(&cfile); + + /* Show the dialog box with the list of conversationss */ + h323conversations_dlg_show(h323conversations_get_info()->strinfo_list); + + /* Tap listener will be removed and cleaned up in h323conversations_on_destroy */ + +} + + +/****************************************************************************/ +/* entry point when called via the GTK menu */ +void h323conversations_launch(GtkWidget *w _U_, gpointer data _U_) +{ + h323conversations_init_tap(""); +} + +/****************************************************************************/ +void +register_tap_listener_h323_conversations_dlg(void) +{ + register_ethereal_tap("h323,conv",h323conversations_init_tap); + + register_tap_menu_item("H.323/Show All H323 Conversations...", REGISTER_TAP_GROUP_NONE, + h323conversations_launch, NULL, NULL, NULL); +} -- cgit v1.2.3