diff options
author | Jörg Mayer <jmayer@loplof.de> | 2012-01-15 21:59:11 +0000 |
---|---|---|
committer | Jörg Mayer <jmayer@loplof.de> | 2012-01-15 21:59:11 +0000 |
commit | be706c63801fb98d42fb743b27b16cc36273651e (patch) | |
tree | 62ed0b552191eb0753d26a3edcbab73459a15f7f /ui/gtk/sctp_chunk_stat.c | |
parent | 6d69ef093cd6868ab51f8b52477a510172033353 (diff) |
Move gtk to ui/gtk.
This looses the last checkin to gtk, will add this manually back.
svn path=/trunk/; revision=40518
Diffstat (limited to 'ui/gtk/sctp_chunk_stat.c')
-rw-r--r-- | ui/gtk/sctp_chunk_stat.c | 339 |
1 files changed, 339 insertions, 0 deletions
diff --git a/ui/gtk/sctp_chunk_stat.c b/ui/gtk/sctp_chunk_stat.c new file mode 100644 index 0000000000..6c7d86c7c0 --- /dev/null +++ b/ui/gtk/sctp_chunk_stat.c @@ -0,0 +1,339 @@ +/* sctp_chunk_stat.c + * SCTP chunk counter for Wireshark + * Copyright 2005 Oleg Terletsky <oleg.terletsky [AT] comverse.com> + * Copyright 2009 Varun Notibala <nbvarun [AT] gmail.com> + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * 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 + +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#include <string.h> + +#include <gtk/gtk.h> + +#include <epan/packet_info.h> +#include <epan/epan.h> +#include <epan/value_string.h> +#include <epan/tap.h> +#include <epan/dissectors/packet-sctp.h> + +#include "../simple_dialog.h" +#include "../file.h" +#include "../globals.h" +#include "../stat_menu.h" + +#include "ui/gtk/gui_stat_util.h" +#include "ui/gtk/dlg_utils.h" +#include "ui/gtk/tap_param_dlg.h" +#include "ui/gtk/gui_utils.h" +#include "ui/gtk/main.h" +#include "ui/gtk/sctp_stat.h" + + +static void sctpstat_init(const char *optarg, void *userdata); + +static tap_param sctp_stat_params[] = { + { PARAM_FILTER, "Filter", NULL } +}; + +static tap_param_dlg sctp_stat_dlg = { + "SCTP Statistics", + "sctp,stat", + sctpstat_init, + -1, + G_N_ELEMENTS(sctp_stat_params), + sctp_stat_params +}; + +typedef struct sctp_ep { + struct sctp_ep* next; + address src; + address dst; + guint16 sport; + guint16 dport; + guint32 chunk_count[256]; +} sctp_ep_t; + +/* used to keep track of the statistics for an entire program interface */ +typedef struct _sctp_stat_t { + GtkWidget *win; + GtkWidget *vbox; + char *filter; + GtkWidget *scrolled_window; + GtkTreeView *table; + guint32 number_of_packets; + sctp_ep_t* ep_list; +} sctpstat_t; + +typedef struct _sctp_info sctp_into_t; + +#define CHUNK_TYPE(x)(tvb_get_guint8((x), CHUNK_TYPE_OFFSET)) + +static void +sctpstat_reset(void *phs) +{ + sctpstat_t* sctp_stat = (sctpstat_t *)phs; + sctp_ep_t* list = (sctp_ep_t*)sctp_stat->ep_list; + sctp_ep_t* tmp = NULL; + guint16 chunk_type; + + if(!list) + return; + + for(tmp = list; tmp ; tmp=tmp->next) + for(chunk_type = 0; chunk_type < 256; chunk_type++) + tmp->chunk_count[chunk_type] = 0; + + sctp_stat->number_of_packets = 0; +} + +static sctp_ep_t* alloc_sctp_ep(struct _sctp_info *si) +{ + sctp_ep_t* ep; + guint16 chunk_type; + + if(!si) + return NULL; + + if (!(ep = g_malloc(sizeof(sctp_ep_t)))) + return NULL; + + COPY_ADDRESS(&ep->src,&si->ip_src); + COPY_ADDRESS(&ep->dst,&si->ip_dst); + ep->sport = si->sport; + ep->dport = si->dport; + ep->next = NULL; + for(chunk_type = 0; chunk_type < 256; chunk_type++) + ep->chunk_count[chunk_type] = 0; + return ep; +} + +static int +sctpstat_packet(void *phs, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *phi) +{ + + sctpstat_t *hs=(sctpstat_t *)phs; + sctp_ep_t *tmp = NULL, *te = NULL; + struct _sctp_info *si = (struct _sctp_info *) phi; + guint32 tvb_number; + + if (!hs) + return (0); + + hs->number_of_packets++; + if(!hs->ep_list) { + hs->ep_list = alloc_sctp_ep(si); + te = hs->ep_list; + } else { + for(tmp=hs->ep_list ; tmp ; tmp=tmp->next) { + if((!CMP_ADDRESS(&tmp->src,&si->ip_src)) && + (!CMP_ADDRESS(&tmp->dst,&si->ip_dst)) && + (tmp->sport == si->sport) && + (tmp->dport == si->dport)) { + te = tmp; + break; + } + } + if(!te) { + if ((te = alloc_sctp_ep(si))) { + te->next = hs->ep_list; + hs->ep_list = te; + } + } + } + + if(!te) + return (0); + + + if (si->number_of_tvbs > 0) { + for(tvb_number = 0; tvb_number < si->number_of_tvbs; tvb_number++) { + if (IS_SCTP_CHUNK_TYPE(CHUNK_TYPE(si->tvb[tvb_number]))) + (te->chunk_count[CHUNK_TYPE(si->tvb[tvb_number])])++; + else + (te->chunk_count[OTHER_CHUNKS_INDEX])++; + } + } + return (1); +} + + +static void +sctpstat_draw(void *phs) +{ + sctpstat_t *hs=(sctpstat_t *)phs; + sctp_ep_t* list = hs->ep_list, *tmp; + GtkListStore *store; + GtkTreeIter iter; + + /* Now print Message and Reason Counter Table */ + /* clear list before printing */ + /* XXX use an iter for new/modified ? */ + store = GTK_LIST_STORE(gtk_tree_view_get_model(hs->table)); + gtk_list_store_clear(store); + + for(tmp = list ; tmp ; tmp=tmp->next) { + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, + 0, ep_address_to_str(&tmp->src), + 1, tmp->sport, + 2, ep_address_to_str(&tmp->dst), + 3, tmp->dport, + 4, tmp->chunk_count[SCTP_DATA_CHUNK_ID], + 5, tmp->chunk_count[SCTP_SACK_CHUNK_ID], + 6, tmp->chunk_count[SCTP_HEARTBEAT_CHUNK_ID], + 7, tmp->chunk_count[SCTP_HEARTBEAT_ACK_CHUNK_ID], + 8, tmp->chunk_count[SCTP_INIT_CHUNK_ID], + 9, tmp->chunk_count[SCTP_INIT_ACK_CHUNK_ID], + 10, tmp->chunk_count[SCTP_COOKIE_ECHO_CHUNK_ID], + 11, tmp->chunk_count[SCTP_COOKIE_ACK_CHUNK_ID], + 12, tmp->chunk_count[SCTP_ABORT_CHUNK_ID], + 13, tmp->chunk_count[SCTP_ERROR_CHUNK_ID], + 14, tmp->chunk_count[SCTP_NR_SACK_CHUNK_ID], + 15, tmp->chunk_count[SCTP_ASCONF_ACK_CHUNK_ID], + 16, tmp->chunk_count[SCTP_PKTDROP_CHUNK_ID], + 17, tmp->chunk_count[SCTP_FORWARD_TSN_CHUNK_ID], + 18, tmp->chunk_count[SCTP_ASCONF_CHUNK_ID], + 19, tmp->chunk_count[OTHER_CHUNKS_INDEX], + -1 + ); + } +} + +static void +win_destroy_cb(GtkWindow *win _U_, gpointer data) +{ + sctpstat_t *hs=(sctpstat_t *)data; + + protect_thread_critical_region(); + remove_tap_listener(hs); + unprotect_thread_critical_region(); + + if(hs->filter){ + g_free(hs->filter); + hs->filter=NULL; + } + g_free(hs); +} + + +static const stat_column titles[]={ + {G_TYPE_STRING, LEFT, "Source IP" }, + {G_TYPE_UINT, RIGHT, "Source Port" }, + {G_TYPE_STRING, LEFT, "Dest IP" }, + {G_TYPE_UINT, RIGHT, "Dest Port" }, + {G_TYPE_UINT, RIGHT, "DATA" }, + {G_TYPE_UINT, RIGHT, "SACK" }, + {G_TYPE_UINT, RIGHT, "HBEAT" }, + {G_TYPE_UINT, RIGHT, "HBEAT-ACK" }, + {G_TYPE_UINT, RIGHT, "INIT" }, + {G_TYPE_UINT, RIGHT, "INIT-ACK" }, + {G_TYPE_UINT, RIGHT, "COOKIE" }, + {G_TYPE_UINT, RIGHT, "COOKIE-ACK" }, + {G_TYPE_UINT, RIGHT, "ABORT" }, + {G_TYPE_UINT, RIGHT, "ERROR" }, + {G_TYPE_UINT, RIGHT, "NR-SACK" }, + {G_TYPE_UINT, RIGHT, "ASCONF-ACK" }, + {G_TYPE_UINT, RIGHT, "PKTDROP" }, + {G_TYPE_UINT, RIGHT, "FORWARD-TSN" }, + {G_TYPE_UINT, RIGHT, "ASCONF" }, + {G_TYPE_UINT, RIGHT, "Others" } +}; + +static void +sctpstat_init(const char *optarg, void *userdata _U_) +{ + sctpstat_t *hs; + GString *error_string; + GtkWidget *bbox; + GtkWidget *close_bt; + + hs=g_malloc(sizeof(sctpstat_t)); + if(strncmp(optarg,"sctp,stat,",10) == 0){ + hs->filter=g_strdup(optarg+10); + } else { + hs->filter=NULL; + } + hs->ep_list = NULL; + hs->number_of_packets = 0; + sctpstat_reset(hs); + + hs->win = dlg_window_new("Wireshark: SCTP Chunk Statistics"); /* transient_for top_level */ + gtk_window_set_destroy_with_parent (GTK_WINDOW(hs->win), TRUE); + gtk_window_set_default_size(GTK_WINDOW(hs->win), 700, 250); + + hs->vbox=gtk_vbox_new(FALSE, 3); + gtk_container_set_border_width(GTK_CONTAINER(hs->vbox), 12); + + init_main_stat_window(hs->win, hs->vbox, "SCTP Chunk Counter", hs->filter); + + /* init a scrolled window*/ + hs->scrolled_window = scrolled_window_new(NULL, NULL); + + hs->table = create_stat_table(hs->scrolled_window, hs->vbox, 20, titles); + + error_string=register_tap_listener("sctp", hs, hs->filter, 0, + sctpstat_reset, + sctpstat_packet, + sctpstat_draw); + if(error_string){ + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str); + g_string_free(error_string, TRUE); + g_free(hs->filter); + g_free(hs); + return; + } + + /* Button row. */ + bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL); + gtk_box_pack_end(GTK_BOX(hs->vbox), bbox, FALSE, FALSE, 0); + + close_bt = g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE); + window_set_cancel_button(hs->win, close_bt, window_cancel_button_cb); + + g_signal_connect(hs->win, "delete_event", G_CALLBACK(window_delete_event_cb), NULL); + g_signal_connect(hs->win, "destroy", G_CALLBACK(win_destroy_cb), hs); + + gtk_widget_show_all(hs->win); + window_present(hs->win); + + cf_retap_packets(&cfile); +} + +void +register_tap_listener_sctpstat(void) +{ + register_dfilter_stat(&sctp_stat_dlg, "S_CTP/Chunk Counter", + REGISTER_STAT_GROUP_TELEPHONY); +} + +void sctp_chunk_counter_cb(GtkAction *action _U_, gpointer user_data _U_) +{ + tap_param_dlg_cb(action, &sctp_stat_dlg); +} + |