PageRenderTime 50ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/ui/gtk/ansi_a_stat.c

https://github.com/labx-technologies-llc/wireshark
C | 372 lines | 229 code | 76 blank | 67 comment | 11 complexity | 129ccda4dc25a2bc953519f6454904cc MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause
  1. /* ansi_a_stat.c
  2. *
  3. * Copyright 2003, Michael Lum <mlum [AT] telostech.com>
  4. * In association with Telos Technology Inc.
  5. *
  6. * MUCH code modified from service_response_time_table.c.
  7. *
  8. * $Id$
  9. *
  10. * Wireshark - Network traffic analyzer
  11. * By Gerald Combs <gerald@wireshark.org>
  12. * Copyright 1998 Gerald Combs
  13. *
  14. * This program is free software; you can redistribute it and/or
  15. * modify it under the terms of the GNU General Public License
  16. * as published by the Free Software Foundation; either version 2
  17. * of the License, or (at your option) any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program; if not, write to the Free Software
  26. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  27. */
  28. /*
  29. * This TAP provides statistics for the ANSI A-Interface:
  30. */
  31. #include "config.h"
  32. #include <gtk/gtk.h>
  33. #include <string.h>
  34. #include "epan/packet_info.h"
  35. #include "epan/epan.h"
  36. #include "epan/value_string.h"
  37. #include <epan/stat_cmd_args.h>
  38. #include <epan/tap.h>
  39. #include <epan/dissectors/packet-bssap.h>
  40. #include <epan/dissectors/packet-ansi_a.h>
  41. #include "../stat_menu.h"
  42. #include "ui/simple_dialog.h"
  43. #include "ui/gtk/gui_stat_menu.h"
  44. #include "ui/gtk/dlg_utils.h"
  45. #include "ui/gtk/filter_dlg.h"
  46. #include "ui/gtk/gui_utils.h"
  47. #include "ui/gtk/old-gtk-compat.h"
  48. enum
  49. {
  50. IEI_COLUMN,
  51. MSG_NAME_COLUMN,
  52. COUNT_COLUMN,
  53. N_COLUMN /* The number of columns */
  54. };
  55. typedef struct _ansi_a_stat_dlg_t {
  56. GtkWidget *win;
  57. GtkWidget *scrolled_win;
  58. GtkWidget *table;
  59. } ansi_a_stat_dlg_t;
  60. typedef struct _ansi_a_stat_t {
  61. int bsmap_message_type[0xff];
  62. int dtap_message_type[0xff];
  63. } ansi_a_stat_t;
  64. static ansi_a_stat_dlg_t dlg_bsmap;
  65. static ansi_a_stat_dlg_t dlg_dtap;
  66. static ansi_a_stat_t ansi_a_stat;
  67. static void
  68. ansi_a_stat_reset(
  69. void *tapdata)
  70. {
  71. ansi_a_stat_t *stat_p = (ansi_a_stat_t *)tapdata;
  72. memset(stat_p, 0, sizeof(ansi_a_stat_t));
  73. }
  74. static gboolean
  75. ansi_a_stat_packet(
  76. void *tapdata,
  77. packet_info *pinfo _U_,
  78. epan_dissect_t *edt _U_,
  79. const void *data)
  80. {
  81. ansi_a_stat_t *stat_p = (ansi_a_stat_t *)tapdata;
  82. const ansi_a_tap_rec_t *data_p = (ansi_a_tap_rec_t *)data;
  83. switch (data_p->pdu_type)
  84. {
  85. case BSSAP_PDU_TYPE_BSMAP:
  86. stat_p->bsmap_message_type[data_p->message_type]++;
  87. break;
  88. case BSSAP_PDU_TYPE_DTAP:
  89. stat_p->dtap_message_type[data_p->message_type]++;
  90. break;
  91. default:
  92. /*
  93. * unknown PDU type !!!
  94. */
  95. return(FALSE);
  96. }
  97. return(TRUE);
  98. }
  99. static void
  100. ansi_a_stat_draw(
  101. void *tapdata)
  102. {
  103. ansi_a_stat_t *stat_p = (ansi_a_stat_t *)tapdata;
  104. int i;
  105. GtkListStore *list_store;
  106. GtkTreeIter iter;
  107. if (dlg_bsmap.win && tapdata)
  108. {
  109. list_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (dlg_bsmap.table))); /* Get store */
  110. i = 0;
  111. while (ansi_a_bsmap_strings[i].strptr){
  112. /* Creates a new row at position. iter will be changed to point to this new row.
  113. * If position is larger than the number of rows on the list, then the new row will be appended to the list.
  114. * The row will be filled with the values given to this function.
  115. * :
  116. * should generally be preferred when inserting rows in a sorted list store.
  117. */
  118. gtk_list_store_insert_with_values( list_store , &iter, G_MAXINT,
  119. IEI_COLUMN, ansi_a_bsmap_strings[i].value,
  120. MSG_NAME_COLUMN, (char *)ansi_a_bsmap_strings[i].strptr,
  121. COUNT_COLUMN, stat_p->bsmap_message_type[ansi_a_bsmap_strings[i].value],
  122. -1);
  123. i++;
  124. }
  125. }
  126. if (dlg_dtap.win && tapdata){
  127. i = 0;
  128. list_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (dlg_dtap.table))); /* Get store */
  129. while (ansi_a_dtap_strings[i].strptr){
  130. /* Creates a new row at position. iter will be changed to point to this new row.
  131. * If position is larger than the number of rows on the list, then the new row will be appended to the list.
  132. * The row will be filled with the values given to this function.
  133. * :
  134. * should generally be preferred when inserting rows in a sorted list store.
  135. */
  136. gtk_list_store_insert_with_values( list_store , &iter, G_MAXINT,
  137. IEI_COLUMN, ansi_a_dtap_strings[i].value,
  138. MSG_NAME_COLUMN, (char *)ansi_a_dtap_strings[i].strptr,
  139. COUNT_COLUMN, stat_p->dtap_message_type[ansi_a_dtap_strings[i].value],
  140. -1);
  141. i++;
  142. }
  143. }
  144. }
  145. static void
  146. ansi_a_stat_gtk_win_destroy_cb(
  147. GtkWindow *win _U_,
  148. gpointer user_data )
  149. {
  150. memset((void *) user_data, 0, sizeof(ansi_a_stat_dlg_t));
  151. }
  152. /* Create list */
  153. static
  154. GtkWidget* create_list(void)
  155. {
  156. GtkListStore *list_store;
  157. GtkWidget *list;
  158. GtkTreeViewColumn *column;
  159. GtkCellRenderer *renderer;
  160. GtkTreeSortable *sortable;
  161. GtkTreeView *list_view;
  162. GtkTreeSelection *selection;
  163. /* Create the store */
  164. list_store = gtk_list_store_new(N_COLUMN, /* Total number of columns XXX */
  165. G_TYPE_UINT, /* IEI */
  166. G_TYPE_STRING, /* Message Name */
  167. G_TYPE_UINT); /* Count */
  168. /* Create a view */
  169. list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
  170. list_view = GTK_TREE_VIEW(list);
  171. sortable = GTK_TREE_SORTABLE(list_store);
  172. /* Speed up the list display */
  173. gtk_tree_view_set_fixed_height_mode(list_view, TRUE);
  174. /* Setup the sortable columns */
  175. gtk_tree_sortable_set_sort_column_id(sortable, IEI_COLUMN, GTK_SORT_ASCENDING);
  176. gtk_tree_view_set_headers_clickable(list_view, FALSE);
  177. /* The view now holds a reference. We can get rid of our own reference */
  178. g_object_unref (G_OBJECT (list_store));
  179. /*
  180. * Create the first column packet, associating the "text" attribute of the
  181. * cell_renderer to the first column of the model
  182. */
  183. renderer = gtk_cell_renderer_text_new ();
  184. column = gtk_tree_view_column_new_with_attributes ("IEI", renderer,
  185. "text", IEI_COLUMN,
  186. NULL);
  187. gtk_tree_view_column_set_cell_data_func(column, renderer, present_as_hex_func,
  188. GINT_TO_POINTER(IEI_COLUMN), NULL);
  189. gtk_tree_view_column_set_sort_column_id(column, IEI_COLUMN);
  190. gtk_tree_view_column_set_resizable(column, TRUE);
  191. gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
  192. gtk_tree_view_column_set_min_width(column, 50);
  193. /* Add the column to the view. */
  194. gtk_tree_view_append_column (list_view, column);
  195. /* Second column.. Message Name. */
  196. renderer = gtk_cell_renderer_text_new ();
  197. column = gtk_tree_view_column_new_with_attributes ("Message Name", renderer,
  198. "text", MSG_NAME_COLUMN,
  199. NULL);
  200. gtk_tree_view_column_set_sort_column_id(column, MSG_NAME_COLUMN);
  201. gtk_tree_view_column_set_resizable(column, TRUE);
  202. gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
  203. gtk_tree_view_column_set_min_width(column, 280);
  204. gtk_tree_view_append_column (list_view, column);
  205. /* Third column.. Count. */
  206. renderer = gtk_cell_renderer_text_new ();
  207. column = gtk_tree_view_column_new_with_attributes ("Count", renderer,
  208. "text", COUNT_COLUMN,
  209. NULL);
  210. gtk_tree_view_column_set_sort_column_id(column, COUNT_COLUMN);
  211. gtk_tree_view_column_set_resizable(column, TRUE);
  212. gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
  213. gtk_tree_view_column_set_min_width(column, 50);
  214. gtk_tree_view_append_column (list_view, column);
  215. /* Now enable the sorting of each column */
  216. gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(list_view), TRUE);
  217. gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(list_view), TRUE);
  218. /* Setup the selection handler */
  219. selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list));
  220. gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
  221. return list;
  222. }
  223. static void
  224. ansi_a_stat_gtk_win_create(
  225. ansi_a_stat_dlg_t *dlg_p,
  226. const char *title)
  227. {
  228. GtkWidget *vbox;
  229. GtkWidget *bt_close;
  230. GtkWidget *bbox;
  231. dlg_p->win= dlg_window_new(title); /* transient_for top_level */
  232. gtk_window_set_destroy_with_parent (GTK_WINDOW(dlg_p->win), TRUE);
  233. gtk_window_set_default_size(GTK_WINDOW(dlg_p->win), 480, 450);
  234. vbox=ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 3, FALSE);
  235. gtk_container_add(GTK_CONTAINER(dlg_p->win), vbox);
  236. gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
  237. dlg_p->scrolled_win = scrolled_window_new(NULL, NULL);
  238. gtk_box_pack_start(GTK_BOX(vbox), dlg_p->scrolled_win, TRUE, TRUE, 0);
  239. dlg_p->table = create_list();
  240. gtk_widget_show(dlg_p->table);
  241. gtk_container_add(GTK_CONTAINER(dlg_p->scrolled_win), dlg_p->table);
  242. /* Button row. */
  243. bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL);
  244. gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
  245. bt_close = (GtkWidget *)g_object_get_data(G_OBJECT(bbox), GTK_STOCK_CLOSE);
  246. window_set_cancel_button(dlg_p->win, bt_close, window_cancel_button_cb);
  247. g_signal_connect(dlg_p->win, "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
  248. g_signal_connect(dlg_p->win, "destroy", G_CALLBACK(ansi_a_stat_gtk_win_destroy_cb), dlg_p);
  249. gtk_widget_show_all(dlg_p->win);
  250. window_present(dlg_p->win);
  251. }
  252. void
  253. ansi_a_stat_gtk_bsmap_cb(GtkAction *action _U_, gpointer user_data _U_)
  254. {
  255. /*
  256. * if the window is already open, bring it to front
  257. */
  258. if (dlg_bsmap.win)
  259. {
  260. gdk_window_raise(gtk_widget_get_window(dlg_bsmap.win));
  261. return;
  262. }
  263. ansi_a_stat_gtk_win_create(&dlg_bsmap, "ANSI A-I/F BSMAP Statistics");
  264. ansi_a_stat_draw(&ansi_a_stat);
  265. }
  266. void
  267. ansi_a_stat_gtk_dtap_cb(GtkAction *action _U_, gpointer user_data _U_)
  268. {
  269. /*
  270. * if the window is already open, bring it to front
  271. */
  272. if (dlg_dtap.win)
  273. {
  274. gdk_window_raise(gtk_widget_get_window(dlg_dtap.win));
  275. return;
  276. }
  277. ansi_a_stat_gtk_win_create(&dlg_dtap, "ANSI A-I/F DTAP Statistics");
  278. ansi_a_stat_draw(&ansi_a_stat);
  279. }
  280. void
  281. register_tap_listener_gtkansi_a_stat(void)
  282. {
  283. GString *err_p;
  284. memset((void *) &ansi_a_stat, 0, sizeof(ansi_a_stat_t));
  285. err_p =
  286. register_tap_listener("ansi_a", &ansi_a_stat, NULL, 0,
  287. ansi_a_stat_reset,
  288. ansi_a_stat_packet,
  289. ansi_a_stat_draw);
  290. if (err_p != NULL)
  291. {
  292. simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_p->str);
  293. g_string_free(err_p, TRUE);
  294. exit(1);
  295. }
  296. }